From 94b7b261b0cb37ce713d5a3264da38e5ed7540c3 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 26 Jun 2020 11:34:11 -0600 Subject: [PATCH 001/206] update default value of PIO_REARR_COMM_MAX_PEND_REQ_COMP2IO --- cime_config/config_component.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 1ab4683ca..ecde8a538 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -1985,10 +1985,14 @@ integer - 0 + -2 run_pio env_run.xml - pio rearranger communication max pending requests (comp2io) : 0 implies that CIME internally calculates the value ( = max(64, 2 * PIO_NUMTASKS) ), -1 implies no bound on max pending requests + pio rearranger communication max pending requests (io2comp) : + -2 implies that CIME internally calculates the value ( = 64), + -1 implies no bound on max pending requests + 0 implies that MPI_ALLTOALL will be used + From b14b314a1b4dfd96b8c8680f17a39b68053f7d81 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Fri, 26 Jun 2020 16:01:42 -0600 Subject: [PATCH 002/206] add wind speed field for HAFS app --- mediator/esmFldsExchange_hafs_mod.F90 | 4 ++-- mediator/fd_cesm.yaml | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index 2c9622010..31f5a13db 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -770,8 +770,8 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! to ocn: temperature at the lowest model level from atm ! to ocn: specific humidity at the lowest model level from atm ! --------------------------------------------------------------------- - allocate(flds(5)) - flds = (/'Sa_pslv', 'Sa_u', 'Sa_v', 'Sa_tbot', 'Sa_shum'/) + allocate(flds(6)) + flds = (/'Sa_pslv', 'Sa_u', 'Sa_v', 'Sa_wspd', 'Sa_tbot', 'Sa_shum'/) do n = 1,size(flds) fldname = trim(flds(n)) diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 5c9199c47..687f1b9b8 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -359,6 +359,11 @@ canonical_units: m s-1 description: atmosphere export - bottom layer meridional wind # + - standard_name: Sa_wspd + alias: inst_wind_speed_height_lowest + canonical_units: m s-1 + description: atmosphere export - bottom layer wind speed + # - standard_name: Sa_z alias: inst_height_lowest canonical_units: m From 4e7d0490b85177491f7526594073c19d42c2978b Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Wed, 1 Jul 2020 15:15:09 -0600 Subject: [PATCH 003/206] change TFREEZE_SALTWATER_OPTION for MOM6 --- cime_config/config_component_cesm.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cime_config/config_component_cesm.xml b/cime_config/config_component_cesm.xml index 693b35f22..ec338fdb2 100644 --- a/cime_config/config_component_cesm.xml +++ b/cime_config/config_component_cesm.xml @@ -545,6 +545,9 @@ char minus1p8,linear_salt,mushy mushy + + linear_salt + run_physics env_run.xml Freezing point calculation for salt water. From 82613c5437b5effd0752294fa9cbe7a1d27f9d1b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 5 Jul 2020 14:01:25 -0600 Subject: [PATCH 004/206] change of cice ice temperature to be consistent with nems --- mediator/fd_cesm.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 5c9199c47..d65f7c870 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -684,7 +684,7 @@ description: sea-ice export to atm # - standard_name: Si_t - alias: sea_ice_temperature + alias: sea_ice_surface_temperature canonical_units: K description: sea-ice export # From bd2ecee11663135b4f8fd65144594837fcd190c1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 5 Jul 2020 14:23:34 -0600 Subject: [PATCH 005/206] more changes to be consistent with updates to nems --- cime_config/runseq/driver_config.py | 11 +- mediator/esmFlds.F90 | 2 +- mediator/esmFldsExchange_nems_mod.F90 | 120 +-- mediator/fd_nems.yaml | 48 +- mediator/med_fraction_mod.F90 | 144 +--- mediator/med_map_mod.F90 | 4 +- mediator/med_phases_prep_ice_mod.F90 | 33 +- mediator/med_phases_prep_ocn_mod.F90 | 1111 +++++++++++++------------ 8 files changed, 745 insertions(+), 728 deletions(-) diff --git a/cime_config/runseq/driver_config.py b/cime_config/runseq/driver_config.py index 3ea092f7a..8251eeebb 100644 --- a/cime_config/runseq/driver_config.py +++ b/cime_config/runseq/driver_config.py @@ -4,10 +4,10 @@ class DriverConfig(dict): ############################################### - def __init__(self, case, coupling_times): + def __init__(self, case, coupling_times): ############################################### - # this initializes the dictionary - super(DriverConfig,self).__init__() + # this initializes the dictionary + super(DriverConfig,self).__init__() self['atm'] = self.__compute_atm(case, coupling_times) self['glc'] = self.__compute_glc(case, coupling_times) @@ -36,7 +36,7 @@ def __compute_atm(self, case, coupling_times): # TODO: need to put in special logical for adiabatic mode - where the atmosphere does # does not really send anything to the mediator - # This will be the case if (case.get_value('COMP_OCN') == 'socn'): + # This will be the case if (case.get_value('COMP_OCN') == 'socn'): # In this case - a special run sequence should be written return (run_atm, med_to_atm, coupling_times["atm_cpl_dt"]) @@ -95,7 +95,7 @@ def __compute_ice(self, case, coupling_times): if (comp_ice == 'sice'): run_ice = False med_to_ice = False - + return (run_ice, med_to_ice, coupling_times["ice_cpl_dt"]) ############################################### @@ -181,4 +181,3 @@ def __compute_wav(self, case, coupling_times): med_to_wav = if_prognostic return (run_wav, med_to_wav, coupling_times["wav_cpl_dt"]) - diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index a4dfb5e3c..010aa3447 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -46,7 +46,7 @@ module esmflds ! Set coupling mode !----------------------------------------------- - character(len=10), public :: coupling_mode ! valid values are [cesm,nems_orig,nems_frac,hafs] + character(len=CS), public :: coupling_mode ! valid values are [cesm,nems_orig,nems_frac,nems_orig_data,hafs] !----------------------------------------------- ! PUblic methods diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 6f6863fdc..fdd898201 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -31,7 +31,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) use esmflds , only : compmed, compatm, compocn, compice, comprof, ncomps use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf - use esmflds , only : coupling_mode, mapuv_with_cart3d + use esmflds , only : coupling_mode, mapuv_with_cart3d, mapnames use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb use med_internalstate_mod , only : mastertask, logunit @@ -41,7 +41,8 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) integer , intent(inout) :: rc ! local variables: - integer :: i, n + integer :: i, n, maptype + character(len=CX) :: msgString character(len=CL) :: cvalue character(len=CS) :: fldname character(len=CS), allocatable :: flds(:) @@ -53,6 +54,15 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! Initialize if use 3d cartesian mapping for u,v mapuv_with_cart3d = .false. + ! Set maptype according to coupling_mode + if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then + maptype = mapnstod_consf + else + maptype = mapconsf + end if + write(msgString,'(A,i6,A)') trim(subname)//': maptype is ',maptype,', '//mapnames(maptype) + call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) + !===================================================================== ! scalar information !===================================================================== @@ -73,26 +83,28 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compocn)%flds, 'So_omask') call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') - ! atm and ocn fields required for atm/ocn flux calculation' - allocate(flds(6)) - flds = (/'Sa_u ','Sa_v ','Sa_z ','Sa_tbot','Sa_pbot','Sa_shum'/) - do n = 1,size(flds) - fldname = trim(flds(n)) - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapnstod_consf, 'none', 'unset') - end do - deallocate(flds) - - ! unused fields needed by the atm/ocn flux computation - allocate(flds(13)) - flds = (/'So_tref ', 'So_qref ','So_u10 ', 'So_ustar ','So_ssq ', & - 'So_re ', 'So_duu10n','Faox_lwup', 'Faox_sen ','Faox_lat ', & - 'Faox_evap', 'Faox_taux','Faox_tauy'/) - do n = 1,size(flds) - fldname = trim(flds(n)) - call addfld(fldListMed_aoflux%flds, trim(fldname)) - end do - deallocate(flds) + if ( trim(coupling_mode) == 'nems_orig_data') then + ! atm and ocn fields required for atm/ocn flux calculation' + allocate(flds(6)) + flds = (/'Sa_u ','Sa_v ', 'Sa_z ', 'Sa_tbot', 'Sa_pbot', 'Sa_shum'/) + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, maptype, 'none', 'unset') + end do + deallocate(flds) + + ! unused fields needed by the atm/ocn flux computation + allocate(flds(13)) + flds = (/'So_tref ', 'So_qref ','So_u10 ', 'So_ustar ','So_ssq ', & + 'So_re ', 'So_duu10n','Faox_lwup', 'Faox_sen ','Faox_lat ', & + 'Faox_evap', 'Faox_taux','Faox_tauy'/) + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListMed_aoflux%flds, trim(fldname)) + end do + deallocate(flds) + end if ! unused fields from ice - but that are needed to be realized by the cice cap call addfld(fldListFr(compice)%flds, 'Si_avsdf') @@ -107,8 +119,8 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) !===================================================================== ! to atm: fractions (computed in med_phases_prep_atm) + call addfld(fldListFr(compice)%flds, 'Si_ifrac') call addfld(fldListTo(compatm)%flds, 'Si_ifrac') - call addfld(fldListTo(compatm)%flds, 'So_ofrac') ! to atm: unmerged from ice ! - zonal surface stress, meridional surface stress @@ -127,7 +139,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) fldname = trim(flds(n)) call addfld(fldListFr(compice)%flds, trim(fldname)) call addfld(fldListTo(compatm)%flds, trim(fldname)) - call addmap(fldListFr(compice)%flds, trim(fldname), compatm, mapnstod_consf, 'ifrac', 'unset') + 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') end do deallocate(flds) @@ -135,27 +147,17 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! to atm: unmerged surface temperatures from ocn call addfld(fldListFr(compocn)%flds, 'So_t') call addfld(fldListTo(compatm)%flds, 'So_t') - call addmap(fldListFr(compocn)%flds, 'So_t', compatm, mapnstod_consf, 'ofrac', 'unset') + 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') !===================================================================== ! FIELDS TO OCEAN (compocn) !===================================================================== - ! to ocn: fractional ice coverage wrt ocean from ice - call addfld(fldListFr(compice)%flds, 'Si_ifrac') - call addfld(fldListTo(compocn)%flds, 'Si_ifrac') - 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') - ! to ocn: sea level pressure from atm call addfld(fldListTo(compocn)%flds, 'Sa_pslv') call addfld(fldListFr(compatm)%flds, 'Sa_pslv') - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compocn, mapbilnr, 'none', 'unset') - end if + 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') ! to ocn: from atm (custom merge in med_phases_prep_ocn) @@ -174,52 +176,32 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) fldname = trim(flds(n)) call addfld(fldListTo(compocn)%flds, trim(fldname)) call addfld(fldListFr(compatm)%flds, trim(fldname)) - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapconsf, 'none', 'unset') - end if + call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, maptype, 'none', 'unset') end do deallocate(flds) ! to ocn: merged sensible heat flux (custom merge in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Faxa_sen') call addfld(fldListFr(compatm)%flds, 'Faxa_sen') - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, mapconsf, 'none', 'unset') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, maptype, 'none', 'unset') ! to ocn: surface latent heat flux and evaporation water flux (custom merge in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Faxa_evap') call addfld(fldListFr(compatm)%flds, 'Faxa_lat') - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, mapconsf, 'none', 'unset') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, maptype, 'none', 'unset') ! to ocn: merge zonal surface stress (custom merge calculation in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Foxx_taux') call addfld(fldListFr(compice)%flds, 'Fioi_taux') call addfld(fldListFr(compatm)%flds, 'Faxa_taux') - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, 'Faxa_taux', compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_taux', compocn, mapconsf, 'none', 'unset') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_taux', compocn, maptype, 'none', 'unset') call addmap(fldListFr(compice)%flds, 'Fioi_taux', compocn, mapfcopy, 'unset', 'unset') ! to ocn: meridional surface stress (custom merge calculation in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Foxx_tauy') call addfld(fldListFr(compice)%flds, 'Fioi_tauy') call addfld(fldListFr(compatm)%flds, 'Faxa_tauy') - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, 'Faxa_tauy', compocn, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_tauy', compocn, mapconsf, 'none', 'unset') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_tauy', compocn, maptype, 'none', 'unset') call addmap(fldListFr(compice)%flds, 'Fioi_tauy', compocn, mapfcopy, 'unset', 'unset') ! to ocn: net shortwave radiation from med (custom merge in med_phases_prep_ocn) @@ -271,11 +253,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) fldname = trim(flds(n)) call addfld(fldListFr(compatm)%flds, trim(fldname)) call addfld(fldListTo(compice)%flds, trim(fldname)) - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapnstod_consf, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapconsf, 'none', 'unset') - end if + 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') end do deallocate(flds) @@ -293,15 +271,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) fldname = trim(flds(n)) call addfld(fldListTo(compice)%flds, trim(fldname)) call addfld(fldListFr(compatm)%flds, trim(fldname)) - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapnstod_consf, 'none', 'unset') - else - if (trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v') then - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mappatch, 'none', 'unset') - else - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapbilnr, 'none', 'unset') - end if - end if + 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') end do deallocate(flds) diff --git a/mediator/fd_nems.yaml b/mediator/fd_nems.yaml index f0fcad822..a74c483c9 100644 --- a/mediator/fd_nems.yaml +++ b/mediator/fd_nems.yaml @@ -43,6 +43,22 @@ # section: atmosphere export #----------------------------------- # + - standard_name: Faxa_bcph + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_dstdry + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_dstwet + canonical_units: kg m-2 s-1 + description: atmosphere export + # + #----------------------------------- + # section: atmosphere export + #----------------------------------- + # - standard_name: Faxa_swdn alias: mean_down_sw_flx canonical_units: W m-2 @@ -105,7 +121,11 @@ - standard_name: Sa_pslv alias: inst_pres_height_surface canonical_units: Pa - description: atmosphere export - instataneous pressure land and sea surface + description: atmosphere export - instantaneous pressure land and sea surface + # + - standard_name: Sa_ptem + canonical_units: K + description: atmosphere export - bottom layer potential temperature # - standard_name: Sa_shum alias: inst_spec_humid_height_lowest @@ -200,6 +220,18 @@ canonical_units: N m-2 description: sea-ice export - air ice meridional stress # + - standard_name: Fioi_bcphi + canonical_units: kg m-2 s-1 + description: sea-ice export to ocean - hydrophilic black carbon flux to ocean + # + - standard_name: Fioi_bcpho + canonical_units: kg m-2 s-1 + description: sea-ice export to ocean - hydrophobic black carbon flux to ocean + # + - standard_name: Fioi_flxdst + canonical_units: kg m-2 s-1 + description: sea-ice export to ocean - dust aerosol flux to ocean + # - standard_name: Fioi_melth alias: net_heat_flx_to_ocn canonical_units: W m-2 @@ -210,6 +242,11 @@ canonical_units: kg m-2 s-1 description: sea-ice export to ocean - fresh water to ocean (h2o flux from melting) # + - standard_name: Fioi_meltw_wiso + alias: mean_fresh_water_to_ocean_rate_wiso + canonical_units: kg m-2 s-1 + description: sea-ice export to ocean - fresh water to ocean (h2o flux from melting) for 16O, 18O, HDO + # - standard_name: Fioi_salt alias: mean_salt_rate canonical_units: kg m-2 s-1 @@ -280,6 +317,10 @@ canonical_units: 1 description: sea-ice export - ice mask # + - standard_name: Si_qref + canonical_units: kg kg-1 + description: sea-ice export to atm + # - standard_name: Si_t alias: sea_ice_surface_temperature canonical_units: K @@ -299,6 +340,10 @@ description: sea-ice export volume of ice per unit area # + - standard_name: Si_snowh + canonical_units: m + description: sea-ice export - surface_snow_water_equivalent + # - standard_name: Si_vsno alias: mean_snow_volume canonical_units: m @@ -453,7 +498,6 @@ canonical_units: N m-2 description: ocean import - meridional surface stress to ocean # - # #----------------------------------- # mediator fields #----------------------------------- diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index af27e3d35..5700f1894 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -2,7 +2,7 @@ module med_fraction_mod !----------------------------------------------------------------------------- ! Mediator Component. - ! Sets fracations on all component grids + ! Sets fractions on all component grids ! the fractions fields are now afrac, ifrac, ofrac, lfrac, and lfrin. ! afrac = fraction of atm on a grid ! lfrac = fraction of lnd on a grid @@ -142,23 +142,7 @@ module med_fraction_mod character(len=5),parameter,dimension(1) :: fraclist_w = (/'wfrac'/) !--- standard --- - real(R8),parameter :: eps_fracsum = 1.0e-02 ! allowed error in sum of fracs - real(R8),parameter :: eps_fracval = 1.0e-02 ! allowed error in any frac +- 0,1 - real(R8),parameter :: eps_fraclim = 1.0e-03 ! truncation limit in fractions_a(lfrac) - logical ,parameter :: atm_frac_correct = .false. ! turn on frac correction on atm grid - - !--- standard plus atm fraction consistency --- - ! real(R8),parameter :: eps_fracsum = 1.0e-12 ! allowed error in sum of fracs - ! real(R8),parameter :: eps_fracval = 1.0e-02 ! allowed error in any frac +- 0,1 - ! real(R8),parameter :: eps_fraclim = 1.0e-03 ! truncation limit in fractions_a(lfrac) - ! logical ,parameter :: atm_frac_correct = .true. ! turn on frac correction on atm grid - - !--- unconstrained and area conserving? --- - ! real(R8),parameter :: eps_fracsum = 1.0e-12 ! allowed error in sum of fracs - ! real(R8),parameter :: eps_fracval = 1.0e-02 ! allowed error in any frac +- 0,1 - ! real(R8),parameter :: eps_fraclim = 1.0e-20 ! truncation limit in fractions_a(lfrac) - ! logical ,parameter :: atm_frac_correct = .true. ! turn on frac correction on atm grid - + real(R8) , parameter :: eps_fraclim = 1.0e-03 ! truncation limit in fractions_a(lfrac) character(*), parameter :: u_FILE_u = & __FILE__ @@ -174,9 +158,10 @@ subroutine med_fraction_init(gcomp, rc) use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_GridCompGet, ESMF_StateIsCreated use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleDestroy + use esmFlds , only : coupling_mode use esmFlds , only : compatm, compocn, compice, complnd use esmFlds , only : comprof, compglc, compwav, compname - use esmFlds , only : mapconsf, mapfcopy + use esmFlds , only : mapconsf, mapfcopy, mapnstod_consf use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created use med_internalstate_mod , only : InternalState use perf_mod , only : t_startf, t_stopf @@ -289,6 +274,7 @@ subroutine med_fraction_init(gcomp, rc) endif end if end do + end if !--------------------------------------- @@ -359,7 +345,7 @@ subroutine med_fraction_init(gcomp, rc) end if !--------------------------------------- - ! Set 'ifrac' in FBFrac(compice) and BFrac(compatm) + ! Set 'ifrac' in FBFrac(compice) and FBFrac(compatm) !--------------------------------------- if (is_local%wrap%comp_present(compice)) then @@ -443,17 +429,11 @@ subroutine med_fraction_init(gcomp, rc) if (.not. is_local%wrap%comp_present(complnd)) then lfrac(:) = 0.0_R8 - if (atm_frac_correct) then - ofrac(:) = 1.0_R8 - end if else do n = 1,size(lfrac) lfrac(n) = 1.0_R8 - ofrac(n) if (abs(lfrac(n)) < eps_fraclim) then lfrac(n) = 0.0_R8 - if (atm_frac_correct) then - ofrac(n) = 1.0_R8 - end if end if end do end if @@ -469,9 +449,6 @@ subroutine med_fraction_init(gcomp, rc) ofrac(n) = 1.0_R8 - lfrac(n) if (abs(ofrac(n)) < eps_fraclim) then ofrac(n) = 0.0_R8 - if (atm_frac_correct) then - lfrac(n) = 1.0_R8 - endif end if end do @@ -627,7 +604,7 @@ subroutine med_fraction_set(gcomp, rc) use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_REGION_TOTAL, ESMF_REGION_SELECT use esmFlds , only : compatm, compocn, compice, compname - use esmFlds , only : mapconsf, mapnstod, mapfcopy + use esmFlds , only : mapconsf, mapnstod, mapfcopy, mapnstod_consf use esmFlds , only : coupling_mode use med_internalstate_mod , only : InternalState use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created @@ -641,7 +618,6 @@ subroutine med_fraction_set(gcomp, rc) type(InternalState) :: is_local real(r8), pointer :: lfrac(:) real(r8), pointer :: ifrac(:) - real(r8), pointer :: ifrac_nstod(:) real(r8), pointer :: ofrac(:) real(r8), pointer :: Si_ifrac(:) real(r8), pointer :: Si_imask(:) @@ -719,12 +695,8 @@ subroutine med_fraction_set(gcomp, rc) ! set ifrac = Si_ifrac * Si_imask ifrac(:) = Si_ifrac(:) * Si_imask(:) - if (trim(coupling_mode) == 'nems_orig') then - ofrac(:) = 1._r8 - ifrac(:) - else - ! set ofrac = Si_imask - ifrac - ofrac(:) = Si_imask(:) - ifrac(:) - end if + ! set ofrac = Si_imask - ifrac + ofrac(:) = Si_imask(:) - ifrac(:) ! ------------------------------------------- ! Set FBfrac(compocn) @@ -751,94 +723,38 @@ subroutine med_fraction_set(gcomp, rc) ! ------------------------------------------- ! Set FBfrac(compatm) ! ------------------------------------------- - if (is_local%wrap%comp_present(compatm)) then - - if (trim(coupling_mode) == 'nems_orig') then - - ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:),mapnstod, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', ifrac_nstod, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:),mapconsf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine ifrac on atm grid - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - where (ifrac .eq. 0.0_R8 .and. abs(ifrac_nstod) .gt. 0.0_R8) - ifrac = ifrac_nstod - endwhere - - ! Determine ofrac and lfrac on atm grid - set ofrac=1-ifrac and lfrac=0 - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ofrac(:) = 1.0_R8 - ifrac(:) - lfrac(:) = 0.0_R8 + if (is_local%wrap%comp_present(compatm)) then + if (trim(coupling_mode) == 'nems_orig' ) then + maptype = mapnstod_consf else - if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then - ! TODO (mvertens, 2019-11-20): this is not being used when ice and atm are on the same grid - ! - this needs to be implemented maptype = mapfcopy else maptype = mapconsf end if + end if - ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Note: 'lfrac' from FBFrac(compatm) is just going to be in the init - if ( is_local%wrap%med_coupling_active(compice,compatm) .and. & - is_local%wrap%med_coupling_active(compocn,compatm) ) then - - if (atm_frac_correct) then - call FB_getFldPtr(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', ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - where (ifrac + ofrac > 0.0_R8) - ifrac = ifrac * ((1.0_R8 - lfrac)/(ofrac+ifrac)) - ofrac = ofrac * ((1.0_R8 - lfrac)/(ofrac+ifrac)) - elsewhere - ifrac = 0.0_R8 - ofrac = 0.0_R8 - end where - endif - endif + ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if - end if + + end if ! end of if present compice !--------------------------------------- ! Diagnostic output diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index bc5ce20f7..aa8fa7974 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -161,7 +161,7 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) srcMaskValue = ispval_mask if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 - else if (coupling_mode(1:5) == 'nems_') then + else if (coupling_mode(1:4) == 'nems') then if (n1 == compatm .and. (n2 == compocn .or. n2 == compice)) then srcMaskValue = 1 dstMaskValue = 0 @@ -225,7 +225,7 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) if (mastertask) then write(llogunit,'(3A)') subname,trim(string),' RH redist ' end if - call ESMF_LogWrite(trim(subname) // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) + call ESMF_LogWrite(subname // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) call ESMF_FieldRedistStore(fldsrc, flddst, & routehandle=is_local%wrap%RH(n1,n2,mapindex), & ignoreUnmatchedIndices = .true., rc=rc) diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index e6a5e95f7..3aabc5691 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -168,22 +168,25 @@ subroutine med_phases_prep_ice(gcomp, rc) 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 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 + 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 !--------------------------------------- diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 3076eab37..d182fe998 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -33,6 +33,10 @@ module med_phases_prep_ocn_mod public :: med_phases_prep_ocn_accum_fast public :: med_phases_prep_ocn_accum_avg + private :: med_phases_prep_ocn_custom_cesm + private :: med_phases_prep_ocn_custom_nems + private :: med_phases_prep_ocn_custom_nemsdata + character(*), parameter :: u_FILE_u = & __FILE__ @@ -46,10 +50,8 @@ 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_Clock, ESMF_Time - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO,ESMF_SUCCESS - use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet, ESMF_ClockPrint - use ESMF , only : ESMF_FieldBundleGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS ! input/output variables type(ESMF_GridComp) :: gcomp @@ -58,37 +60,29 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: n1, ncnt - integer :: dbrc 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, rc=dbrc) + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) end if - rc = ESMF_SUCCESS call memcheck(subname, 5, mastertask) - !--------------------------------------- - ! --- 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 - !--------------------------------------- + ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - !--------------------------------------- - !--- map all fields in FBImp that have active ocean coupling to the ocean grid - !--------------------------------------- - + ! map all fields in FBImp that have active ocean coupling to the ocean grid do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compocn)) then call med_map_FB_Regrid_Norm( & @@ -107,17 +101,15 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) call t_stopf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO, rc=dbrc) + 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) - use ESMF , only : ESMF_GridComp, ESMF_FieldBundleGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR ! input/output variables @@ -127,78 +119,34 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: n, ncnt - real(R8) :: c1,c2,c3,c4 - real(R8), pointer :: dataptr(:) - real(R8), pointer :: dataptr_o(:) - real(R8), pointer :: ifrac(:), ofrac(:) - real(R8), pointer :: ifracr(:), ofracr(:) - real(R8), pointer :: avsdr(:), avsdf(:) - real(R8), pointer :: anidr(:), anidf(:) - real(R8), pointer :: Faxa_swvdf(:), Faxa_swndf(:) - real(R8), pointer :: Faxa_swvdr(:), Faxa_swndr(:) - real(R8), pointer :: Foxx_swnet(:) - real(R8), pointer :: Foxx_swnet_afracr(:) - real(R8), pointer :: Foxx_swnet_vdr(:), Foxx_swnet_vdf(:) - real(R8), pointer :: Foxx_swnet_idr(:), Foxx_swnet_idf(:) - real(R8), pointer :: Fioi_swpen_vdr(:), Fioi_swpen_vdf(:) - real(R8), pointer :: Fioi_swpen_idr(:), Fioi_swpen_idf(:) - real(R8), pointer :: Fioi_swpen(:) - real(R8) :: ifrac_scaled, ofrac_scaled - real(R8) :: ifracr_scaled, ofracr_scaled - real(R8) :: frac_sum - real(R8) :: albvis_dir, albvis_dif - real(R8) :: albnir_dir, albnir_dif - real(R8) :: fswabsv, fswabsi - logical :: export_swnet_by_bands - logical :: import_swpen_by_bands - logical :: export_swnet_afracr - logical :: first_precip_fact_call = .true. - real(R8) :: precip_fact - integer :: lsize - integer :: dbrc - character(CS) :: cvalue - real(R8), pointer :: ocnwgt1(:) ! NEMS_orig_data - real(R8), pointer :: icewgt1(:) ! NEMS_orig_data - real(R8), pointer :: wgtp01(:) ! NEMS_orig_data - real(R8), pointer :: wgtm01(:) ! NEMS_orig_data - real(R8), pointer :: customwgt(:) ! NEMS_orig_data - character(len=64), allocatable :: fldnames(:) - real(R8) , parameter :: const_lhvap = 2.501e6_R8 ! latent heat of evaporation ~ J/kg - real(R8) , parameter :: albdif = 0.06_r8 ! 60 deg reference albedo, diffuse character(len=*), parameter :: subname='(med_phases_prep_ocn_merge)' - logical :: compare_to_mct = .false. ! Set the following to true if want to compare directly to MCT !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS call memcheck(subname, 5, mastertask) - !--------------------------------------- - ! --- 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 - !--------------------------------------- - + ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then !--------------------------------------- - !--- auto merges to ocn + ! merges to ocean !--------------------------------------- + ! auto merges to ocn if (trim(coupling_mode) == 'cesm' .or. & - trim(coupling_mode) == 'nems_orig_data' .or. & + trim(coupling_mode) == 'nems_orig_data' .or. & trim(coupling_mode) == 'hafs') then call med_merge_auto(trim(compname(compocn)), & is_local%wrap%FBExp(compocn), is_local%wrap%FBFrac(compocn), & @@ -212,415 +160,40 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - + ! custom merges to ocean if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - - !------------- - ! Compute netsw for ocean - !------------- - - ! netsw_for_ocn = downsw_from_atm * (1-ocn_albedo) * (1-ice_fraction) + pensw_from_ice * (ice_fraction) - - ! Input from atm - call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swvdr', Faxa_swvdr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swndr', Faxa_swndr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swvdf', Faxa_swvdf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swndf', Faxa_swndf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - lsize = size(Faxa_swvdr) - - ! Input from mediator, ice-covered ocean and open ocean fractions - call FB_GetFldPtr(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' , ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Input from mediator, ocean albedos - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_avsdr' , avsdr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_anidr' , anidr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_avsdf' , avsdf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_anidf' , anidf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBfrac(compocn), 'ifrad' , ifracr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBfrac(compocn), 'ofrad' , ofracr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Input from ice - if (is_local%wrap%comp_present(compice)) then - call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen', Fioi_swpen, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (FB_fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdr', rc=rc)) then - import_swpen_by_bands = .true. - call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_vdr', Fioi_swpen_vdr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_vdf', Fioi_swpen_vdf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_idr', Fioi_swpen_idr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_idf', Fioi_swpen_idf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - import_swpen_by_bands = .false. - end if - end if - - ! Output to ocean swnet - if (FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet', rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet', Foxx_swnet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - lsize = size(Faxa_swvdr) - allocate(Foxx_swnet(lsize)) - end if - - ! Output to ocean swnet by radiation bands - if (FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc)) then - export_swnet_by_bands = .true. - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', Foxx_swnet_vdr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', Foxx_swnet_vdf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', Foxx_swnet_idr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', Foxx_swnet_idf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - export_swnet_by_bands = .false. - end if - - ! Swnet without swpen from sea-ice - if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_afracr',rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_afracr', Foxx_swnet_afracr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - export_swnet_afracr = .true. - else - export_swnet_afracr = .false. - end if - - do n = 1,lsize - - ! Determine ocean albedos - albvis_dir = avsdr(n) - albvis_dif = avsdf(n) - albnir_dir = anidr(n) - albnir_dif = anidf(n) - - ! Compute total swnet to ocean independent of swpen from sea-ice - fswabsv = Faxa_swvdr(n) * (1.0_R8 - albvis_dir) + Faxa_swvdf(n) * (1.0_R8 - albvis_dif) - fswabsi = Faxa_swndr(n) * (1.0_R8 - albnir_dir) + Faxa_swndf(n) * (1.0_R8 - albnir_dif) - Foxx_swnet(n) = fswabsv + fswabsi - - ! Add swpen from sea ice if sea ice is present - if (is_local%wrap%comp_present(compice)) then - - ifrac_scaled = ifrac(n) - ofrac_scaled = ofrac(n) - frac_sum = ifrac(n) + ofrac(n) - if (frac_sum /= 0._R8) then - ifrac_scaled = ifrac(n) / (frac_sum) - ofrac_scaled = ofrac(n) / (frac_sum) - endif - - ifracr_scaled = ifracr(n) - ofracr_scaled = ofracr(n) - frac_sum = ifracr(n) + ofracr(n) - if (frac_sum /= 0._R8) then - ifracr_scaled = ifracr(n) / (frac_sum) - ofracr_scaled = ofracr(n) / (frac_sum) - endif - - Foxx_swnet(n) = ofracr_scaled*(fswabsv + fswabsi) + ifrac_scaled*Fioi_swpen(n) - - if (export_swnet_afracr) then - Foxx_swnet_afracr(n) = ofracr_scaled*(fswabsv + fswabsi) - end if - - ! To compare to mct - if (compare_to_mct) then - c1 = 0.285 - c2 = 0.285 - c3 = 0.215 - c4 = 0.215 - Foxx_swnet_vdr(n) = c1 * Foxx_swnet(n) - Foxx_swnet_vdf(n) = c2 * Foxx_swnet(n) - Foxx_swnet_idr(n) = c3 * Foxx_swnet(n) - Foxx_swnet_idf(n) = c4 * Foxx_swnet(n) - else - if (export_swnet_by_bands) then - if (import_swpen_by_bands) then - ! use each individual band for swpen coming from the sea-ice - Foxx_swnet_vdr(n) = Faxa_swvdr(n)*(1.0_R8-albvis_dir)*ofracr_scaled + Fioi_swpen_vdr(n)*ifrac_scaled - Foxx_swnet_vdf(n) = Faxa_swvdf(n)*(1.0_R8-albvis_dif)*ofracr_scaled + Fioi_swpen_vdf(n)*ifrac_scaled - Foxx_swnet_idr(n) = Faxa_swndr(n)*(1.0_R8-albnir_dir)*ofracr_scaled + Fioi_swpen_idr(n)*ifrac_scaled - Foxx_swnet_idf(n) = Faxa_swndf(n)*(1.0_R8-albnir_dif)*ofracr_scaled + Fioi_swpen_idf(n)*ifrac_scaled - else - ! scale total Foxx_swnet to get contributions from each band - c1 = 0.285 - c2 = 0.285 - c3 = 0.215 - c4 = 0.215 - Foxx_swnet_vdr(n) = c1 * Foxx_swnet(n) - Foxx_swnet_vdf(n) = c2 * Foxx_swnet(n) - Foxx_swnet_idr(n) = c3 * Foxx_swnet(n) - Foxx_swnet_idf(n) = c4 * Foxx_swnet(n) - end if - end if - end if - - end if ! if sea-ice is present - end do - - ! Deallocate Foxx_swnet if it was allocated in this subroutine - if (.not. FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet', rc=rc)) then - deallocate(Foxx_swnet) - end if - - ! Output to ocean per ice thickness fraction and sw penetrating into ocean - if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Sf_afrac', rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Sf_afrac', fldptr1=dataptr_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - dataptr_o(:) = ofrac(:) - end if - if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Sf_afracr', rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Sf_afracr', fldptr1=dataptr_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - dataptr_o(:) = ofracr(:) - end if - - !------------- - ! application of precipitation factor from ocean - !------------- - 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_ocn): Scaling rain, snow, liquid and ice runoff by precip_fact ' - first_precip_fact_call = .false. - end if - write(cvalue,*) precip_fact - call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO, rc=dbrc) - - allocate(fldnames(4)) - fldnames = (/'Faxa_rain','Faxa_snow', 'Foxx_rofl', 'Foxx_rofi'/) - do n = 1,size(fldnames) - if (FB_fldchk(is_local%wrap%FBExp(compocn), trim(fldnames(n)), rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compocn), trim(fldnames(n)) , dataptr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = dataptr(:) * precip_fact - end if - end do - deallocate(fldnames) - end if - end if - - !------------- - ! Custom calculation for nems_orig or nems_frac - !------------- - - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then - - ! get ice and open ocean fractions on the ocn mesh - call FB_GetFldPtr(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' , ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - lsize = size(ofrac) - allocate(customwgt(lsize)) - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_lwnet', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lwnet', wgtA=ofrac, rc=rc) + call med_phases_prep_ocn_custom_cesm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - customwgt(:) = -ofrac(:) / const_lhvap - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lat' , wgtA=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - customwgt(:) = -ofrac(:) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & - FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_taux' , wgtB=customwgt, rc=rc) + else if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then + call med_phases_prep_ocn_custom_nems(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & - FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_tauy' , wgtA=ifrac, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_tauy' , wgtB=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - - ! netsw_for_ocn = [downsw_from_atm*(1-ice_fraction)*(1-ocn_albedo)] + [pensw_from_ice*(ice_fraction)] - customwgt(:) = ofrac(:) * (1.0 - 0.06) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdr' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdr', wgtB=ifrac, rc=rc) + else if (trim(coupling_mode) == 'nems_orig_data') then + call med_phases_prep_ocn_custom_nemsdata(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdf' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdf', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndr' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idr', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndf' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idf', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate(customwgt) - - end if ! end of nems_orig or nems_frac - - !------------- - ! Custom calculation for nems_orig_data - !------------- - - if (trim(coupling_mode) == 'nems_orig_data') then - - ! open ocean (i.e. atm) and ice fraction - ! ocnwgt and icewgt are the "normal" fractions - ! ocnwgt1, icewgt1, and wgtp01 are the fractions that switch between atm and mediator fluxes - ! ocnwgt1+icewgt1+wgtp01 = 1.0 always - ! wgtp01 and wgtm01 are the same just one is +1 and the other is -1 to change sign depending on the ice fraction. - ! wgtp01 = 1 and wgtm01 = -1 when ice fraction = 0 - ! wgtp01 = 0 and wgtm01 = 0 when ice fraction > 0 - - allocate(ocnwgt1(lsize)) - allocate(icewgt1(lsize)) - allocate(wgtp01(lsize)) - allocate(wgtm01(lsize)) - allocate(customwgt(lsize)) - - do n = 1,lsize - if (ifrac(n) <= 0._R8) then - ! ice fraction is 0 - ocnwgt1(n) = 0.0_R8 - icewgt1(n) = 0.0_R8 - wgtp01(n) = 1.0_R8 - wgtm01(n) = -1.0_R8 - else - ! ice fraction is > 0 - ocnwgt1(n) = ofrac(n) - icewgt1(n) = ifrac(n) - wgtp01(n) = 0.0_R8 - wgtm01(n) = 0.0_R8 - end if - - ! check wgts do add to 1 as expected - if ( abs( ofrac(n) + ifrac(n) - 1.0_R8) > 1.0e-12 .or. & - abs( ocnwgt1(n) + icewgt1(n) + wgtp01(n) - 1.0_R8) > 1.0e-12 .or. & - abs( ocnwgt1(n) + icewgt1(n) - wgtm01(n) - 1.0_R8) > 1.0e-12) then - - write(6,100)trim(subname)//'ERROR: n, ofrac, ifrac, sum',& - n,ofrac(n),ifrac(n),ofrac(n)+ifrac(n) - write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, wgtp01, sum ', & - n,ocnwgt1(n),icewgt1(n),wgtp01(n),ocnwgt1(n)+icewgt1(n)+wgtp01(n) - write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, -wgtm01, sum ', & - n,ocnwgt1(n),icewgt1(n),-wgtp01(n),ocnwgt1(n)+icewgt1(n)-wgtm01(n) -100 format(a,i8,2x,3(d20.13,2x)) -101 format(a,i8,2x,4(d20.13,2x)) - - call ESMF_LogWrite(trim(subname)//": ERROR atm + ice fracs inconsistent", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__, rc=dbrc) - rc = ESMF_FAILURE - return - endif - end do - - customwgt(:) = wgtm01(:) / const_lhvap - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_evap', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lat' , wgtB=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_sen ', wgtA=ocnwgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_sen' , wgtB=wgtm01, rc=rc) - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_taux ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_taux' , wgtB=icewgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_taux' , wgtC=wgtm01, rc=rc) - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_tauy ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_tauy' , wgtB=icewgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_tauy' , wgtC=wgtm01, rc=rc) - - ! If there is no ice on the ocn gridcell (ocnwgt1=0) - sum Faxa_lwdn and Faxa_lwup - ! If there is ice on the ocn gridcell - merge Faox_lwup and Faxa_lwdn and ignore Faxa_lwup - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_lwnet', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_lwup ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lwdn' , wgtB=ocnwgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_lwnet', wgtC=wgtp01, rc=rc) - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain' , & - FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow' , & - FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) - - deallocate(ocnwgt1) - deallocate(icewgt1) - deallocate(wgtp01) - deallocate(wgtm01) - deallocate(customwgt) - end if ! end of nems_orig_data custom - !--------------------------------------- - !--- diagnose output - !--------------------------------------- - + ! diagnose output if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compocn), & - string=trim(subname)//' FBexp(compocn) ', rc=rc) + 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 - ! TODO (mvertens, 2018-12-16): document above custom calculation - - !--------------------------------------- - !--- clean up - !--------------------------------------- - endif if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) 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_Clock, ESMF_Time + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_Clock, ESMF_Time use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet, ESMF_ClockPrint - use ESMF , only : ESMF_FieldBundleGet ! input/output variables type(ESMF_GridComp) :: gcomp @@ -629,39 +202,29 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) ! local variables type(ESMF_Clock) :: clock type(ESMF_Time) :: time - character(len=64) :: timestr type(InternalState) :: is_local integer :: i,j,n,ncnt - integer :: dbrc character(len=*), parameter :: subname='(med_phases_accum_fast)' !--------------------------------------- - call t_startf('MED:'//subname) - if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) - endif rc = ESMF_SUCCESS - !--------------------------------------- - ! --- Get the internal state - !--------------------------------------- + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + ! 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 - !--------------------------------------- + ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - - !--------------------------------------- - !--- ocean accumulator - !--------------------------------------- - + ! 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 @@ -672,96 +235,70 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) string=trim(subname)//' FBExpAccum accumulation ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - - !--------------------------------------- - !--- clean up - !--------------------------------------- endif if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) end subroutine med_phases_prep_ocn_accum_fast !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) ! Prepare the OCN import Fields. - use ESMF , only : ESMF_GridComp, ESMF_Clock, ESMF_Time - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet + use ESMF , only : ESMF_GridComp, 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 - character(len=64) :: timestr type(InternalState) :: is_local - integer :: i,j,n,ncnt - integer :: dbrc + integer :: ncnt character(len=*),parameter :: subname='(med_phases_prep_ocn_accum_avg)' !--------------------------------------- - call t_startf('MED:'//subname) - if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) - endif rc = ESMF_SUCCESS - !--------------------------------------- - ! --- Get the internal state - !--------------------------------------- + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + ! 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 - !--------------------------------------- + ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExpAccum(compocn), trim(subname)//"FBExpAccum(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - !--------------------------------------- - !--- average ocn accumulator - !--------------------------------------- - + ! average ocn accumulator if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & string=trim(subname)//' FBExpAccum(compocn) before avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call FB_average(is_local%wrap%FBExpAccum(compocn), & is_local%wrap%FBExpAccumCnt(compocn), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExp(compocn), & string=trim(subname)//' FBExpAccum(compocn) after avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - !--- copy to FBExp(compocn) - !--------------------------------------- - + ! copy to FBExp(compocn) call FB_copy(is_local%wrap%FBExp(compocn), is_local%wrap%FBExpAccum(compocn), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - !--- zero accumulator - !--------------------------------------- - + ! zero accumulator is_local%wrap%FBExpAccumFlag(compocn) = .true. is_local%wrap%FBExpAccumCnt(compocn) = 0 call FB_reset(is_local%wrap%FBExpAccum(compocn), value=czero, rc=rc) @@ -770,10 +307,558 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) end if if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) end subroutine med_phases_prep_ocn_accum_avg + !----------------------------------------------------------------------------- + subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) + + !--------------------------------------- + ! custom calculations for cesm + !--------------------------------------- + + use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + real(R8), pointer :: ifrac(:), ofrac(:) + real(R8), pointer :: ifracr(:), ofracr(:) + real(R8), pointer :: avsdr(:), avsdf(:) + real(R8), pointer :: anidr(:), anidf(:) + real(R8), pointer :: Faxa_swvdf(:), Faxa_swndf(:) + real(R8), pointer :: Faxa_swvdr(:), Faxa_swndr(:) + real(R8), pointer :: Foxx_swnet(:) + real(R8), pointer :: Foxx_swnet_afracr(:) + real(R8), pointer :: Foxx_swnet_vdr(:), Foxx_swnet_vdf(:) + real(R8), pointer :: Foxx_swnet_idr(:), Foxx_swnet_idf(:) + real(R8), pointer :: Fioi_swpen_vdr(:), Fioi_swpen_vdf(:) + real(R8), pointer :: Fioi_swpen_idr(:), Fioi_swpen_idf(:) + real(R8), pointer :: Fioi_swpen(:) + real(R8), pointer :: dataptr(:) + real(R8), pointer :: dataptr_o(:) + real(R8) :: frac_sum + real(R8) :: ifrac_scaled, ofrac_scaled + real(R8) :: ifracr_scaled, ofracr_scaled + logical :: export_swnet_by_bands + logical :: import_swpen_by_bands + logical :: export_swnet_afracr + logical :: first_precip_fact_call = .true. + real(R8) :: precip_fact + character(CS) :: cvalue + real(R8) :: fswabsv, fswabsi + integer :: n + integer :: lsize + real(R8) :: c1,c2,c3,c4 + character(len=64), allocatable :: fldnames(:) + character(len=*), parameter :: subname='(med_phases_prep_ocn_custom_cesm)' + !--------------------------------------- + + 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 + + !--------------------------------------- + ! Compute netsw for ocean + !--------------------------------------- + ! netsw_for_ocn = downsw_from_atm * (1-ocn_albedo) * (1-ice_fraction) + pensw_from_ice * (ice_fraction) + + ! Input from atm + call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swvdr', Faxa_swvdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swndr', Faxa_swndr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swvdf', Faxa_swvdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compatm,compocn), 'Faxa_swndf', Faxa_swndf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + lsize = size(Faxa_swvdr) + + ! Input from mediator, ocean albedos + call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_avsdr' , avsdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_anidr' , anidr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_avsdf' , avsdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, 'So_anidf' , anidf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Output to ocean swnet total + if (FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet', rc=rc)) then + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet', Foxx_swnet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + lsize = size(Faxa_swvdr) + allocate(Foxx_swnet(lsize)) + end if + + ! Output to ocean swnet by radiation bands + if (FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc)) then + export_swnet_by_bands = .true. + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', Foxx_swnet_vdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', Foxx_swnet_vdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', Foxx_swnet_idr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', Foxx_swnet_idf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + export_swnet_by_bands = .false. + end if + + ! ----------------------- + ! If cice IS NOT PRESENT + ! ----------------------- + if (.not. is_local%wrap%comp_present(compice)) then + ! Compute total swnet to ocean independent of swpen from sea-ice + do n = 1,lsize + fswabsv = Faxa_swvdr(n) * (1.0_R8 - avsdr(n)) + Faxa_swvdf(n) * (1.0_R8 - avsdf(n)) + fswabsi = Faxa_swndr(n) * (1.0_R8 - anidr(n)) + Faxa_swndf(n) * (1.0_R8 - anidf(n)) + Foxx_swnet(n) = fswabsv + fswabsi + end do + ! Compute sw export to ocean bands if required + if (export_swnet_by_bands) then + c1 = 0.285; c2 = 0.285; c3 = 0.215; c4 = 0.215 + Foxx_swnet_vdr(:) = c1 * Foxx_swnet(:) + Foxx_swnet_vdf(:) = c2 * Foxx_swnet(:) + Foxx_swnet_idr(:) = c3 * Foxx_swnet(:) + Foxx_swnet_idf(:) = c4 * Foxx_swnet(:) + end if + end if + + ! ----------------------- + ! If cice IS PRESENT + ! ----------------------- + if (is_local%wrap%comp_present(compice)) then + + ! Input from mediator, ice-covered ocean and open ocean fractions + call FB_GetFldPtr(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' , ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBfrac(compocn), 'ifrad' , ifracr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBfrac(compocn), 'ofrad' , ofracr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen', Fioi_swpen, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (FB_fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdr', rc=rc)) then + import_swpen_by_bands = .true. + call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_vdr', Fioi_swpen_vdr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_vdf', Fioi_swpen_vdf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_idr', Fioi_swpen_idr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_GetFldPtr(is_local%wrap%FBImp(compice,compocn), 'Fioi_swpen_idf', Fioi_swpen_idf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + import_swpen_by_bands = .false. + end if + + ! Swnet without swpen from sea-ice + if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_afracr',rc=rc)) then + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Foxx_swnet_afracr', Foxx_swnet_afracr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + export_swnet_afracr = .true. + else + export_swnet_afracr = .false. + end if + + do n = 1,lsize + ! Compute total swnet to ocean independent of swpen from sea-ice + fswabsv = Faxa_swvdr(n) * (1.0_R8 - avsdr(n)) + Faxa_swvdf(n) * (1.0_R8 - avsdf(n)) + fswabsi = Faxa_swndr(n) * (1.0_R8 - anidr(n)) + Faxa_swndf(n) * (1.0_R8 - anidf(n)) + Foxx_swnet(n) = fswabsv + fswabsi + + ! Add swpen from sea ice + ifrac_scaled = ifrac(n) + ofrac_scaled = ofrac(n) + frac_sum = ifrac(n) + ofrac(n) + if (frac_sum /= 0._R8) then + ifrac_scaled = ifrac(n) / (frac_sum) + ofrac_scaled = ofrac(n) / (frac_sum) + endif + ifracr_scaled = ifracr(n) + ofracr_scaled = ofracr(n) + frac_sum = ifracr(n) + ofracr(n) + if (frac_sum /= 0._R8) then + ifracr_scaled = ifracr(n) / (frac_sum) + ofracr_scaled = ofracr(n) / (frac_sum) + endif + Foxx_swnet(n) = ofracr_scaled*(fswabsv + fswabsi) + ifrac_scaled*Fioi_swpen(n) + + if (export_swnet_afracr) then + Foxx_swnet_afracr(n) = ofracr_scaled*(fswabsv + fswabsi) + end if + + ! Compute sw export to ocean bands if required + if (export_swnet_by_bands) then + if (import_swpen_by_bands) then + ! use each individual band for swpen coming from the sea-ice + Foxx_swnet_vdr(n) = Faxa_swvdr(n)*(1.0_R8-avsdr(n))*ofracr_scaled + Fioi_swpen_vdr(n)*ifrac_scaled + Foxx_swnet_vdf(n) = Faxa_swvdf(n)*(1.0_R8-avsdf(n))*ofracr_scaled + Fioi_swpen_vdf(n)*ifrac_scaled + Foxx_swnet_idr(n) = Faxa_swndr(n)*(1.0_R8-anidr(n))*ofracr_scaled + Fioi_swpen_idr(n)*ifrac_scaled + Foxx_swnet_idf(n) = Faxa_swndf(n)*(1.0_R8-anidf(n))*ofracr_scaled + Fioi_swpen_idf(n)*ifrac_scaled + else + ! scale total Foxx_swnet to get contributions from each band + c1 = 0.285; c2 = 0.285; c3 = 0.215; c4 = 0.215 + Foxx_swnet_vdr(n) = c1 * Foxx_swnet(n) + Foxx_swnet_vdf(n) = c2 * Foxx_swnet(n) + Foxx_swnet_idr(n) = c3 * Foxx_swnet(n) + Foxx_swnet_idf(n) = c4 * Foxx_swnet(n) + end if + end if + end do + + ! Output to ocean per ice thickness fraction and sw penetrating into ocean + if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Sf_afrac', rc=rc)) then + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Sf_afrac', fldptr1=dataptr_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + dataptr_o(:) = ofrac(:) + end if + if ( FB_fldchk(is_local%wrap%FBExp(compocn), 'Sf_afracr', rc=rc)) then + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), 'Sf_afracr', fldptr1=dataptr_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + dataptr_o(:) = ofracr(:) + end if + + end if ! if sea-ice is present + + ! Deallocate Foxx_swnet if it was allocated in this subroutine + if (.not. FB_fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet', rc=rc)) then + deallocate(Foxx_swnet) + end if + + !--------------------------------------- + ! application of precipitation factor from ocean + !--------------------------------------- + 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_ocn): Scaling rain, snow, liquid and ice runoff by precip_fact ' + first_precip_fact_call = .false. + end if + write(cvalue,*) precip_fact + call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO) + + allocate(fldnames(4)) + fldnames = (/'Faxa_rain','Faxa_snow', 'Foxx_rofl', 'Foxx_rofi'/) + do n = 1,size(fldnames) + if (FB_fldchk(is_local%wrap%FBExp(compocn), trim(fldnames(n)), rc=rc)) then + call FB_GetFldPtr(is_local%wrap%FBExp(compocn), trim(fldnames(n)) , dataptr, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = dataptr(:) * precip_fact + end if + end do + deallocate(fldnames) + 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_custom_cesm + + !----------------------------------------------------------------------------- + subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) + + ! ---------------------------------------------- + ! Custom calculation for nems_orig or nems_frac + ! ---------------------------------------------- + + use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + real(R8), pointer :: ocnwgt1(:) + real(R8), pointer :: icewgt1(:) + real(R8), pointer :: wgtp01(:) + real(R8), pointer :: wgtm01(:) + real(R8), pointer :: customwgt(:) + real(R8), pointer :: ifrac(:) + real(R8), pointer :: ofrac(:) + integer :: lsize + real(R8) , parameter :: const_lhvap = 2.501e6_R8 ! latent heat of evaporation ~ J/kg + character(len=*), parameter :: subname='(med_phases_prep_ocn_custom_nems)' + !--------------------------------------- + + 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 + + ! get ice and open ocean fractions on the ocn mesh + call FB_GetFldPtr(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' , ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + lsize = size(ofrac) + allocate(customwgt(lsize)) + + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_lwnet', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lwnet', wgtA=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + customwgt(:) = -ofrac(:) / const_lhvap + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lat' , wgtA=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + customwgt(:) = -ofrac(:) + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & + FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_taux' , wgtB=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & + FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_tauy' , wgtA=ifrac, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_tauy' , wgtB=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! netsw_for_ocn = [downsw_from_atm*(1-ice_fraction)*(1-ocn_albedo)] + [pensw_from_ice*(ice_fraction)] + customwgt(:) = ofrac(:) * (1.0 - 0.06) + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdr' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdr', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdf' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdf', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndr' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idr', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndf' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idf', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate(customwgt) + + 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_custom_nems + + !----------------------------------------------------------------------------- + subroutine med_phases_prep_ocn_custom_nemsdata(gcomp, rc) + + ! ---------------------------------------------- + ! Custom calculation for nems_orig_data + ! ---------------------------------------------- + + use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + real(R8), pointer :: ocnwgt1(:) ! NEMS_orig_data + real(R8), pointer :: icewgt1(:) ! NEMS_orig_data + real(R8), pointer :: wgtp01(:) ! NEMS_orig_data + real(R8), pointer :: wgtm01(:) ! NEMS_orig_data + real(R8), pointer :: customwgt(:) ! NEMS_orig_data + real(R8), pointer :: ifrac(:) + real(R8), pointer :: ofrac(:) + integer :: lsize + integer :: n + real(R8) , parameter :: const_lhvap = 2.501e6_R8 ! latent heat of evaporation ~ J/kg + character(len=*), parameter :: subname='(med_phases_prep_ocn_custom_nemsdata)' + !--------------------------------------- + + 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 + + ! get ice and open ocean fractions on the ocn mesh + call FB_GetFldPtr(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' , ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + lsize = size(ofrac) + allocate(customwgt(lsize)) + + ! open ocean (i.e. atm) and ice fraction + ! ocnwgt and icewgt are the "normal" fractions + ! ocnwgt1, icewgt1, and wgtp01 are the fractions that switch between atm and mediator fluxes + ! ocnwgt1+icewgt1+wgtp01 = 1.0 always + ! wgtp01 and wgtm01 are the same just one is +1 and the other is -1 to change sign depending on the ice fraction. + ! wgtp01 = 1 and wgtm01 = -1 when ice fraction = 0 + ! wgtp01 = 0 and wgtm01 = 0 when ice fraction > 0 + + allocate(ocnwgt1(lsize)) + allocate(icewgt1(lsize)) + allocate(wgtp01(lsize)) + allocate(wgtm01(lsize)) + allocate(customwgt(lsize)) + + do n = 1,lsize + if (ifrac(n) <= 0._R8) then + ! ice fraction is 0 + ocnwgt1(n) = 1.0_R8 + icewgt1(n) = 0.0_R8 + wgtp01(n) = 0.0_R8 + wgtm01(n) = 0.0_R8 + else + ! ice fraction is > 0 + ocnwgt1(n) = ofrac(n) + icewgt1(n) = ifrac(n) + wgtp01(n) = 0.0_R8 + wgtm01(n) = 0.0_R8 + end if + + ! check wgts do add to 1 as expected + ! TODO: check if this condition is still required + if(ofrac(n)+ifrac(n) /= 0._R8)then + if ( abs( ofrac(n) + ifrac(n) - 1.0_R8) > 1.0e-12 .or. & + abs( ocnwgt1(n) + icewgt1(n) + wgtp01(n) - 1.0_R8) > 1.0e-12 .or. & + abs( ocnwgt1(n) + icewgt1(n) - wgtm01(n) - 1.0_R8) > 1.0e-12) then + + write(6,100)trim(subname)//'ERROR: n, ofrac, ifrac, sum',& + n,ofrac(n),ifrac(n),ofrac(n)+ifrac(n) + write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, wgtp01, sum ', & + n,ocnwgt1(n),icewgt1(n),wgtp01(n),ocnwgt1(n)+icewgt1(n)+wgtp01(n) + write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, -wgtm01, sum ', & + n,ocnwgt1(n),icewgt1(n),-wgtp01(n),ocnwgt1(n)+icewgt1(n)-wgtm01(n) +100 format(a,i8,2x,3(d20.13,2x)) +101 format(a,i8,2x,4(d20.13,2x)) + + call ESMF_LogWrite(trim(subname)//": ERROR atm + ice fracs inconsistent", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) + rc = ESMF_FAILURE + return + endif + endif + end do + + customwgt(:) = wgtm01(:) / const_lhvap + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & + FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_evap', wgtA=ocnwgt1, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lat' , wgtB=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & + FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_sen ', wgtA=ocnwgt1, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_sen' , wgtB=wgtm01, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & + FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_taux ', wgtA=ocnwgt1, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_taux' , wgtB=icewgt1, & + FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_taux' , wgtC=wgtm01, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & + FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_tauy ', wgtA=ocnwgt1, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_tauy' , wgtB=icewgt1, & + FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_tauy' , wgtC=wgtm01, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! If there is no ice on the ocn gridcell (ocnwgt1=0) - sum Faxa_lwdn and Faxa_lwup + ! If there is ice on the ocn gridcell - merge Faox_lwup and Faxa_lwdn and ignore Faxa_lwup + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_lwnet', & + FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_lwup ', wgtA=ocnwgt1, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lwdn' , wgtB=ocnwgt1, & + FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_lwnet', wgtC=wgtp01, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain' , & + FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow' , & + FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! netsw_for_ocn = [downsw_from_atm*(1-ice_fraction)*(1-ocn_albedo)] + [pensw_from_ice*(ice_fraction)] + customwgt(:) = ofrac(:) * (1.0 - 0.06) + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdr' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdr', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdf' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdf', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndr' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idr', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndf' , wgtA=customwgt, & + FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idf', wgtB=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + deallocate(ocnwgt1) + deallocate(icewgt1) + deallocate(wgtp01) + deallocate(wgtm01) + deallocate(customwgt) + + 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_custom_nemsdata + end module med_phases_prep_ocn_mod From 70593ad9022d2691d89a09717d88b4071be3749b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 5 Jul 2020 14:30:30 -0600 Subject: [PATCH 006/206] additional changes needed for consistency with nems as well of cleanup of spaces --- cime_config/buildexe | 9 ++++- cime_config/buildnml | 35 ++++++++++++++------ cime_config/config_pes.xml | 1 - cime_config/namelist_definition_drv_flds.xml | 2 +- cime_config/runseq/gen_runseq.py | 8 ++--- cime_config/runseq/runseq_D.py | 4 +-- cime_config/runseq/runseq_TG.py | 4 +-- cime_config/runseq/runseq_general.py | 8 ++--- mediator/med_merge_mod.F90 | 2 +- mediator/med_phases_prep_atm_mod.F90 | 8 +---- 10 files changed, 46 insertions(+), 35 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index 8171511b1..41551d39d 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -49,7 +49,14 @@ def _main_func(): if valid: valid_comps.append(item) - if len(valid_comps) == 2 and "dwav" not in case.get_value("COMP_WAV") and "dlnd" not in case.get_value("COMP_LND"): + datamodel_in_compset = ("datm" in case.get_value("COMP_ATM") or + "dice" in case.get_value("COMP_ICE") or + "dlnd" in case.get_value("COMP_LND") or + "docn" in case.get_value("COMP_OCN") or + "drof" in case.get_value("COMP_ROF") or + "dwav" in case.get_value("COMP_WAV")) + + if len(valid_comps) == 2 and not datamodel_in_compset: skip_mediator = True else: skip_mediator = False diff --git a/cime_config/buildnml b/cime_config/buildnml index 56e630214..471282dcc 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -236,15 +236,27 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): if valid: valid_comps.append(item) - # set the driver rpointer file if there is only one non-stub component then skip mediator - - if len(valid_comps) == 2 and "dwav" not in case.get_value("COMP_WAV") and "dlnd" not in case.get_value("COMP_LND"): + # Determine if there are any data components in the compset + datamodel_in_compset = ("datm" in case.get_value("COMP_ATM") or + "dice" in case.get_value("COMP_ICE") or + "dlnd" in case.get_value("COMP_LND") or + "docn" in case.get_value("COMP_OCN") or + "drof" in case.get_value("COMP_ROF") or + "dwav" in case.get_value("COMP_WAV")) + + + + # Determine if will skip the mediator and then set the + # driver rpointer file if there is only one non-stub component then skip mediator + if len(valid_comps) == 2 and not datamodel_in_compset: + # skip the mediator if there is a prognostic component and all other components are stub skip_mediator = True valid_comps.remove("CPL") nmlgen.set_value('mediator_present', value='.false.') nmlgen.set_value("drv_restart_pointer", value="none") nmlgen.set_value("component_list", value=" ".join(valid_comps)) else: + # do not skip mediator if there is a data component but all other components are stub skip_mediator = False nmlgen.set_value("drv_restart_pointer", value="rpointer.cpl") valid_comps_string = " ".join(valid_comps) @@ -252,13 +264,13 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): logger.info("Writing nuopc_runseq for components {}".format(valid_comps)) nuopc_config_file = os.path.join(confdir, "nuopc.runconfig") - nmlgen.write_nuopc_config_file(nuopc_config_file, data_list_path=data_list_path) + nmlgen.write_nuopc_config_file(nuopc_config_file, data_list_path=data_list_path) #-------------------------------- - # (3.1) Update nuopc.runconfig file if component needs it + # (3.1) Update nuopc.runconfig file if component needs it #-------------------------------- - # Read nuopc.runconfig + # Read nuopc.runconfig with open(nuopc_config_file, 'r') as f: lines_cpl = f.readlines() @@ -268,7 +280,8 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): if comp != 'CPL' and case.get_value("COMP_{}".format(comp)) != 'd'+comp.lower(): # Read *.configure file for component caseroot = case.get_value('CASEROOT') - comp_config_file = os.path.join(caseroot,"Buildconf","{}conf".format(case.get_value("COMP_{}".format(comp))),"{}.configure".format(case.get_value("COMP_{}".format(comp)))) + comp_config_file = os.path.join(caseroot,"Buildconf","{}conf".format(case.get_value("COMP_{}".format(comp))), + "{}.configure".format(case.get_value("COMP_{}".format(comp)))) if os.path.isfile(comp_config_file): with open(comp_config_file, 'r') as f: lines_comp = f.readlines() @@ -359,7 +372,7 @@ def _create_runseq(case, coupling_times, valid_comps): else: - if len(valid_comps) == 1: + if len(valid_comps) == 1: # Create run sequence with no mediator outfile = open(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), "w") @@ -371,7 +384,7 @@ def _create_runseq(case, coupling_times, valid_comps): outfile.write (":: \n") outfile.close() shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) - + else: # Create a run sequence file appropriate for target compset @@ -389,7 +402,7 @@ def _create_runseq(case, coupling_times, valid_comps): 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: + else: from runseq_general import gen_runseq # create the run sequence @@ -473,7 +486,7 @@ def _create_component_modelio_namelists(confdir, case, files): outfile.write(" {}{}{}".format("logfile = ", logfile,"\n")) outfile.write("::\n\n") - # also write out a driver log file + # also write out a driver log file if model == 'cpl': name = "DRV" logfile = 'drv' + inst_string + ".log." + str(lid) diff --git a/cime_config/config_pes.xml b/cime_config/config_pes.xml index ad332b3ff..7a358cc80 100644 --- a/cime_config/config_pes.xml +++ b/cime_config/config_pes.xml @@ -207,4 +207,3 @@ - diff --git a/cime_config/namelist_definition_drv_flds.xml b/cime_config/namelist_definition_drv_flds.xml index 08847103a..cef475978 100644 --- a/cime_config/namelist_definition_drv_flds.xml +++ b/cime_config/namelist_definition_drv_flds.xml @@ -4,7 +4,7 @@ - - + char nuopc DRIVER_attributes @@ -19,7 +19,7 @@ - + char nuopc DRIVER_attributes @@ -28,7 +28,7 @@ - + char nuopc MED_attributes @@ -37,7 +37,7 @@ - + char nuopc ATM_attributes @@ -46,7 +46,7 @@ - + char nuopc OCN_attributes @@ -55,7 +55,7 @@ - + char nuopc ICE_attributes @@ -64,7 +64,7 @@ - + char nuopc ROF_attributes @@ -73,7 +73,7 @@ - + char nuopc LND_attributes @@ -82,7 +82,7 @@ - + char nuopc GLC_attributes @@ -91,7 +91,7 @@ - + char nuopc WAV_attributes From eb20102d449845fc3d54167ad9a7534e3f6d0c78 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 11:33:25 -0600 Subject: [PATCH 014/206] fix to use HAFS yaml field dictionary --- cime_config/buildnml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index 56e630214..90fcda829 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -556,8 +556,10 @@ def buildnml(case, caseroot, component): cimeroot = case.get_value("CIMEROOT") fd_dir = os.path.join(cimeroot, "src","drivers","nuopc","mediator") coupling_mode = case.get_value('COUPLING_MODE') - if coupling_mode == 'cesm' or coupling_mode == 'hafs': + if coupling_mode == 'cesm': filename = os.path.join(fd_dir,"fd_cesm.yaml") + elif coupling_mode == 'hafs': + filename = os.path.join(fd_dir,"fd_hafs.yaml") else: filename = os.path.join(fd_dir,"fd_nems.yaml") shutil.copy(filename, os.path.join(rundir, "fd.yaml")) From 9a751549089bce5fd3f9642e9c27b9ae08b0bf98 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 11:34:25 -0600 Subject: [PATCH 015/206] make aoflux phase optional, default is still true --- cime_config/config_component.xml | 13 +++++++++++++ cime_config/runseq/runseq_general.py | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index ecde8a538..2f029f123 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -2572,6 +2572,19 @@ if true, create ESMF PET log files even if there is no error encountered + + + + + + logical + TRUE,FALSE + TRUE + run_coupling + env_run.xml + add aoflux calculation to runseq + + ========================================= Notes: diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 6d9275660..fd68d5ee9 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -18,6 +18,7 @@ def gen_runseq(case, coupling_times): rundir = case.get_value("RUNDIR") caseroot = case.get_value("CASEROOT") cpl_seq_option = case.get_value('CPL_SEQ_OPTION') + cpl_add_aoflux = case.get_value('ADD_AOFLUX_TO_RUNSEQ') # It is assumed that if a component will be run it will send information to the mediator # so the flags run_xxx and xxx_to_med are redundant @@ -82,7 +83,8 @@ def gen_runseq(case, coupling_times): if (cpl_seq_option == 'RASM'): 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)) + 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)) @@ -104,7 +106,8 @@ def gen_runseq(case, coupling_times): runseq.add_action("OCN -> MED :remapMethod=redist" , run_ocn and not ocn_outer_loop) if (cpl_seq_option == 'TIGHT'): 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) + 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) From 59ac2c50afa888063adf7da9c4df9e5995fea848 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 11:43:54 -0600 Subject: [PATCH 016/206] clean field exchange file for HAFS app --- mediator/esmFldsExchange_hafs_mod.F90 | 396 +++----------------------- 1 file changed, 33 insertions(+), 363 deletions(-) diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index 31f5a13db..409cafc7b 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -30,12 +30,11 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) use esmFlds , only : addfld => med_fldList_AddFld 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 : compmed, compatm, compocn, compice, ncomps use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf use esmflds , only : mapuv_with_cart3d - use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb + use esmflds , only : fldListTo, fldListFr use esmFlds , only : coupling_mode ! input/output parameters: @@ -49,27 +48,13 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) integer :: num, i, n integer :: n1, n2, n3, n4 logical :: isPresent - character(len=5) :: iso(2) + !character(len=5) :: iso(2) character(len=CL) :: cvalue character(len=CS) :: name, fldname character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' - character(len=CX) :: atm2lnd_fmap='unset', atm2lnd_smap='unset' - character(len=CX) :: glc2lnd_smap='unset', glc2lnd_fmap='unset' - character(len=CX) :: glc2ice_rmap='unset' - character(len=CX) :: glc2ocn_liq_rmap='unset', glc2ocn_ice_rmap='unset' character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' - character(len=CX) :: lnd2atm_fmap='unset', lnd2atm_smap='unset' - character(len=CX) :: lnd2glc_fmap='unset', lnd2glc_smap='unset' - character(len=CX) :: lnd2rof_fmap='unset' - character(len=CX) :: rof2lnd_fmap='unset' - character(len=CX) :: rof2ocn_fmap='unset', rof2ocn_ice_rmap='unset', rof2ocn_liq_rmap='unset' - character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' - character(len=CX) :: wav2ocn_smap='unset' - logical :: flds_co2a ! use case - logical :: flds_co2b ! use case - logical :: flds_co2c ! use case character(len=CS), allocatable :: flds(:) character(len=CS), allocatable :: suffix(:) character(len=*) , parameter :: subname='(esmFldsExchange_hafs)' @@ -77,9 +62,6 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) rc = ESMF_SUCCESS - !iso(1) = '' - !iso(2) = '_wiso' - !--------------------------------------- ! Get the internal state !--------------------------------------- @@ -230,17 +212,6 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! --------------------------------------------------------------------- ! to med: unused fields needed by the atm/ocn flux computation ! --------------------------------------------------------------------- - if (phase /= 'advertise') then - allocate(flds(13)) - flds = (/'So_tref ', 'So_qref ', 'So_u10 ', 'So_ustar ', 'So_ssq ', & - 'So_re ', 'So_duu10n', 'Faox_lwup', 'Faox_sen ', 'Faox_lat ', & - 'Faox_evap', 'Faox_taux', 'Faox_tauy'/) - do n = 1, size(flds) - fldname = trim(flds(n)) - call addfld(fldListMed_aoflux%flds, trim(fldname)) - end do - deallocate(flds) - end if if (phase /= 'advertise') then call addfld(fldListFr(compatm)%flds, 'Sa_u') @@ -263,11 +234,6 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Sa_shum') call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, mapbilnr, 'one', atm2ocn_smap) - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_shum_wiso', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_shum_wiso') - call addmap(fldListFr(compatm)%flds, 'Sa_shum_wiso', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_ptem', rc=rc)) then call addfld(fldListFr(compatm)%flds, 'Sa_ptem') call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) @@ -282,19 +248,10 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! --------------------------------------------------------------------- ! to med: swnet fluxes used for budget calculation ! --------------------------------------------------------------------- - ! TODO (mvertens, 2019-01-11): budget implemention needs to be done in CMEPS if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Fall_swnet') - call addfld(fldListFr(compice)%flds, 'Faii_swnet') call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') else - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsf, 'one' , atm2ice_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one' , atm2ocn_fmap) - end if - if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Faii_swnet', compocn, mapfcopy, 'unset', 'unset') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one', atm2ocn_fmap) end if !===================================================================== @@ -306,188 +263,10 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) !---------------------------------------------------------- if (phase == 'advertise') then ! the following are computed in med_phases_prep_atm - call addfld(fldListTo(compatm)%flds, 'Sl_lfrac') call addfld(fldListTo(compatm)%flds, 'Si_ifrac') call addfld(fldListTo(compatm)%flds, 'So_ofrac') end if - ! --------------------------------------------------------------------- - ! to atm: merged direct albedo (visible radiation) - ! to atm: merged diffuse albedo (visible radiation) - ! to atm: merged direct albedo (near-infrared radiation) - ! to atm: merged diffuse albedo (near-infrared radiation) - ! --------------------------------------------------------------------- - allocate(suffix(4)) - suffix = (/'avsdr', 'avsdf', 'anidr', 'anidf'/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds, 'Si_'//trim(suffix(n))) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged reference temperature at 2 meters - ! to atm: merged reference specific humidity at 2 meters - ! --------------------------------------------------------------------- - allocate(suffix(3)) - suffix = (/'tref ', 'u10 ', 'qref '/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds , 'Sl_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds , 'Si_'//trim(suffix(n))) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged zonal surface stress - ! to atm: merged meridional surface stress - ! --------------------------------------------------------------------- - allocate(suffix(2)) - suffix = (/'taux', 'tauy'/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_'//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))) - else - ! (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') - - ! (cam, aqua-planet) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged surface temperature and unmerged temperatures from ice and ocn - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Sl_t') - call addfld(fldListFr(compice)%flds, 'Si_t') - call addfld(fldListFr(compocn)%flds, 'So_t') - - call addfld(fldListTo(compatm)%flds, 'So_t') - call addfld(fldListTo(compatm)%flds, 'Sx_t') - else - ! 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') - call addmrg(fldListTo(compatm)%flds, 'So_t', & - mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') - end if - end if - - ! --------------------------------------------------------------------- - ! to atm: surface saturation specific humidity in ocean from med aoflux - ! to atm: square of exch. coeff (tracers) from med aoflux - ! to atm: surface fraction velocity from med aoflux - ! --------------------------------------------------------------------- - allocate(flds(3)) - flds = (/'So_ssq', 'So_ustar', 'So_re'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , trim(fldname)) - call addfld(fldListTo(compatm)%flds , trim(fldname)) - 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 addmrg(fldListTo(compatm)%flds , trim(fldname), & - mrg_from1=compmed, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - !===================================================================== ! FIELDS TO OCEAN (compocn) !===================================================================== @@ -497,7 +276,7 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) !---------------------------------------------------------- allocate(flds(2)) flds = (/'Faxa_snowc', 'Faxa_snowl'/) -! + do n = 1,size(flds) fldname = trim(flds(n)) if (phase == 'advertise') then @@ -571,36 +350,15 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) deallocate(flds) ! --------------------------------------------------------------------- - ! to ocn: surface upward longwave heat flux from mediator - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_lwup') - call addfld(fldListTo(compocn)%flds , 'Foxx_lwup') - else - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: merged longwave net heat flux + ! to ocn: longwave net heat flux ! --------------------------------------------------------------------- if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_lwdn') - call addfld(fldListMed_aoflux%flds , 'Faox_lwup' ) - call addfld(fldListTo(compocn)%flds , 'Foxx_lwnet') + call addfld(fldListFr(compatm)%flds, 'Faxa_lwnet') + call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') else - ! (mom6) (send longwave net to ocn via auto merge) - if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_lwnet', rc=rc) .and. & - fldchk(is_local%wrap%FBMed_aoflux_o , 'Faox_lwup' , rc=rc) .and. & - 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') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_lwnet', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & + mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy') end if ! --------------------------------------------------------------------- @@ -619,59 +377,15 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) end if ! --------------------------------------------------------------------- - ! to ocn: net shortwave radiation from med + ! to ocn: net shortwave radiation from atm ! --------------------------------------------------------------------- if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swvdr') - call addfld(fldListFr(compatm)%flds, 'Faxa_swndr') - call addfld(fldListFr(compatm)%flds, 'Faxa_swvdf') - call addfld(fldListFr(compatm)%flds, 'Faxa_swndf') - - call addfld(fldListFr(compice)%flds, 'Fioi_swpen') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdf') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idf') - + call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') call addfld(fldListTo(compocn)%flds, 'Foxx_swnet') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdf') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idf') else - ! Net shortwave ocean (custom calculation in prep_phases_ocn_mod.F90) - - ! import swpen from ice without bands - if (fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Fioi_swpen', compocn, mapfcopy, 'unset', 'unset') - end if - - ! import swpen from ice by bands - if ( fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdf', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idf', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdr', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdf', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idr', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idf', compocn, mapfcopy, 'unset', 'unset') - end if - - ! import sw from atm by bands - if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdf', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & - (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet' , rc=rc)) .or. & - (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', rc=rc))) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swvdr', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swvdf', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swndr', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swndf', compocn, mapconsf, 'one', atm2ocn_fmap) - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_swnet', & + mrg_from1=compatm, mrg_fld1='Faxa_swnet', mrg_type1='copy') end if ! --------------------------------------------------------------------- @@ -700,78 +414,40 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) end if ! --------------------------------------------------------------------- - ! to ocn: merged sensible heat flux + ! to ocn: sensible heat flux from atm ! --------------------------------------------------------------------- if (phase == 'advertise') then call addfld(fldListFr(compatm)%flds , 'Faxa_sen') - call addfld(fldListMed_aoflux%flds , 'Faox_sen') - call addfld(fldListFr(compice)%flds , 'Fioi_melth') call addfld(fldListTo(compocn)%flds , 'Foxx_sen') else - 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') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_sen', & + mrg_from1=compatm, mrg_fld1='Faxa_sen', mrg_type1='copy') end if ! --------------------------------------------------------------------- ! to ocn: surface latent heat flux and evaporation water flux ! --------------------------------------------------------------------- if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_lat' ) - call addfld(fldListMed_aoflux%flds , 'Faox_lat' ) - call addfld(fldListMed_aoflux%flds , 'Faox_evap') - call addfld(fldListTo(compocn)%flds, 'Foxx_lat' ) - call addfld(fldListTo(compocn)%flds, 'Foxx_evap') - else - 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') - 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') - end if - end if - - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_lat_wiso' ) - call addfld(fldListTo(compocn)%flds, 'Foxx_lat_wiso' ) - else - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: wind speed squared at 10 meters from med - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'So_duu10n') - call addfld(fldListTo(compocn)%flds, 'So_duu10n') + call addfld(fldListFr(compatm)%flds , 'Faxa_lat') + call addfld(fldListTo(compocn)%flds , 'Foxx_lat') else - if ( fldchk(is_local%wrap%FBMed_aoflux_o, 'So_duu10n', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'So_duu10n', rc=rc)) then - 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') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_lat', & + mrg_from1=compatm, mrg_fld1='Faxa_lat', mrg_type1='copy') end if ! --------------------------------------------------------------------- ! to ocn: sea level pressure from atm ! to ocn: zonal wind at the lowest model level from atm ! to ocn: meridional wind at the lowest model level from atm + ! to ocn: wind speed at the lowest model level from atm ! to ocn: temperature at the lowest model level from atm + ! to ocn: sea surface skin temperature ! to ocn: specific humidity at the lowest model level from atm ! --------------------------------------------------------------------- - allocate(flds(6)) - flds = (/'Sa_pslv', 'Sa_u', 'Sa_v', 'Sa_wspd', 'Sa_tbot', 'Sa_shum'/) + allocate(flds(7)) + flds = (/'Sa_pslv', 'Sa_u', 'Sa_v', 'Sa_wspd', 'Sa_tbot', 'Sa_tskn', 'Sa_shum'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -790,25 +466,19 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) deallocate(flds) ! --------------------------------------------------------------------- - ! to ocn: merge zonal surface stress from ice and (atm or med) + ! to ocn: zonal and meridional surface stress from atm ! --------------------------------------------------------------------- allocate(suffix(2)) suffix = (/'taux', 'tauy'/) do n = 1,size(suffix) if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(suffix(n))) call addfld(fldListFr(compatm)%flds , 'Faxa_'//trim(suffix(n))) call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) else - if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_'//trim(suffix(n)), rc=rc) .and. & - 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') - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n)), compocn, mapconsf, 'one', atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & + mrg_from1=compatm, mrg_fld1='Faxa_'//trim(suffix(n)), mrg_type1='copy') end if end do deallocate(suffix) From fba6d60d0f7bbed35992ef6b32b07c215e04c835 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 11:46:46 -0600 Subject: [PATCH 017/206] fix for ESMF verbosity attribute --- mediator/med.F90 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index ce870f81e..a965b06ec 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -430,11 +430,16 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) logUnit = 6 endif - call ESMF_AttributeGet(gcomp, name="Verbosity", value=value, defaultValue="max", & + call ESMF_AttributeGet(gcomp, name="Verbosity", value=value, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(value), ESMF_LOGMSG_INFO) + call ESMF_AttributeGet(gcomp, name="Profiling", value=value, & + convention="NUOPC", purpose="Instance", rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//": Mediator profiling is "//trim(value), ESMF_LOGMSG_INFO) + write(msgString,'(A,i6)') trim(subname)//' dbug_flag = ',dbug_flag call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) From 2f70edb32a740b360bd388e8f194169bbfa5218b Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 11:47:11 -0600 Subject: [PATCH 018/206] do not need custom calculations for HAFS app --- mediator/med_phases_prep_ocn_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 3076eab37..0d9357457 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -216,7 +216,7 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) !--- custom calculations !--------------------------------------- - if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then + if (trim(coupling_mode) == 'cesm') then !------------- ! Compute netsw for ocean From 55f8f98667b4e092a920160790fd41f23130b5be Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 14:54:49 -0600 Subject: [PATCH 019/206] remove newly added Sa_wspd from CESM field dictionary --- drivers/cime/ensemble_driver.F90 | 4 ++++ mediator/fd_cesm.yaml | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/cime/ensemble_driver.F90 b/drivers/cime/ensemble_driver.F90 index 8ddbb727f..6b21d8f05 100644 --- a/drivers/cime/ensemble_driver.F90 +++ b/drivers/cime/ensemble_driver.F90 @@ -261,6 +261,10 @@ subroutine SetModelServices(ensemble_driver, rc) endif call shr_file_setLogUnit (logunit) + ! Disable hierarchy connectors + !call NUOPC_CompAttributeSet(driver, name="HierarchyProtocol", value="OFF", rc=rc) + !if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Create a clock for each driver instance call esm_time_clockInit(ensemble_driver, driver, logunit, mastertask, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 687f1b9b8..5c9199c47 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -359,11 +359,6 @@ canonical_units: m s-1 description: atmosphere export - bottom layer meridional wind # - - standard_name: Sa_wspd - alias: inst_wind_speed_height_lowest - canonical_units: m s-1 - description: atmosphere export - bottom layer wind speed - # - standard_name: Sa_z alias: inst_height_lowest canonical_units: m From 215cea72658d5e461479535773f6f5c2b05262f3 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Tue, 21 Jul 2020 14:57:25 -0600 Subject: [PATCH 020/206] remove newly added Sa_wspd from CESM field dictionary --- mediator/fd_cesm.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 687f1b9b8..5c9199c47 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -359,11 +359,6 @@ canonical_units: m s-1 description: atmosphere export - bottom layer meridional wind # - - standard_name: Sa_wspd - alias: inst_wind_speed_height_lowest - canonical_units: m s-1 - description: atmosphere export - bottom layer wind speed - # - standard_name: Sa_z alias: inst_height_lowest canonical_units: m From 9037506ff6a5340e266bdd53115030963dc78351 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 22 Jul 2020 11:48:27 -0600 Subject: [PATCH 021/206] add HAFS specific field dictionary --- mediator/fd_hafs.yaml | 485 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 mediator/fd_hafs.yaml diff --git a/mediator/fd_hafs.yaml b/mediator/fd_hafs.yaml new file mode 100644 index 000000000..a4d737360 --- /dev/null +++ b/mediator/fd_hafs.yaml @@ -0,0 +1,485 @@ + field_dictionary: + version_number: 0.0.0 + institution: National ESPC, CSC & MCL Working Groups + source: automatically generated by the NUOPC Layer + description: Community-based dictionary for shared coupling fields + entries: + # + #----------------------------------- + # section: atmosphere export + #----------------------------------- + # + # + - standard_name: Faxa_snowc + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_snowl + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_swnet + canonical_units: W m-2 + description: atmosphere export + # + - standard_name: Faxa_lwnet + canonical_units: W m-2 + description: atmosphere export + # + - standard_name: Sa_topo + alias: inst_surface_height + canonical_units: m + description: atmosphere export - topographic height + # + - standard_name: Sa_z + alias: inst_height_lowest + canonical_units: m + description: atmosphere export - bottom layer height + # + - standard_name: Sa_pbot + alias: inst_pres_height_lowest + canonical_units: Pa + description: atmosphere export - pressure at lowest model layer + # + - standard_name: Sa_ptem + canonical_units: K + description: atmosphere export - bottom layer potential temperature + # + - standard_name: Faxa_lwdn + alias: mean_down_lw_flx + canonical_units: W m-2 + description: atmosphere export - mean downward SW heat flux + # + - standard_name: Faxa_swndf + alias: mean_down_sw_ir_dif_flx + canonical_units: W m-2 + description: atmosphere export - mean surface downward nir diffuse flux + # + - standard_name: Faxa_swndr + alias: mean_down_sw_ir_dir_flx + canonical_units: W m-2 + description: atmosphere export - mean surface downward nir direct flux + # + - standard_name: Faxa_swvdf + alias: mean_down_sw_vis_dif_flx + canonical_units: W m-2 + description: atmosphere export - mean surface downward uv+vis diffuse flux + # + - standard_name: Faxa_swvdr + alias: mean_down_sw_vis_dir_flx + canonical_units: W m-2 + description: atmosphere export - mean surface downward uv+visvdirect flux + # + - standard_name: Faxa_swdn + alias: mean_down_sw_flx + canonical_units: W m-2 + description: atmosphere export - mean downward SW heat flux + # + - standard_name: Faxa_rainc + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_rainl + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_rain + alias: mean_prec_rate + canonical_units: kg m-2 s-1 + description: atmosphere export + # + - standard_name: Faxa_lat + alias: mean_laten_heat_flx_atm + canonical_units: W m-2 + description: atmosphere export + # + - standard_name: Faxa_sen + alias: mean_sensi_heat_flx_atm + canonical_units: W m-2 + description: atmosphere export + # + - standard_name: Sa_pslv + alias: inst_pres_height_surface + canonical_units: Pa + description: atmosphere export + # + - standard_name: Sa_u + alias: inst_zonal_wind_height_lowest + canonical_units: m s-1 + description: atmosphere export - bottom layer zonal wind + # + - standard_name: Sa_v + alias: inst_merid_wind_height_lowest + canonical_units: m s-1 + description: atmosphere export - bottom layer meridional wind + # + - standard_name: Sa_wspd + alias: inst_wind_speed_height_lowest + canonical_units: m s-1 + description: atmosphere export - bottom layer wind speed + # + - standard_name: Sa_tbot + alias: inst_temp_height_lowest + canonical_units: K + description: atmosphere export - bottom layer temperature + # + - standard_name: Sa_tskn + alias: inst_temp_skin_temperature + canonical_units: K + description: atmosphere export - sea surface skin temperature + # + - standard_name: Sa_shum + alias: inst_spec_humid_height_lowest + canonical_units: kg kg-1 + description: atmosphere export - bottom layer specific humidity + # + - standard_name: Faxa_taux + alias: mean_zonal_moment_flx_atm + canonical_units: N m-2 + description: atmosphere export - zonal component of momentum flux + # + - standard_name: Faxa_tauy + alias: mean_merid_moment_flx_atm + canonical_units: N m-2 + description: atmosphere export - meridional component of momentum flux + # + - standard_name: Sa_dens + alias: air_density_height_lowest + canonical_units: kg m-3 + description: atmosphere export - density at the lowest model layer + # + #----------------------------------- + # section: atmosphere import + #----------------------------------- + # + - standard_name: Faxx_taux + alias: mean_zonal_moment_flx + canonical_units: N m-2 + description: atmosphere import - zonal component of momentum flux + # + - standard_name: Faxx_tauy + alias: mean_merid_moment_flx + canonical_units: N m-2 + description: atmosphere import - meridional component of momentum flux + # + - standard_name: Sx_anidf + canonical_units: 1 + description: atmosphere import + # + - standard_name: Sx_anidr + canonical_units: 1 + description: atmosphere import + # + - standard_name: Sx_avsdf + canonical_units: 1 + description: atmosphere import + # + - standard_name: Sx_avsdr + canonical_units: 1 + description: atmosphere import + # + - standard_name: Sx_tref + canonical_units: K + description: atmosphere import + # + - standard_name: Sx_qref + canonical_units: kg kg-1 + description: atmosphere import + # + - standard_name: Sx_t + alias: surface_temperature + canonical_units: K + description: atmosphere import + # + - standard_name: Sx_u10 + canonical_units: m + description: atmosphere import + # + #----------------------------------- + # section: ocean export to mediator + #----------------------------------- + # + - standard_name: So_t + alias: sea_surface_temperature + canonical_units: K + description: ocean export + # + - standard_name: So_s + alias: s_surf + canonical_units: g kg-1 + description: ocean export + # + - standard_name: So_ssq + canonical_units: kg kg-1 + description: ocean export + # + - standard_name: So_u + alias: ocn_current_zonal + canonical_units: m s-1 + description: ocean export + # + - standard_name: So_v + alias: ocn_current_merid + canonical_units: m s-1 + description: ocean export + # + - standard_name: So_ustar + canonical_units: m s-1 + description: ocean export + # + - standard_name: So_re + canonical_units: 1 + description: ocean export + # + - standard_name: So_duu10n + canonical_units: m2 s-2 + description: ocean export + # + - standard_name: So_omask + alias: ocean_mask + canonical_units: 1 + description: ocean export + # + - standard_name: So_ofrac + canonical_units: 1 + description: ocean export + # + #----------------------------------- + # section: ocean import + #----------------------------------- + # + - standard_name: Foxx_evap + alias: mean_evap_rate + canonical_units: kg m-2 s-1 + description: ocean import - specific humidity flux + # + - standard_name: Foxx_evap_wiso + alias: mean_evap_rate_wiso + canonical_units: kg m-2 s-1 + description: ocean import - specific humidity flux 16O, 18O, HDO + # + - standard_name: Foxx_swnet + alias: mean_net_sw_flx + canonical_units: W m-2 + description: ocean import - net shortwave radiation to ocean + # + - standard_name: Foxx_lwnet + alias: mean_net_lw_flx + canonical_units: W m-2 + description: ocean import - net long wave radiation to ocean + # + - standard_name: Foxx_lwup + canonical_units: W m-2 + description: ocean import - surface upward longwave heat flux + # + - standard_name: Foxx_swnet_vdr + alias: mean_net_sw_vis_dir_flx + canonical_units: W m-2 + description: ocean import - net shortwave visible direct radiation to ocean + # + - standard_name: Foxx_swnet_vdf + alias: mean_net_sw_vis_dif_flx + canonical_units: W m-2 + description: ocean import - net shortwave visible diffuse radiation to ocean + # + - standard_name: Foxx_swnet_idr + alias: mean_net_sw_ir_dir_flx + canonical_units: W m-2 + description: ocean import - net shortwave ir direct radiation to ocean + # + - standard_name: Foxx_swnet_idf + alias: mean_net_sw_ir_dif_flx + canonical_units: W m-2 + description: ocean import - net shortwave ir diffuse radiation to ocean + # + - standard_name: Foxx_sen + alias: mean_sensi_heat_flx + canonical_units: W m-2 + description: ocean import - sensible heat flux into ocean + # + - standard_name: Foxx_lat + canonical_units: W m-2 + description: ocean import - latent heat flux into ocean + # + - standard_name: Foxx_lat_wiso + canonical_units: W m-2 + description: ocean import - latent heat flux into ocean for 16O, 18O, HDO + # + - standard_name: Foxx_taux + alias: mean_zonal_moment_flx + canonical_units: N m-2 + description: ocean import - zonal surface stress + # + - standard_name: Foxx_tauy + alias: mean_merid_moment_flx + canonical_units: N m-2 + description: ocean import - meridional surface stress + # + #----------------------------------- + # section: sea-ice export + #----------------------------------- + # + - standard_name: Si_ifrac + alias: ice_fraction + canonical_units: 1 + description: sea-ice export to atm ice fraction (varies with time) + # + - standard_name: Si_imask + alias: ice_mask + canonical_units: 1 + description: sea-ice export - ice mask + # + - standard_name: Faii_swnet + canonical_units: W m-2 + description: sea-ice export to atm + # + - standard_name: Si_anidf + alias: inst_ice_ir_dif_albedo + canonical_units: 1 + description: sea-ice export to atm + # + - standard_name: Si_anidr + alias: inst_ice_ir_dir_albedo + canonical_units: 1 + description: sea-ice export to atm + # + - standard_name: Si_avsdf + alias: inst_ice_vis_dif_albedo + canonical_units: 1 + description: sea-ice export to atm + # + - standard_name: Si_avsdr + alias: inst_ice_vis_dir_albedo + canonical_units: 1 + description: sea-ice export to atm + # + - standard_name: Si_t + alias: sea_ice_temperature + canonical_units: K + description: sea-ice export + # + - standard_name: Si_tref + canonical_units: K + description: sea-ice export + # + - standard_name: Si_qref + canonical_units: kg kg-1 + description: sea-ice export to atm + # + - standard_name: Si_u10 + canonical_units: m + description: sea-ice export + # + - standard_name: Faii_taux + alias: stress_on_air_ice_zonal + canonical_units: N m-2 + description: sea-ice export to atm - air ice zonal stress + # + - standard_name: Faii_tauy + alias: stress_on_air_ice_merid + canonical_units: N m-2 + description: sea-ice export - air ice meridional stress + # + - standard_name: Fioi_swpen + alias: mean_sw_pen_to_ocn + canonical_units: W m-2 + description: sea-ice export to ocean - flux of shortwave through ice to ocean + # + - standard_name: Fioi_swpen_vdr + alias: mean_sw_pen_to_ocn_vis_dir_flx + canonical_units: W m-2 + description: sea-ice export to ocean - flux of vis dir shortwave through ice to ocean + # + - standard_name: Fioi_swpen_vdf + alias: mean_sw_pen_to_ocn_vis_dif_flx + canonical_units: W m-2 + description: sea-ice export to ocean - flux of vif dir shortwave through ice to ocean + # + - standard_name: Fioi_swpen_idr + alias: mean_sw_pen_to_ocn_ir_dir_flx + canonical_units: W m-2 + description: sea-ice export to ocean - flux of ir dir shortwave through ice to ocean + # + - standard_name: Fioi_swpen_idf + alias: mean_sw_pen_to_ocn_ir_dif_flx + canonical_units: W m-2 + description: sea-ice export to ocean - flux of ir dif shortwave through ice to ocean + # + - standard_name: Fioi_melth + alias: net_heat_flx_to_ocn + canonical_units: W m-2 + description: sea-ice export to ocean - net heat flux to ocean + # + - standard_name: Fioi_taux + alias: stress_on_ocn_ice_zonal + canonical_units: N m-2 + description: sea-ice export to ocean - ice ocean zonal stress + # + - standard_name: Fioi_tauy + alias: stress_on_ocn_ice_merid + canonical_units: N m-2 + description: sea-ice export to ocean - ice ocean meridional stress + # + #----------------------------------- + # section: sea-ice import + #----------------------------------- + # + # + #----------------------------------- + # section: land export + #----------------------------------- + # + - standard_name: Sl_lfrac + canonical_units: 1 + description: land export + # + - standard_name: Fall_swnet + canonical_units: W m-2 + description: land export + # + - standard_name: Sl_anidf + canonical_units: 1 + description: land export + # + - standard_name: Sl_anidr + canonical_units: 1 + description: land export + # + - standard_name: Sl_avsdf + canonical_units: 1 + description: land export + # + - standard_name: Sl_avsdr + canonical_units: 1 + description: land export + # + - standard_name: Sl_t + canonical_units: K + description: land export + # + - standard_name: Sl_tref + canonical_units: K + description: mediator export to glc - no elevation classes + # + - standard_name: Sl_qref + canonical_units: kg kg-1 + description: land export + # + - standard_name: Fall_taux + canonical_units: N m-2 + description: land export + # + - standard_name: Fall_tauy + canonical_units: N m-2 + description: land export + # + - standard_name: Sl_u10 + canonical_units: m + description: land export + # + #----------------------------------- + # mediator fields + #----------------------------------- + # + - standard_name: cpl_scalars + canonical_units: unitless From 130ad41fa126b6ca6a3caca9fb8e6546065e9ce5 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 22 Jul 2020 14:14:15 -0600 Subject: [PATCH 022/206] more fix for CMEPS verbosity and profiling --- cime_config/namelist_definition_drv.xml | 32 +++++++++++++++---------- mediator/med.F90 | 4 ++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 125eca3f2..6e0b69e08 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -12,19 +12,19 @@ char nuopc DRIVER_attributes + off,low,high,max - $INFO_DBUG + low - - char nuopc DRIVER_attributes + off,low,high,max - 0 + off @@ -32,8 +32,9 @@ char nuopc MED_attributes + off,low,high,max - $INFO_DBUG + low @@ -41,8 +42,9 @@ char nuopc ATM_attributes + off,low,high,max - $INFO_DBUG + low @@ -50,8 +52,9 @@ char nuopc OCN_attributes + off,low,high,max - $INFO_DBUG + low @@ -59,8 +62,9 @@ char nuopc ICE_attributes + off,low,high,max - $INFO_DBUG + low @@ -68,8 +72,9 @@ char nuopc ROF_attributes + off,low,high,max - $INFO_DBUG + low @@ -77,8 +82,9 @@ char nuopc LND_attributes + off,low,high,max - $INFO_DBUG + low @@ -86,17 +92,19 @@ char nuopc GLC_attributes + off,low,high,max - $INFO_DBUG + low char nuopc + off,low,high,max WAV_attributes - $INFO_DBUG + low diff --git a/mediator/med.F90 b/mediator/med.F90 index a965b06ec..811948099 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -433,12 +433,12 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) call ESMF_AttributeGet(gcomp, name="Verbosity", value=value, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(value), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": Mediator verbosity is set to "//trim(value), ESMF_LOGMSG_INFO) call ESMF_AttributeGet(gcomp, name="Profiling", value=value, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator profiling is "//trim(value), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(value), ESMF_LOGMSG_INFO) write(msgString,'(A,i6)') trim(subname)//' dbug_flag = ',dbug_flag call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) From 802dd3cf5ccc4dccd17acd481d56571146b2f97c Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 22 Jul 2020 15:51:04 -0600 Subject: [PATCH 023/206] fix for ESMF verbosity and profiling --- cime_config/config_component.xml | 27 +++++++++++++++++++++++++ cime_config/namelist_definition_drv.xml | 23 ++++++++++----------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 2f029f123..036930492 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -996,6 +996,33 @@ + + char + off,low,high,max + low + run_flags + env_run.xml + + Determines the verbosity level in ESMF log files + "off": no verbosity + "low": some verbosity + "high": more verbosity + "max": all lower 16 bits + By default, the verbosity level is set to "low" + + + + + char + 0 + run_flags + env_run.xml + + Determines the profiling level in ESMF log files + by default, it is set to 0 (only run method execution timings) + + + logical TRUE,FALSE diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 6e0b69e08..be38a1fdc 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -8,13 +8,13 @@ - + char nuopc DRIVER_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -22,9 +22,8 @@ char nuopc DRIVER_attributes - off,low,high,max - off + $ESMF_PROFILING_LEVEL @@ -34,7 +33,7 @@ MED_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -44,7 +43,7 @@ ATM_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -54,7 +53,7 @@ OCN_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -64,7 +63,7 @@ ICE_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -74,7 +73,7 @@ ROF_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -84,7 +83,7 @@ LND_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -94,7 +93,7 @@ GLC_attributes off,low,high,max - low + $ESMF_VERBOSITY_LEVEL @@ -104,7 +103,7 @@ off,low,high,max WAV_attributes - low + $ESMF_VERBOSITY_LEVEL From c5309aa738babd7315186e60eda752d9f7ed2b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ufuk=20Turun=C3=A7o=C4=9Flu?= Date: Fri, 24 Jul 2020 15:55:25 -0600 Subject: [PATCH 024/206] put extra control to coupling mode --- cime_config/buildnml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index 60c5a5c53..13cf826db 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -571,8 +571,10 @@ 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") - else: + elif coupling_mode == 'nems': filename = os.path.join(fd_dir,"fd_nems.yaml") + else: + expect(False, "coupling mode currently only supports cesm, hafs and nems") shutil.copy(filename, os.path.join(rundir, "fd.yaml")) ############################################################################### From 58d78baa46f3b1d24008c4755f0580da39ab764e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ufuk=20Turun=C3=A7o=C4=9Flu?= Date: Fri, 24 Jul 2020 15:59:11 -0600 Subject: [PATCH 025/206] add modify_via_xml to remaining verbosity and profiling variables --- cime_config/namelist_definition_drv.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index be38a1fdc..3bbc58483 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -18,7 +18,7 @@ - + char nuopc DRIVER_attributes @@ -27,7 +27,7 @@ - + char nuopc MED_attributes @@ -37,7 +37,7 @@ - + char nuopc ATM_attributes @@ -47,7 +47,7 @@ - + char nuopc OCN_attributes @@ -57,7 +57,7 @@ - + char nuopc ICE_attributes @@ -67,7 +67,7 @@ - + char nuopc ROF_attributes @@ -77,7 +77,7 @@ - + char nuopc LND_attributes @@ -87,7 +87,7 @@ - + char nuopc GLC_attributes @@ -97,7 +97,7 @@ - + char nuopc off,low,high,max From 2a653f369773b3505f6c112241fc9309977af499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ufuk=20Turun=C3=A7o=C4=9Flu?= Date: Fri, 24 Jul 2020 16:00:23 -0600 Subject: [PATCH 026/206] the debug code is removed --- drivers/cime/ensemble_driver.F90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/cime/ensemble_driver.F90 b/drivers/cime/ensemble_driver.F90 index 6b21d8f05..8ddbb727f 100644 --- a/drivers/cime/ensemble_driver.F90 +++ b/drivers/cime/ensemble_driver.F90 @@ -261,10 +261,6 @@ subroutine SetModelServices(ensemble_driver, rc) endif call shr_file_setLogUnit (logunit) - ! Disable hierarchy connectors - !call NUOPC_CompAttributeSet(driver, name="HierarchyProtocol", value="OFF", rc=rc) - !if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create a clock for each driver instance call esm_time_clockInit(ensemble_driver, driver, logunit, mastertask, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return From 96053fb8100253a6cdc771d94b79e38b3f6c3d65 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Fri, 24 Jul 2020 16:06:25 -0600 Subject: [PATCH 027/206] fix run sequence for HAFS app --- cime_config/runseq/runseq_general.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 19bb247d4..8a7126ab5 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -19,6 +19,7 @@ def gen_runseq(case, coupling_times): caseroot = case.get_value("CASEROOT") cpl_seq_option = case.get_value('CPL_SEQ_OPTION') cpl_add_aoflux = case.get_value('ADD_AOFLUX_TO_RUNSEQ') + coupling_mode = case.get_value('COUPLING_MODE') # It is assumed that if a component will be run it will send information to the mediator # so the flags run_xxx and xxx_to_med are redundant @@ -103,7 +104,10 @@ def gen_runseq(case, coupling_times): 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("OCN -> MED :remapMethod=redist" , 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) + else: + runseq.add_action("OCN -> MED :remapMethod=redist" , 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: @@ -128,7 +132,10 @@ def gen_runseq(case, coupling_times): #------------------ runseq.add_action("OCN" , run_ocn and ocn_outer_loop) - runseq.add_action("OCN -> MED :remapMethod=redist" , 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) + else: + runseq.add_action("OCN -> MED :remapMethod=redist" , run_ocn and ocn_outer_loop) #------------------ runseq.leave_time_loop(ocn_outer_loop) From 8277b3201b26bdb7908d490a1db12f396f95a75f Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Mon, 27 Jul 2020 09:14:42 -0600 Subject: [PATCH 028/206] remove nems_orig from conditional --- mediator/med_phases_prep_atm_mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index efbe9d288..dc5ebf4bd 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -138,7 +138,6 @@ subroutine med_phases_prep_atm(gcomp, rc) ! Assumption here is that fluxes are computed on the ocean grid if (trim(coupling_mode) == 'cesm' .or. & - trim(coupling_mode) == 'nems_orig' .or. & trim(coupling_mode) == 'hafs') then call med_map_FB_Regrid_Norm(& fldsSrc=fldListMed_aoflux%flds, & From d1d06c1b62a1e0d737939ef87c2334b778f79c8c Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 29 Jul 2020 12:30:20 -0600 Subject: [PATCH 029/206] add missing fields to CESM field dictionary to work with ERA5 --- mediator/fd_cesm.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index d65f7c870..08cba35a1 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -282,6 +282,10 @@ canonical_units: W m-2 description: atmosphere export # + - standard_name: Faxa_lwnet + canonical_units: W m-2 + description: atmosphere export + # - standard_name: Faxa_swndf alias: mean_down_sw_ir_dif_flx canonical_units: W m-2 @@ -349,6 +353,11 @@ canonical_units: K description: atmosphere export - bottom layer temperature # + - standard_name: Sa_tskn + alias: inst_temp_skin_temperature + canonical_units: K + description: atmosphere export - sea surface skin temperature + # - standard_name: Sa_u alias: inst_zonal_wind_height_lowest canonical_units: m s-1 @@ -359,6 +368,11 @@ canonical_units: m s-1 description: atmosphere export - bottom layer meridional wind # + - standard_name: Sa_wspd + alias: inst_wind_speed_height_lowest + canonical_units: m s-1 + description: atmosphere export - bottom layer wind speed + # - standard_name: Sa_z alias: inst_height_lowest canonical_units: m From b20e191c71b5ae4889faace3b5c722d693cd4198 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sun, 2 Aug 2020 12:22:52 -0600 Subject: [PATCH 030/206] fix for FB diagnose using wrong bundle --- mediator/med_phases_prep_ocn_mod.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index d182fe998..7ed2de5f8 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -280,19 +280,19 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) if (ncnt > 0) then ! average ocn accumulator - if (dbug_flag > 1) then + !if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & string=trim(subname)//' FBExpAccum(compocn) before avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + !end if call FB_average(is_local%wrap%FBExpAccum(compocn), & is_local%wrap%FBExpAccumCnt(compocn), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compocn), & + !if (dbug_flag > 1) then + call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & string=trim(subname)//' FBExpAccum(compocn) after avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + !end if ! copy to FBExp(compocn) call FB_copy(is_local%wrap%FBExp(compocn), is_local%wrap%FBExpAccum(compocn), rc=rc) From a914eb99df337f9a73b2d4c2b5e8d9428c754d6d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 12 Aug 2020 10:02:06 -0600 Subject: [PATCH 031/206] fix for char initialization --- cime_config/config_component_cesm.xml | 4 ++-- mediator/esmFldsExchange_hafs_mod.F90 | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cime_config/config_component_cesm.xml b/cime_config/config_component_cesm.xml index ec338fdb2..8abf8d37f 100644 --- a/cime_config/config_component_cesm.xml +++ b/cime_config/config_component_cesm.xml @@ -84,7 +84,7 @@ integer - 4 + 12 run_flags env_run.xml Maximum code stack depth of enabled timers. @@ -527,7 +527,7 @@ TRUE + feedbacks for a TG compset, this will give us additional diagnostics --> TRUE run_glc diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index 409cafc7b..92b90d16c 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -195,7 +195,7 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! --------------------------------------------------------------------- if (phase /= 'advertise') then allocate(flds(6)) - flds = (/'Sa_u', 'Sa_v', 'Sa_z', 'Sa_tbot', 'Sa_pbot', 'Sa_shum'/) + flds = (/'Sa_u ', 'Sa_v ', 'Sa_z ', 'Sa_tbot', 'Sa_pbot', 'Sa_shum'/) do n = 1,size(flds) fldname = trim(flds(n)) call addfld(fldListFr(compatm)%flds, trim(fldname)) @@ -294,7 +294,7 @@ subroutine esmFldsExchange_hafs(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)) @@ -331,7 +331,7 @@ subroutine esmFldsExchange_hafs(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)) @@ -377,7 +377,7 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) end if ! --------------------------------------------------------------------- - ! to ocn: net shortwave radiation from atm + ! to ocn: net shortwave radiation from atm ! --------------------------------------------------------------------- if (phase == 'advertise') then call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') @@ -447,7 +447,7 @@ subroutine esmFldsExchange_hafs(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', 'Sa_shum'/) + flds = (/'Sa_pslv', 'Sa_u ', 'Sa_v ', 'Sa_wspd', 'Sa_tbot', 'Sa_tskn', 'Sa_shum'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -463,7 +463,7 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) end if end if end do - deallocate(flds) + deallocate(flds) ! --------------------------------------------------------------------- ! to ocn: zonal and meridional surface stress from atm From 593c52697274072be6bb728d3127cb00a715ef6d Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 07:27:33 -0400 Subject: [PATCH 032/206] reset if flags for debugging --- mediator/med_phases_prep_ocn_mod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 6b22dbd7c..e1189049d 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -280,19 +280,19 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) if (ncnt > 0) then ! average ocn accumulator - !if (dbug_flag > 1) then + if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & string=trim(subname)//' FBExpAccum(compocn) before avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !end if + end if call FB_average(is_local%wrap%FBExpAccum(compocn), & is_local%wrap%FBExpAccumCnt(compocn), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !if (dbug_flag > 1) then + if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & string=trim(subname)//' FBExpAccum(compocn) after avg ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !end if + end if ! copy to FBExp(compocn) call FB_copy(is_local%wrap%FBExp(compocn), is_local%wrap%FBExpAccum(compocn), rc=rc) From dd8022cd5fb57e318b2b2af22d8ac798c5875a90 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 07:31:56 -0400 Subject: [PATCH 033/206] white space change --- mediator/med_methods_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index 649f8eb3c..8061a1752 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -163,7 +163,7 @@ subroutine med_methods_FB_RWFields(mode,fname,FB,flag,rc) enddo call med_methods_FB_diagnose(FB, 'read '//trim(fname), rc) - if (present(flag)) flag = .true. + if (present(flag)) flag = .true. endif else From d1632af7506d1a59397f0f66cb6aedbe06900a75 Mon Sep 17 00:00:00 2001 From: Denise Worthen Date: Fri, 14 Aug 2020 07:47:42 -0400 Subject: [PATCH 034/206] Update med.F90 Change a few comments --- mediator/med.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 4a9f343f8..5be4575a6 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -430,7 +430,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) logUnit = 6 endif - ! Obtain Verbosity setting from MED_attributes + ! Obtain Verbosity call ESMF_AttributeGet(gcomp, name="Verbosity", value=cvalue, defaultValue="max", & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -446,7 +446,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(value), ESMF_LOGMSG_INFO) - ! Obtain dbug_flag setting from MED_attributes if present; otherwise use default value in med_constants + ! 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) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then From cc416c2a83440ec5c6d8850c58e59ea90e7650ff Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 09:43:58 -0400 Subject: [PATCH 035/206] minor clode cleanup remove error codes on LOGMSG write remote chk_error on return codes from LOGMSG writes --- mediator/esmFlds.F90 | 36 +++++------ mediator/med.F90 | 57 +++++++----------- mediator/med_fraction_mod.F90 | 10 ++-- mediator/med_merge_mod.F90 | 12 ++-- mediator/med_methods_mod.F90 | 90 ++++++++++++++-------------- mediator/med_phases_aofluxes_mod.F90 | 10 ++-- mediator/med_phases_ocnalb_mod.F90 | 17 +++--- mediator/med_phases_prep_atm_mod.F90 | 9 ++- mediator/med_phases_prep_rof_mod.F90 | 23 ++++--- mediator/med_phases_prep_wav_mod.F90 | 5 +- mediator/med_phases_profile_mod.F90 | 2 +- mediator/med_utils_mod.F90 | 4 +- 12 files changed, 126 insertions(+), 149 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 010aa3447..cf3afec5a 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -106,7 +106,7 @@ module esmflds type (med_fldList_type), public :: fldListMed_aoflux type (med_fldList_type), public :: fldListMed_ocnalb - integer :: dbrc + integer :: rc character(len=CL) :: infostr character(len=*),parameter :: u_FILE_u = & __FILE__ @@ -394,7 +394,7 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num if (present(grid) .and. present(mesh)) then call ESMF_LogWrite(trim(subname)//trim(tag)//": ERROR both grid and mesh not allowed", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=rc) rc = ESMF_FAILURE return endif @@ -408,13 +408,13 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return write(infostr,'(i6)') itemCount - call ESMF_LogWrite(trim(subname)//trim(tag)//" count = "//trim(infostr), ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//trim(tag)//" count = "//trim(infostr), ESMF_LOGMSG_INFO) if (itemCount > 0) then allocate(itemNameList(itemCount)) call ESMF_StateGet(state, itemNameList=itemNameList, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return do n = 1,itemCount - call ESMF_LogWrite(trim(subname)//trim(tag)//" itemNameList = "//trim(itemNameList(n)), ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//trim(tag)//" itemNameList = "//trim(itemNameList(n)), ESMF_LOGMSG_INFO) enddo deallocate(itemNameList) endif @@ -424,23 +424,23 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num NamespaceList=NamespaceList, itemNameList=itemNameList, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return write(infostr,'(i6)') size(StandardNameList) - call ESMF_LogWrite(trim(subname)//trim(tag)//" size = "//trim(infostr), ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//trim(tag)//" size = "//trim(infostr), ESMF_LOGMSG_INFO) do n = 1,size(StandardNameList) call ESMF_LogWrite(trim(subname)//trim(tag)//" StandardNameList = "//trim(StandardNameList(n)), & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) enddo do n = 1,size(ConnectedList) call ESMF_LogWrite(trim(subname)//trim(tag)//" ConnectedList = "//trim(ConnectedList(n)), & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) enddo do n = 1,size(NamespaceList) call ESMF_LogWrite(trim(subname)//trim(tag)//" NamespaceList = "//trim(NamespaceList(n)), & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) enddo do n = 1,size(ItemnameList) call ESMF_LogWrite(trim(subname)//trim(tag)//" ItemnameList = "//trim(ItemnameList(n)), & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) enddo #endif @@ -464,7 +464,7 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num do n = 1, nflds shortname = fldList%flds(n)%shortname - ! call ESMF_LogWrite(subname//' fld = '//trim(shortname), ESMF_LOGMSG_INFO, rc=dbrc) + ! call ESMF_LogWrite(subname//' fld = '//trim(shortname), ESMF_LOGMSG_INFO) if (NUOPC_IsConnected(state, fieldName=shortname)) then call ESMF_StateGet(state, field=field, itemName=trim(shortname), rc=rc) @@ -480,30 +480,30 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num if (trim(transferAction) == "accept") then ! accept call ESMF_LogWrite(trim(subname)//trim(tag)//" Field = "//trim(shortname)//" is connected, grid/mesh TBD", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) else ! provide if (shortname == trim(flds_scalar_name)) then call ESMF_LogWrite(trim(subname)//trim(tag)//" Field = "//trim(shortname)//" is connected on root pe", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) call SetScalarField(field, flds_scalar_name, flds_scalar_num, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return elseif (present(grid)) then call ESMF_LogWrite(trim(subname)//trim(tag)//" Field = "//trim(shortname)//" is connected using grid", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) ! Create the field field = ESMF_FieldCreate(grid, ESMF_TYPEKIND_R8, name=shortname,rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return elseif (present(mesh)) then call ESMF_LogWrite(trim(subname)//trim(tag)//" Field = "//trim(shortname)//" is connected using mesh", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) ! Create the field field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, name=shortname, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return else call ESMF_LogWrite(trim(subname)//trim(tag)//": ERROR grid or mesh expected", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) rc = ESMF_FAILURE return endif @@ -520,7 +520,7 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num else call ESMF_LogWrite(subname // trim(tag) // " Field = "// trim(shortname) // " is not connected.", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) call ESMF_StateRemove(state, (/shortname/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return @@ -528,7 +528,7 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num end do - call ESMF_LogWrite(subname//' done ', ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(subname//' done ', ESMF_LOGMSG_INFO) contains !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -694,7 +694,7 @@ subroutine med_fldList_GetFldNames(flds, fldnames, rc) end do else call ESMF_LogWrite("med_fldList_GetFldNames: ERROR either flds or fldnames have not been allocate ", & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if diff --git a/mediator/med.F90 b/mediator/med.F90 index 5be4575a6..755dfe5a6 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -714,10 +714,9 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) transferOffer = 'cannot provide' end if call NUOPC_Advertise(is_local%wrap%NStateImp(ncomp), standardName=stdname, shortname=shortname, name=shortname, & - TransferOfferGeomObject=transferOffer) + TransferOfferGeomObject=transferOffer, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//':Fr_'//trim(compname(ncomp))//': '//trim(shortname), ESMF_LOGMSG_INFO) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end do nflds = med_fldList_GetNumFlds(fldListTo(ncomp)) @@ -729,11 +728,10 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) transferOffer = 'cannot provide' end if call NUOPC_Advertise(is_local%wrap%NStateExp(ncomp), standardName=stdname, shortname=shortname, name=shortname, & - TransferOfferGeomObject=transferOffer) + 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end do end if end do ! end of ncomps loop @@ -1013,7 +1011,7 @@ subroutine realizeConnectedGrid(State,string,rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do i1 = 1,arbDimCount write(msgString,'(A,3i8)') trim(subname)//':PTile =',i1,minIndexPTile(i1,1),maxIndexPTile(i1,1) - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) enddo deallocate(minIndexPTile,maxIndexPTile) @@ -1031,7 +1029,7 @@ subroutine realizeConnectedGrid(State,string,rc) else ! grid_arbopt call ESMF_LogWrite(trim(subname)//trim(string)//": ERROR grid_arbopt setting = "//trim(grid_arbopt), & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1099,7 +1097,7 @@ subroutine realizeConnectedGrid(State,string,rc) ! allocate(connectionList(1)) ! nxg = maxIndexPTile(1,1) - minIndexPTile(1,1) + 1 ! write(msgstring,*) trim(subname)//trim(string),': connlist nxg = ',nxg - ! call ESMF_LogWrite(trim(msgstring), ESMF_LOGMSG_INFO, rc=rc) + ! call ESMF_LogWrite(trim(msgstring), ESMF_LOGMSG_INFO) ! if (ChkErr(rc,__LINE__,u_FILE_u)) return ! call ESMF_DistGridConnectionSet(connectionList(1), tileIndexA=1, & ! tileIndexB=1, positionVector=(/nxg, 0/), rc=rc) @@ -1115,8 +1113,7 @@ subroutine realizeConnectedGrid(State,string,rc) connectionList=connectionList, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with dimcount=2', ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with dimcount=2', ESMF_LOGMSG_INFO) ! Create a new Grid on the new DistGrid and swap it in the Field grid = ESMF_GridCreate(distgrid, gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/0,1/), rc=rc) @@ -1126,8 +1123,7 @@ subroutine realizeConnectedGrid(State,string,rc) maxIndexPTile=maxIndexPTile, regDecompPTile=regDecompPTile, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with dimcount=1', ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//trim(string)//': distgrid with dimcount=1', ESMF_LOGMSG_INFO) ! Create a new Grid on the new DistGrid and swap it in the Field grid = ESMF_GridCreate(distgrid, gridEdgeLWidth=(/0/), gridEdgeUWidth=(/0/), rc=rc) @@ -1154,8 +1150,7 @@ subroutine realizeConnectedGrid(State,string,rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//trim(string)//": attach grid for "//trim(fieldNameList(n1)), & - ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ESMF_LOGMSG_INFO) if (dbug_flag > 1) then call Field_GeomPrint(field,trim(fieldNameList(n1))//'_new',rc) @@ -1163,8 +1158,7 @@ subroutine realizeConnectedGrid(State,string,rc) end if else call ESMF_LogWrite(trim(subname)//trim(string)//": NOT replacing grid for field: "//& - trim(fieldNameList(n1)), ESMF_LOGMSG_WARNING, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + trim(fieldNameList(n1)), ESMF_LOGMSG_WARNING) endif enddo @@ -1215,8 +1209,7 @@ subroutine realizeConnectedGrid(State,string,rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//trim(string)//": attach mesh for "//& - trim(fieldNameList(n1)), ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + trim(fieldNameList(n1)), ESMF_LOGMSG_INFO) if (dbug_flag > 1) then call Field_GeomPrint(field,trim(fieldNameList(n1))//'_new',rc) @@ -1224,14 +1217,13 @@ subroutine realizeConnectedGrid(State,string,rc) end if else call ESMF_LogWrite(trim(subname)//trim(string)//": NOT replacing mesh for field: "//& - trim(fieldNameList(n1)), ESMF_LOGMSG_WARNING, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + trim(fieldNameList(n1)), ESMF_LOGMSG_WARNING) endif enddo else ! geomtype - call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", ESMF_LOGMSG_INFO) rc=ESMF_FAILURE return @@ -1249,7 +1241,7 @@ subroutine realizeConnectedGrid(State,string,rc) else - call ESMF_LogWrite(trim(subname)//": ERROR fieldStatus not supported ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": ERROR fieldStatus not supported ", ESMF_LOGMSG_INFO) rc=ESMF_FAILURE return @@ -1306,7 +1298,7 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc) if (ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then call ESMF_LogWrite(trim(subname)//": calling completeFieldInitialize import states from "//trim(compname(n1)), & ESMF_LOGMSG_INFO) - call completeFieldInitialization(is_local%wrap%NStateImp(n1), rc) + call completeFieldInitialization(is_local%wrap%NStateImp(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call State_reset(is_local%wrap%NStateImp(n1), value=spval_init, rc=rc) @@ -1316,7 +1308,7 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc) if (ESMF_StateIsCreated(is_local%wrap%NStateExp(n1),rc=rc)) then call ESMF_LogWrite(trim(subname)//": calling completeFieldInitialize export states to "//trim(compname(n1)), & ESMF_LOGMSG_INFO) - call completeFieldInitialization(is_local%wrap%NStateExp(n1), rc) + call completeFieldInitialization(is_local%wrap%NStateExp(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call State_reset(is_local%wrap%NStateExp(n1), value=spval_init, rc=rc) @@ -1424,7 +1416,7 @@ subroutine completeFieldInitialization(State,rc) if (fieldStatus==ESMF_FIELDSTATUS_GRIDSET) then call ESMF_LogWrite(subname//" is allocating field memory for field "//trim(fieldName), & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) call ESMF_AttributeGet(fieldList(n), name="GridToFieldMap", convention="NUOPC", & purpose="Instance", itemCount=gridToFieldMapCount, rc=rc) @@ -1939,8 +1931,7 @@ subroutine DataInitialize(gcomp, rc) ! If any atm import fields are not time stamped correctly, ! then dependency is not satisified - must return to atm call ESMF_LogWrite("MED - Initialize-Data-Dependency from ATM NOT YET SATISFIED!!!", & - ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ESMF_LOGMSG_INFO) if (mastertask) then write(logunit,'(A)') trim(subname)//"MED - Initialize-Data-Dependency from ATM NOT YET SATISFIED!!!" end if @@ -1970,8 +1961,7 @@ subroutine DataInitialize(gcomp, rc) deallocate(fieldNameList) ! Connectors will be automatically called between the mediator and atm until allDone is true - call ESMF_LogWrite("MED - Initialize-Data-Dependency Sending Data to ATM", ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite("MED - Initialize-Data-Dependency Sending Data to ATM", ESMF_LOGMSG_INFO) endif endif end if @@ -2009,8 +1999,7 @@ subroutine DataInitialize(gcomp, rc) ! to the driver that this Component has fully initialized its data call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="true", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check Passed", ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check Passed", ESMF_LOGMSG_INFO) end if !--------------------------------------- @@ -2055,8 +2044,7 @@ subroutine DataInitialize(gcomp, rc) 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, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(subname//' read_restart = '//trim(cvalue), ESMF_LOGMSG_INFO) read(cvalue,*) read_restart if (read_restart) then @@ -2070,8 +2058,7 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check Failed, another loop is required", & - ESMF_LOGMSG_INFO, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ESMF_LOGMSG_INFO) end if @@ -2176,7 +2163,7 @@ subroutine SetRunClock(gcomp, 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=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE RETURN end if diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 5ae2c3016..14cb9f4c3 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -187,14 +187,13 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: So_omask(:) integer :: i,j,n,n1 integer :: maptype - integer :: dbrc logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -586,7 +585,7 @@ subroutine med_fraction_init(gcomp, rc) end if if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) @@ -622,14 +621,13 @@ subroutine med_fraction_set(gcomp, rc) real(r8), pointer :: Si_ifrac(:) real(r8), pointer :: Si_imask(:) integer :: n - integer :: dbrc integer :: maptype character(len=*),parameter :: subname='(med_fraction_set)' !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -772,7 +770,7 @@ subroutine med_fraction_set(gcomp, rc) end if if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index c0bf98c9c..9b32f4ff0 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -426,7 +426,7 @@ subroutine med_merge_field_1D(FBout, fnameout, & ! ---------------------------------------------- if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif rc=ESMF_SUCCESS @@ -553,7 +553,7 @@ subroutine med_merge_field_1D(FBout, fnameout, & enddo ! n if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif end subroutine med_merge_field_1D @@ -606,7 +606,7 @@ subroutine med_merge_field_2D(FBout, fnameout, & ! ---------------------------------------------- if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif rc=ESMF_SUCCESS @@ -738,7 +738,7 @@ subroutine med_merge_field_2D(FBout, fnameout, & enddo ! n if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif end subroutine med_merge_field_2D @@ -811,7 +811,7 @@ subroutine merge_listGetName(list, k, name, rc) end if if (.not. valid_list) then write(logunit,*) "ERROR: invalid list = ",trim(list) - call ESMF_LogWrite("ERROR: invalid list = "//trim(list), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite("ERROR: invalid list = "//trim(list), ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if @@ -821,7 +821,7 @@ subroutine merge_listGetName(list, k, name, rc) if (k<1 .or. kFlds 5) then - call ESMF_LogWrite(trim(subname)//": FBout from input State and field pointers", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": FBout from input State and field pointers", ESMF_LOGMSG_INFO) end if end subroutine med_methods_FB_init_pointer @@ -425,7 +425,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S allocate(lfieldNameList(fieldcount)) lfieldNameList = fieldNameList if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from argument", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from argument", ESMF_LOGMSG_INFO) end if elseif (present(FBflds)) then call ESMF_FieldBundleGet(FBflds, fieldCount=fieldCount, rc=rc) @@ -434,7 +434,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_FieldBundleGet(FBflds, fieldNameList=lfieldNameList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from FBflds", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from FBflds", ESMF_LOGMSG_INFO) end if elseif (present(STflds)) then call ESMF_StateGet(STflds, itemCount=fieldCount, rc=rc) @@ -443,7 +443,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_StateGet(STflds, itemNameList=lfieldNameList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from STflds", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from STflds", ESMF_LOGMSG_INFO) end if elseif (present(FBgeom)) then call ESMF_FieldBundleGet(FBgeom, fieldCount=fieldCount, rc=rc) @@ -452,7 +452,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_FieldBundleGet(FBgeom, fieldNameList=lfieldNameList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from FBgeom", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from FBgeom", ESMF_LOGMSG_INFO) end if elseif (present(STgeom)) then call ESMF_StateGet(STgeom, itemCount=fieldCount, rc=rc) @@ -461,7 +461,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_StateGet(STgeom, itemNameList=lfieldNameList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from STflds", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" fieldNameList from STflds", ESMF_LOGMSG_INFO) end if else call ESMF_LogWrite(trim(subname)//": ERROR fieldNameList, FBflds, STflds, FBgeom, or STgeom must be passed", & @@ -1747,11 +1747,11 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) if (status /= ESMF_FIELDSTATUS_COMPLETE) then lrank = 0 if (labort) then - call ESMF_LogWrite(trim(subname)//": ERROR data not allocated ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": ERROR data not allocated ", ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return else - call ESMF_LogWrite(trim(subname)//": WARNING data not allocated ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": WARNING data not allocated ", ESMF_LOGMSG_INFO) endif else @@ -1773,7 +1773,7 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) else call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return endif ! geomtype @@ -2237,14 +2237,14 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) ! no local data elseif (lrank == 1) then write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=1 ",lbound(dataptr1,1),ubound(dataptr1,1) - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (lrank == 2) then write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=1 ",lbound(dataptr2,1),ubound(dataptr2,1) - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=2 ",lbound(dataptr2,2),ubound(dataptr2,2) - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (lrank == 0) then ! means data allocation does not exist yet @@ -2304,7 +2304,7 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": distGrid=element" - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distgrid, deLayout=deLayout, dimCount=dimCount, & @@ -2312,22 +2312,22 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DELayoutGet(deLayout, localDeCount=localDeCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount @@ -2340,11 +2340,11 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2356,7 +2356,7 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": distGrid=nodal" - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distgrid, deLayout=deLayout, dimCount=dimCount, & @@ -2364,22 +2364,22 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DELayoutGet(deLayout, localDeCount=localDeCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount @@ -2392,11 +2392,11 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2417,13 +2417,13 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": parametricDim=", pdim - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) write (msgString,*) trim(subname)//":"//trim(string)//": spatialDim=", sdim - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) write (msgString,*) trim(subname)//":"//trim(string)//": numOwnedNodes=", nnodes - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) write (msgString,*) trim(subname)//":"//trim(string)//": numOwnedElements=", nelements - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return endif @@ -2469,7 +2469,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! get dimCount and tileCount @@ -2477,15 +2477,15 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount @@ -2498,11 +2498,11 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2512,14 +2512,14 @@ subroutine med_methods_Grid_Print(grid, string, rc) ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! write (msgString,*) trim(subname)//":"//trim(string)//": staggerlocCount=", staggerlocCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) +! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! call ESMF_GridGet(grid, arbDimCount=arbDimCount, rc=rc) ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! write (msgString,*) trim(subname)//":"//trim(string)//": arbDimCount=", arbDimCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) +! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! get rank @@ -2527,7 +2527,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": rank=", rank - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return do n1 = 1,2 @@ -2539,13 +2539,13 @@ subroutine med_methods_Grid_Print(grid, string, rc) staggerstr = 'ESMF_STAGGERLOC_CORNER' else rc = ESMF_FAILURE - call ESMF_LogWrite(trim(subname)//":staggerloc failure", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//":staggerloc failure", ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return endif call ESMF_GridGetCoord(grid, staggerloc=staggerloc, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(staggerstr)//" present=",isPresent - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return if (isPresent) then do n3 = 0,localDECount-1 @@ -2560,7 +2560,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr2),maxval(fldptr2) endif - call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return enddo enddo @@ -3433,7 +3433,7 @@ subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fl rc = ESMF_SUCCESS if (associated(fldnames_shared)) then - call ESMF_LogWrite(trim(subname)//": ERROR fldnames_shared must not be associated ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": ERROR fldnames_shared must not be associated ", ESMF_LOGMSG_INFO) rc = ESMF_FAILURE RETURN end if diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 42aec5983..6a303da80 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -367,12 +367,12 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, aoflux%mask(:) = 1 write(tmpstr,'(i12,g22.12,i12)') lsize,sum(aoflux%rmask),sum(aoflux%mask) - call ESMF_LogWrite(trim(subname)//" : maskA= "//trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : maskA= "//trim(tmpstr), ESMF_LOGMSG_INFO) where (aoflux%rmask(:) == 0._R8) aoflux%mask(:) = 0 ! like nint write(tmpstr,'(i12,g22.12,i12)') lsize,sum(aoflux%rmask),sum(aoflux%mask) - call ESMF_LogWrite(trim(subname)//" : maskB= "//trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : maskB= "//trim(tmpstr), ESMF_LOGMSG_INFO) ! TODO: need to check if this logic is correct ! then check ofrac + ifrac @@ -479,16 +479,16 @@ subroutine med_aofluxes_run(gcomp, aoflux, rc) lsize = size(aoflux%mask) write(tmpstr,'(i12,g22.12,i12)') lsize,sum(aoflux%rmask),sum(aoflux%mask) - call ESMF_LogWrite(trim(subname)//" : maskA= "//trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : maskA= "//trim(tmpstr), ESMF_LOGMSG_INFO) aoflux%mask(:) = 1 where (aoflux%rmask(:) == 0._R8) aoflux%mask(:) = 0 ! like nint write(tmpstr,'(i12,g22.12,i12)') lsize,sum(aoflux%rmask),sum(aoflux%mask) - call ESMF_LogWrite(trim(subname)//" : maskB= "//trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : maskB= "//trim(tmpstr), ESMF_LOGMSG_INFO) write(tmpstr,'(3i12)') lsize,size(aoflux%mask),sum(aoflux%mask) - call ESMF_LogWrite(trim(subname)//" : mask= "//trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : mask= "//trim(tmpstr), ESMF_LOGMSG_INFO) !---------------------------------- ! Update atmosphere/ocean surface fluxes diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 2e017cd07..957641d5e 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -101,14 +101,13 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) type(InternalState) :: is_local real(R8), pointer :: ownedElemCoords(:) character(len=CL) :: tempc1,tempc2 - integer :: dbrc logical :: mastertask character(*), parameter :: subname = '(med_phases_ocnalb_init) ' !----------------------------------------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif rc = ESMF_SUCCESS @@ -154,7 +153,7 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (geomtype == ESMF_GEOMTYPE_MESH) then - call ESMF_LogWrite(trim(subname)//" : FBAtm is on a mesh ", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//" : FBAtm is on a mesh ", ESMF_LOGMSG_INFO) call ESMF_FieldGet(lfield, mesh=lmesh, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) @@ -164,7 +163,7 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) write(tempc1,'(i10)') numOwnedElements write(tempc2,'(i10)') lsize call ESMF_LogWrite(trim(subname)//": ERROR numOwnedElements "// trim(tempc1) // & - " not equal to local size "// trim(tempc2), ESMF_LOGMSG_INFO, rc=rc) + " not equal to local size "// trim(tempc2), ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if @@ -178,7 +177,7 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) ocnalb%lats(n) = ownedElemCoords(2*n) end do else - call ESMF_LogWrite(trim(subname)//": ERROR field bundle must be either on mesh", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": ERROR field bundle must be either on mesh", ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if @@ -188,7 +187,7 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif call t_stopf('MED:'//subname) @@ -249,7 +248,6 @@ subroutine med_phases_ocnalb_run(gcomp, rc) real(R8), parameter :: albdif = 0.06_r8 ! 60 deg reference albedo, diffuse real(R8), parameter :: albdir = 0.07_r8 ! 60 deg reference albedo, direct real(R8), parameter :: const_deg2rad = shr_const_pi/180.0_R8 ! deg to rads - integer :: dbrc character(CL) :: msg logical :: first_call = .true. character(len=*) , parameter :: subname='(med_phases_ocnalb_run)' @@ -294,7 +292,7 @@ subroutine med_phases_ocnalb_run(gcomp, rc) ! - nextsw_cday is just what cam was setting it as the current calendar day if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif call t_startf('MED:'//subname) @@ -453,13 +451,12 @@ subroutine med_phases_ocnalb_mapo2a(gcomp, rc) ! Local variables type(InternalState) :: is_local - integer :: dbrc character(*), parameter :: subName = '(med_ocnalb_mapo2a) ' !----------------------------------------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif rc = ESMF_SUCCESS diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index dc5ebf4bd..95994d30f 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -54,7 +54,6 @@ subroutine med_phases_prep_atm(gcomp, rc) type(InternalState) :: is_local real(R8), pointer :: dataPtr1(:),dataPtr2(:) integer :: i, j, n, n1, ncnt - integer :: dbrc character(len=*),parameter :: subname='(med_phases_prep_atm)' !------------------------------------------------------------------------------- @@ -62,7 +61,7 @@ subroutine med_phases_prep_atm(gcomp, rc) rc = ESMF_SUCCESS if (dbug_flag > 5) then - call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) end if call memcheck(subname, 3, mastertask) @@ -86,7 +85,7 @@ subroutine med_phases_prep_atm(gcomp, rc) if (ncnt == 0) then call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(compatm), returning", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) else !--------------------------------------- @@ -98,7 +97,7 @@ subroutine med_phases_prep_atm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TimeGet(time,timestring=timestr) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": time = "//trim(timestr), ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": time = "//trim(timestr), ESMF_LOGMSG_INFO) if (dbug_flag > 1) then if (mastertask) then call ESMF_ClockPrint(clock, options="currTime", & @@ -220,7 +219,7 @@ subroutine med_phases_prep_atm(gcomp, rc) endif if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index f314ded75..f8f89f2c8 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -82,14 +82,13 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: i,j,n,ncnt - integer :: dbrc character(len=*), parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_accum)' !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -108,7 +107,7 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) 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, rc=dbrc) + 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 @@ -141,7 +140,7 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end if if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) @@ -167,7 +166,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: i,j,n,n1,ncnt - integer :: dbrc logical :: connected real(r8), pointer :: dataptr(:) character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_avg)' @@ -175,7 +173,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -200,7 +198,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (ncnt == 0) then call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(comprof), returning", & - ESMF_LOGMSG_INFO, rc=dbrc) + ESMF_LOGMSG_INFO) else !--------------------------------------- @@ -298,7 +296,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) endif if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) @@ -340,7 +338,6 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! local variables integer :: r,l - integer :: dbrc type(InternalState) :: is_local real(r8), pointer :: volr_l(:) real(r8), pointer :: volr_r(:), volr_r_import(:) @@ -356,7 +353,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) call t_startf('MED:'//subname) if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -370,13 +367,13 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),mapconsf, rc=rc)) then call ESMF_LogWrite(trim(subname)//": ERROR conservativing route handle not created for lnd->rof mapping", & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if if (.not. med_map_RH_is_created(is_local%wrap%RH(comprof,complnd,:),mapconsf, rc=rc)) then call ESMF_LogWrite(trim(subname)//": ERROR conservativing route handle not created for rof->lnd mapping", & - ESMF_LOGMSG_INFO, rc=rc) + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if @@ -525,7 +522,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) end do if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index 7fcc73691..bee6ad614 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -42,13 +42,12 @@ subroutine med_phases_prep_wav(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: i,j,n,n1,ncnt - integer :: dbrc character(len=*),parameter :: subname='(med_phases_prep_wav)' !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if rc = ESMF_SUCCESS @@ -129,7 +128,7 @@ subroutine med_phases_prep_wav(gcomp, rc) endif if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=dbrc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index 8408e6c11..f69696733 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -198,7 +198,7 @@ subroutine med_phases_profile(gcomp, rc) !--- clean up !--------------------------------------- - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO, rc=rc) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) call t_stopf('MED:'//subname) end subroutine med_phases_profile diff --git a/mediator/med_utils_mod.F90 b/mediator/med_utils_mod.F90 index 84ad8e3ba..9aef4cff9 100644 --- a/mediator/med_utils_mod.F90 +++ b/mediator/med_utils_mod.F90 @@ -50,7 +50,7 @@ logical function med_utils_ChkErr(rc, line, file, mpierr) integer, parameter :: MPI_MAX_ERROR_STRING=80 #endif character(MPI_MAX_ERROR_STRING) :: lstring - integer :: dbrc, lrc, len, ierr + integer :: lrc, len, ierr med_utils_ChkErr = .false. lrc = rc @@ -61,7 +61,7 @@ logical function med_utils_ChkErr(rc, line, file, mpierr) #else write(lstring,*) "ERROR in mct mpi-serial library rc=",rc #endif - call ESMF_LogWrite("ERROR: "//trim(lstring), ESMF_LOGMSG_INFO, line=line, file=file, rc=dbrc) + call ESMF_LogWrite("ERROR: "//trim(lstring), ESMF_LOGMSG_INFO, line=line, file=file) lrc = ESMF_FAILURE endif From 46be10e5ef00569eebaa97441f2ec5050c9ab7e1 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 09:50:21 -0500 Subject: [PATCH 036/206] fix compile error --- mediator/med.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 755dfe5a6..eb51b936b 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -436,15 +436,15 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(cvalue), ESMF_LOGMSG_INFO) - call ESMF_AttributeGet(gcomp, name="Verbosity", value=value, & + call ESMF_AttributeGet(gcomp, name="Verbosity", value=cvalue, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator verbosity is set to "//trim(value), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": Mediator verbosity is set to "//trim(cvalue), ESMF_LOGMSG_INFO) - call ESMF_AttributeGet(gcomp, name="Profiling", value=value, & + call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(value), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(cvalue), ESMF_LOGMSG_INFO) ! 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) From 43461172417d8deb490a8b6509976e1561f39915 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 10:27:58 -0500 Subject: [PATCH 037/206] remove more chk_err statements after LogWrites --- mediator/med_methods_mod.F90 | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index efa02b491..0dbc322f7 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -2305,7 +2305,6 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": distGrid=element" call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distgrid, deLayout=deLayout, dimCount=dimCount, & tileCount=tileCount, deCount=deCount, rc=rc) @@ -2313,22 +2312,18 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DELayoutGet(deLayout, localDeCount=localDeCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount allocate(minIndexPTile(dimCount, tileCount), & @@ -2357,7 +2352,6 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": distGrid=nodal" call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DistGridGet(distgrid, deLayout=deLayout, dimCount=dimCount, & tileCount=tileCount, deCount=deCount, rc=rc) @@ -2365,22 +2359,18 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_DELayoutGet(deLayout, localDeCount=localDeCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount allocate(minIndexPTile(dimCount, tileCount), & @@ -2393,11 +2383,9 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2470,7 +2458,6 @@ subroutine med_methods_Grid_Print(grid, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": localDeCount=", localDeCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! get dimCount and tileCount call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, deCount=deCount, rc=rc) @@ -2478,15 +2465,12 @@ subroutine med_methods_Grid_Print(grid, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! allocate minIndexPTile and maxIndexPTile accord. to dimCount and tileCount allocate(minIndexPTile(dimCount, tileCount), & @@ -2499,11 +2483,9 @@ subroutine med_methods_Grid_Print(grid, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2528,7 +2510,6 @@ subroutine med_methods_Grid_Print(grid, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": rank=", rank call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return do n1 = 1,2 if (n1 == 1) then @@ -2546,7 +2527,6 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(staggerstr)//" present=",isPresent call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return if (isPresent) then do n3 = 0,localDECount-1 do n2 = 1,dimCount @@ -2561,7 +2541,6 @@ subroutine med_methods_Grid_Print(grid, string, rc) write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr2),maxval(fldptr2) endif call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return enddo enddo endif From 32a11a5fd1d0cf9ee00b10fdada5fa0f8995b9e1 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Fri, 14 Aug 2020 10:37:30 -0500 Subject: [PATCH 038/206] remove more chk_err statements after LogWrites --- mediator/med_methods_mod.F90 | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index 0dbc322f7..f63638b46 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -2238,14 +2238,11 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) elseif (lrank == 1) then write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=1 ",lbound(dataptr1,1),ubound(dataptr1,1) call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (lrank == 2) then write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=1 ",lbound(dataptr2,1),ubound(dataptr2,1) call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": dataptr bounds dim=2 ",lbound(dataptr2,2),ubound(dataptr2,2) call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (lrank == 0) then ! means data allocation does not exist yet continue @@ -2336,11 +2333,9 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(minIndexPTile, maxIndexPTile) @@ -2521,7 +2516,6 @@ subroutine med_methods_Grid_Print(grid, string, rc) else rc = ESMF_FAILURE call ESMF_LogWrite(trim(subname)//":staggerloc failure", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return endif call ESMF_GridGetCoord(grid, staggerloc=staggerloc, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return From 76540383e4bd37142814812903fc2eed4a1b39e1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 18 Aug 2020 15:21:42 -0600 Subject: [PATCH 039/206] fix pylint issues --- cime_config/buildexe | 3 +-- cime_config/buildnml | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index 211d2b6d1..2059d4c23 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -37,7 +37,6 @@ def _main_func(): ocn_model = case.get_value("COMP_OCN") atm_model = case.get_value("COMP_ATM") gmake_args = get_standard_makefile_args(case) - blddir = os.path.join(case.get_value("EXEROOT"),"cpl","obj") # Determine valid components valid_comps = [] @@ -50,7 +49,7 @@ def _main_func(): if valid: valid_comps.append(item) - datamodel_in_compset = False + datamodel_in_compset = False for comp in comp_classes: dcompname = "d"+comp.lower() if dcompname in case.get_value("COMP_{}".format(comp)): diff --git a/cime_config/buildnml b/cime_config/buildnml index 13cf826db..25cd73da2 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -237,7 +237,7 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): valid_comps.append(item) # Determine if there are any data components in the compset - datamodel_in_compset = False + datamodel_in_compset = False comp_classes = case.get_values("COMP_CLASSES") for comp in comp_classes: dcompname = "d"+comp.lower() @@ -248,14 +248,12 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): # driver rpointer file if there is only one non-stub component then skip mediator if len(valid_comps) == 2 and not datamodel_in_compset: # skip the mediator if there is a prognostic component and all other components are stub - skip_mediator = True valid_comps.remove("CPL") nmlgen.set_value('mediator_present', value='.false.') nmlgen.set_value("drv_restart_pointer", value="none") nmlgen.set_value("component_list", value=" ".join(valid_comps)) else: # do not skip mediator if there is a data component but all other components are stub - skip_mediator = False nmlgen.set_value("drv_restart_pointer", value="rpointer.cpl") valid_comps_string = " ".join(valid_comps) nmlgen.set_value("component_list", value=valid_comps_string.replace("CPL","MED")) From 864600801593e1c08345188f89a9c41067bd5a0f Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Thu, 3 Sep 2020 10:16:44 -0600 Subject: [PATCH 040/206] Fix CPP ESMF_VERSION_MAJOR and ESMF_VERSION_MINOR definitions. --- mediator/Makefile | 5 +++++ mediator/esmFlds.F90 | 21 ++++++++++++--------- mediator/med.F90 | 12 +++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/mediator/Makefile b/mediator/Makefile index fae000dae..8e8a79977 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -12,6 +12,11 @@ ifdef INTERNAL_PIO_INIT CPPDEFS := -DINTERNAL_PIO_INIT endif +ESMF_VERSION_MAJOR ?= 0 +ESMF_VERSION_MINOR ?= 0 +CPPDEFS += -DESMF_VERSION_MAJOR=$(ESMF_VERSION_MAJOR) +CPPDEFS += -DESMF_VERSION_MINOR=$(ESMF_VERSION_MINOR) + LIBRARY := libcmeps.a OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 010aa3447..f57575d0c 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -358,9 +358,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 @@ -378,9 +380,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(:) @@ -445,7 +449,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" @@ -459,6 +465,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 @@ -469,12 +476,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/med.F90 b/mediator/med.F90 index a1c627fee..b3f44dbf7 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -741,9 +741,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 @@ -775,9 +777,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, & @@ -785,9 +789,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, & From 07d3cabeef8672ad34a1e616f13826ff0ca21a97 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sat, 12 Sep 2020 16:28:06 -0500 Subject: [PATCH 041/206] remove custom merges for rain and snow --- mediator/esmFldsExchange_nems_mod.F90 | 9 +++++++++ mediator/med_phases_prep_ocn_mod.F90 | 12 ++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index fdd898201..43d0c182c 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -180,6 +180,15 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) + allocate(flds(2)) + flds = (/'Faxa_rain', 'Faxa_snow'/) + do n = 1,size(flds) + fldname = trim(flds(n)) + call addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + end do + deallocate(flds) + ! to ocn: merged sensible heat flux (custom merge in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Faxa_sen') call addfld(fldListFr(compatm)%flds, 'Faxa_sen') diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index e1189049d..a8969da4e 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -632,12 +632,12 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) lsize = size(ofrac) allocate(customwgt(lsize)) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + !call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain', & + ! FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) return + !call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow', & + ! FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) + !if (ChkErr(rc,__LINE__,u_FILE_u)) return call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_lwnet', & FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lwnet', wgtA=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 51b19ac1ca35b6c2ba8a9efb17179680149cdb77 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sun, 13 Sep 2020 08:23:54 -0500 Subject: [PATCH 042/206] new aliases in fd_nems.yaml --- mediator/fd_nems.yaml | 66 +++++++++++++++------------- mediator/med_phases_prep_ocn_mod.F90 | 6 --- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/mediator/fd_nems.yaml b/mediator/fd_nems.yaml index a74c483c9..7b27d884c 100644 --- a/mediator/fd_nems.yaml +++ b/mediator/fd_nems.yaml @@ -4,26 +4,16 @@ source: automatically generated by the NUOPC Layer description: Community-based dictionary for shared coupling fields entries: - # - #----------------------------------- - # section: mediator calculation for atm/ocn flux calculation - #----------------------------------- - # - - standard_name: Faox_evap - alias: mean_evap_rate_atm_into_ocn - canonical_units: kg m-2 s-1 - description: mediator calculation - atm/ocn evaporation water flux + # + #----------------------------------- + # section: mediator calculation for atm/ocn flux calculation + #----------------------------------- # - standard_name: Faox_lat alias: mean_laten_heat_flx_atm_into_ocn canonical_units: W m-2 description: mediator calculation - atm/ocn surface latent heat flux # - - standard_name: Faox_sen - alias: mean_sensi_heat_flx_atm_into_ocn - canonical_units: W m-2 - description: mediator calculation - atm/ocn surface sensible heat flux - # - standard_name: Faox_lwup alias: mean_up_lw_flx_ocn canonical_units: W m-2 @@ -67,12 +57,7 @@ - standard_name: Faxa_lwdn alias: mean_down_lw_flx canonical_units: W m-2 - description: atmosphere export - mean downward SW heat flux - # - - standard_name: Faxa_lwnet - alias: mean_net_lw_flx - canonical_units: W m-2 - description: atmosphere export - mean merge longwave flux from atm + description: atmosphere export - mean downward LW heat flux # - standard_name: Faxa_rain alias: mean_prec_rate @@ -167,16 +152,6 @@ canonical_units: W m-2 description: atmosphere export - latent heat flux # - - standard_name: Faxa_sen - alias: mean_sensi_heat_flx - canonical_units: W m-2 - description: atmosphere export - sensible heat flux - # - - standard_name: Faxa_evap - alias: mean_evap_rate - canonical_units: kg m-2 s-1 - description: calculated in mediator - specific humidity flux to ocean - # - standard_name: Faxx_lwup alias: mean_up_lw_flx canonical_units: W m-2 @@ -512,6 +487,37 @@ canonical_units: 1 # #----------------------------------- + # aliased fields for active and datm + #----------------------------------- + # + - standard_name: mean_net_lw_flx + canonical_units: W m-2 + - alias: Faxa_lwnet + standard_name : mean_net_lw_flx + description: atmosphere export - mean net longwave flux from atm + - alias: Foxx_lwnet + standard_name : mean_net_lw_flx + description: mediator calculation - atm/ocn net longwave flux + # + - standard_name: mean_sensi_heat_flx + canonical_units: W m-2 + - alias: Faxa_sen + standard_name : mean_sensi_heat_flx + description: atmosphere export - sensible heat flux + - alias: Faox_sen + standard_name : mean_sensi_heat_flx + description: mediator calculation - atm/ocn surface sensible heat flux + # + - standard_name: mean_evap_rate + canonical_units: kg m-2 s-1 + - alias: Faxa_evap + standard_name : mean_evap_rate + description: atmosphere export - latent heat flux conversion + - alias: Faox_evap + standard_name : mean_evap_rate + description: mediator calculation - atm/ocn specific humidity flux + # + #----------------------------------- # section: atmosphere fields that need to be defined but are not used #----------------------------------- # diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index a8969da4e..9a6e8e800 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -632,12 +632,6 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) lsize = size(ofrac) allocate(customwgt(lsize)) - !call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain', & - ! FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return - !call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow', & - ! FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_lwnet', & FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lwnet', wgtA=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From f68a3d257b50f3654e2699c0221471d648f34b37 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sun, 13 Sep 2020 11:10:13 -0500 Subject: [PATCH 043/206] combine fields exchange for nems orig/data; make corresponding changes in prep_ocn --- mediator/esmFldsExchange_nems_mod.F90 | 50 ++++++++++++++++++++------- mediator/med_phases_prep_ocn_mod.F90 | 5 +-- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 43d0c182c..08c217f19 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -167,11 +167,9 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! - downward diffuse visible incident solar radiation ! - longwave net heat flux ! - longwave downward flux - ! - rain - ! - snow - allocate(flds(8)) + allocate(flds(6)) flds = (/'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf',& - 'Faxa_lwnet', 'Faxa_lwdn ', 'Faxa_rain ', 'Faxa_snow '/) + 'Faxa_lwnet', 'Faxa_lwdn '/) do n = 1,size(flds) fldname = trim(flds(n)) call addfld(fldListTo(compocn)%flds, trim(fldname)) @@ -180,24 +178,50 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) + ! to ocn: rain and snow via auto merge allocate(flds(2)) flds = (/'Faxa_rain', 'Faxa_snow'/) do n = 1,size(flds) fldname = trim(flds(n)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + 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') end do deallocate(flds) - ! to ocn: merged sensible heat flux (custom merge in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Faxa_sen') - call addfld(fldListFr(compatm)%flds, 'Faxa_sen') - call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, maptype, 'none', 'unset') - - ! to ocn: surface latent heat flux and evaporation water flux (custom merge in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Faxa_evap') - call addfld(fldListFr(compatm)%flds, 'Faxa_lat') - call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, maptype, 'none', 'unset') + if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then + ! to ocn: long wave net via auto merge + call addmrg(fldListTo(compocn)%flds, 'Faxa_lwnet', & + mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + + ! to ocn: merged sensible heat flux (custom merge in med_phases_prep_ocn) + call addfld(fldListTo(compocn)%flds, 'Faxa_sen') + call addfld(fldListFr(compatm)%flds, 'Faxa_sen') + call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, maptype, 'none', 'unset') + + ! to ocn: evaporation water flux (custom merge in med_phases_prep_ocn) + call addfld(fldListTo(compocn)%flds, 'Faxa_evap') + call addfld(fldListFr(compatm)%flds, 'Faxa_lat') + call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, maptype, 'none', 'unset') + else + ! to ocn: long wave net via auto merge + call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') + 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') + + ! 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') + + ! 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') + end if ! to ocn: merge zonal surface stress (custom merge calculation in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Foxx_taux') diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 9a6e8e800..c250b0a2f 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -632,10 +632,6 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) lsize = size(ofrac) allocate(customwgt(lsize)) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_lwnet', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lwnet', wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - customwgt(:) = -ofrac(:) / const_lhvap call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lat' , wgtA=customwgt, rc=rc) @@ -645,6 +641,7 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_taux' , wgtB=customwgt, rc=rc) From 54d8607c3e49556785196288e413d8cfede74fa2 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Sun, 13 Sep 2020 13:12:21 -0500 Subject: [PATCH 044/206] remove nems_data prep_ocn; make nems prep_ocn work for all nems modes regression tests fail comparison of mediator restart files but all other files reproduce. cprnc not working on orion, so will run on hera to try to determine cause --- mediator/med_phases_prep_ocn_mod.F90 | 199 ++------------------------- 1 file changed, 12 insertions(+), 187 deletions(-) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index c250b0a2f..7b9948ed2 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -35,7 +35,6 @@ module med_phases_prep_ocn_mod private :: med_phases_prep_ocn_custom_cesm private :: med_phases_prep_ocn_custom_nems - private :: med_phases_prep_ocn_custom_nemsdata character(*), parameter :: u_FILE_u = & __FILE__ @@ -164,13 +163,10 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) 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) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then + 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 - else if (trim(coupling_mode) == 'nems_orig_data') then - call med_phases_prep_ocn_custom_nemsdata(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if ! end of nems_orig_data custom + end if ! diagnose output if (dbug_flag > 1) then @@ -632,15 +628,17 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) lsize = size(ofrac) allocate(customwgt(lsize)) - customwgt(:) = -ofrac(:) / const_lhvap - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lat' , wgtA=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then + customwgt(:) = -ofrac(:) / const_lhvap + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_lat' , wgtA=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - customwgt(:) = -ofrac(:) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + customwgt(:) = -ofrac(:) + call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & + FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & @@ -679,177 +677,4 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) end subroutine med_phases_prep_ocn_custom_nems - !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_custom_nemsdata(gcomp, rc) - - ! ---------------------------------------------- - ! Custom calculation for nems_orig_data - ! ---------------------------------------------- - - use ESMF , only : ESMF_GridComp - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR - - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - real(R8), pointer :: ocnwgt1(:) ! NEMS_orig_data - real(R8), pointer :: icewgt1(:) ! NEMS_orig_data - real(R8), pointer :: wgtp01(:) ! NEMS_orig_data - real(R8), pointer :: wgtm01(:) ! NEMS_orig_data - real(R8), pointer :: customwgt(:) ! NEMS_orig_data - real(R8), pointer :: ifrac(:) - real(R8), pointer :: ofrac(:) - integer :: lsize - integer :: n - real(R8) , parameter :: const_lhvap = 2.501e6_R8 ! latent heat of evaporation ~ J/kg - character(len=*), parameter :: subname='(med_phases_prep_ocn_custom_nemsdata)' - !--------------------------------------- - - 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 - - ! get ice and open ocean fractions on the ocn mesh - call FB_GetFldPtr(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' , ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - lsize = size(ofrac) - allocate(customwgt(lsize)) - - ! open ocean (i.e. atm) and ice fraction - ! ocnwgt and icewgt are the "normal" fractions - ! ocnwgt1, icewgt1, and wgtp01 are the fractions that switch between atm and mediator fluxes - ! ocnwgt1+icewgt1+wgtp01 = 1.0 always - ! wgtp01 and wgtm01 are the same just one is +1 and the other is -1 to change sign depending on the ice fraction. - ! wgtp01 = 1 and wgtm01 = -1 when ice fraction = 0 - ! wgtp01 = 0 and wgtm01 = 0 when ice fraction > 0 - - allocate(ocnwgt1(lsize)) - allocate(icewgt1(lsize)) - allocate(wgtp01(lsize)) - allocate(wgtm01(lsize)) - allocate(customwgt(lsize)) - - do n = 1,lsize - if (ifrac(n) <= 0._R8) then - ! ice fraction is 0 - ocnwgt1(n) = 1.0_R8 - icewgt1(n) = 0.0_R8 - wgtp01(n) = 0.0_R8 - wgtm01(n) = 0.0_R8 - else - ! ice fraction is > 0 - ocnwgt1(n) = ofrac(n) - icewgt1(n) = ifrac(n) - wgtp01(n) = 0.0_R8 - wgtm01(n) = 0.0_R8 - end if - - ! check wgts do add to 1 as expected - ! TODO: check if this condition is still required - if(ofrac(n)+ifrac(n) /= 0._R8)then - if ( abs( ofrac(n) + ifrac(n) - 1.0_R8) > 1.0e-12 .or. & - abs( ocnwgt1(n) + icewgt1(n) + wgtp01(n) - 1.0_R8) > 1.0e-12 .or. & - abs( ocnwgt1(n) + icewgt1(n) - wgtm01(n) - 1.0_R8) > 1.0e-12) then - - write(6,100)trim(subname)//'ERROR: n, ofrac, ifrac, sum',& - n,ofrac(n),ifrac(n),ofrac(n)+ifrac(n) - write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, wgtp01, sum ', & - n,ocnwgt1(n),icewgt1(n),wgtp01(n),ocnwgt1(n)+icewgt1(n)+wgtp01(n) - write(6,101)trim(subname)//'ERROR: n, ocnwgt1, icewgt1, -wgtm01, sum ', & - n,ocnwgt1(n),icewgt1(n),-wgtp01(n),ocnwgt1(n)+icewgt1(n)-wgtm01(n) -100 format(a,i8,2x,3(d20.13,2x)) -101 format(a,i8,2x,4(d20.13,2x)) - - call ESMF_LogWrite(trim(subname)//": ERROR atm + ice fracs inconsistent", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) - rc = ESMF_FAILURE - return - endif - endif - end do - - customwgt(:) = wgtm01(:) / const_lhvap - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_evap', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_evap', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lat' , wgtB=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_sen ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_sen' , wgtB=wgtm01, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_taux ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_taux' , wgtB=icewgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_taux' , wgtC=wgtm01, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_tauy ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_tauy' , wgtB=icewgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_tauy' , wgtC=wgtm01, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! If there is no ice on the ocn gridcell (ocnwgt1=0) - sum Faxa_lwdn and Faxa_lwup - ! If there is ice on the ocn gridcell - merge Faox_lwup and Faxa_lwdn and ignore Faxa_lwup - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_lwnet', & - FBinA=is_local%wrap%FBMed_aoflux_o , fnameA='Faox_lwup ', wgtA=ocnwgt1, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_lwdn' , wgtB=ocnwgt1, & - FBinC=is_local%wrap%FBImp(compatm,compocn), fnameC='Faxa_lwnet', wgtC=wgtp01, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_rain' , & - FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_rain' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_snow' , & - FBInA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_snow' , wgtA=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! netsw_for_ocn = [downsw_from_atm*(1-ice_fraction)*(1-ocn_albedo)] + [pensw_from_ice*(ice_fraction)] - customwgt(:) = ofrac(:) * (1.0 - 0.06) - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdr' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdr', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swvdf' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_vdf', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndr' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idr', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', & - FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_swndf' , wgtA=customwgt, & - FBinB=is_local%wrap%FBImp(compice,compocn), fnameB='Fioi_swpen_idf', wgtB=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - deallocate(ocnwgt1) - deallocate(icewgt1) - deallocate(wgtp01) - deallocate(wgtm01) - deallocate(customwgt) - - 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_custom_nemsdata - end module med_phases_prep_ocn_mod From 1438b9dfefbed8bc559cd68df497996f1064f2ff Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Mon, 14 Sep 2020 12:39:39 +0000 Subject: [PATCH 045/206] fix coupling_mode if statement --- mediator/esmFldsExchange_nems_mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 08c217f19..ede7b4613 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -169,7 +169,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! - longwave downward flux allocate(flds(6)) flds = (/'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf',& - 'Faxa_lwnet', 'Faxa_lwdn '/) + 'Faxa_lwnet', 'Faxa_lwdn'/) do n = 1,size(flds) fldname = trim(flds(n)) call addfld(fldListTo(compocn)%flds, trim(fldname)) @@ -191,7 +191,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then + if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then ! to ocn: long wave net via auto merge call addmrg(fldListTo(compocn)%flds, 'Faxa_lwnet', & mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') From 83bca27cffe7d335c6b89a04852a6a751700512f Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Mon, 14 Sep 2020 21:01:42 +0000 Subject: [PATCH 046/206] prep ocn cleanup for datm --- mediator/esmFldsExchange_nems_mod.F90 | 69 +++++++++++++++------------ mediator/med_phases_prep_ocn_mod.F90 | 19 ++++---- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index ede7b4613..02336276e 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -46,6 +46,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) character(len=CL) :: cvalue character(len=CS) :: fldname character(len=CS), allocatable :: flds(:) + character(len=CS), allocatable :: suffix(:) character(len=*) , parameter :: subname='(esmFldsExchange_nems)' !-------------------------------------- @@ -167,9 +168,9 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! - downward diffuse visible incident solar radiation ! - longwave net heat flux ! - longwave downward flux - allocate(flds(6)) + allocate(flds(5)) flds = (/'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf',& - 'Faxa_lwnet', 'Faxa_lwdn'/) + 'Faxa_lwdn' /) do n = 1,size(flds) fldname = trim(flds(n)) call addfld(fldListTo(compocn)%flds, trim(fldname)) @@ -191,8 +192,23 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) + allocate(suffix(2)) + suffix = (/'taux', 'tauy'/) + if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then + ! to ocn: merge surface stress (custom merge calculation in med_phases_prep_ocn) + do n = 1,size(suffix) + call addfld(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds, 'Fioi_'//trim(suffix(n))) + call addfld(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n))) + call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n)), compocn, maptype, 'none', 'unset') + call addmap(fldListFr(compice)%flds, 'Fioi_'//trim(suffix(n)), compocn, mapfcopy, 'unset', 'unset') + end do + ! to ocn: long wave net via auto merge + call addfld(fldListTo(compocn)%flds, 'Faxa_lwnet') + 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') @@ -206,6 +222,16 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Faxa_lat') call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, maptype, 'none', 'unset') else + ! to ocn: surface stress from mediator and ice stress via auto merge + do n = 1,size(suffix) + call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(suffix(n))) + 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') + end do + ! to ocn: long wave net via auto merge call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & @@ -222,34 +248,17 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addmrg(fldListTo(compocn)%flds, 'Faox_evap', & mrg_from1=compmed, mrg_fld1='Faox_evap', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') end if - - ! to ocn: merge zonal surface stress (custom merge calculation in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Foxx_taux') - call addfld(fldListFr(compice)%flds, 'Fioi_taux') - call addfld(fldListFr(compatm)%flds, 'Faxa_taux') - call addmap(fldListFr(compatm)%flds, 'Faxa_taux', compocn, maptype, 'none', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_taux', compocn, mapfcopy, 'unset', 'unset') - - ! to ocn: meridional surface stress (custom merge calculation in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Foxx_tauy') - call addfld(fldListFr(compice)%flds, 'Fioi_tauy') - call addfld(fldListFr(compatm)%flds, 'Faxa_tauy') - call addmap(fldListFr(compatm)%flds, 'Faxa_tauy', compocn, maptype, 'none', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_tauy', compocn, mapfcopy, 'unset', 'unset') - - ! to ocn: net shortwave radiation from med (custom merge in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdf') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idf') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdf') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idf') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdr' , compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdf' , compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idr' , compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idf' , compocn, mapfcopy, 'unset', 'unset') + deallocate(suffix) + + allocate(suffix(4)) + ! to ocn: net shortwave radiation (custom merge in med_phases_prep_ocn) + suffix = (/'vdr', 'vdf', 'idr', 'idf'/) + do n = 1,size(suffix) + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_'//trim(suffix(n))) + call addmap(fldListFr(compice)%flds, 'Fioi_swpen'//trim(suffix(n)), compocn, mapfcopy, 'unset', 'unset') + end do + deallocate(suffix) ! to ocn: water flux due to melting ice from ice ! to ocn: heat flux from melting ice from ice diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 7b9948ed2..69eab1a42 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -638,16 +638,17 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) call med_merge_field(is_local%wrap%FBExp(compocn), 'Faxa_sen', & FBinA=is_local%wrap%FBImp(compatm,compocn), fnameA='Faxa_sen', wgtA=customwgt, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & - FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_taux' , wgtB=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & - FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_tauy' , wgtA=ifrac, & - FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_tauy' , wgtB=customwgt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + customwgt(:) = -ofrac(:) + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_taux', & + FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_taux' , wgtA=ifrac, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_taux' , wgtB=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_merge_field(is_local%wrap%FBExp(compocn), 'Foxx_tauy', & + FBinA=is_local%wrap%FBImp(compice,compocn), fnameA='Fioi_tauy' , wgtA=ifrac, & + FBinB=is_local%wrap%FBImp(compatm,compocn), fnameB='Faxa_tauy' , wgtB=customwgt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if ! netsw_for_ocn = [downsw_from_atm*(1-ice_fraction)*(1-ocn_albedo)] + [pensw_from_ice*(ice_fraction)] customwgt(:) = ofrac(:) * (1.0 - 0.06) From a6ece4141615486f3a1577fc6b0af41e95a1a623 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Tue, 15 Sep 2020 11:47:07 +0000 Subject: [PATCH 047/206] more consolidation in fields exchange --- mediator/esmFldsExchange_nems_mod.F90 | 72 ++++++++++++++------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 02336276e..6ca1efab7 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -46,7 +46,6 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) character(len=CL) :: cvalue character(len=CS) :: fldname character(len=CS), allocatable :: flds(:) - character(len=CS), allocatable :: suffix(:) character(len=*) , parameter :: subname='(esmFldsExchange_nems)' !-------------------------------------- @@ -166,11 +165,8 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! - downward diffuse near-infrared incident solar radiation ! - downward dirrect visible incident solar radiation ! - downward diffuse visible incident solar radiation - ! - longwave net heat flux - ! - longwave downward flux - allocate(flds(5)) - flds = (/'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf',& - 'Faxa_lwdn' /) + allocate(flds(4)) + flds = (/'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf'/) do n = 1,size(flds) fldname = trim(flds(n)) call addfld(fldListTo(compocn)%flds, trim(fldname)) @@ -179,6 +175,20 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) + ! to ocn: from ice net shortwave radiation (custom merge in med_phases_prep_ocn) + ! - downward direct near-infrared incident solar radiation + ! - downward diffuse near-infrared incident solar radiation + ! - downward dirrect visible incident solar radiation + ! - downward diffuse visible incident solar radiation + allocate(flds(4)) + flds = (/'vdr', 'vdf', 'idr', 'idf'/) + do n = 1,size(flds) + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_'//trim(flds(n))) + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_'//trim(flds(n))) + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_'//trim(flds(n)), compocn, mapfcopy, 'unset', 'unset') + end do + deallocate(flds) + ! to ocn: rain and snow via auto merge allocate(flds(2)) flds = (/'Faxa_rain', 'Faxa_snow'/) @@ -192,20 +202,20 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) - allocate(suffix(2)) - suffix = (/'taux', 'tauy'/) - if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_frac') then ! to ocn: merge surface stress (custom merge calculation in med_phases_prep_ocn) - do n = 1,size(suffix) - call addfld(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds, 'Fioi_'//trim(suffix(n))) - call addfld(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n))) - call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n)), compocn, maptype, 'none', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_'//trim(suffix(n)), compocn, mapfcopy, 'unset', 'unset') + allocate(flds(2)) + flds = (/'taux', 'tauy'/) + do n = 1,size(flds) + call addfld(fldListTo(compocn)%flds, 'Foxx_'//trim(flds(n))) + call addfld(fldListFr(compice)%flds, 'Fioi_'//trim(flds(n))) + call addfld(fldListFr(compatm)%flds, 'Faxa_'//trim(flds(n))) + call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(flds(n)), compocn, maptype, 'none', 'unset') + call addmap(fldListFr(compice)%flds, 'Fioi_'//trim(flds(n)), compocn, mapfcopy, 'unset', 'unset') end do + deallocate(flds) - ! to ocn: long wave net via auto merge + ! to ocn: net long wave via auto merge call addfld(fldListTo(compocn)%flds, 'Faxa_lwnet') call addfld(fldListFr(compatm)%flds, 'Faxa_lwnet') call addmap(fldListFr(compatm)%flds, 'Faxa_lwnet', compocn, maptype, 'none', 'unset') @@ -223,17 +233,22 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, maptype, 'none', 'unset') else ! to ocn: surface stress from mediator and ice stress via auto merge - do n = 1,size(suffix) - call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(suffix(n))) - 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') + allocate(flds(2)) + flds = (/'taux', 'tauy'/) + do n = 1,size(flds) + call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(flds(n))) + 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') end do + deallocate(flds) ! to ocn: long wave net via auto merge call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') + 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') @@ -248,17 +263,6 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addmrg(fldListTo(compocn)%flds, 'Faox_evap', & mrg_from1=compmed, mrg_fld1='Faox_evap', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') end if - deallocate(suffix) - - allocate(suffix(4)) - ! to ocn: net shortwave radiation (custom merge in med_phases_prep_ocn) - suffix = (/'vdr', 'vdf', 'idr', 'idf'/) - do n = 1,size(suffix) - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_'//trim(suffix(n))) - call addmap(fldListFr(compice)%flds, 'Fioi_swpen'//trim(suffix(n)), compocn, mapfcopy, 'unset', 'unset') - end do - deallocate(suffix) ! to ocn: water flux due to melting ice from ice ! to ocn: heat flux from melting ice from ice From af0d961386080ced7f63a14ca194b4c2bbe5a95d Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Tue, 15 Sep 2020 07:55:11 -0400 Subject: [PATCH 048/206] white space --- mediator/esmFldsExchange_nems_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 6ca1efab7..7d5e7eabe 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -239,7 +239,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(flds(n))) 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)), & + 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') end do From 9c171464145ef56cb7ea15d7d1cb052b1477a72b Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 18 Sep 2020 16:16:26 -0600 Subject: [PATCH 049/206] change method to find CIMEROOT --- cime_config/buildnml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index 25cd73da2..9bc8e20f4 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -3,7 +3,10 @@ """ import os, sys -_CIMEROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..","..","..","..") +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") + sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) import shutil, glob, itertools From 887c30eec82a80e245c9ea981a04651abb17c4c0 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 21 Sep 2020 10:44:25 -0600 Subject: [PATCH 050/206] fix hardcoded paths --- cime_config/buildnml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index 9bc8e20f4..e9d8a3ed1 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -393,7 +393,7 @@ def _create_runseq(case, coupling_times, valid_comps): comp_lnd = case.get_value("COMP_LND") comp_ocn = case.get_value("COMP_OCN") - sys.path.append(os.path.join(_CIMEROOT, "src", "drivers", "nuopc", "cime_config", "runseq")) + sys.path.append(os.path.join(os.path.dirname(__file__), "runseq")) if (comp_ice == "cice" and comp_atm == 'datm' and comp_ocn == "docn"): from runseq_D import gen_runseq @@ -566,7 +566,7 @@ def buildnml(case, caseroot, component): # copy fd_cesm.yaml to rundir cimeroot = case.get_value("CIMEROOT") - fd_dir = os.path.join(cimeroot, "src","drivers","nuopc","mediator") + fd_dir = os.path.join(os.path.dirname(__file__),os.pardir,"mediator") coupling_mode = case.get_value('COUPLING_MODE') if coupling_mode == 'cesm': filename = os.path.join(fd_dir,"fd_cesm.yaml") From 3c79b2c58d392a8dd1eb850fc6d63735a997785a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 21 Sep 2020 11:14:47 -0600 Subject: [PATCH 051/206] fix hardcoded paths in buildexe --- cime_config/buildexe | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index 2059d4c23..82d018768 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -6,7 +6,10 @@ build model executable import sys, os -_CIMEROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..","..","..","..") +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") + sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) from standard_script_setup import * @@ -80,10 +83,11 @@ def _main_func(): os.makedirs(bld_root) with open(os.path.join(bld_root,'Filepath'), 'w') as out: + cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) if not skip_mediator: - out.write(os.path.join(cimeroot, "src", "drivers", "nuopc", "mediator") + "\n") + out.write(os.path.join(cmeps_dir, "mediator") + "\n") out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") - out.write(os.path.join(cimeroot, "src", "drivers", "nuopc", "drivers", "cime") + "\n") + out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") # build model executable makefile = os.path.join(casetools, "Makefile") From 72fdeec4abd7f9c42a425638c148b6129585cda3 Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 23 Sep 2020 15:24:56 -0600 Subject: [PATCH 052/206] fix copling mode issue --- cime_config/config_component.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 036930492..aa7ab6510 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -28,7 +28,7 @@ char - cesm,nems_orig_active,nems_orig_data,nems_frac,hafs + cesm,nems_orig,nems_orig_data,nems_frac,hafs cesm run_coupling env_run.xml From b36a949252338a3d6bb8ebaf42d476bc8968a23f Mon Sep 17 00:00:00 2001 From: uturuncoglu Date: Wed, 23 Sep 2020 16:16:55 -0600 Subject: [PATCH 053/206] support multiple coupling mode for nems --- cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index e9d8a3ed1..ee9b0f1f7 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -572,7 +572,7 @@ 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 coupling_mode == 'nems': + 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") From 318350638073343cafa11fca52392422a56a4126 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 27 Sep 2020 19:49:36 -0600 Subject: [PATCH 054/206] bug fix for creation of ocean and ice fractions on atm mesh --- mediator/med_fraction_mod.F90 | 318 +++++++++++++++++----------------- 1 file changed, 163 insertions(+), 155 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 14cb9f4c3..074e000b6 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -3,8 +3,7 @@ module med_fraction_mod !----------------------------------------------------------------------------- ! Mediator Component. ! Sets fractions on all component grids - ! the fractions fields are now afrac, ifrac, ofrac, lfrac, and lfrin. - ! afrac = fraction of atm on a grid + ! the fractions fields are now ifrac, ofrac, lfrac, and lfrin. ! lfrac = fraction of lnd on a grid ! ifrac = fraction of ice on a grid ! ofrac = fraction of ocn on a grid @@ -12,7 +11,7 @@ module med_fraction_mod ! ifrad = fraction of ocn on a grid at last radiation time ! ofrad = fraction of ice on a grid at last radiation time ! - ! afrac, lfrac, ifrac, and ofrac: + ! lfrac, ifrac, and ofrac: ! are the self-consistent values in the system ! lfrin: ! is the fraction on the land grid and is allowed to @@ -22,10 +21,10 @@ module med_fraction_mod ! ! the fractions fields are defined for each grid in the fraction bundles as ! needed as follows. - ! character(*),parameter :: fraclist_a = 'afrac:ifrac:ofrac:lfrac:lfrin' - ! character(*),parameter :: fraclist_o = 'afrac:ifrac:ofrac:ifrad:ofrad' - ! character(*),parameter :: fraclist_i = 'afrac:ifrac:ofrac' - ! character(*),parameter :: fraclist_l = 'afrac:lfrac:lfrin' + ! character(*),parameter :: fraclist_a = 'ifrac:ofrac:lfrac:lfrin' + ! character(*),parameter :: fraclist_o = 'ifrac:ofrac:ifrad:ofrad' + ! character(*),parameter :: fraclist_i = 'ifrac:ofrac' + ! character(*),parameter :: fraclist_l = 'lfrac:lfrin' ! character(*),parameter :: fraclist_g = 'gfrac:lfrac' ! character(*),parameter :: fraclist_r = 'lfrac:rfrac' ! @@ -39,26 +38,20 @@ module med_fraction_mod ! we assume that component fractions sent at runtime ! are always the relative fraction covered. ! for example, if an ice cell can be up to 50% covered in - ! ice and 50% land, then the ice domain should have a fraction + ! ice and 50% land, then the ice should have a fraction ! value of 0.5 at that grid cell. at run time though, the ice ! fraction will be between 0.0 and 1.0 meaning that grid cells ! is covered with between 0.0 and 0.5 by ice. the "relative" fractions ! sent at run-time are corrected by the model to be total fractions ! such that in general, on every grid, - ! fractions_*(afrac) = 1.0 ! fractions_*(ifrac) + fractions_*(ofrac) + fractions_*(lfrac) = 1.0 ! where fractions_* are a bundle of fractions on a particular grid and - ! *frac (ie afrac) is the fraction of a particular component in the bundle. + ! *frac is the fraction of a particular component in the bundle. ! ! the fractions are computed fundamentally as follows (although the ! detailed implementation might be slightly different) ! ! initialization: - ! afrac is set on all grids - ! fractions_a(afrac) = 1.0 - ! fractions_o(afrac) = mapa2o(fractions_a(afrac)) - ! fractions_i(afrac) = mapa2i(fractions_a(afrac)) - ! fractions_l(afrac) = mapa2l(fractions_a(afrac)) ! initially assume ifrac on all grids is zero ! fractions_*(ifrac) = 0.0 ! fractions/masks provided by surface components @@ -94,8 +87,6 @@ module med_fraction_mod ! mapi2a uses *fractions_i(ifrac) and /fractions_a(ifrac) ! mapl2a uses *fractions_l(lfrin) and /fractions_a(lfrin) ! mapl2g weights by fractions_l(lfrac) with normalization and multiplies by fractions_g(lfrac) - ! mapa2* should use *fractions_a(afrac) and /fractions_*(afrac) but this - ! has been defered since the ratio always close to 1.0 ! ! run time: ! fractions_a(lfrac) + fractions_a(ofrac) + fractions_a(ifrac) ~ 1.0 @@ -123,6 +114,7 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps + use ESMF , only : ESMF_RouteHandle implicit none private @@ -133,10 +125,10 @@ module med_fraction_mod integer, parameter :: nfracs = 5 character(len=5) :: fraclist(nfracs,ncomps) - character(len=5),parameter,dimension(5) :: fraclist_a = (/'afrac','ifrac','ofrac','lfrac','lfrin'/) - character(len=5),parameter,dimension(5) :: fraclist_o = (/'afrac','ifrac','ofrac','ifrad','ofrad'/) - character(len=5),parameter,dimension(3) :: fraclist_i = (/'afrac','ifrac','ofrac'/) - character(len=5),parameter,dimension(3) :: fraclist_l = (/'afrac','lfrac','lfrin'/) + character(len=5),parameter,dimension(4) :: fraclist_a = (/'ifrac','ofrac','lfrac','lfrin'/) + character(len=5),parameter,dimension(4) :: fraclist_o = (/'ifrac','ofrac','ifrad','ofrad'/) + character(len=5),parameter,dimension(2) :: fraclist_i = (/'ifrac','ofrac'/) + character(len=5),parameter,dimension(2) :: fraclist_l = (/'lfrac','lfrin'/) character(len=5),parameter,dimension(2) :: fraclist_g = (/'gfrac','lfrac'/) character(len=5),parameter,dimension(2) :: fraclist_r = (/'rfrac','lfrac'/) character(len=5),parameter,dimension(1) :: fraclist_w = (/'wfrac'/) @@ -146,6 +138,8 @@ module med_fraction_mod character(*), parameter :: u_FILE_u = & __FILE__ + type(ESMF_RouteHandle) :: rh_ice2atm + !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -166,18 +160,29 @@ subroutine med_fraction_init(gcomp, rc) use med_internalstate_mod , only : InternalState use perf_mod , only : t_startf, t_stopf + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR + use ESMF , only : ESMF_Field, ESMF_FieldRegrid + use ESMF , only : ESMF_FieldRegridStore, ESMF_FieldRegridRelease + use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRedistRelease + use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL, ESMF_REGION_SELECT + use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA + use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint + use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables type(InternalState) :: is_local + type(ESMF_Field) :: fldsrc + type(ESMF_Field) :: flddst type(ESMF_FieldBundle) :: FBtemp real(R8), pointer :: frac(:) real(R8), pointer :: ofrac(:) real(R8), pointer :: lfrac(:) real(R8), pointer :: ifrac(:) - real(R8), pointer :: afrac(:) real(R8), pointer :: gfrac(:) real(R8), pointer :: lfrin(:) real(R8), pointer :: rfrac(:) @@ -187,9 +192,14 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: So_omask(:) integer :: i,j,n,n1 integer :: maptype + type(ESMF_RouteHandle) :: rh_ocn2atm + type(ESMF_RouteHandle) :: rh_lnd2atm + type(ESMF_RouteHandle) :: rh_atm2lnd + integer :: srcTermProcessing_Value = 0 logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' !--------------------------------------- + call t_startf('MED:'//subname) if (dbug_flag > 20) then @@ -238,44 +248,6 @@ subroutine med_fraction_init(gcomp, rc) first_call = .false. endif - !--------------------------------------- - ! Set 'afrac' for FBFrac(compatm), FBFrac(compice), FBFrac(compocn), FBFrac(complnd) - !--------------------------------------- - - if (is_local%wrap%comp_present(compatm)) then - - ! Set 'afrac' for FBFrac(compatm) to 1 - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'afrac', afrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - afrac(:) = 1.0_R8 - - ! Set 'afrac' for FBFrac(compice), FBFrac(compocn) and FBFrac(complnd) - do n = 1,ncomps - if (n == compice .or. n == compocn .or. n == complnd) then - if (is_local%wrap%med_coupling_active(compatm,n)) then - if (med_map_RH_is_created(is_local%wrap%RH(compatm,n,:),mapfcopy, rc=rc)) then - maptype = mapfcopy - else - maptype = mapconsf - if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,n,:),mapconsf, rc=rc)) then - call med_map_Fractions_init( gcomp, compatm, n, & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,n), & - RouteHandle=is_local%wrap%RH(compatm,n,mapconsf), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compatm), 'afrac', & - is_local%wrap%FBfrac(n), 'afrac', & - is_local%wrap%RH(compatm,n,:),maptype, rc=rc) - if(ChkErr(rc,__LINE__,u_FILE_u)) return - endif - end if - end do - - end if - !--------------------------------------- ! Set 'lfrin' for FBFrac(complnd) and FBFrac(compatm) !--------------------------------------- @@ -354,81 +326,96 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ifrac(:) = Si_imask(:) ! Set 'ifrac' in FBFrac(compatm) - if (is_local%wrap%comp_present(compatm)) then - if (is_local%wrap%med_coupling_active(compice,compatm)) then - if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then - maptype = mapfcopy - else - maptype = mapconsf - end if - if (.not. med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),maptype, rc=rc)) then - call med_map_Fractions_init( gcomp, compice, compatm, & - FBSrc=is_local%wrap%FBImp(compice,compice), & - FBDst=is_local%wrap%FBImp(compice,compatm), & - RouteHandle=is_local%wrap%RH(compice,compatm,maptype), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + if (is_local%wrap%comp_present(compatm) .and. is_local%wrap%med_coupling_active(compice,compatm)) then + + if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then + ! If ice and atm are on the same mesh - a redist route handle has already been created call FB_FieldRegrid(& is_local%wrap%FBfrac(compice), 'ifrac', & is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) + is_local%wrap%RH(compice,compatm,:), mapfcopy, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! generate a new route hande for ice->atm mapping with no masks + ! should not set srcMaskValue or dstMaskValue + call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ifrac', fldsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ifrac', flddst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=rh_ice2atm, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & + srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & + termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) end if - endif - endif + end if + end if !--------------------------------------- - ! Set 'ofrac' in FBFrac(compocn) and FBFrac(compatm) + ! Set 'ofrac' in FBFrac(compocn) and 'ofrac' in FBFrac(compatm) !--------------------------------------- if (is_local%wrap%comp_present(compocn)) then + ! Set 'ofrac' in FBFrac(compocn) call FB_getFldPtr(is_local%wrap%FBImp(compocn,compocn) , 'So_omask', So_omask, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ofrac(:) = So_omask(:) - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compatm,:),mapconsf, rc=rc)) then - call med_map_Fractions_init( gcomp, compocn, compatm, & - FBSrc=is_local%wrap%FBImp(compocn,compocn), & - FBDst=is_local%wrap%FBImp(compocn,compatm), & - RouteHandle=is_local%wrap%RH(compocn,compatm,mapconsf), rc=rc) + ! Set 'ofrac' in FBFrac(compatm) + ! This is mapping the ocean mask to the atm grid - so in effect it is the 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 + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compocn,compatm,:),mapfcopy, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! generate a new route hande for ocn->atm mapping with no masks + ! should not set srcMaskValue or dstMaskValue + call FB_GetFieldByName(is_local%wrap%FBfrac(compocn), 'ofrac', fldsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ofrac', flddst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=rh_ocn2atm, & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & + srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ocn2atm, & + termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) + call ESMF_FieldRegridRelease(rh_ocn2atm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:),mapconsf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if - !--------------------------------------- ! Set 'lfrac' in FBFrac(compatm) and correct 'ofrac' in FBFrac(compatm) ! --------------------------------------- - ! These should actually be mapo2a of ofrac and lfrac but we can't - ! map lfrac from o2a due to masked mapping weights. So we have to - ! settle for a residual calculation that is truncated to zero to - ! try to preserve "all ocean" cells. - if (is_local%wrap%comp_present(compatm)) then if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) if (.not. is_local%wrap%comp_present(complnd)) then + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) lfrac(:) = 0.0_R8 else + ! These should actually be mapo2a of ofrac and lfrac but we can't + ! map lfrac from o2a due to masked mapping weights. So we have to + ! settle for a residual calculation that is truncated to zero to + ! try to preserve "all ocean" cells. + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) do n = 1,size(lfrac) lfrac(n) = 1.0_R8 - ofrac(n) if (abs(lfrac(n)) < eps_fraclim) then @@ -570,6 +557,41 @@ subroutine med_fraction_init(gcomp, rc) wfrac(:) = 1.0_R8 endif + !--------------------------------------- + ! Create route handles ocn<->ice if not created + !--------------------------------------- + + 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, & + STgeom=is_local%wrap%NStateImp(compocn), & + STflds=is_local%wrap%NStateImp(compice), & + name='FBImp'//trim(compname(compice))//'_'//trim(compname(compocn)), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call med_map_Fractions_init( gcomp, compice, compocn, & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compocn), & + RouteHandle=is_local%wrap%RH(compice,compocn,mapfcopy), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + 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, & + STgeom=is_local%wrap%NStateImp(compice), & + STflds=is_local%wrap%NStateImp(compocn), & + name='FBImp'//trim(compname(compocn))//'_'//trim(compname(compice)), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call med_map_Fractions_init( gcomp, compocn, compice, & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compice), & + RouteHandle=is_local%wrap%RH(compocn,compice,mapfcopy), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + !--------------------------------------- ! Diagnostic output !--------------------------------------- @@ -602,12 +624,15 @@ subroutine med_fraction_set(gcomp, rc) use ESMF , only : ESMF_FieldBundleIsCreated use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_REGION_TOTAL, ESMF_REGION_SELECT + use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag + use ESMF , only : ESMF_Field, ESMF_FieldRegrid use esmFlds , only : compatm, compocn, compice, compname use esmFlds , only : mapconsf, mapnstod, mapfcopy, mapnstod_consf use esmFlds , only : coupling_mode use med_internalstate_mod , only : InternalState use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created use perf_mod , only : t_startf, t_stopf + use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName ! input/output variables type(ESMF_GridComp) :: gcomp @@ -615,6 +640,8 @@ subroutine med_fraction_set(gcomp, rc) ! local variables type(InternalState) :: is_local + type(ESMF_Field) :: fldsrc + type(ESMF_Field) :: flddst real(r8), pointer :: lfrac(:) real(r8), pointer :: ifrac(:) real(r8), pointer :: ofrac(:) @@ -640,37 +667,6 @@ subroutine med_fraction_set(gcomp, rc) ! Update FBFrac(compice), FBFrac(compocn) and FBFrac(compatm) field bundles !--------------------------------------- - 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, & - STgeom=is_local%wrap%NStateImp(compocn), & - STflds=is_local%wrap%NStateImp(compice), & - name='FBImp'//trim(compname(compice))//'_'//trim(compname(compocn)), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call med_map_Fractions_init( gcomp, compice, compocn, & - FBSrc=is_local%wrap%FBImp(compice,compice), & - FBDst=is_local%wrap%FBImp(compice,compocn), & - RouteHandle=is_local%wrap%RH(compice,compocn,mapfcopy), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - 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, & - STgeom=is_local%wrap%NStateImp(compice), & - STflds=is_local%wrap%NStateImp(compocn), & - name='FBImp'//trim(compname(compocn))//'_'//trim(compname(compice)), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call med_map_Fractions_init( gcomp, compocn, compice, & - FBSrc=is_local%wrap%FBImp(compocn,compocn), & - FBDst=is_local%wrap%FBImp(compocn,compice), & - RouteHandle=is_local%wrap%RH(compocn,compice,mapfcopy), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - if (is_local%wrap%comp_present(compice)) then ! ------------------------------------------- @@ -725,33 +721,46 @@ subroutine med_fraction_set(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then if (trim(coupling_mode) == 'nems_orig' ) then - maptype = mapnstod_consf + ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:), mapnstod_consf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compice,compatm,:), mapnstod_consf, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if else - if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then - maptype = mapfcopy - else - maptype = mapconsf + ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compice,compatm)) then + Call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ifrac', fldsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ifrac', flddst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & + termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - end if - - ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compice,compatm,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ofrac', fldsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ofrac', flddst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & + termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if - end if + end if ! end of if present compatm end if ! end of if present compice @@ -762,8 +771,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 FB_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 From f69e39ca1739d9e06e9d33b70bf1c97237e92299 Mon Sep 17 00:00:00 2001 From: jedwards4b Date: Wed, 30 Sep 2020 13:12:16 -0600 Subject: [PATCH 055/206] Create extbuild.yml --- .github/workflows/extbuild.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/extbuild.yml diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml new file mode 100644 index 000000000..9ddbd2eb7 --- /dev/null +++ b/.github/workflows/extbuild.yml @@ -0,0 +1,33 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Run a one-line script + run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + echo Add other actions to build, + echo test, and deploy your project. From 7b430580f10874bd65886a854d7f3ea9e264c991 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 30 Sep 2020 13:54:22 -0600 Subject: [PATCH 056/206] cleanup of fix to map fractions --- mediator/med_fraction_mod.F90 | 303 +++++++++++++++------------------- mediator/med_map_mod.F90 | 90 ++++------ 2 files changed, 159 insertions(+), 234 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 074e000b6..2b8b9875f 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -114,7 +114,6 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps - use ESMF , only : ESMF_RouteHandle implicit none private @@ -138,8 +137,6 @@ module med_fraction_mod character(*), parameter :: u_FILE_u = & __FILE__ - type(ESMF_RouteHandle) :: rh_ice2atm - !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -155,29 +152,17 @@ subroutine med_fraction_init(gcomp, rc) use esmFlds , only : coupling_mode use esmFlds , only : compatm, compocn, compice, complnd use esmFlds , only : comprof, compglc, compwav, compname - use esmFlds , only : mapconsf, mapfcopy, mapnstod_consf - use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created + use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd + use med_map_mod , only : med_map_fractions_init, med_map_rh_is_created use med_internalstate_mod , only : InternalState use perf_mod , only : t_startf, t_stopf - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR - use ESMF , only : ESMF_Field, ESMF_FieldRegrid - use ESMF , only : ESMF_FieldRegridStore, ESMF_FieldRegridRelease - use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRedistRelease - use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL, ESMF_REGION_SELECT - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA - use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint - use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName - ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables type(InternalState) :: is_local - type(ESMF_Field) :: fldsrc - type(ESMF_Field) :: flddst type(ESMF_FieldBundle) :: FBtemp real(R8), pointer :: frac(:) real(R8), pointer :: ofrac(:) @@ -192,10 +177,6 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: So_omask(:) integer :: i,j,n,n1 integer :: maptype - type(ESMF_RouteHandle) :: rh_ocn2atm - type(ESMF_RouteHandle) :: rh_lnd2atm - type(ESMF_RouteHandle) :: rh_atm2lnd - integer :: srcTermProcessing_Value = 0 logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' !--------------------------------------- @@ -234,13 +215,12 @@ subroutine med_fraction_init(gcomp, rc) ! Note - must use import state here - since export state might not ! contain anything other than scalar data if the component is not prognostic do n1 = 1,ncomps - if (is_local%wrap%comp_present(n1) .and. ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then - + 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, & STgeom=is_local%wrap%NStateImp(n1), fieldNameList=fraclist(:,n1), & name='FBfrac'//trim(compname(n1)), rc=rc) - - ! zero out FBfracs call FB_reset(is_local%wrap%FBfrac(n1), value=czero, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -252,8 +232,6 @@ subroutine med_fraction_init(gcomp, rc) ! Set 'lfrin' for FBFrac(complnd) and FBFrac(compatm) !--------------------------------------- - ! The following is just an initial "guess", updated later - if (is_local%wrap%comp_present(complnd)) then ! Set 'lfrin' for FBFrac(complnd) @@ -263,55 +241,45 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return lfrin(:) = Sl_lfrin(:) - ! Set 'lfrin for FBFrac(compatm) + ! Set 'lfrin for FBFrac(compatm) + ! The following is just an initial "guess", updated later if (is_local%wrap%comp_present(compatm) .and. (is_local%wrap%med_coupling_active(compatm,complnd))) then - ! Note - need to do the following if compatm->complnd is active, even if complnd->compatm is not active - - ! Create a temporary field bundle if one does not exists - if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then - call FB_init(FBout=FBtemp, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(compatm,compatm), & - fieldNameList=(/'Fldtemp'/), name='FBtemp', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - ! Determine map type if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then maptype = mapfcopy else - maptype = mapconsf - end if - - ! Create route handle from lnd->atm if necessary - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then - call med_map_Fractions_init( gcomp, complnd, compatm, & - FBSrc=is_local%wrap%FBImp(complnd,complnd), & - FBDst=is_local%wrap%FBImp(complnd,compatm), & - RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - call med_map_Fractions_init( gcomp, complnd, compatm, & - FBSrc=is_local%wrap%FBImp(complnd,complnd), & - FBDst=FBtemp, & - RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then + call med_map_Fractions_init( gcomp, complnd, compatm, & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compatm), & + RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + ! Note - need to do the following if + ! compatm->complnd is active, even if complnd->compatm is not active + call FB_init(FBout=FBtemp, & + flds_scalar_name=is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBImp(compatm,compatm), & + fieldNameList=(/'Fldtemp'/), name='FBtemp', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_Fractions_init( gcomp, complnd, compatm, & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=FBtemp, & + RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleDestroy(FBtemp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if end if - ! Regrid 'lfrin' from FBFrac(complnd) -> FBFrac(compatm) call FB_FieldRegrid(& is_local%wrap%FBfrac(complnd), 'lfrin', & is_local%wrap%FBfrac(compatm), 'lfrin', & is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Destroy temporary field bundle if created - if (ESMF_FieldBundleIsCreated(FBTemp)) then - call ESMF_FieldBundleDestroy(FBtemp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if end if end if @@ -328,30 +296,32 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ifrac(:) = Si_imask(:) - ! Set 'ifrac' in FBFrac(compatm) + ! Set 'ifrac' in FBFrac(compatm) - at this point this is the ice mask mapped to the atm mesh + ! This maps the ice mask (which is the same as the ocean mask) to the atm mesh if (is_local%wrap%comp_present(compatm) .and. is_local%wrap%med_coupling_active(compice,compatm)) then if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then ! If ice and atm are on the same mesh - a redist route handle has already been created - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), mapfcopy, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - ! generate a new route hande for ice->atm mapping with no masks - ! should not set srcMaskValue or dstMaskValue - call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ifrac', fldsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ifrac', flddst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=rh_ice2atm, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & - termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) + maptype = mapfcopy + else + if (trim(coupling_mode) == 'nems_orig' ) then + maptype = mapnstod_consd + else + maptype = mapconsd + end if + if (.not. med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),maptype, rc=rc)) then + call med_map_Fractions_init( gcomp, compice, compatm, & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compatm), & + RouteHandle=is_local%wrap%RH(compice,compatm,maptype), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -368,33 +338,33 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ofrac(:) = So_omask(:) - ! Set 'ofrac' in FBFrac(compatm) - ! This is mapping the ocean mask to the atm grid - so in effect it is the land fraction on the atm grid + ! 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 - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:),mapfcopy, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + maptype = mapfcopy else - ! generate a new route hande for ocn->atm mapping with no masks - ! should not set srcMaskValue or dstMaskValue - call FB_GetFieldByName(is_local%wrap%FBfrac(compocn), 'ofrac', fldsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ofrac', flddst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=rh_ocn2atm, & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - srcTermProcessing=srcTermProcessing_Value, ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ocn2atm, & - termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) - call ESMF_FieldRegridRelease(rh_ocn2atm, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (trim(coupling_mode) == 'nems_orig' ) then + maptype = mapnstod_consd + else + maptype = mapconsd + end if + if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compatm,:),maptype, rc=rc)) then + call med_map_Fractions_init( gcomp, compocn, compatm, & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compatm), & + RouteHandle=is_local%wrap%RH(compocn,compatm,maptype), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if @@ -403,41 +373,37 @@ subroutine med_fraction_init(gcomp, rc) ! --------------------------------------- if (is_local%wrap%comp_present(compatm)) then - - if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then - - if (.not. is_local%wrap%comp_present(complnd)) then - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - lfrac(:) = 0.0_R8 - else + if (is_local%wrap%comp_present(complnd)) then + ! land is present + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrin', lfrin, rc=rc) + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) + if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then + ! ocean is present ! These should actually be mapo2a of ofrac and lfrac but we can't ! map lfrac from o2a due to masked mapping weights. So we have to ! settle for a residual calculation that is truncated to zero to ! try to preserve "all ocean" cells. - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) do n = 1,size(lfrac) lfrac(n) = 1.0_R8 - ofrac(n) if (abs(lfrac(n)) < eps_fraclim) then lfrac(n) = 0.0_R8 end if end do + else + ! If the ocean or ice are absent, then simply set 'lfrac' to 'lfrin' for FBFrac(compatm) + do n = 1,size(lfrac) + lfrac(n) = lfrin(n) + ofrac(n) = 1.0_R8 - lfrac(n) + if (abs(ofrac(n)) < eps_fraclim) then + ofrac(n) = 0.0_R8 + end if + end do end if - - else if (is_local%wrap%comp_present(complnd)) then - - ! If the ocean or ice are absent, then simply set 'lfrac' to 'lfrin' for FBFrac(compatm) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrin', lfrin, rc=rc) + else + ! land is not present call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) - do n = 1,size(lfrac) - lfrac(n) = lfrin(n) - ofrac(n) = 1.0_R8 - lfrac(n) - if (abs(ofrac(n)) < eps_fraclim) then - ofrac(n) = 0.0_R8 - end if - end do - + lfrac(:) = 0.0_R8 end if end if @@ -451,17 +417,18 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then ! If atm -> lnd coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) if (is_local%wrap%med_coupling_active(compatm,complnd)) then - if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapconsf, rc=rc)) then + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then call med_map_Fractions_init( gcomp, compatm, complnd, & FBSrc=is_local%wrap%FBImp(compatm,compatm), & FBDst=is_local%wrap%FBImp(compatm,complnd), & - RouteHandle=is_local%wrap%RH(compatm,complnd,mapconsf), rc=rc) + RouteHandle=is_local%wrap%RH(compatm,complnd,maptype), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& is_local%wrap%FBfrac(compatm), 'lfrac', & is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%RH(compatm,complnd,:),mapconsf, rc=rc) + is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if else @@ -482,8 +449,8 @@ 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 + 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 FB_getFldPtr(is_local%wrap%FBfrac(comprof) , 'rfrac', rfrac, rc=rc) call FB_getFldPtr(is_local%wrap%FBImp(comprof,comprof), 'frac' , frac, rc=rc) rfrac(:) = frac(:) @@ -496,17 +463,18 @@ subroutine med_fraction_init(gcomp, rc) ! Set 'lfrac' in FBFrac(comprof) if (is_local%wrap%comp_present(complnd)) then - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),mapconsf, rc=rc)) then + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc)) then call med_map_Fractions_init( gcomp, complnd, comprof, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=is_local%wrap%FBImp(complnd,comprof), & - RouteHandle=is_local%wrap%RH(complnd,comprof,mapconsf), rc=rc) + RouteHandle=is_local%wrap%RH(complnd,comprof,maptype), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& is_local%wrap%FBfrac(complnd), 'lfrac', & is_local%wrap%FBfrac(comprof), 'lfrac', & - is_local%wrap%RH(complnd,comprof,:),mapconsf, rc=rc) + is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif endif @@ -531,17 +499,18 @@ subroutine med_fraction_init(gcomp, rc) ! Set 'lfrac' in FBFrac(compglc) if ( is_local%wrap%comp_present(complnd) .and. is_local%wrap%med_coupling_active(complnd,compglc)) then - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc,:),mapconsf, rc=rc)) then + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc,:),maptype, rc=rc)) then call med_map_Fractions_init( gcomp, complnd, compglc, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=is_local%wrap%FBImp(complnd,compglc), & - RouteHandle=is_local%wrap%RH(complnd,compglc,mapconsf), rc=rc) + RouteHandle=is_local%wrap%RH(complnd,compglc,maptype), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& is_local%wrap%FBfrac(complnd), 'lfrac', & is_local%wrap%FBfrac(compglc), 'lfrac', & - is_local%wrap%RH(complnd,compglc,:),mapconsf, rc=rc) + is_local%wrap%RH(complnd,compglc,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif endif @@ -621,18 +590,14 @@ subroutine med_fraction_set(gcomp, rc) ! Update time varying fractions use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_FieldBundleIsCreated + use ESMF , only : ESMF_Field, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_REGION_TOTAL, ESMF_REGION_SELECT - use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag - use ESMF , only : ESMF_Field, ESMF_FieldRegrid use esmFlds , only : compatm, compocn, compice, compname - use esmFlds , only : mapconsf, mapnstod, mapfcopy, mapnstod_consf + use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd use esmFlds , only : coupling_mode use med_internalstate_mod , only : InternalState use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created use perf_mod , only : t_startf, t_stopf - use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName ! input/output variables type(ESMF_GridComp) :: gcomp @@ -640,8 +605,6 @@ subroutine med_fraction_set(gcomp, rc) ! local variables type(InternalState) :: is_local - type(ESMF_Field) :: fldsrc - type(ESMF_Field) :: flddst real(r8), pointer :: lfrac(:) real(r8), pointer :: ifrac(:) real(r8), pointer :: ofrac(:) @@ -651,12 +614,14 @@ subroutine med_fraction_set(gcomp, rc) integer :: maptype character(len=*),parameter :: subname='(med_fraction_set)' !--------------------------------------- + + rc = ESMF_SUCCESS + call t_startf('MED:'//subname) if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if - rc = ESMF_SUCCESS ! Get the internal state from Component. nullify(is_local%wrap) @@ -720,43 +685,35 @@ subroutine med_fraction_set(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then + ! Determine maptype if (trim(coupling_mode) == 'nems_orig' ) then - ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) + maptype = mapnstod_consd + else + if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then + maptype = mapfcopy + else + maptype = mapconsd + end if + end if + + ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compice,compatm)) then if (is_local%wrap%med_coupling_active(compice,compatm)) then call FB_FieldRegrid(& is_local%wrap%FBfrac(compice), 'ifrac', & is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), mapnstod_consf, rc=rc) + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) + end if + + ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) + if (is_local%wrap%med_coupling_active(compocn,compatm)) then if (is_local%wrap%med_coupling_active(compocn,compatm)) then call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ofrac', & + is_local%wrap%FBfrac(compocn), 'ofrac', & is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compice,compatm,:), mapnstod_consf, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - else - ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compice,compatm)) then - Call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ifrac', fldsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ifrac', flddst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & - termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_GetFieldByName(is_local%wrap%FBfrac(compice), 'ofrac', fldsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldByName(is_local%wrap%FBfrac(compatm), 'ofrac', flddst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegrid(fldsrc, flddst, routehandle=rh_ice2atm, & - termorderflag=ESMF_TERMORDER_SRCSEQ, zeroregion=ESMF_REGION_TOTAL, rc=rc) + is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index e0aafb600..a88cd1241 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -14,6 +14,7 @@ module med_map_mod use esmFlds , only : fldListFr, fldListTo use esmFlds , only : coupling_mode use med_internalstate_mod , only : InternalState + use med_internalstate_mod , only : logunit, mastertask use med_constants_mod , only : ispval_mask => med_constants_ispval_mask use med_constants_mod , only : czero => med_constants_czero use med_constants_mod , only : dbug_flag => med_constants_dbug_flag @@ -36,7 +37,7 @@ module med_map_mod ! public routines public :: med_map_RouteHandles_init public :: med_map_RH_is_created - public :: med_map_Fractions_init + public :: med_map_fractions_init public :: med_map_MapNorm_init public :: med_map_FB_Regrid_Norm public :: med_map_FB_Field_Regrid @@ -272,7 +273,6 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) factorList=factorList, & ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - !unmappedDstList=unmappedDstList, & rc=rc) else if ((mapindex == mapconsd .or. mapindex == mapnstod_consd) .and. & .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapconsd,rc)) then @@ -286,7 +286,6 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) factorList=factorList, & ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - !unmappedDstList=unmappedDstList, & rc=rc) else if (mapindex == mappatch) then call ESMF_FieldRegridStore(fldsrc, flddst, & @@ -417,19 +416,20 @@ end function med_map_RH_is_created_RH1d !================================================================================ - subroutine med_map_Fractions_init(gcomp, n1, n2, FBSrc, FBDst, RouteHandle, rc) + subroutine med_map_fractions_init(gcomp, n1, n2, FBSrc, FBDst, RouteHandle, rc) !--------------------------------------------- ! Initialize initialize additional route handles ! for mapping fractions !--------------------------------------------- - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only : ESMF_GridComp, ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field - use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldSMMStore, ESMF_FieldRegridStore - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA - use NUOPC , only : NUOPC_CompAttributeGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush + use ESMF , only : ESMF_GridComp, ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field + use ESMF , only : ESMF_FieldRegridStore + use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE + use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA + ! input/output variables type(ESMF_GridComp) :: gcomp integer , intent(in) :: n1 integer , intent(in) :: n2 @@ -441,82 +441,50 @@ subroutine med_map_Fractions_init(gcomp, n1, n2, FBSrc, FBDst, RouteHandle, rc) ! local variables type(ESMF_Field) :: fldsrc type(ESMF_Field) :: flddst - character(len=128) :: rhname - character(len=CS) :: mapname - character(len=CX) :: mapfile character(len=CS) :: string integer :: SrcMaskValue integer :: DstMaskValue - real(R8), pointer :: factorList(:) character(len=*), parameter :: subname=' (med_map_fractions_init: ) ' !--------------------------------------------- - call t_startf('MED:'//subname) + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS if (dbug_flag > 1) then call ESMF_LogWrite("Initializing RHs not yet created and needed for mapping fractions", & ESMF_LOGMSG_INFO) call ESMF_LogFlush() endif - rc = ESMF_SUCCESS - - call FB_getFieldN(FBsrc, 1, fldsrc, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call FB_getFieldN(FBDst, 1, flddst, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + string = trim(compname(n1))//"2"//trim(compname(n2))//'_weights' + write(logunit,'(a)') trim(subname) // trim(string) //' RH consd computed on the fly for fractions' + end if dstMaskValue = ispval_mask srcMaskValue = ispval_mask if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 - rhname = trim(compname(n1))//"2"//trim(compname(n2)) - string = trim(rhname)//'_weights' - if ( (n1 == compocn .and. n2 == compice) .or. (n1 == compice .and. n2 == compocn)) then - mapfile = 'idmap' - else - call ESMF_LogWrite("Querying for attribute "//trim(rhname)//"_fmapname = ", ESMF_LOGMSG_INFO) - call NUOPC_CompAttributeGet(gcomp, name=trim(rhname)//"_fmapname", value=mapfile, rc=rc) - mapname = trim(mapnames(mapconsf)) - end if - - if (mapfile == 'idmap') then - call ESMF_LogWrite(trim(subname) // trim(string) //& - ' RH '//trim(mapname)// ' is redist', ESMF_LOGMSG_INFO) - call ESMF_FieldRedistStore(fldsrc, flddst, & - routehandle=RouteHandle, & - ignoreUnmatchedIndices = .true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (mapfile /= 'unset') then - call ESMF_LogWrite(subname // trim(string) //& - ' RH '//trim(mapname)//' via input file '//trim(mapfile), ESMF_LOGMSG_INFO) - call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, & - routehandle=RouteHandle, & - ignoreUnmatchedIndices=.true., & - srcTermProcessing=srcTermProcessing_Value, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(subname // trim(string) //& - ' RH '//trim(mapname)//' computed on the fly '//trim(mapfile), ESMF_LOGMSG_INFO) - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=RouteHandle, & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - normType=ESMF_NORMTYPE_FRACAREA, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - end if + call FB_getFieldN(FBsrc, 1, fldsrc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_getFieldN(FBDst, 1, flddst, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=RouteHandle, & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & + normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif call t_stopf('MED:'//subname) - end subroutine med_map_Fractions_init + end subroutine med_map_fractions_init !================================================================================ From 4ece2770b03248b7c9b5fe2bad3b8a9c002353b9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 30 Sep 2020 17:01:37 -0600 Subject: [PATCH 057/206] more updates to fix nems problems --- mediator/esmFldsExchange_cesm_mod.F90 | 2 +- mediator/med_fraction_mod.F90 | 43 +++-- mediator/med_map_mod.F90 | 263 ++++++++++++++++++-------- mediator/med_phases_prep_glc_mod.F90 | 19 +- mediator/med_phases_prep_lnd_mod.F90 | 16 +- 5 files changed, 225 insertions(+), 118 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index f7615256a..411b5a39d 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -528,7 +528,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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, mapconsf, 'one', glc2lnd_smap) + 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 diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 2b8b9875f..5b6512b94 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -146,14 +146,15 @@ subroutine med_fraction_init(gcomp, rc) ! Initialize FBFrac(:) field bundles use ESMF , only : ESMF_GridComp, ESMF_Field - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_GridCompGet, ESMF_StateIsCreated use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleDestroy use esmFlds , only : coupling_mode use esmFlds , only : compatm, compocn, compice, complnd use esmFlds , only : comprof, compglc, compwav, compname use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd - use med_map_mod , only : med_map_fractions_init, med_map_rh_is_created + use med_map_mod , only : med_map_routehandles_init, med_map_rh_is_created use med_internalstate_mod , only : InternalState use perf_mod , only : t_startf, t_stopf @@ -251,10 +252,10 @@ subroutine med_fraction_init(gcomp, rc) maptype = mapconsd if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then - call med_map_Fractions_init( gcomp, complnd, compatm, & + call med_map_routehandles_init( complnd, compatm, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=is_local%wrap%FBImp(complnd,compatm), & - RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return else ! Note - need to do the following if @@ -264,10 +265,10 @@ subroutine med_fraction_init(gcomp, rc) FBgeom=is_local%wrap%FBImp(compatm,compatm), & fieldNameList=(/'Fldtemp'/), name='FBtemp', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_Fractions_init( gcomp, complnd, compatm, & + call med_map_routehandles_init( complnd, compatm, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=FBtemp, & - RouteHandle=is_local%wrap%RH(complnd,compatm,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleDestroy(FBtemp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -310,10 +311,10 @@ subroutine med_fraction_init(gcomp, rc) maptype = mapconsd end if if (.not. med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),maptype, rc=rc)) then - call med_map_Fractions_init( gcomp, compice, compatm, & + call med_map_routehandles_init( compice, compatm, & FBSrc=is_local%wrap%FBImp(compice,compice), & FBDst=is_local%wrap%FBImp(compice,compatm), & - RouteHandle=is_local%wrap%RH(compice,compatm,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -352,10 +353,10 @@ subroutine med_fraction_init(gcomp, rc) maptype = mapconsd end if if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compatm,:),maptype, rc=rc)) then - call med_map_Fractions_init( gcomp, compocn, compatm, & + call med_map_routehandles_init( compocn, compatm, & FBSrc=is_local%wrap%FBImp(compocn,compocn), & FBDst=is_local%wrap%FBImp(compocn,compatm), & - RouteHandle=is_local%wrap%RH(compocn,compatm,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -419,10 +420,10 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%med_coupling_active(compatm,complnd)) then maptype = mapconsd if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then - call med_map_Fractions_init( gcomp, compatm, complnd, & + call med_map_routehandles_init( compatm, complnd, & FBSrc=is_local%wrap%FBImp(compatm,compatm), & FBDst=is_local%wrap%FBImp(compatm,complnd), & - RouteHandle=is_local%wrap%RH(compatm,complnd,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& @@ -465,10 +466,10 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(complnd)) then maptype = mapconsd if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc)) then - call med_map_Fractions_init( gcomp, complnd, comprof, & + call med_map_routehandles_init( complnd, comprof, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=is_local%wrap%FBImp(complnd,comprof), & - RouteHandle=is_local%wrap%RH(complnd,comprof,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& @@ -501,10 +502,10 @@ subroutine med_fraction_init(gcomp, rc) 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_Fractions_init( gcomp, complnd, compglc, & + call med_map_routehandles_init( complnd, compglc, & FBSrc=is_local%wrap%FBImp(complnd,complnd), & FBDst=is_local%wrap%FBImp(complnd,compglc), & - RouteHandle=is_local%wrap%RH(complnd,compglc,maptype), rc=rc) + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& @@ -539,10 +540,10 @@ subroutine med_fraction_init(gcomp, rc) name='FBImp'//trim(compname(compice))//'_'//trim(compname(compocn)), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call med_map_Fractions_init( gcomp, compice, compocn, & + call med_map_routehandles_init(compice, compocn, & FBSrc=is_local%wrap%FBImp(compice,compice), & FBDst=is_local%wrap%FBImp(compice,compocn), & - RouteHandle=is_local%wrap%RH(compice,compocn,mapfcopy), rc=rc) + mapindex=mapfcopy, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compice,:),mapfcopy, rc=rc)) then @@ -553,10 +554,10 @@ subroutine med_fraction_init(gcomp, rc) name='FBImp'//trim(compname(compocn))//'_'//trim(compname(compice)), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call med_map_Fractions_init( gcomp, compocn, compice, & + call med_map_routehandles_init( compocn, compice, & FBSrc=is_local%wrap%FBImp(compocn,compocn), & FBDst=is_local%wrap%FBImp(compocn,compice), & - RouteHandle=is_local%wrap%RH(compocn,compice,mapfcopy), rc=rc) + mapindex=mapfcopy, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -596,7 +597,7 @@ subroutine med_fraction_set(gcomp, rc) use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd use esmFlds , only : coupling_mode use med_internalstate_mod , only : InternalState - use med_map_mod , only : med_map_Fractions_init, med_map_RH_is_created + use med_map_mod , only : med_map_RH_is_created use perf_mod , only : t_startf, t_stopf ! input/output variables diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index a88cd1241..6534db0aa 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -6,7 +6,7 @@ module med_map_mod use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_LOGMSG_INFO, ESMF_LogWrite use esmFlds , only : mapbilnr, mapconsf, mapconsd, mappatch, mapfcopy use esmFlds , only : mapunset, mapnames, nmappers - use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf + use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd use esmFlds , only : ncomps, compatm, compice, compocn, compname use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod use esmFlds , only : mapuv_with_cart3d @@ -35,14 +35,18 @@ module med_map_mod private ! public routines - public :: med_map_RouteHandles_init + public :: med_map_routehandles_init public :: med_map_RH_is_created - public :: med_map_fractions_init public :: med_map_MapNorm_init public :: med_map_FB_Regrid_Norm public :: med_map_FB_Field_Regrid public :: med_map_Field_Regrid + interface med_map_routehandles_init + module procedure med_map_routehandles_init_esmflds + module procedure med_map_routehandles_init_field + end interface + interface med_map_FB_Regrid_norm module procedure med_map_FB_Regrid_Norm_All end interface @@ -64,7 +68,7 @@ module med_map_mod contains !================================================================================ - subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) + subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) !--------------------------------------------- ! Initialize route handles in the mediator @@ -319,7 +323,8 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if !if (associated(unmappedDstList)) then - ! write(logMsg,*) trim(subname),trim(string),' number of unmapped dest points = ', size(unmappedDstList) + ! write(logMsg,*) trim(subname),trim(string),& + ! number of unmapped dest points = ', size(unmappedDstList) ! call ESMF_LogWrite(trim(logMsg), ESMF_LOGMSG_INFO) !end if end if @@ -347,10 +352,184 @@ subroutine med_map_RouteHandles_init(gcomp, llogunit, rc) endif call t_stopf('MED:'//subname) - end subroutine med_map_RouteHandles_init + end subroutine med_map_RouteHandles_init_esmflds !================================================================================ + subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) + + !--------------------------------------------- + ! Initialize initialize additional route handles + ! for mapping fractions + ! + !--------------------------------------------- + + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush + use ESMF , only : ESMF_GridComp, ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field + use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Field, ESMF_PoleMethod_Flag, ESMF_POLEMETHOD_ALLAVG + use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_FieldSMMStore + use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRegridStore, ESMF_REGRIDMETHOD_BILINEAR + use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA, ESMF_NORMTYPE_FRACAREA + use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_NEAREST_STOD + use ESMF , only : ESMF_REGRIDMETHOD_PATCH + + ! input/output variables + integer , intent(in) :: n1 + integer , intent(in) :: n2 + type(ESMF_FieldBundle) , intent(in) :: FBsrc + type(ESMF_FieldBundle) , intent(in) :: fBdst + integer , intent(in) :: mapindex + type(ESMF_RouteHandle) , intent(inout) :: RouteHandle(:,:,:) + integer , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: fldsrc + type(ESMF_Field) :: flddst + character(len=CS) :: string + character(len=CS) :: mapname + integer :: SrcMaskValue + integer :: DstMaskValue + type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG + character(len=*), parameter :: subname=' (module_med_map: med_map_routehandles_init) ' + !--------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + if (dbug_flag > 1) then + call ESMF_LogWrite("Initializing RHs not yet created and needed", & + ESMF_LOGMSG_INFO) + call ESMF_LogFlush() + endif + + mapname = trim(mapnames(mapindex)) + if (mastertask) then + string = trim(compname(n1))//"2"//trim(compname(n2))//'_weights' + write(logunit,'(3A)') subname, trim(string),& + ' RH regrid for '//trim(mapname)//' computed on the fly' + end if + + if (trim(coupling_mode) == 'cesm') then + dstMaskValue = ispval_mask + srcMaskValue = ispval_mask + if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 + if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 + else if (coupling_mode(1:4) == 'nems') then + if (n1 == compatm .and. (n2 == compocn .or. n2 == compice)) then + srcMaskValue = 1 + dstMaskValue = 0 + else if (n2 == compatm .and. (n1 == compocn .or. n1 == compice)) then + srcMaskValue = 0 + dstMaskValue = 1 + else if ((n1 == compocn .and. n2 == compice) .or. (n1 == compice .and. n2 == compocn)) then + srcMaskValue = 0 + dstMaskValue = 0 + else + ! TODO: what should the condition be here? + dstMaskValue = ispval_mask + srcMaskValue = ispval_mask + end if + else if (trim(coupling_mode) == 'hafs') then + dstMaskValue = ispval_mask + srcMaskValue = ispval_mask + if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 + if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 + end if + + call FB_getFieldN(FBsrc, 1, fldsrc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_getFieldN(FBDst, 1, flddst, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle on the fly + if (mastertask) write(logunit,'(3A)') subname,trim(string),& + ' RH regrid for '//trim(mapname)//' computed on the fly' + call ESMF_LogWrite(subname // trim(string) //& + ' RH regrid for '//trim(mapname)//' computed on the fly', ESMF_LOGMSG_INFO) + + if (mapindex == mapfcopy) then + if (mastertask) then + write(logunit,'(3A)') subname,trim(string),' RH redist ' + end if + call ESMF_LogWrite(subname // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) + call ESMF_FieldRedistStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapindex), & + ignoreUnmatchedIndices = .true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (mapindex == mapbilnr) then + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapindex), & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & + polemethod=polemethod, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (mapindex == mapconsf .or. mapindex == mapnstod_consf) then + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapconsf), & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & + normType=ESMF_NORMTYPE_FRACAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (mapindex == mapconsd .or. mapindex == mapnstod_consd) then + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapconsd), & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & + normType=ESMF_NORMTYPE_DSTAREA, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (mapindex == mappatch) then + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapindex), & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_PATCH, & + polemethod=polemethod, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//' mapindex '//trim(mapnames(mapindex))//& + ' not supported for fraction mapping', & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + end if + ! consd_nstod method requires a second routehandle + if (mapindex == mapnstod .or. mapindex == mapnstod_consd .or. mapindex == mapnstod_consf) then + call ESMF_FieldRegridStore(fldsrc, flddst, & + routehandle=routehandle(n1,n2,mapnstod), & + srcMaskValues=(/srcMaskValue/), & + dstMaskValues=(/dstMaskValue/), & + regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, & + srcTermProcessing=srcTermProcessing_Value, & + ignoreDegenerate=.true., & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + call t_stopf('MED:'//subname) + + end subroutine med_map_routehandles_init_field + +!================================================================================ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) use ESMF , only : ESMF_RouteHandle @@ -414,78 +593,6 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) end function med_map_RH_is_created_RH1d -!================================================================================ - - subroutine med_map_fractions_init(gcomp, n1, n2, FBSrc, FBDst, RouteHandle, rc) - - !--------------------------------------------- - ! Initialize initialize additional route handles - ! for mapping fractions - !--------------------------------------------- - - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only : ESMF_GridComp, ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field - use ESMF , only : ESMF_FieldRegridStore - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE - use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA - - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer , intent(in) :: n1 - integer , intent(in) :: n2 - type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(in) :: FBDst - type(ESMF_RouteHandle) , intent(inout) :: RouteHandle - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: fldsrc - type(ESMF_Field) :: flddst - character(len=CS) :: string - integer :: SrcMaskValue - integer :: DstMaskValue - character(len=*), parameter :: subname=' (med_map_fractions_init: ) ' - !--------------------------------------------- - - call t_startf('MED:'//subname) - rc = ESMF_SUCCESS - if (dbug_flag > 1) then - call ESMF_LogWrite("Initializing RHs not yet created and needed for mapping fractions", & - ESMF_LOGMSG_INFO) - call ESMF_LogFlush() - endif - - if (mastertask) then - string = trim(compname(n1))//"2"//trim(compname(n2))//'_weights' - write(logunit,'(a)') trim(subname) // trim(string) //' RH consd computed on the fly for fractions' - end if - - dstMaskValue = ispval_mask - srcMaskValue = ispval_mask - if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 - if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 - - call FB_getFieldN(FBsrc, 1, fldsrc, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFieldN(FBDst, 1, flddst, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=RouteHandle, & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - normType=ESMF_NORMTYPE_DSTAREA, & - srcTermProcessing=srcTermProcessing_Value, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - call t_stopf('MED:'//subname) - - end subroutine med_map_fractions_init - !================================================================================ subroutine med_map_MapNorm_init(gcomp, llogunit, rc) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 704c14520..4ab32080d 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -18,13 +18,13 @@ module med_phases_prep_glc_mod use ESMF , only : ESMF_DistGrid, ESMF_AttributeSet use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT use ESMF , only : ESMF_TYPEKIND_R8 - use esmFlds , only : compglc, complnd, mapbilnr, mapconsf, compname + use esmFlds , only : compglc, complnd, mapbilnr, mapconsf, mapconsd, compname use esmFlds , only : med_fldlist_type use med_internalstate_mod , only : InternalState, mastertask, logunit 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_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_Fractions_Init + use med_map_mod , only : med_map_routehandles_init use med_methods_mod , only : FB_Init => med_methods_FB_init use med_methods_mod , only : FB_getFldPtr => med_methods_FB_getFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose @@ -220,11 +220,10 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! 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 med_map_Fractions_init( gcomp, complnd, compglc, & - FBSrc=FBlndAccum_lnd, & - FBDst=FBlndAccum_glc, & - RouteHandle=is_local%wrap%RH(complnd,compglc,mapbilnr), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//" mapbilnr is not created ", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return end if ! Determine if renormalize smb @@ -336,11 +335,11 @@ subroutine med_phases_prep_glc_init(gcomp, rc) fldlist_glc2lnd_frac%flds(1)%mapnorm(complnd) = trim(Sg_icemask_field) ! will use FBglc_icemask ! Create route handle if it has not been created - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsf,rc=rc)) then - call med_map_Fractions_init( gcomp, compglc, complnd, & + if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsd,rc=rc)) then + call med_map_routehandles_init( compglc, complnd, & FBSrc=FBlndAccum_glc, & FBDst=FBlndAccum_lnd, & - RouteHandle=is_local%wrap%RH(compglc,complnd,mapconsf), rc=rc) + mapindex=mapconsd, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index f8d140bad..203af93f6 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -15,7 +15,7 @@ module med_phases_prep_lnd_mod use ESMF , only : ESMF_Mesh, ESMF_MeshLoc, ESMF_MESHLOC_ELEMENT use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_TYPEKIND_R8 - use esmFlds , only : complnd, compatm, compglc, ncomps, compname, mapconsf + use esmFlds , only : complnd, compatm, compglc, ncomps, compname, mapconsd use esmFlds , only : fldListFr, fldListTo use esmFlds , only : med_fldlist_type use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN @@ -30,7 +30,7 @@ module med_phases_prep_lnd_mod use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_internalstate_mod , only : InternalState, logunit use med_map_mod , only : med_map_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_Fractions_Init + use med_map_mod , only : med_map_routehandles_init 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 @@ -309,10 +309,10 @@ subroutine med_map_glc2lnd_init(gcomp, rc) ! Create route handle if it has not been created ! ------------------------------- - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsf,rc=rc)) then - call med_map_Fractions_init( gcomp, compglc, complnd, & + if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:), mapconsd,rc=rc)) then + call med_map_routehandles_init( compglc, complnd, & FBSrc=FBglc_ec, FBDst=FBlnd_ec, & - RouteHandle=is_local%wrap%RH(compglc,complnd,mapconsf), rc=rc) + mapindex=mapconsd, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -419,7 +419,7 @@ subroutine med_map_glc2lnd( gcomp, rc) end if allocate(fldlist%flds(1)) fldlist%flds(1)%shortname = 'field_ec' - fldlist%flds(1)%mapindex(complnd) = mapconsf + fldlist%flds(1)%mapindex(complnd) = mapconsd fldlist%flds(1)%mapnorm(complnd) = trim(Sg_icemask) call med_map_FB_Regrid_Norm( & fldsSrc=fldList%flds, & @@ -465,7 +465,7 @@ subroutine med_map_glc2lnd( gcomp, rc) end if allocate(fldlist%flds(1)) fldlist%flds(1)%shortname = 'field_ec' - fldlist%flds(1)%mapindex(complnd) = mapconsf + fldlist%flds(1)%mapindex(complnd) = mapconsd fldlist%flds(1)%mapnorm(complnd) = 'none' call med_map_FB_Regrid_Norm( & fldsSrc=fldlist%flds, & @@ -488,7 +488,7 @@ subroutine med_map_glc2lnd( gcomp, rc) end if allocate(fldlist%flds(1)) fldlist%flds(1)%shortname = trim(Sg_frac_x_icemask) - fldlist%flds(1)%mapindex(complnd) = mapconsf + fldlist%flds(1)%mapindex(complnd) = mapconsd fldlist%flds(1)%mapnorm(complnd) = 'none' call med_map_FB_Regrid_Norm( & fldsSrc=fldList%flds, & From 8ecdcc91a8cbafa28f32b8440bc332e8feed786d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 30 Sep 2020 20:24:41 -0600 Subject: [PATCH 058/206] more updates for fraction calculation --- mediator/esmFldsExchange_cesm_mod.F90 | 16 +++++++--------- mediator/med_fraction_mod.F90 | 20 +++++++++++++------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 411b5a39d..0f8f9fd23 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -679,7 +679,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compice)%flds, 'Faii_'//trim(suffix(n))) call addfld(fldListTo(compatm)%flds, 'Faxx_'//trim(suffix(n))) else - ! (non aqua-planet) + ! 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. & @@ -692,7 +692,6 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') - ! (cam, aqua-planet) 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) @@ -710,11 +709,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Sl_t') call addfld(fldListFr(compice)%flds, 'Si_t') call addfld(fldListFr(compocn)%flds, 'So_t') - call addfld(fldListTo(compatm)%flds, 'So_t') call addfld(fldListTo(compatm)%flds, 'Sx_t') else - ! merged ocn/ice/lnd temp and unmerged ocn temp + ! 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. & @@ -1798,11 +1796,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Flgl_qice_elev') ! glacier ice flux (1->glc_nec+1) else if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Flgl_qice_elev', rc=rc)) then - ! custom merging will be done here + ! 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 + ! 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 @@ -1898,7 +1896,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') else - call addmap(fldListFr(complnd)%flds, 'Fall_fco2_lnd', compatm, mapconsf, 'one', atm2lnd_smap) + 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') end if @@ -1946,7 +1944,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') else - call addmap(fldListFr(complnd)%flds, 'Fall_fco2_lnd', compatm, mapconsf, 'one', atm2lnd_smap) + 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') end if @@ -1958,7 +1956,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compocn)%flds, 'Faoo_fco2_ocn') call addfld(fldListTo(compatm)%flds, 'Faoo_fco2_ocn') else - call addmap(fldListFr(compocn)%flds, 'Faoo_fco2_ocn', compatm, mapconsf, 'one', atm2lnd_smap) + call addmap(fldListFr(compocn)%flds, 'Faoo_fco2_ocn', compatm, mapconsf, 'one', ocn2atm_fmap) ! custom merge in med_phases_prep_atm end if endif diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 5b6512b94..d30554e44 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -248,7 +248,9 @@ subroutine med_fraction_init(gcomp, rc) ! Determine map type if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then maptype = mapfcopy + write(6,*)'DEBUG: maptype is mapfcopy' else + write(6,*)'DEBUG: maptype is mapconsd' maptype = mapconsd if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then @@ -418,13 +420,17 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then ! If atm -> lnd coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) if (is_local%wrap%med_coupling_active(compatm,complnd)) then - maptype = mapconsd - if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then - call med_map_routehandles_init( compatm, complnd, & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,complnd), & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then + maptype = mapfcopy + else + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then + call med_map_routehandles_init( compatm, complnd, & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,complnd), & + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if call FB_FieldRegrid(& is_local%wrap%FBfrac(compatm), 'lfrac', & From e4b0b8185513bfd9ee2058bcab7c9756b1b64443 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 05:16:34 -0600 Subject: [PATCH 059/206] cmake and action without dir changes --- .github/workflows/extbuild.yml | 105 +++++++++++++++++++++++++++++++++ CMakeLists.txt | 48 +++++++++++++++ mediator/CMakeLists.txt | 26 ++++++++ nems/util/CMakeLists.txt | 7 +++ 4 files changed, 186 insertions(+) create mode 100644 .github/workflows/extbuild.yml create mode 100644 CMakeLists.txt create mode 100644 mediator/CMakeLists.txt create mode 100644 nems/util/CMakeLists.txt diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml new file mode 100644 index 000000000..c5b6a5e8f --- /dev/null +++ b/.github/workflows/extbuild.yml @@ -0,0 +1,105 @@ +# This is a workflow to compile the cdeps source without cime +name: extbuild + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build-cmeps: + runs-on: ubuntu-latest + env: + CC: mpicc + FC: mpifort + CXX: mpicxx + CPPFLAGS: "-I/usr/include -I/usr/local/include" + # Versions of all dependencies can be updated here + ESMF_VERSION: ESMF_8_1_0_beta_snapshot_31 + PNETCDF_VERSION: pnetcdf-1.12.1 + NETCDF_FORTRAN_VERSION: v4.5.2 + # PIO version is awkward + PIO_VERSION_DIR: pio2_5_2 + PIO_VERSION: pio-2.5.2 + steps: + - uses: actions/checkout@v2 + # Build the ESMF library, if the cache contains a previous build + # it will be used instead + - id: cache-esmf + uses: actions/cache@v2 + with: + path: ~/ESMF + key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF + - id: load-env + run: sudo apt-get install gfortran wget openmpi-bin netcdf-bin libopenmpi-dev + - id: build-ESMF + if: steps.cache-esmf.outputs.cache-hit != 'true' + run: | + wget https://github.com/esmf-org/esmf/archive/${{ env.ESMF_VERSION }}.tar.gz + tar -xzvf ${{ env.ESMF_VERSION }}.tar.gz + pushd esmf-${{ env.ESMF_VERSION }} + export ESMF_DIR=`pwd` + export ESMF_COMM=openmpi + export ESMF_YAMLCPP="internal" + export ESMF_INSTALL_PREFIX=$HOME/ESMF + export ESMF_BOPT=g + make + make install + popd + - id: cache-pnetcdf + uses: actions/cache@v2 + with: + path: ~/pnetcdf + key: ${{ runner.os }}-${{ env.PNETCDF_VERSION}}-pnetcdf + - name: pnetcdf build + if: steps.cache-pnetcdf.outputs.cache-hit != 'true' + run: | + wget https://parallel-netcdf.github.io/Release/${{ env.PNETCDF_VERSION }}.tar.gz + tar -xzvf ${{ env.PNETCDF_VERSION }}.tar.gz + ls -l + pushd ${{ env.PNETCDF_VERSION }} + ./configure --prefix=$HOME/pnetcdf --enable-shared --disable-cxx + make + make install + popd + - name: Cache netcdf-fortran + id: cache-netcdf-fortran + uses: actions/cache@v2 + with: + path: ~/netcdf-fortran + key: ${{ runner.os }}-${{ env.NETCDF_FORTRAN_VERSION }}-netcdf-fortran + - name: netcdf fortran build + if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' + run: | + sudo apt-get install libnetcdf-dev + wget https://github.com/Unidata/netcdf-fortran/archive/${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz + tar -xzvf ${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz + ls -l + pushd netcdf-fortran-* + ./configure --prefix=$HOME/netcdf-fortran + make + make install + + - name: Build PIO + if: steps.cache-PIO.outputs.cache-hit != 'true' + run: | + mkdir build-pio + pushd build-pio + cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../CMEPS/nems/lib/ParallelIO + make VERBOSE=1 + make install + popd + + - name: Build CMEPS + run: | + export ESMFMKFILE=$HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk + export PIO=$HOME/pio + mkdir build-cmeps + pushd build-cmeps + cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ + make VERBOSE=1 + popd 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/mediator/CMakeLists.txt b/mediator/CMakeLists.txt new file mode 100644 index 000000000..77fb16829 --- /dev/null +++ b/mediator/CMakeLists.txt @@ -0,0 +1,26 @@ +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) + +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/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}) From b7770f4220cad7ae582a6804ebf4615696d2a1ea Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 05:33:51 -0600 Subject: [PATCH 060/206] whitespace error fix --- .github/workflows/extbuild.yml | 130 ++++++++++++++++----------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index c5b6a5e8f..607bc6b9a 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -27,79 +27,79 @@ jobs: PIO_VERSION: pio-2.5.2 steps: - uses: actions/checkout@v2 - # Build the ESMF library, if the cache contains a previous build - # it will be used instead + # Build the ESMF library, if the cache contains a previous build + # it will be used instead - id: cache-esmf - uses: actions/cache@v2 - with: - path: ~/ESMF - key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF + uses: actions/cache@v2 + with: + path: ~/ESMF + key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF - id: load-env - run: sudo apt-get install gfortran wget openmpi-bin netcdf-bin libopenmpi-dev + run: sudo apt-get install gfortran wget openmpi-bin netcdf-bin libopenmpi-dev - id: build-ESMF - if: steps.cache-esmf.outputs.cache-hit != 'true' - run: | - wget https://github.com/esmf-org/esmf/archive/${{ env.ESMF_VERSION }}.tar.gz - tar -xzvf ${{ env.ESMF_VERSION }}.tar.gz - pushd esmf-${{ env.ESMF_VERSION }} - export ESMF_DIR=`pwd` - export ESMF_COMM=openmpi - export ESMF_YAMLCPP="internal" - export ESMF_INSTALL_PREFIX=$HOME/ESMF - export ESMF_BOPT=g - make - make install - popd + if: steps.cache-esmf.outputs.cache-hit != 'true' + run: | + wget https://github.com/esmf-org/esmf/archive/${{ env.ESMF_VERSION }}.tar.gz + tar -xzvf ${{ env.ESMF_VERSION }}.tar.gz + pushd esmf-${{ env.ESMF_VERSION }} + export ESMF_DIR=`pwd` + export ESMF_COMM=openmpi + export ESMF_YAMLCPP="internal" + export ESMF_INSTALL_PREFIX=$HOME/ESMF + export ESMF_BOPT=g + make + make install + popd - id: cache-pnetcdf - uses: actions/cache@v2 - with: - path: ~/pnetcdf - key: ${{ runner.os }}-${{ env.PNETCDF_VERSION}}-pnetcdf + uses: actions/cache@v2 + with: + path: ~/pnetcdf + key: ${{ runner.os }}-${{ env.PNETCDF_VERSION}}-pnetcdf - name: pnetcdf build - if: steps.cache-pnetcdf.outputs.cache-hit != 'true' - run: | - wget https://parallel-netcdf.github.io/Release/${{ env.PNETCDF_VERSION }}.tar.gz - tar -xzvf ${{ env.PNETCDF_VERSION }}.tar.gz - ls -l - pushd ${{ env.PNETCDF_VERSION }} - ./configure --prefix=$HOME/pnetcdf --enable-shared --disable-cxx - make - make install - popd + if: steps.cache-pnetcdf.outputs.cache-hit != 'true' + run: | + wget https://parallel-netcdf.github.io/Release/${{ env.PNETCDF_VERSION }}.tar.gz + tar -xzvf ${{ env.PNETCDF_VERSION }}.tar.gz + ls -l + pushd ${{ env.PNETCDF_VERSION }} + ./configure --prefix=$HOME/pnetcdf --enable-shared --disable-cxx + make + make install + popd - name: Cache netcdf-fortran - id: cache-netcdf-fortran - uses: actions/cache@v2 - with: - path: ~/netcdf-fortran - key: ${{ runner.os }}-${{ env.NETCDF_FORTRAN_VERSION }}-netcdf-fortran + id: cache-netcdf-fortran + uses: actions/cache@v2 + with: + path: ~/netcdf-fortran + key: ${{ runner.os }}-${{ env.NETCDF_FORTRAN_VERSION }}-netcdf-fortran - name: netcdf fortran build - if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' - run: | - sudo apt-get install libnetcdf-dev - wget https://github.com/Unidata/netcdf-fortran/archive/${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz - tar -xzvf ${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz - ls -l - pushd netcdf-fortran-* - ./configure --prefix=$HOME/netcdf-fortran - make - make install + if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' + run: | + sudo apt-get install libnetcdf-dev + wget https://github.com/Unidata/netcdf-fortran/archive/${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz + tar -xzvf ${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz + ls -l + pushd netcdf-fortran-* + ./configure --prefix=$HOME/netcdf-fortran + make + make install - name: Build PIO - if: steps.cache-PIO.outputs.cache-hit != 'true' - run: | - mkdir build-pio - pushd build-pio - cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../CMEPS/nems/lib/ParallelIO - make VERBOSE=1 - make install - popd + if: steps.cache-PIO.outputs.cache-hit != 'true' + run: | + mkdir build-pio + pushd build-pio + cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../CMEPS/nems/lib/ParallelIO + make VERBOSE=1 + make install + popd - name: Build CMEPS - run: | - export ESMFMKFILE=$HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk - export PIO=$HOME/pio - mkdir build-cmeps - pushd build-cmeps - cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ - make VERBOSE=1 - popd + run: | + export ESMFMKFILE=$HOME/ESMF/lib/libg/Linux.gfortran.64.openmpi.default/esmf.mk + export PIO=$HOME/pio + mkdir build-cmeps + pushd build-cmeps + cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ + make VERBOSE=1 + popd From 513959e5308914eb206164d5525c4b5c19a312c9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 05:58:54 -0600 Subject: [PATCH 061/206] fix path --- .github/workflows/extbuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 607bc6b9a..e2a926212 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -89,7 +89,7 @@ jobs: run: | mkdir build-pio pushd build-pio - cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../CMEPS/nems/lib/ParallelIO + cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../nems/lib/ParallelIO make VERBOSE=1 make install popd From 6962be089a1dfab6502f53eb5ed7430a5e0230e8 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 06:21:45 -0600 Subject: [PATCH 062/206] populate pio submodule --- .github/workflows/extbuild.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index e2a926212..41ca57a7e 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -87,6 +87,8 @@ jobs: - name: Build PIO if: steps.cache-PIO.outputs.cache-hit != 'true' run: | + git submodule init + git submodule update mkdir build-pio pushd build-pio cmake -Wno-dev -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so -DNetCDF_C_INCLUDE_DIR=/usr/include -DCMAKE_PREFIX_PATH=/usr -DCMAKE_INSTALL_PREFIX=$HOME/pio -DPIO_HDF5_LOGGING=On -DPIO_USE_MALLOC=On -DPIO_ENABLE_LOGGING=On -DPIO_ENABLE_TIMING=Off -DPIO_ENABLE_TESTS=OFF -DNetCDF_Fortran_PATH=$HOME/netcdf-fortran -DPnetCDF_PATH=$HOME/pnetcdf ../nems/lib/ParallelIO From cd9c7b3082aaa978571ec2936b9fa600bd85bec9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 06:47:48 -0600 Subject: [PATCH 063/206] add cmake helpers --- cmake/FindESMF.cmake | 47 ++++++ cmake/FindPIO.cmake | 103 +++++++++++++ cmake/LibCheck.cmake | 104 ++++++++++++++ cmake/LibFind.cmake | 333 +++++++++++++++++++++++++++++++++++++++++++ tcipylint | 3 +- 5 files changed, 589 insertions(+), 1 deletion(-) create mode 100644 cmake/FindESMF.cmake create mode 100644 cmake/FindPIO.cmake create mode 100644 cmake/LibCheck.cmake create mode 100644 cmake/LibFind.cmake 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/tcipylint b/tcipylint index 00c371711..e5284a303 100755 --- a/tcipylint +++ b/tcipylint @@ -3,4 +3,5 @@ args="--disable=I,C,R,logging-not-lazy,wildcard-import,unused-wildcard-import,fi for file in cime_config/buildexe cime_config/buildnml cime_config/runseq/* do pylint $args $file -done \ No newline at end of file +done +exit $? From 31e3c8d87cdda231e6bb4d64885d7ee17962ed3e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:09:17 -0600 Subject: [PATCH 064/206] fix error trapping in pylint script --- tcipylint | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcipylint b/tcipylint index e5284a303..8b970b640 100755 --- a/tcipylint +++ b/tcipylint @@ -2,6 +2,6 @@ args="--disable=I,C,R,logging-not-lazy,wildcard-import,unused-wildcard-import,fixme,broad-except,bare-except,eval-used,exec-used,global-statement,logging-format-interpolation,no-name-in-module,import-error" for file in cime_config/buildexe cime_config/buildnml cime_config/runseq/* do - pylint $args $file + pylint $args $file || exit $? done -exit $? +exit 0 From 5bc3f2214857273a9ea5ff3fd05b2dccd9b61f99 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:15:12 -0600 Subject: [PATCH 065/206] fix pylint issue --- cime_config/buildexe | 69 ++++++++++++++++++++++---------------------- tcipylint | 5 ++-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index 82d018768..c4d6c12cc 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -30,64 +30,63 @@ def _main_func(): logger.info("Building a single executable version of target coupled model") with Case(caseroot) as case: - casetools = case.get_value("CASETOOLS") - cimeroot = case.get_value("CIMEROOT") - exeroot = case.get_value("EXEROOT") - gmake = case.get_value("GMAKE") - gmake_j = case.get_value("GMAKE_J") - cime_model = case.get_value("MODEL") - num_esp = case.get_value("NUM_COMP_INST_ESP") - ocn_model = case.get_value("COMP_OCN") - atm_model = case.get_value("COMP_ATM") - gmake_args = get_standard_makefile_args(case) + casetools = case.get_value("CASETOOLS") + exeroot = case.get_value("EXEROOT") + gmake = case.get_value("GMAKE") + gmake_j = case.get_value("GMAKE_J") + cime_model = case.get_value("MODEL") + num_esp = case.get_value("NUM_COMP_INST_ESP") + ocn_model = case.get_value("COMP_OCN") + atm_model = case.get_value("COMP_ATM") + gmake_args = get_standard_makefile_args(case) # Determine valid components valid_comps = [] comp_classes = case.get_values("COMP_CLASSES") for item in comp_classes: - comp = case.get_value("COMP_" + item) - valid = True - if comp == 's' + item.lower(): - valid = False - if valid: - valid_comps.append(item) + comp = case.get_value("COMP_" + item) + valid = True + if comp == 's' + item.lower(): + valid = False + if valid: + valid_comps.append(item) datamodel_in_compset = False for comp in comp_classes: - dcompname = "d"+comp.lower() - if dcompname in case.get_value("COMP_{}".format(comp)): - datamodel_in_compset = True + dcompname = "d"+comp.lower() + if dcompname in case.get_value("COMP_{}".format(comp)): + datamodel_in_compset = True if len(valid_comps) == 2 and not datamodel_in_compset: - skip_mediator = True + skip_mediator = True else: - skip_mediator = False + skip_mediator = False if ocn_model == 'mom' or atm_model == "ufsatm": - gmake_args += "USE_FMS=TRUE" + gmake_args += "USE_FMS=TRUE" comp_classes = case.get_values("COMP_CLASSES") for comp in comp_classes: - model = case.get_value("COMP_{}".format(comp)) - stubcomp = "s{}".format(comp.lower()) - if model == stubcomp: - gmake_args += " {}_PRESENT=FALSE".format(comp) + model = case.get_value("COMP_{}".format(comp)) + stubcomp = "s{}".format(comp.lower()) + if model == stubcomp: + gmake_args += " {}_PRESENT=FALSE".format(comp) if skip_mediator: - gmake_args += " MED_PRESENT=FALSE" + gmake_args += " MED_PRESENT=FALSE" gmake_args += " IAC_PRESENT=FALSE" expect((num_esp is None) or (int(num_esp) == 1), "ESP component restricted to one instance") bld_root = os.path.join(exeroot,'cpl','obj') if not os.path.isdir(bld_root): - os.makedirs(bld_root) + os.makedirs(bld_root) with open(os.path.join(bld_root,'Filepath'), 'w') as out: - cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) - if not skip_mediator: - out.write(os.path.join(cmeps_dir, "mediator") + "\n") - out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") - out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") + cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) + if not skip_mediator: + out.write(os.path.join(cmeps_dir, "mediator") + "\n") + out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") + out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") # build model executable makefile = os.path.join(casetools, "Makefile") @@ -95,10 +94,10 @@ def _main_func(): # always relink if os.path.isfile(exename): - os.remove(exename) + os.remove(exename) cmd = "{} exec_se -j {} EXEC_SE={} MODEL=driver {} -f {} "\ - .format(gmake, gmake_j, exename, gmake_args, makefile) + .format(gmake, gmake_j, exename, gmake_args, makefile) rc, out, err = run_cmd(cmd,from_dir=bld_root) diff --git a/tcipylint b/tcipylint index 8b970b640..6e020a085 100755 --- a/tcipylint +++ b/tcipylint @@ -1,7 +1,8 @@ #!/usr/bin/env sh args="--disable=I,C,R,logging-not-lazy,wildcard-import,unused-wildcard-import,fixme,broad-except,bare-except,eval-used,exec-used,global-statement,logging-format-interpolation,no-name-in-module,import-error" +failed=0 for file in cime_config/buildexe cime_config/buildnml cime_config/runseq/* do - pylint $args $file || exit $? + pylint $args $file || failed=$failed+1 done -exit 0 +exit $failed From afe65f91142859ffe8d6458b4e6e975461ffadf4 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:21:31 -0600 Subject: [PATCH 066/206] try again --- .travis.yml | 4 +++- cime_config/buildnml | 1 - tcipylint | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 386d2310a..7abb73a9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,11 @@ install: python: - '2.7' - '3.6' + - '3.8' + - 'nightly' branches: only: - master -script: ./tcipylint \ No newline at end of file +script: ./tcipylint diff --git a/cime_config/buildnml b/cime_config/buildnml index ee9b0f1f7..9d18d7136 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -565,7 +565,6 @@ def buildnml(case, caseroot, component): shutil.copy(filename, rundir) # copy fd_cesm.yaml to rundir - cimeroot = case.get_value("CIMEROOT") fd_dir = os.path.join(os.path.dirname(__file__),os.pardir,"mediator") coupling_mode = case.get_value('COUPLING_MODE') if coupling_mode == 'cesm': diff --git a/tcipylint b/tcipylint index 6e020a085..e9517f94b 100755 --- a/tcipylint +++ b/tcipylint @@ -3,6 +3,6 @@ args="--disable=I,C,R,logging-not-lazy,wildcard-import,unused-wildcard-import,fi failed=0 for file in cime_config/buildexe cime_config/buildnml cime_config/runseq/* do - pylint $args $file || failed=$failed+1 + pylint $args $file || failed=$(( failed + 1 )) done exit $failed From 3e858a93f74dfb91c3f9425bc9f49cab330b2888 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:24:34 -0600 Subject: [PATCH 067/206] fix whitespace --- cime_config/buildexe | 68 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index c4d6c12cc..0d336d9a8 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -30,63 +30,63 @@ def _main_func(): logger.info("Building a single executable version of target coupled model") with Case(caseroot) as case: - casetools = case.get_value("CASETOOLS") - exeroot = case.get_value("EXEROOT") - gmake = case.get_value("GMAKE") - gmake_j = case.get_value("GMAKE_J") - cime_model = case.get_value("MODEL") - num_esp = case.get_value("NUM_COMP_INST_ESP") - ocn_model = case.get_value("COMP_OCN") - atm_model = case.get_value("COMP_ATM") - gmake_args = get_standard_makefile_args(case) + casetools = case.get_value("CASETOOLS") + exeroot = case.get_value("EXEROOT") + gmake = case.get_value("GMAKE") + gmake_j = case.get_value("GMAKE_J") + cime_model = case.get_value("MODEL") + num_esp = case.get_value("NUM_COMP_INST_ESP") + ocn_model = case.get_value("COMP_OCN") + atm_model = case.get_value("COMP_ATM") + gmake_args = get_standard_makefile_args(case) # Determine valid components valid_comps = [] comp_classes = case.get_values("COMP_CLASSES") for item in comp_classes: - comp = case.get_value("COMP_" + item) - valid = True - if comp == 's' + item.lower(): - valid = False - if valid: - valid_comps.append(item) + comp = case.get_value("COMP_" + item) + valid = True + if comp == 's' + item.lower(): + valid = False + if valid: + valid_comps.append(item) datamodel_in_compset = False for comp in comp_classes: - dcompname = "d"+comp.lower() - if dcompname in case.get_value("COMP_{}".format(comp)): - datamodel_in_compset = True + dcompname = "d"+comp.lower() + if dcompname in case.get_value("COMP_{}".format(comp)): + datamodel_in_compset = True if len(valid_comps) == 2 and not datamodel_in_compset: - skip_mediator = True + skip_mediator = True else: - skip_mediator = False + skip_mediator = False if ocn_model == 'mom' or atm_model == "ufsatm": - gmake_args += "USE_FMS=TRUE" + gmake_args += "USE_FMS=TRUE" comp_classes = case.get_values("COMP_CLASSES") for comp in comp_classes: - model = case.get_value("COMP_{}".format(comp)) - stubcomp = "s{}".format(comp.lower()) - if model == stubcomp: - gmake_args += " {}_PRESENT=FALSE".format(comp) + model = case.get_value("COMP_{}".format(comp)) + stubcomp = "s{}".format(comp.lower()) + if model == stubcomp: + gmake_args += " {}_PRESENT=FALSE".format(comp) if skip_mediator: - gmake_args += " MED_PRESENT=FALSE" + gmake_args += " MED_PRESENT=FALSE" gmake_args += " IAC_PRESENT=FALSE" expect((num_esp is None) or (int(num_esp) == 1), "ESP component restricted to one instance") bld_root = os.path.join(exeroot,'cpl','obj') if not os.path.isdir(bld_root): - os.makedirs(bld_root) + os.makedirs(bld_root) with open(os.path.join(bld_root,'Filepath'), 'w') as out: - cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) - if not skip_mediator: - out.write(os.path.join(cmeps_dir, "mediator") + "\n") - out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") - out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") + cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) + if not skip_mediator: + out.write(os.path.join(cmeps_dir, "mediator") + "\n") + out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") + out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") # build model executable makefile = os.path.join(casetools, "Makefile") @@ -94,10 +94,10 @@ def _main_func(): # always relink if os.path.isfile(exename): - os.remove(exename) + os.remove(exename) cmd = "{} exec_se -j {} EXEC_SE={} MODEL=driver {} -f {} "\ - .format(gmake, gmake_j, exename, gmake_args, makefile) + .format(gmake, gmake_j, exename, gmake_args, makefile) rc, out, err = run_cmd(cmd,from_dir=bld_root) From 9c9eac37c5e96bb473cbc2d3f4462a706e5d0ff3 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:28:13 -0600 Subject: [PATCH 068/206] find netcdf.h --- .github/workflows/extbuild.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 41ca57a7e..0c086e380 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -35,7 +35,7 @@ jobs: path: ~/ESMF key: ${{ runner.os }}-${{ env.ESMF_VERSION }}-ESMF - id: load-env - run: sudo apt-get install gfortran wget openmpi-bin netcdf-bin libopenmpi-dev + run: sudo apt-get install gfortran wget openmpi-bin netcdf-bin libopenmpi-dev libnetcdf-dev - id: build-ESMF if: steps.cache-esmf.outputs.cache-hit != 'true' run: | @@ -75,7 +75,6 @@ jobs: - name: netcdf fortran build if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' run: | - sudo apt-get install libnetcdf-dev wget https://github.com/Unidata/netcdf-fortran/archive/${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz tar -xzvf ${{ env.NETCDF_FORTRAN_VERSION }}.tar.gz ls -l From 715d7ba5802e75ccb7068aac09410ef876fcd8cd Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 07:31:54 -0600 Subject: [PATCH 069/206] remove python nightly - too extreme --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7abb73a9e..0a14a61ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ python: - '2.7' - '3.6' - '3.8' - - 'nightly' branches: only: From 5c79fb2c41f9f44375a8c4236df3909a47055470 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 11:41:55 -0600 Subject: [PATCH 070/206] fix gnu compiler errors --- mediator/med_map_mod.F90 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 6534db0aa..2b21ac0bc 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -58,9 +58,8 @@ module med_map_mod ! private module variables - character(len=CS) :: flds_scalar_name + character(len=CL) :: flds_scalar_name integer :: srcTermProcessing_Value = 0 ! should this be a module variable? - logical :: mastertask character(*), parameter :: u_FILE_u = & __FILE__ @@ -354,13 +353,13 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) end subroutine med_map_RouteHandles_init_esmflds -!================================================================================ +!================================================================================ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) !--------------------------------------------- ! Initialize initialize additional route handles ! for mapping fractions - ! + ! !--------------------------------------------- use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush @@ -406,7 +405,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route write(logunit,'(3A)') subname, trim(string),& ' RH regrid for '//trim(mapname)//' computed on the fly' end if - + if (trim(coupling_mode) == 'cesm') then dstMaskValue = ispval_mask srcMaskValue = ispval_mask @@ -529,7 +528,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route end subroutine med_map_routehandles_init_field -!================================================================================ +!================================================================================ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) use ESMF , only : ESMF_RouteHandle @@ -552,7 +551,7 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) end function med_map_RH_is_created_RH3d -!================================================================================ +!================================================================================ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) @@ -737,7 +736,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & type(ESMF_Field) :: frac_field_dst real(R8), allocatable :: data_srctmp(:) real(R8), allocatable :: data_srctmp_1d(:) - real(R8), allocatable :: data_srctmp_2d(:,:) + real(R8), allocatable :: data_srctmp_2d(:,:) real(R8), pointer :: data_src_1d(:) real(R8), pointer :: data_src_2d(:,:) real(R8), pointer :: data_frac(:) @@ -955,7 +954,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & if (lrank == 1) then data_src_1d(:) = data_srctmp_1d(:) elseif (lrank == 2) then - data_src_2d(:,:) = data_srctmp_2d(:,:) + data_src_2d(:,:) = data_srctmp_2d(:,:) end if ! regrid fraction from source to dest From 9965df13b566ae71bef7f54ed906feed452b7f92 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 1 Oct 2020 13:55:18 -0600 Subject: [PATCH 071/206] updates to fix rof problem --- mediator/esmFldsExchange_cesm_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 0f8f9fd23..8282308d3 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1766,7 +1766,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBExp(comprof) , trim(fldname), rc=rc)) then - call addmap(fldListFr(complnd)%flds, trim(fldname), comprof, mapconsd, 'lfrac', lnd2rof_fmap) + 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') end if From f649a0319db7dec958050f080460988479a9a1a9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 1 Oct 2020 16:10:53 -0600 Subject: [PATCH 072/206] correct esmf error message --- mediator/med_fraction_mod.F90 | 12 +++++------- mediator/med_phases_prep_rof_mod.F90 | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index d30554e44..65a4002cb 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -242,15 +242,13 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return lfrin(:) = Sl_lfrin(:) - ! Set 'lfrin for FBFrac(compatm) + ! Set 'lfrin for FBFrac(compatm) ! The following is just an initial "guess", updated later if (is_local%wrap%comp_present(compatm) .and. (is_local%wrap%med_coupling_active(compatm,complnd))) then ! Determine map type if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then maptype = mapfcopy - write(6,*)'DEBUG: maptype is mapfcopy' else - write(6,*)'DEBUG: maptype is mapconsd' maptype = mapconsd if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then @@ -306,7 +304,7 @@ subroutine med_fraction_init(gcomp, rc) if (med_map_RH_is_created(is_local%wrap%RH(compice,compatm,:),mapfcopy, rc=rc)) then ! If ice and atm are on the same mesh - a redist route handle has already been created maptype = mapfcopy - else + else if (trim(coupling_mode) == 'nems_orig' ) then maptype = mapnstod_consd else @@ -393,7 +391,7 @@ subroutine med_fraction_init(gcomp, rc) lfrac(n) = 0.0_R8 end if end do - else + else ! If the ocean or ice are absent, then simply set 'lfrac' to 'lfrin' for FBFrac(compatm) do n = 1,size(lfrac) lfrac(n) = lfrin(n) @@ -403,7 +401,7 @@ subroutine med_fraction_init(gcomp, rc) end if end do end if - else + else ! land is not present call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) lfrac(:) = 0.0_R8 @@ -439,7 +437,7 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if else - ! If the atm ->lnd coupling is not active - simply set 'lfrac' to 'lfrin' + ! If the atm ->lnd coupling is not active - simply set 'lfrac' to 'lfrin' call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrin', lfrin, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index f8f89f2c8..e484bcb26 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -2,7 +2,7 @@ module med_phases_prep_rof_mod !----------------------------------------------------------------------------- ! Create rof export fields - ! - accumulate import lnd fields on the land grid that are sent to rof + ! - accumulate import lnd fields on the land grid that are sent to rof ! this will be done in med_phases_prep_rof_accum ! - time avergage accumulated import lnd fields when necessary ! map the time averaged accumulated lnd fields to the rof grid @@ -40,7 +40,7 @@ module med_phases_prep_rof_mod public :: med_phases_prep_rof_accum public :: med_phases_prep_rof_avg - private :: med_phases_prep_rof_irrig + private :: med_phases_prep_rof_irrig type(ESMF_FieldBundle) :: FBlndVolr ! needed for lnd2rof irrigation type(ESMF_FieldBundle) :: FBrofVolr ! needed for lnd2rof irrigation @@ -64,7 +64,7 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) !------------------------------------ ! Carry out fast accumulation for the river (rof) component - ! Accumulation and averaging is done on the land input on the land grid for the fields that will + ! Accumulation and averaging is done on the land input on the land grid for the fields that will ! will be sent to the river component ! Mapping from the land to the rof grid is then done with the time averaged fields !------------------------------------ @@ -108,7 +108,7 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) ncnt = 0 call ESMF_LogWrite(trim(subname)//": FBImp(complnd,complnd) is not created", & ESMF_LOGMSG_INFO) - else + 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) @@ -118,7 +118,7 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end if !--------------------------------------- - ! Accumulate lnd input on lnd grid + ! Accumulate lnd input on lnd grid !--------------------------------------- ! Note that all import fields from the land are accumulated - but @@ -155,7 +155,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !------------------------------------ use NUOPC , only : NUOPC_IsConnected - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FieldBundleGet @@ -330,7 +330,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) use ESMF , only : ESMF_GridComp, ESMF_Field use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite + use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR ! input/output variables type(ESMF_GridComp) :: gcomp @@ -366,14 +366,14 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),mapconsf, rc=rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR conservativing route handle not created for lnd->rof mapping", & - ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for lnd->rof mapping", & + ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return end if if (.not. med_map_RH_is_created(is_local%wrap%RH(comprof,complnd,:),mapconsf, rc=rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR conservativing route handle not created for rof->lnd mapping", & - ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for rof->lnd mapping", & + ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return end if From 42a992ff35833902b42beda36c73ac7e63fec63d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 4 Oct 2020 16:48:50 -0600 Subject: [PATCH 073/206] updates needed for nems --- mediator/med_fraction_mod.F90 | 43 +++++++++++++++-------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 65a4002cb..e2a176e6c 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -114,6 +114,7 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps + use med_internalstate_mod, only : mastertask, logunit implicit none private @@ -418,17 +419,13 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then ! If atm -> lnd coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) if (is_local%wrap%med_coupling_active(compatm,complnd)) then - if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then - maptype = mapfcopy - else - maptype = mapconsd - if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then - call med_map_routehandles_init( compatm, complnd, & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,complnd), & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then + call med_map_routehandles_init( compatm, complnd, & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,complnd), & + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if call FB_FieldRegrid(& is_local%wrap%FBfrac(compatm), 'lfrac', & @@ -703,24 +700,20 @@ subroutine med_fraction_set(gcomp, rc) ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compice,compatm)) then - if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compocn,compatm)) then - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if ! end of if present compatm From 59a108a13dcf2c92f4a54658e17252d77907f2ab Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 6 Oct 2020 15:34:40 -0600 Subject: [PATCH 074/206] updated med_fraction_mod to deal with I2000 bug --- mediator/med_fraction_mod.F90 | 250 ++++++++++++++++------------------ 1 file changed, 117 insertions(+), 133 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index e2a176e6c..8b1c8a991 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -3,28 +3,24 @@ module med_fraction_mod !----------------------------------------------------------------------------- ! Mediator Component. ! Sets fractions on all component grids - ! the fractions fields are now ifrac, ofrac, lfrac, and lfrin. + ! the fractions fields are now ifrac, ofrac, lfrac ! lfrac = fraction of lnd on a grid ! ifrac = fraction of ice on a grid ! ofrac = fraction of ocn on a grid - ! lfrin = land fraction defined by the land model ! ifrad = fraction of ocn on a grid at last radiation time ! ofrad = fraction of ice on a grid at last radiation time ! ! lfrac, ifrac, and ofrac: ! are the self-consistent values in the system - ! lfrin: - ! is the fraction on the land grid and is allowed to - ! vary from the self-consistent value as descibed below. ! ifrad and ofrad: ! are needed for the swnet calculation. ! ! the fractions fields are defined for each grid in the fraction bundles as ! needed as follows. - ! character(*),parameter :: fraclist_a = 'ifrac:ofrac:lfrac:lfrin' + ! character(*),parameter :: fraclist_a = 'ifrac:ofrac:lfrac ! character(*),parameter :: fraclist_o = 'ifrac:ofrac:ifrad:ofrad' ! character(*),parameter :: fraclist_i = 'ifrac:ofrac' - ! character(*),parameter :: fraclist_l = 'lfrac:lfrin' + ! character(*),parameter :: fraclist_l = 'lfrac' ! character(*),parameter :: fraclist_g = 'gfrac:lfrac' ! character(*),parameter :: fraclist_r = 'lfrac:rfrac' ! @@ -56,10 +52,8 @@ module med_fraction_mod ! fractions_*(ifrac) = 0.0 ! fractions/masks provided by surface components ! fractions_o(ofrac) = ocean "mask" provided by ocean - ! fractions_l(lfrin) = land "fraction provided by land ! then mapped to the atm model ! fractions_a(ofrac) = mapo2a(fractions_o(ofrac)) - ! fractions_a(lfrin) = mapl2a(fractions_l(lfrin)) ! and a few things are then derived ! fractions_a(lfrac) = 1.0 - fractions_a(ofrac) ! this is truncated to zero for very small values (< 0.001) @@ -85,7 +79,7 @@ module med_fraction_mod ! fraction corrections in mapping are as follows ! mapo2a uses *fractions_o(ofrac) and /fractions_a(ofrac) ! mapi2a uses *fractions_i(ifrac) and /fractions_a(ifrac) - ! mapl2a uses *fractions_l(lfrin) and /fractions_a(lfrin) + ! mapl2a uses *fractions_l(lfrac) ! mapl2g weights by fractions_l(lfrac) with normalization and multiplies by fractions_g(lfrac) ! ! run time: @@ -114,7 +108,6 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps - use med_internalstate_mod, only : mastertask, logunit implicit none private @@ -125,10 +118,10 @@ module med_fraction_mod integer, parameter :: nfracs = 5 character(len=5) :: fraclist(nfracs,ncomps) - character(len=5),parameter,dimension(4) :: fraclist_a = (/'ifrac','ofrac','lfrac','lfrin'/) + character(len=5),parameter,dimension(3) :: fraclist_a = (/'ifrac','ofrac','lfrac'/) character(len=5),parameter,dimension(4) :: fraclist_o = (/'ifrac','ofrac','ifrad','ofrad'/) character(len=5),parameter,dimension(2) :: fraclist_i = (/'ifrac','ofrac'/) - character(len=5),parameter,dimension(2) :: fraclist_l = (/'lfrac','lfrin'/) + character(len=5),parameter,dimension(1) :: fraclist_l = (/'lfrac'/) character(len=5),parameter,dimension(2) :: fraclist_g = (/'gfrac','lfrac'/) character(len=5),parameter,dimension(2) :: fraclist_r = (/'rfrac','lfrac'/) character(len=5),parameter,dimension(1) :: fraclist_w = (/'wfrac'/) @@ -156,7 +149,7 @@ subroutine med_fraction_init(gcomp, rc) use esmFlds , only : comprof, compglc, compwav, compname use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd use med_map_mod , only : med_map_routehandles_init, med_map_rh_is_created - use med_internalstate_mod , only : InternalState + use med_internalstate_mod , only : InternalState, logunit, mastertask use perf_mod , only : t_startf, t_stopf ! input/output variables @@ -165,19 +158,17 @@ subroutine med_fraction_init(gcomp, rc) ! local variables type(InternalState) :: is_local - type(ESMF_FieldBundle) :: FBtemp real(R8), pointer :: frac(:) real(R8), pointer :: ofrac(:) real(R8), pointer :: lfrac(:) real(R8), pointer :: ifrac(:) real(R8), pointer :: gfrac(:) - real(R8), pointer :: lfrin(:) real(R8), pointer :: rfrac(:) real(R8), pointer :: wfrac(:) real(R8), pointer :: Sl_lfrin(:) real(R8), pointer :: Si_imask(:) real(R8), pointer :: So_omask(:) - integer :: i,j,n,n1 + integer :: i,j,n,n1,n2 integer :: maptype logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' @@ -211,7 +202,7 @@ subroutine med_fraction_init(gcomp, rc) fraclist(1:size(fraclist_g),compglc) = fraclist_g !--------------------------------------- - ! Initialize FBFrac(:) to zero + ! Create field bundles and initialize them to zero !--------------------------------------- ! Note - must use import state here - since export state might not @@ -219,70 +210,39 @@ subroutine med_fraction_init(gcomp, rc) do n1 = 1,ncomps 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, & - 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! now determine if there will be any active coupling back - and if so create + ! field bundle + do n2 = 1,ncomps + if (n2 /= n1) then + if (is_local%wrap%med_coupling_active(n2,n1)) then + ! create FBFrac and zero out FBfrac(n1) + call FB_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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a)') trim(subname)//' Created FBFrac('//trim(compname(n1))//') field bundle ' + end if + exit + end if + end if + end do end if end do first_call = .false. endif !--------------------------------------- - ! Set 'lfrin' for FBFrac(complnd) and FBFrac(compatm) + ! Set 'lfrac' for FBFrac(complnd) - this might be overwritten later !--------------------------------------- - if (is_local%wrap%comp_present(complnd)) then - - ! Set 'lfrin' for FBFrac(complnd) + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(complnd))) then call FB_getFldPtr(is_local%wrap%FBImp(complnd,complnd) , 'Sl_lfrin' , Sl_lfrin, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrin', lfrin, rc=rc) + call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - lfrin(:) = Sl_lfrin(:) - - ! Set 'lfrin for FBFrac(compatm) - ! The following is just an initial "guess", updated later - if (is_local%wrap%comp_present(compatm) .and. (is_local%wrap%med_coupling_active(compatm,complnd))) then - ! Determine map type - if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then - maptype = mapfcopy - else - maptype = mapconsd - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then - call med_map_routehandles_init( complnd, compatm, & - FBSrc=is_local%wrap%FBImp(complnd,complnd), & - FBDst=is_local%wrap%FBImp(complnd,compatm), & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - ! Note - need to do the following if - ! compatm->complnd is active, even if complnd->compatm is not active - call FB_init(FBout=FBtemp, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(compatm,compatm), & - fieldNameList=(/'Fldtemp'/), name='FBtemp', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_routehandles_init( complnd, compatm, & - FBSrc=is_local%wrap%FBImp(complnd,complnd), & - FBDst=FBtemp, & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleDestroy(FBtemp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - end if - ! Regrid 'lfrin' from FBFrac(complnd) -> FBFrac(compatm) - call FB_FieldRegrid(& - is_local%wrap%FBfrac(complnd), 'lfrin', & - is_local%wrap%FBfrac(compatm), 'lfrin', & - is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + lfrac(:) = Sl_lfrin(:) end if !--------------------------------------- @@ -370,22 +330,55 @@ subroutine med_fraction_init(gcomp, rc) end if end if + !--------------------------------------- + ! Finally, set 'lfrac' in FBFrac(complnd) by mapping FBFrac(compatm) if appropriate + !--------------------------------------- + + if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(compatm)) .and. & + ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(complnd))) then + + ! This assumes that atm->lnd and lnd->atm coupling is occuring + ! based on the logic in the initialization of fractions + ! Reset 'lfrac' in FBFrac(complnd) by mapping the Frac + ! If lnd -> atm coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) + + if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then + maptype = mapfcopy + else + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then + call med_map_routehandles_init( compatm, complnd, & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,complnd), & + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compatm), 'lfrac', & + is_local%wrap%FBfrac(complnd), 'lfrac', & + is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif + !--------------------------------------- ! Set 'lfrac' in FBFrac(compatm) and correct 'ofrac' in FBFrac(compatm) ! --------------------------------------- - if (is_local%wrap%comp_present(compatm)) then - if (is_local%wrap%comp_present(complnd)) then - ! land is present - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrin', lfrin, rc=rc) + ! These should actually be mapo2a of ofrac and lfrac but we can't + ! map lfrac from o2a due to masked mapping weights. So we have to + ! settle for a residual calculation that is truncated to zero to + ! try to preserve "all ocean" cells. + + if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(compatm))) then + + if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then + + ! Ocean is present call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) - if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then - ! ocean is present - ! These should actually be mapo2a of ofrac and lfrac but we can't - ! map lfrac from o2a due to masked mapping weights. So we have to - ! settle for a residual calculation that is truncated to zero to - ! try to preserve "all ocean" cells. + + if (is_local%wrap%comp_present(complnd)) then do n = 1,size(lfrac) lfrac(n) = 1.0_R8 - ofrac(n) if (abs(lfrac(n)) < eps_fraclim) then @@ -393,56 +386,43 @@ subroutine med_fraction_init(gcomp, rc) end if end do else - ! If the ocean or ice are absent, then simply set 'lfrac' to 'lfrin' for FBFrac(compatm) - do n = 1,size(lfrac) - lfrac(n) = lfrin(n) - ofrac(n) = 1.0_R8 - lfrac(n) - if (abs(ofrac(n)) < eps_fraclim) then - ofrac(n) = 0.0_R8 - end if - end do + lfrac(:) = 0.0_R8 end if - else - ! land is not present - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - lfrac(:) = 0.0_R8 - end if - end if - - !--------------------------------------- - ! Set 'lfrac' in FBFrac(complnd) - !--------------------------------------- - if (is_local%wrap%comp_present(complnd)) then + else if (is_local%wrap%comp_present(complnd) .and. is_local%wrap%med_coupling_active(complnd,compatm)) then - ! Set 'lfrac' in FBFrac(complnd) - if (is_local%wrap%comp_present(compatm)) then - ! If atm -> lnd coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) - if (is_local%wrap%med_coupling_active(compatm,complnd)) then + ! If the ocean or ice are absent, regrid 'lfrac' from FBFrac(complnd) -> FBFrac(compatm) + if (med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),mapfcopy, rc=rc)) then + maptype = mapfcopy + else maptype = mapconsd - if (.not. med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc)) then - call med_map_routehandles_init( compatm, complnd, & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,complnd), & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc)) then + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,compatm))) then + call med_map_routehandles_init( complnd, compatm, & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compatm), & + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compatm), 'lfrac', & - is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - else - ! If the atm ->lnd coupling is not active - simply set 'lfrac' to 'lfrin' - call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrin', lfrin, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) + call FB_FieldRegrid(& + is_local%wrap%FBfrac(complnd), 'lfrac', & + is_local%wrap%FBfrac(compatm), 'lfrac', & + is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - lfrac(:) = lfrin(:) - endif - endif + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) + do n = 1,size(lfrac) + ofrac(n) = 1.0_R8 - lfrac(n) + if (abs(ofrac(n)) < eps_fraclim) then + ofrac(n) = 0.0_R8 + end if + end do + + end if + end if !--------------------------------------- ! Set 'rfrac' and 'lfrac' for FBFrac(comprof) @@ -700,20 +680,24 @@ subroutine med_fraction_set(gcomp, rc) ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if end if ! end of if present compatm From bfc2e9a059bee814955996685d5017fd715a7d4c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 6 Oct 2020 16:16:45 -0600 Subject: [PATCH 075/206] fixes to get I compset to work --- mediator/med_fraction_mod.F90 | 66 +++++++++++++---------------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 8b1c8a991..839cc9422 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -168,7 +168,7 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: Sl_lfrin(:) real(R8), pointer :: Si_imask(:) real(R8), pointer :: So_omask(:) - integer :: i,j,n,n1,n2 + integer :: i,j,n,n1 integer :: maptype logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' @@ -210,34 +210,23 @@ subroutine med_fraction_init(gcomp, rc) do n1 = 1,ncomps if ( is_local%wrap%comp_present(n1) .and. & ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then - ! now determine if there will be any active coupling back - and if so create - ! field bundle - do n2 = 1,ncomps - if (n2 /= n1) then - if (is_local%wrap%med_coupling_active(n2,n1)) then - ! create FBFrac and zero out FBfrac(n1) - call FB_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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) then - write(logunit,'(a)') trim(subname)//' Created FBFrac('//trim(compname(n1))//') field bundle ' - end if - exit - end if - end if - end do + ! create FBFrac and zero out FBfrac(n1) + call FB_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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do first_call = .false. + endif !--------------------------------------- ! Set 'lfrac' for FBFrac(complnd) - this might be overwritten later !--------------------------------------- - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(complnd))) then + if (is_local%wrap%comp_present(complnd)) then call FB_getFldPtr(is_local%wrap%FBImp(complnd,complnd) , 'Sl_lfrin' , Sl_lfrin, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) @@ -331,17 +320,14 @@ subroutine med_fraction_init(gcomp, rc) end if !--------------------------------------- - ! Finally, set 'lfrac' in FBFrac(complnd) by mapping FBFrac(compatm) if appropriate + ! Reset 'lfrac' in FBFrac(complnd) by mapping FBFrac(compatm) if appropriate !--------------------------------------- - if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(compatm)) .and. & - ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(complnd))) then + if (is_local%wrap%comp_present(complnd) .and. is_local%wrap%med_coupling_active(complnd,compatm)) then - ! This assumes that atm->lnd and lnd->atm coupling is occuring - ! based on the logic in the initialization of fractions ! Reset 'lfrac' in FBFrac(complnd) by mapping the Frac ! If lnd -> atm coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) - + if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then maptype = mapfcopy else @@ -359,7 +345,7 @@ subroutine med_fraction_init(gcomp, rc) is_local%wrap%FBfrac(complnd), 'lfrac', & is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif + end if !--------------------------------------- ! Set 'lfrac' in FBFrac(compatm) and correct 'ofrac' in FBFrac(compatm) @@ -370,7 +356,7 @@ subroutine med_fraction_init(gcomp, rc) ! settle for a residual calculation that is truncated to zero to ! try to preserve "all ocean" cells. - if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(compatm))) then + if (is_local%wrap%comp_present(compatm)) then if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then @@ -680,24 +666,20 @@ subroutine med_fraction_set(gcomp, rc) ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compice,compatm)) then - if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compice), 'ifrac', & + is_local%wrap%FBfrac(compatm), 'ifrac', & + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compocn,compatm)) then - if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + call FB_FieldRegrid(& + is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compatm), 'ofrac', & + is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if ! end of if present compatm From c4506251305b55dabedca0735096a093c76ece78 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 6 Oct 2020 16:23:08 -0600 Subject: [PATCH 076/206] improve error message --- drivers/cime/esm_time_mod.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/cime/esm_time_mod.F90 b/drivers/cime/esm_time_mod.F90 index 3554394d7..8990632d5 100644 --- a/drivers/cime/esm_time_mod.F90 +++ b/drivers/cime/esm_time_mod.F90 @@ -185,7 +185,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, mastert if (mastertask) then write(logunit,*) ' NOTE: the current compset has no mediator - which provides the clock restart information' - write(logunit,*) ' In this case the restarts are handled solely by the component being used and' + write(logunit,*) ' In this case the restarts are handled solely by the component being used and' write(logunit,*) ' and the driver clock will always be starting from the initial date on restart' end if curr_ymd = start_ymd @@ -650,8 +650,7 @@ subroutine esm_time_read_restart(restart_file, start_ymd, start_tod, curr_ymd, c ! use netcdf here since it's serial status = nf90_open(restart_file, NF90_NOWRITE, ncid) if (status /= nf90_NoErr) then - print *,__FILE__,__LINE__,trim(restart_file) - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_open', ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_open: '//trim(restart_file), ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return endif From 298f84f33862bb2c3fb72b6a3a32f11ef6779751 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 10 Jun 2019 12:42:58 -0600 Subject: [PATCH 077/206] addition of water and energy global diagnostics --- cime_config/namelist_definition_drv.xml | 32 +- mediator/esmFldsExchange_cesm_mod.F90 | 1 + mediator/med.F90 | 89 +- mediator/med_diag_mod.F90 | 2396 +++++++++++++++++++++++ mediator/med_internalstate_mod.F90 | 28 +- mediator/med_map_mod.F90 | 6 +- 6 files changed, 2507 insertions(+), 45 deletions(-) create mode 100644 mediator/med_diag_mod.F90 diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 3bbc58483..02ce42833 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -868,7 +868,7 @@ on_if_glc_coupled_fluxes - off + off @@ -901,7 +901,7 @@ mapping ATM_attributes - DOMAIN description of atm grid + DOMAIN description of atm grid $ATM_DOMAIN_PATH/$ATM_DOMAIN_FILE @@ -925,7 +925,7 @@ mapping LND_attributes - DOMAIN description of lnd grid + DOMAIN description of lnd grid $LND_DOMAIN_PATH/$LND_DOMAIN_FILE @@ -1095,32 +1095,6 @@ - - char - mapping - MED_attributes - ocn,atm,exch - - Grid for atm ocn flux calc (untested) - default: ocn - - - ocn - - - - - real - control - MED_attributes - - wind gustiness factor - - - 0.0D0 - - - logical budget diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 8282308d3..2b1bc0997 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -700,6 +700,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) end if end if end do + deallocate(suffix) ! --------------------------------------------------------------------- diff --git a/mediator/med.F90 b/mediator/med.F90 index eb51b936b..3bc13cca7 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -69,7 +69,8 @@ module MED subroutine SetServices(gcomp, rc) - use ESMF , only: ESMF_SUCCESS, ESMF_GridCompSetEntryPoint, ESMF_METHOD_INITIALIZE, ESMF_METHOD_RUN + 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_Mediator , only: mediator_routine_SS => SetServices @@ -96,6 +97,13 @@ subroutine SetServices(gcomp, rc) use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum_avg 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 + use med_diag_mod , only: med_phases_diag_atm + use med_diag_mod , only: med_phases_diag_lnd + use med_diag_mod , only: med_phases_diag_rof + use med_diag_mod , only: med_phases_diag_glc + use med_diag_mod , only: med_phases_diag_ocn + use med_diag_mod , only: med_phases_diag_ice_ice2med, med_phases_diag_ice_med2ice use med_fraction_mod , only: med_fraction_init, med_fraction_set use med_phases_profile_mod , only: med_phases_profile @@ -345,6 +353,64 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_fraction_set", specRoutine=med_fraction_set, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ + ! phase routines for budget diagnostics + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_diag_atm"/), userRoutine=mediator_routine_Run, rc=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_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_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_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_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_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_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_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_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 + !------------------ ! attach specializing method(s) ! -> NUOPC specializes by default --->>> first need to remove the default @@ -1503,6 +1569,7 @@ subroutine DataInitialize(gcomp, rc) 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 + use med_diag_mod , only : med_diag_zero, med_diag_init use med_map_mod , only : med_map_MapNorm_init, med_map_RouteHandles_init use med_io_mod , only : med_io_init @@ -1689,6 +1756,9 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return is_local%wrap%FBExpAccumCnt(n1) = 0 + ! Create mesh info data + call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), is_local%wrap%mesh_info(n1), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return endif ! The following are FBImp and FBImpAccum mapped to different grids. @@ -2037,9 +2107,18 @@ subroutine DataInitialize(gcomp, rc) call med_io_init() - !--------------------------------------- - ! read mediator restarts - !--------------------------------------- + !--------------------------------------- + ! 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------------- + ! read mediator restarts + !--------------------------------------- call NUOPC_CompAttributeGet(gcomp, name="read_restart", value=cvalue, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -2056,12 +2135,10 @@ subroutine DataInitialize(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", & ESMF_LOGMSG_INFO) end if - if (profile_memory) call ESMF_VMLogMemInfo("Leaving "//trim(subname)) if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 new file mode 100644 index 000000000..5fc59496f --- /dev/null +++ b/mediator/med_diag_mod.F90 @@ -0,0 +1,2396 @@ +module med_diag_mod + + !---------------------------------------------------------------------------- + ! Compute spatial and time averages of fluxed quatities for water and + ! energy balance + ! + ! Sign convention for fluxes is positive downward with hierarchy being + ! atm/glc/lnd/rof/ice/ocn + ! Sign convention: + ! positive value <=> the model is gaining water, heat, momentum, etc. + ! Unit convention: + ! heat flux ~ W/m^2 + ! momentum flux ~ N/m^2 + ! water flux ~ (kg/s)/m^2 + ! salt flux ~ (kg/s)/m^2 + !---------------------------------------------------------------------------- + + use NUOPC + use ESMF + use shr_sys_mod , only : shr_sys_abort + 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_constants_mod , only : R8, CS, CL + use med_internalstate_mod , only : InternalState, logunit, mastertask + use shr_nuopc_methods_mod , only : fldchk => shr_nuopc_methods_FB_FldChk + use shr_nuopc_utils_mod , only : chkerr => shr_nuopc_utils_ChkErr + use shr_nuopc_methods_mod , only : FB_GetFldPtr => shr_nuopc_methods_FB_GetFldPtr + + implicit none + private + + public :: med_diag_init + public :: med_diag_zero + public :: med_phases_diag_accum + public :: med_phases_diag_atm + public :: med_phases_diag_lnd + public :: med_phases_diag_rof + public :: med_phases_diag_glc + 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 + private :: med_diag_print_lnd_ice_ocn + private :: med_diag_print_summary + + type, public :: budget_diag_type + character(CS) :: name + end type budget_diag_type + type, public :: budget_diag_indices + type(budget_diag_type), pointer :: comps(:) + type(budget_diag_type), pointer :: fields(:) + type(budget_diag_type), pointer :: periods(:) + end type budget_diag_indices + type(budget_diag_indices) :: budget_diags + + ! --------------------------------- + ! print options (obtained from mediator config input) + ! --------------------------------- + + ! sets the diagnotics level of the annual budgets. [0,1,2,3], + ! 0 = none, + ! 1 = net summary budgets + ! 2 = 1 + detailed lnd/ocn/ice component budgets + ! 3 = 2 + detailed atm budgets + + integer :: budget_print_inst ! default is 0 + integer :: budget_print_daily ! default is 0 + integer :: budget_print_month ! default is 1 + integer :: budget_print_ann ! default is 1 + integer :: budget_print_ltann ! default is 1 + integer :: budget_print_ltend ! default is 0 + + ! formats for output tables + character(*), parameter :: F00 = "('(med_phases_diag_print) ',4a)" + character(*), parameter :: FAH = "(4a,i9,i6)" + character(*), parameter :: FA0 = "(' ',12x,6(6x,a8,1x))" + character(*), parameter :: FA1 = "(' ',a12,6f15.8)" + character(*), parameter :: FA0r = "(' ',12x,8(6x,a8,1x))" + character(*), parameter :: FA1r = "(' ',a12,8f15.8)" + + ! --------------------------------- + ! C for component + ! --------------------------------- + + ! "r" is receive from the component to the mediator + ! "s" is send from the mediator to the component + + integer :: c_atm_send ! model index: atm + integer :: c_atm_recv ! model index: atm + integer :: c_inh_send ! model index: ice, northern + integer :: c_inh_recv ! model index: ice, northern + integer :: c_ish_send ! model index: ice, southern + integer :: c_ish_recv ! model index: ice, southern + integer :: c_lnd_send ! model index: lnd + integer :: c_lnd_recv ! model index: lnd + integer :: c_ocn_send ! model index: ocn + integer :: c_ocn_recv ! model index: ocn + integer :: c_rof_send ! model index: rof + integer :: c_rof_recv ! model index: rof + integer :: c_glc_send ! model index: glc + integer :: c_glc_recv ! model index: glc + + ! The folowing is needed for detailing the atm budgets and breakdown into components + integer :: c_inh_asend ! model index: ice, northern, on atm grid + integer :: c_inh_arecv ! model index: ice, northern, on atm grid + integer :: c_ish_asend ! model index: ice, southern, on atm grid + integer :: c_ish_arecv ! model index: ice, southern, on atm grid + integer :: c_lnd_asend ! model index: lnd, on atm grid + integer :: c_lnd_arecv ! model index: lnd, on atm grid + integer :: c_ocn_asend ! model index: ocn, on atm grid + integer :: c_ocn_arecv ! model index: ocn, on atm grid + + ! --------------------------------- + ! F for field + ! --------------------------------- + + integer :: f_area ! area (wrt to unit sphere) + integer :: f_heat_frz ! heat : latent, freezing + integer :: f_heat_melt ! heat : latent, melting + integer :: f_heat_swnet ! heat : short wave, net + integer :: f_heat_lwdn ! heat : longwave down + integer :: f_heat_lwup ! heat : longwave up + integer :: f_heat_latvap ! heat : latent, vaporization + integer :: f_heat_latf ! heat : latent, fusion, snow + integer :: f_heat_ioff ! heat : latent, fusion, frozen runoff + integer :: f_heat_sen ! heat : sensible + integer :: f_watr_frz ! water: freezing + integer :: f_watr_melt ! water: melting + integer :: f_watr_rain ! water: precip, liquid + integer :: f_watr_snow ! water: precip, frozen + integer :: f_watr_evap ! water: evaporation + integer :: f_watr_salt ! water: water equivalent of salt flux + integer :: f_watr_roff ! water: runoff/flood + integer :: f_watr_ioff ! water: frozen runoff + integer :: f_watr_frz_16O ! water isotope: freezing + integer :: f_watr_melt_16O ! water isotope: melting + integer :: f_watr_rain_16O ! water isotope: precip, liquid + integer :: f_watr_snow_16O ! water isotope: prcip, frozen + integer :: f_watr_evap_16O ! water isotope: evaporation + integer :: f_watr_roff_16O ! water isotope: runoff/flood + integer :: f_watr_ioff_16O ! water isotope: frozen runoff + integer :: f_watr_frz_18O ! water isotope: freezing + integer :: f_watr_melt_18O ! water isotope: melting + integer :: f_watr_rain_18O ! water isotope: precip, liquid + integer :: f_watr_snow_18O ! water isotope: precip, frozen + integer :: f_watr_evap_18O ! water isotope: evaporation + integer :: f_watr_roff_18O ! water isotope: runoff/flood + integer :: f_watr_ioff_18O ! water isotope: frozen runoff + integer :: f_watr_frz_HDO ! water isotope: freezing + integer :: f_watr_melt_HDO ! water isotope: melting + integer :: f_watr_rain_HDO ! water isotope: precip, liquid + integer :: f_watr_snow_HDO ! water isotope: precip, frozen + integer :: f_watr_evap_HDO ! water isotope: evaporation + integer :: f_watr_roff_HDO ! water isotope: runoff/flood + integer :: f_watr_ioff_HDO ! water isotope: frozen runoff + + integer :: f_heat_beg ! 1st index for heat + integer :: f_heat_end ! Last index for heat + integer :: f_watr_beg ! 1st index for water + integer :: f_watr_end ! Last index for water + + integer :: f_16O_beg ! 1st index for 16O water isotope + integer :: f_16O_end ! Last index for 16O water isotope + integer :: f_18O_beg ! 1st index for 18O water isotope + integer :: f_18O_end ! Last index for 18O water isotope + integer :: f_HDO_beg ! 1st index for HDO water isotope + integer :: f_HDO_end ! Last index for HDO water isotope + + ! --------------------------------- + ! water isotopes names and indices + ! --------------------------------- + + logical :: flds_wiso = .false.! If water isotope fields are active - + ! TODO: for now set to .false. - but this needs to be set in an initialization phase + + integer, parameter :: nisotopes = 3 + integer :: iso0(nisotopes) + integer :: isof(nisotopes) + character(len=5) :: isoname(nisotopes) + + ! --------------------------------- + ! P for period + ! --------------------------------- + + integer :: period_inst + integer :: period_day + integer :: period_mon + integer :: period_ann + integer :: period_inf + + ! --------------------------------- + ! local constants + ! --------------------------------- + + 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) + real(r8), parameter :: SFLXtoWFLX = & ! water flux implied by salt flux (kg/m^2s) + -1._r8/(shr_const_ocn_ref_sal*1.e-3_r8) + + ! --------------------------------- + ! public data members + ! --------------------------------- + + ! note: call med_diag_sum_master then save budget_global and budget_counter on restart from/to root pe --- + + real(r8), allocatable :: budget_local (:,:,:) ! local sum, valid on all pes + real(r8), allocatable :: budget_global (:,:,:) ! global sum, valid only on root pe + real(r8), allocatable :: budget_counter(:,:,:) ! counter, valid only on root pe + real(r8), allocatable :: budget_local_1d(:) ! needed for ESMF_VMReduce call + real(r8), allocatable :: budget_global_1d(:) ! needed for ESMF_VMReduce call + + + character(len=*), parameter :: modName = "(med_diag) " + character(len=*), parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine med_diag_init(gcomp, rc) + + ! ------------------------------------------------------------------ + ! Initialize module variables and allocate dynamic memory + ! ------------------------------------------------------------------ + + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(out) :: rc + + ! local variables + character(CS) :: cvalue + integer :: c_size ! number of component send/recvs + integer :: f_size ! number of fields + integer :: p_size ! number of period types + ! ------------------------------------------------------------------ + + rc = ESMF_SUCCESS + + call add_to_budget_diag(budget_diags%comps, c_atm_send , 'c2a_atm' ) ! comp index: atm + call add_to_budget_diag(budget_diags%comps, c_atm_recv , 'a2c_atm' ) ! comp index: atm + call add_to_budget_diag(budget_diags%comps, c_inh_send , 'c2i_inh' ) ! comp index: ice, northern + call add_to_budget_diag(budget_diags%comps, c_inh_recv , 'i2c_inh' ) ! comp index: ice, northern + call add_to_budget_diag(budget_diags%comps, c_ish_send , 'c2i_ish' ) ! comp index: ice, southern + call add_to_budget_diag(budget_diags%comps, c_ish_recv , 'i2c_ish' ) ! comp index: ice, southern + call add_to_budget_diag(budget_diags%comps, c_lnd_send , 'c2l_lnd' ) ! comp index: lnd + call add_to_budget_diag(budget_diags%comps, c_lnd_recv , 'l2c_lnd' ) ! comp index: lnd + call add_to_budget_diag(budget_diags%comps, c_ocn_send , 'c2o_ocn' ) ! comp index: ocn + call add_to_budget_diag(budget_diags%comps, c_ocn_recv , 'o2c_ocn' ) ! comp index: ocn + call add_to_budget_diag(budget_diags%comps, c_rof_send , 'c2r_rof' ) ! comp index: rof + call add_to_budget_diag(budget_diags%comps, c_rof_recv , 'r2c_rof' ) ! comp index: rof + call add_to_budget_diag(budget_diags%comps, c_glc_send , 'c2g_glc' ) ! comp index: glc + call add_to_budget_diag(budget_diags%comps, c_glc_recv , 'g2c_glc' ) ! comp index: glc + call add_to_budget_diag(budget_diags%comps, c_inh_asend, 'c2a_inh' ) ! comp index: ice, northern, on atm grid + call add_to_budget_diag(budget_diags%comps, c_inh_arecv, 'a2c_inh' ) ! comp index: ice, northern, on atm grid + call add_to_budget_diag(budget_diags%comps, c_ish_asend, 'c2a_ish' ) ! comp index: ice, southern, on atm grid + call add_to_budget_diag(budget_diags%comps, c_ish_arecv, 'a2c_ish' ) ! comp index: ice, southern, on atm grid + call add_to_budget_diag(budget_diags%comps, c_lnd_asend, 'c2a_lnd' ) ! comp index: lnd, on atm grid + call add_to_budget_diag(budget_diags%comps, c_lnd_arecv, 'a2c_lnd' ) ! comp index: lnd, on atm grid + call add_to_budget_diag(budget_diags%comps, c_ocn_asend, 'c2a_ocn' ) ! comp index: ocn, on atm grid + call add_to_budget_diag(budget_diags%comps, c_ocn_arecv, 'a2c_ocn' ) ! comp index: ocn, on atm grid + + call add_to_budget_diag(budget_diags%fields, f_area ,'area' ) ! field area (wrt to unit sphere) + call add_to_budget_diag(budget_diags%fields, f_heat_frz ,'hfreeze' ) ! field heat : latent, freezing + call add_to_budget_diag(budget_diags%fields, f_heat_melt ,'hmelt' ) ! field heat : latent, melting + call add_to_budget_diag(budget_diags%fields, f_heat_swnet ,'hnetsw' ) ! field heat : short wave, net + call add_to_budget_diag(budget_diags%fields, f_heat_lwdn ,'hlwdn' ) ! field heat : longwave down + call add_to_budget_diag(budget_diags%fields, f_heat_lwup ,'hlwup' ) ! field heat : longwave up + call add_to_budget_diag(budget_diags%fields, f_heat_latvap ,'hlatvap' ) ! field heat : latent, vaporization + call add_to_budget_diag(budget_diags%fields, f_heat_latf ,'hlatfus' ) ! field heat : latent, fusion, snow + call add_to_budget_diag(budget_diags%fields, f_heat_ioff ,'hiroff' ) ! field heat : latent, fusion, frozen runoff + call add_to_budget_diag(budget_diags%fields, f_heat_sen ,'hsen' ) ! field heat : sensible + call add_to_budget_diag(budget_diags%fields, f_watr_frz ,'wfreeze' ) ! field water: freezing + call add_to_budget_diag(budget_diags%fields, f_watr_melt ,'wmelt' ) ! field water: melting + call add_to_budget_diag(budget_diags%fields, f_watr_rain ,'wrain' ) ! field water: precip, liquid + call add_to_budget_diag(budget_diags%fields, f_watr_snow ,'wsnow' ) ! field water: precip, frozen + call add_to_budget_diag(budget_diags%fields, f_watr_evap ,'wevap' ) ! field water: evaporation + call add_to_budget_diag(budget_diags%fields, f_watr_salt ,'weqsaltf' ) ! field water: water equivalent of salt flux + call add_to_budget_diag(budget_diags%fields, f_watr_roff ,'wrunoff' ) ! field water: runoff/flood + call add_to_budget_diag(budget_diags%fields, f_watr_ioff ,'wfrzrof' ) ! field water: frozen runoff + call add_to_budget_diag(budget_diags%fields, f_watr_frz_16O ,'wfreeze_16O' ) ! field water isotope: freezing + call add_to_budget_diag(budget_diags%fields, f_watr_melt_16O ,'wmelt_16O' ) ! field water isotope: melting + call add_to_budget_diag(budget_diags%fields, f_watr_rain_16O ,'wrain_16O' ) ! field water isotope: precip, liquid + call add_to_budget_diag(budget_diags%fields, f_watr_snow_16O ,'wsnow_16O' ) ! field water isotope: prcip, frozen + call add_to_budget_diag(budget_diags%fields, f_watr_evap_16O ,'wevap_16O' ) ! field water isotope: evaporation + call add_to_budget_diag(budget_diags%fields, f_watr_roff_16O ,'wrunoff_16O' ) ! field water isotope: runoff/flood + call add_to_budget_diag(budget_diags%fields, f_watr_ioff_16O ,'wfrzrof_16O' ) ! field water isotope: frozen runoff + call add_to_budget_diag(budget_diags%fields, f_watr_frz_18O ,'wfreeze_18O' ) ! field water isotope: freezing + call add_to_budget_diag(budget_diags%fields, f_watr_melt_18O ,'wmelt_18O' ) ! field water isotope: melting + call add_to_budget_diag(budget_diags%fields, f_watr_rain_18O ,'wrain_18O' ) ! field water isotope: precip, liquid + call add_to_budget_diag(budget_diags%fields, f_watr_snow_18O ,'wsnow_18O' ) ! field water isotope: precip, frozen + call add_to_budget_diag(budget_diags%fields, f_watr_evap_18O ,'wevap_18O' ) ! field water isotope: evaporation + call add_to_budget_diag(budget_diags%fields, f_watr_roff_18O ,'wrunoff_18O' ) ! field water isotope: runoff/flood + call add_to_budget_diag(budget_diags%fields, f_watr_ioff_18O ,'wfrzrof_18O' ) ! field water isotope: frozen runoff + call add_to_budget_diag(budget_diags%fields, f_watr_frz_HDO ,'wfreeze_HDO' ) ! field water isotope: freezing + call add_to_budget_diag(budget_diags%fields, f_watr_melt_HDO ,'wmelt_HDO' ) ! field water isotope: melting + call add_to_budget_diag(budget_diags%fields, f_watr_rain_HDO ,'wrain_HDO' ) ! field water isotope: precip, liquid + call add_to_budget_diag(budget_diags%fields, f_watr_snow_HDO ,'wsnow_HDO' ) ! field water isotope: precip, frozen + call add_to_budget_diag(budget_diags%fields, f_watr_evap_HDO ,'wevap_HDO' ) ! field water isotope: evaporation + call add_to_budget_diag(budget_diags%fields, f_watr_roff_HDO ,'wrunoff_HDO' ) ! field water isotope: runoff/flood + call add_to_budget_diag(budget_diags%fields, f_watr_ioff_HDO ,'wfrzrof_HDO' ) ! field water isotope: frozen runoff + + f_heat_beg = f_heat_frz ! field first index for heat + f_heat_end = f_heat_sen ! field last index for heat + f_watr_beg = f_watr_frz ! field firs index for water + f_watr_end = f_watr_ioff ! field last index for water + + f_16O_beg = f_watr_frz_16O ! field 1st index for 16O water isotope + f_16O_end = f_watr_ioff_16O ! field Last index for 16O water isotope + f_18O_beg = f_watr_frz_18O ! field 1st index for 18O water isotope + f_18O_end = f_watr_ioff_18O ! field Last index for 18O water isotope + f_HDO_beg = f_watr_frz_HDO ! field 1st index for HDO water isotope + f_HDO_end = f_watr_ioff_HDO ! field Last index for HDO water isotope + + ! water isotopes + iso0(:) = (/ f_16O_beg, f_18O_beg, f_hdO_beg /) + isof(:) = (/ f_16O_end, f_18O_end, f_hdO_end /) + isoname(:) = (/ 'H216O', 'H218O', ' HDO' /) + + ! period types + call add_to_budget_diag(budget_diags%periods, period_inst,' inst') + call add_to_budget_diag(budget_diags%periods, period_day ,' daily') + call add_to_budget_diag(budget_diags%periods, period_mon ,' monthly') + call add_to_budget_diag(budget_diags%periods, period_ann ,' annual') + call add_to_budget_diag(budget_diags%periods, period_inf ,'all_time') + + ! allocate module budget arrays + c_size = size(budget_diags%comps) + f_size = size(budget_diags%fields) + p_size = size(budget_diags%periods) + + allocate(budget_local (f_size , c_size , p_size)) ! local sum, valid on all pes + allocate(budget_global (f_size , c_size , p_size)) ! global sum, valid only on root pe + allocate(budget_counter (f_size , c_size , p_size)) ! counter, valid only on root pe + allocate(budget_local_1d (f_size * c_size * p_size)) ! needed for ESMF_VMReduce call + allocate(budget_global_1d(f_size * c_size * p_size)) ! needed for ESMF_VMReduce call + + !------------------------------------------------------------------------------- + ! Get config variables + !------------------------------------------------------------------------------- + + call NUOPC_CompAttributeGet(gcomp, name='budget_inst', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_inst + + call NUOPC_CompAttributeGet(gcomp, name='budget_daily', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_daily + + call NUOPC_CompAttributeGet(gcomp, name='budget_month', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_month + + call NUOPC_CompAttributeGet(gcomp, name='budget_ann', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_ann + + call NUOPC_CompAttributeGet(gcomp, name='budget_ltann', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_ltann + + call NUOPC_CompAttributeGet(gcomp, name='budget_ltend', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) budget_print_ltend + + end subroutine med_diag_init + + !=============================================================================== + + subroutine med_diag_zero( gcomp, mode, rc) + + ! ------------------------------------------------------------------ + ! Zero out global budget diagnostic data. + ! ------------------------------------------------------------------ + + ! input/output variables + type(ESMF_GridComp) :: gcomp + character(len=*), intent(in),optional :: mode + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_Time) :: currTime + integer :: ip + integer :: curr_year, curr_mon, curr_day, curr_tod + character(*), parameter :: subName = '(med_diag_zero) ' + ! ------------------------------------------------------------------ + + if (present(mode)) then + + if (trim(mode) == 'inst') then + budget_local(:,:,period_inst) = 0.0_r8 + budget_global(:,:,period_inst) = 0.0_r8 + budget_counter(:,:,period_inst) = 0.0_r8 + elseif (trim(mode) == 'day') then + budget_local(:,:,period_day) = 0.0_r8 + budget_global(:,:,period_day) = 0.0_r8 + budget_counter(:,:,period_day) = 0.0_r8 + elseif (trim(mode) == 'mon') then + budget_local(:,:,period_mon) = 0.0_r8 + budget_global(:,:,period_mon) = 0.0_r8 + budget_counter(:,:,period_mon) = 0.0_r8 + elseif (trim(mode) == 'ann') then + budget_local(:,:,period_ann) = 0.0_r8 + budget_global(:,:,period_ann) = 0.0_r8 + budget_counter(:,:,period_ann) = 0.0_r8 + elseif (trim(mode) == 'inf') then + budget_local(:,:,period_inf) = 0.0_r8 + budget_global(:,:,period_inf) = 0.0_r8 + budget_counter(:,:,period_inf) = 0.0_r8 + elseif (trim(mode) == 'all') then + budget_local(:,:,:) = 0.0_r8 + budget_global(:,:,:) = 0.0_r8 + budget_counter(:,:,:) = 0.0_r8 + else + call shr_sys_abort(subname//' ERROR in mode '//trim(mode)) + endif + + else + call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ClockGet( clock, currTime=currTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_TimeGet( currTime, yy=curr_year, mm=curr_mon, dd=curr_day, s=curr_tod, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + do ip = 1,size(budget_diags%periods) + if (ip == period_inst) then + budget_local(:,:,ip) = 0.0_r8 + budget_global(:,:,ip) = 0.0_r8 + budget_counter(:,:,ip) = 0.0_r8 + endif + if (ip==period_day .and. curr_tod==0) then + budget_local(:,:,ip) = 0.0_r8 + budget_global(:,:,ip) = 0.0_r8 + budget_counter(:,:,ip) = 0.0_r8 + endif + if (ip==period_mon .and. curr_day==1 .and. curr_tod==0) then + budget_local(:,:,ip) = 0.0_r8 + budget_global(:,:,ip) = 0.0_r8 + budget_counter(:,:,ip) = 0.0_r8 + endif + if (ip==period_ann .and. curr_mon==1 .and. curr_day==1 .and. curr_tod==0) then + budget_local(:,:,ip) = 0.0_r8 + budget_global(:,:,ip) = 0.0_r8 + budget_counter(:,:,ip) = 0.0_r8 + endif + enddo + end if + + end subroutine med_diag_zero + + !=============================================================================== + + subroutine med_phases_diag_accum(gcomp, rc) + + ! ------------------------------------------------------------------ + ! Accumulate out global budget diagnostic data. + ! ------------------------------------------------------------------ + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + integer :: ip + character(*), parameter :: subName = '(med_diag_accum) ' + ! ------------------------------------------------------------------ + + 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 + + end subroutine med_phases_diag_accum + + !=============================================================================== + + subroutine med_diag_sum_master(gcomp, rc) + + ! ------------------------------------------------------------------ + ! Sum local values to global on root + ! ------------------------------------------------------------------ + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(ESMF_VM) :: vm + integer :: nf,nc,np,n + integer :: count + integer :: c_size ! number of component send/recvs + integer :: f_size ! number of fields + integer :: p_size ! number of period types + character(*), parameter :: subName = '(med_diag_sum_master) ' + ! ------------------------------------------------------------------ + + rc = ESMF_SUCCESS + + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + f_size = size(budget_diags%fields) + c_size = size(budget_diags%comps) + p_size = size(budget_diags%periods) + + n = 0 + do np = 1,p_size + do nc = 1,c_size + do nf = 1,f_size + n = n + 1 + budget_local_1d(n) = budget_local(nf,nc,np) + end do + end do + end do + !budget_local_1d = reshape(budget_local,(/1/)) + + count = size(budget_global_1d) + budget_global_1d(:) = 0.0_r8 + call ESMF_VMReduce(vm, budget_local_1d, budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + n = 0 + do np = 1,p_size + do nc = 1,c_size + do nf = 1,f_size + n = n + 1 + budget_global(nf,nc,np) = budget_global_1d(n) + end do + end do + end do + + budget_local(:,:,:) = 0.0_r8 + + end subroutine med_diag_sum_master + + !=============================================================================== + + subroutine med_phases_diag_atm(gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global atm input/output flux diagnostics + ! ------------------------------------------------------------------ + + use esmFlds, only : compatm + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: n,nf,ic,ip + real(r8), pointer :: afrac(:) + real(r8), pointer :: lfrac(:) + real(r8), pointer :: ifrac(:) + real(r8), pointer :: ofrac(:) + real(r8), pointer :: areas(:) + real(r8), pointer :: lats(:) + character(*), parameter :: subName = '(med_phases_diag_atm) ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get fractions on atm mesh + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'afrac', fldptr1=afrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', fldptr1=lfrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', fldptr1=ifrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', fldptr1=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 + + !------------------------------- + ! from atm to mediator + !------------------------------- + + 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) + budget_local(nf,c_lnd_arecv,ip) = budget_local(nf,c_lnd_arecv,ip) + areas(n)*lfrac(n) + budget_local(nf,c_ocn_arecv,ip) = budget_local(nf,c_ocn_arecv,ip) + areas(n)*ofrac(n) + if (is_local%wrap%mesh_info(compatm)%lats(n) > 0.0_r8) then + budget_local(nf,c_inh_arecv,ip) = budget_local(nf,c_inh_arecv,ip) + areas(n)*ifrac(n) + else + budget_local(nf,c_ish_arecv,ip) = budget_local(nf,c_ish_arecv,ip) + areas(n)*ifrac(n) + end if + end do + + call diag_atm(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, & + 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, & + 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, & + 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, & + 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, & + 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', & + 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', & + 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 + 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 + budget_local(f_heat_latf,c_inh_arecv,ip) = -budget_local(f_watr_snow,c_inh_arecv,ip)*shr_const_latice + budget_local(f_heat_latf,c_ish_arecv,ip) = -budget_local(f_watr_snow,c_ish_arecv,ip)*shr_const_latice + + !------------------------------- + ! from mediator to atm + !------------------------------- + + ip = period_inst + + do n = 1,size(afrac) + budget_local(f_area,c_atm_send ,ip) = budget_local(f_area,c_atm_send ,ip) - areas(n)*afrac(n) + budget_local(f_area,c_lnd_asend,ip) = budget_local(f_area,c_lnd_asend,ip) + areas(n)*lfrac(n) + budget_local(f_area,c_ocn_asend,ip) = budget_local(f_area,c_ocn_asend,ip) + areas(n)*ofrac(n) + if (is_local%wrap%mesh_info(compatm)%lats(n) > 0.0_r8) then + budget_local(f_area,c_inh_asend,ip) = budget_local(f_area,c_inh_asend,ip) + areas(n)*ifrac(n) + else + budget_local(f_area,c_ish_asend,ip) = budget_local(f_area,c_ish_asend,ip) + areas(n)*ifrac(n) + end if + end do + + call diag_atm(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, & + 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, & + 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, & + 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', & + f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, & + areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) + + !----------- + contains + !----------- + + subroutine diag_atm(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 + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=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) + 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) + else + budget(nf,c_ish_asend,ip) = budget(nf,c_ish_asend,ip) + areas(n)*ifrac(n)*data(n) + end if + end do + end if + end subroutine diag_atm + + subroutine diag_atm_wiso(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 + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=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_recv,ip) = budget(nf_16O,c_atm_recv,ip) - areas(n)*afrac(n)*data(1,n) + budget(nf_16O,c_lnd_arecv,ip) = budget(nf_16O,c_lnd_arecv,ip) + areas(n)*lfrac(n)*data(1,n) + budget(nf_16O,c_ocn_arecv,ip) = budget(nf_16O,c_ocn_arecv,ip) + areas(n)*ofrac(n)*data(1,n) + if (lats(n) > 0.0_r8) then + budget(nf_16O,c_inh_arecv,ip) = budget(nf_16O,c_inh_arecv,ip) + areas(n)*ifrac(n)*data(1,n) + else + budget(nf_16O,c_ish_arecv,ip) = budget(nf_16O,c_ish_arecv,ip) + areas(n)*ifrac(n)*data(1,n) + end if + + budget(nf_18O,c_atm_recv,ip) = budget(nf_18O,c_atm_recv,ip) - areas(n)*afrac(n)*data(2,n) + budget(nf_18O,c_lnd_arecv,ip) = budget(nf_18O,c_lnd_arecv,ip) + areas(n)*lfrac(n)*data(2,n) + budget(nf_18O,c_ocn_arecv,ip) = budget(nf_18O,c_ocn_arecv,ip) + areas(n)*ofrac(n)*data(2,n) + if (lats(n) > 0.0_r8) then + budget(nf_18O,c_inh_arecv,ip) = budget(nf_18O,c_inh_arecv,ip) + areas(n)*ifrac(n)*data(2,n) + else + budget(nf_18O,c_ish_arecv,ip) = budget(nf_18O,c_ish_arecv,ip) + areas(n)*ifrac(n)*data(2,n) + end if + + budget(nf_HDO,c_atm_recv,ip) = budget(nf_HDO,c_atm_recv,ip) - areas(n)*afrac(n)*data(3,n) + budget(nf_HDO,c_lnd_arecv,ip) = budget(nf_HDO,c_lnd_arecv,ip) + areas(n)*lfrac(n)*data(3,n) + budget(nf_HDO,c_ocn_arecv,ip) = budget(nf_HDO,c_ocn_arecv,ip) + areas(n)*ofrac(n)*data(3,n) + if (lats(n) > 0.0_r8) then + budget(nf_HDO,c_inh_arecv,ip) = budget(nf_HDO,c_inh_arecv,ip) + areas(n)*ifrac(n)*data(3,n) + else + budget(nf_HDO,c_ish_arecv,ip) = budget(nf_HDO,c_ish_arecv,ip) + areas(n)*ifrac(n)*data(3,n) + end if + end do + end if + end subroutine diag_atm_wiso + + end subroutine med_phases_diag_atm + + !=============================================================================== + + subroutine med_phases_diag_lnd( gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global lnd input/output flux diagnostics + ! ------------------------------------------------------------------ + + use esmFlds, only : complnd + + ! intput/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + real(r8), pointer :: lfrac(:) + integer :: n,ip, ic + real(r8), pointer :: areas(:) + character(*), parameter :: subName = '(med_phases_diag_lnd) ' + ! ------------------------------------------------------------------ + + rc = ESMF_SUCCESS + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + areas => is_local%wrap%mesh_info(complnd)%areas + + !------------------------------- + ! from land to mediator + !------------------------------- + + ic = c_lnd_recv + ip = period_inst + + do n = 1, size(lfrac) + budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*lfrac(n) + end do + + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Fall_swnet', f_heat_swnet , ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Fall_lwup' , f_heat_lwup , ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Fall_lat' , f_heat_latvap , ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Fall_sen' , f_heat_sen , ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Fall_evap' , f_watr_evap , ic, areas, lfrac, budget_local, rc=rc) + + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofsur', f_watr_roff, ic, & + areas, lfrac, budget_local, minus=.true., rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofgwl', f_watr_roff, ic,& + areas, lfrac, budget_local, minus=.true., rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofsub', f_watr_roff, ic,& + areas, lfrac, budget_local, minus=.true., rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofdto', f_watr_roff, ic,& + areas, lfrac, budget_local, minus=.true., rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_irrig' , f_watr_roff, ic,& + areas, lfrac, budget_local, minus=.true., rc=rc) + call diag_lnd(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofi' , f_watr_ioff, ic,& + areas, lfrac, budget_local, minus=.true., rc=rc) + + call diag_lnd_wiso(is_local%wrap%FBImp(complnd,complnd), 'Flrl_evap_wiso', & + f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofl_wiso', & + f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBImp(complnd,complnd), 'Flrl_rofi_wiso', & + f_watr_ioff_16O, f_watr_ioff_18O, f_watr_ioff_HDO, ic, areas, lfrac, budget_local, rc=rc) + + !------------------------------- + ! to land from mediator + !------------------------------- + + ic = c_lnd_send + ip = period_inst + + do n = 1,size(lfrac) + budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*lfrac(n) + end do + + call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_lwdn' , f_heat_lwdn, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_rainc', f_watr_rain, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_rainl', f_watr_rain, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_snowc', f_watr_snow, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_snowl', f_watr_snow, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd(is_local%wrap%FBExp(complnd), 'Flrl_flood', f_watr_roff, ic, areas, lfrac, budget_local, minus=.true., rc=rc) + + call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Faxa_rainc_wiso', & + f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Faxa_rainl_wiso', & + f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Faxa_snowc_wiso', & + f_watr_snow_16O, f_watr_snow_18O, f_watr_snow_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Faxa_snowl_wiso', & + f_watr_snow_16O, f_watr_snow_18O, f_watr_snow_HDO, ic, areas, lfrac, budget_local, rc=rc) + call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Flrl_flood_wiso', & + f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, lfrac, budget_local, minus=.true., rc=rc) + + budget_local(f_heat_latf,ic,ip) = -budget_local(f_watr_snow,ic,ip)*shr_const_latice + + !----------- + contains + !----------- + + subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: lfrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + ! local variables + integer :: n, ip + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data) + if (present(minus)) then + budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*lfrac(n)*data(n) + else + budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*lfrac(n)*data(n) + end if + end do + end if + end subroutine diag_lnd + + subroutine diag_lnd_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, lfrac, budget, minus, 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 + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: lfrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + ! local variables + integer :: n, ip + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data, dim=2) + if (present(minus)) then + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) - areas(n)*lfrac(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) - areas(n)*lfrac(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) - areas(n)*lfrac(n)*data(3,n) + else + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) + areas(n)*lfrac(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) + areas(n)*lfrac(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) + areas(n)*lfrac(n)*data(3,n) + end if + end do + end if + end subroutine diag_lnd_wiso + + end subroutine med_phases_diag_lnd + + !=============================================================================== + + subroutine med_phases_diag_rof( gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global river input/output + ! ------------------------------------------------------------------ + + use esmFlds, only : comprof + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: ic, ip, n + real(r8), pointer :: areas(:) + character(*), parameter :: subName = '(med_phases_diag_rof) ' + ! ------------------------------------------------------------------ + + 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(comprof)%areas + + !------------------------------- + ! from river to mediator + !------------------------------- + + ic = c_rof_send + ip = period_inst + + call diag_rof(is_local%wrap%FBImp(comprof,comprof), 'Flrr_flood', f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBImp(comprof,comprof), 'Forr_rofl' , f_watr_roff, ic, areas, budget_local, minus=.true., rc=rc) + call diag_rof(is_local%wrap%FBImp(comprof,comprof), 'Forr_rofi' , f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) + call diag_rof(is_local%wrap%FBImp(comprof,comprof), 'Firr_rofi' , f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) + + call diag_rof_wiso(is_local%wrap%FBExp(comprof), 'Forr_flood_wiso', & + f_watr_ioff_16O, f_watr_ioff_18O, f_watr_ioff_HDO, ic, areas, budget_local, rc=rc) + call diag_rof_wiso(is_local%wrap%FBExp(comprof), 'Forr_rofl_wiso', & + f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, budget_local, minus=.true., rc=rc) + call diag_rof_wiso(is_local%wrap%FBExp(comprof), 'Forr_rofi_wiso', & + f_watr_ioff_16O, f_watr_ioff_18O, f_watr_ioff_HDO, ic, areas, budget_local, minus=.true., rc=rc) + + budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice + + !------------------------------- + ! to river from mediator + !------------------------------- + + ic = c_rof_recv + ip = period_inst + + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_rofsur', f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_rofgwl', f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_rofsub', f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_rofdto', f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_irrig' , f_watr_roff, ic, areas, budget_local, rc=rc) + call diag_rof(is_local%wrap%FBExp(comprof), 'Flrl_rofi' , f_watr_ioff, ic, areas, budget_local, rc=rc) + + call diag_rof_wiso(is_local%wrap%FBExp(comprof), 'Flrl_rofl_wiso', & + f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, budget_local, rc=rc) + call diag_rof_wiso(is_local%wrap%FBExp(comprof), 'Flrl_rofi_wiso', & + 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 + !----------- + + subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + + ! local variables + integer :: n, ip + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data) + if (present(minus)) then + budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*data(n) + else + budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*data(n) + end if + end do + end if + end subroutine diag_rof + + subroutine diag_rof_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, budget, minus, 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 + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + + ! local variables + integer :: n, ip + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data, dim=2) + if (present(minus)) then + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) - areas(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) - areas(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) - areas(n)*data(3,n) + else + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) + areas(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) + areas(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) + areas(n)*data(3,n) + end if + end do + end if + 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 + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: ic, ip + real(r8), pointer :: areas(:) + character(*), parameter :: subName = '(med_phases_diag_glc) ' + ! ------------------------------------------------------------------ + + 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 + !------------------------------- + + 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) + + budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice + + !----------- + contains + !----------- + + subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + ! local variables + integer :: n, ip + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data) + if (present(minus)) then + budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*data(n) + else + budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*data(n) + end if + end do + end if + end subroutine diag_glc + + end subroutine med_phases_diag_glc + + !=============================================================================== + + subroutine med_phases_diag_ocn( gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global ocn input from mediator + ! ------------------------------------------------------------------ + + use esmFlds, only : compocn + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: n,ic,ip + real(r8) :: wgt_i,wgt_o + real(r8), pointer :: ifrac(:) ! ice fraction in ocean grid cell + real(r8), pointer :: ofrac(:) ! non-ice fraction nin ocean grid cell + real(r8), pointer :: sfrac(:) ! sum of ifrac and ofrac + real(r8), pointer :: areas(:) + real(r8), pointer :: data(:) + character(*), parameter :: subName = '(med_phases_diag_ocn) ' + ! ------------------------------------------------------------------ + + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ofrac', fldptr1=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(sfrac(size(ofrac))) + sfrac(:) = ifrac(:) + ofrac(:) + + areas => is_local%wrap%mesh_info(compocn)%areas + + !------------------------------- + ! from ocn to mediator + !------------------------------- + + ip = period_inst + ic = c_ocn_recv + + do n = 1,size(ofrac) + budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*ofrac(n) + end do + + if ( 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 (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(ifrac) + wgt_o = areas(n) * ofrac(n) + wgt_i = areas(n) * ifrac(n) + budget_local(f_heat_frz,ic,ip) = budget_local(f_heat_frz,ic,ip) + (wgt_o + wgt_i)*max(0.0_r8,data(n)) + end do + end if + + call diag_ocn(is_local%wrap%FBImp(compocn,compocn), 'Faox_lwup', f_heat_lwup , ic, areas, ofrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBImp(compocn,compocn), 'Faox_lat' , f_heat_latvap , ic, areas, ofrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBImp(compocn,compocn), 'Faox_sen' , f_heat_sen , ic, areas, ofrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBImp(compocn,compocn), 'Faox_evap', f_watr_evap , ic, areas, ofrac, budget_local, rc=rc) + + call diag_ocn_wiso(is_local%wrap%FBImp(compocn,compocn), 'Faox_evap_wiso', & + f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, ic, areas, ofrac, budget_local, rc=rc) + + budget_local(f_watr_frz,ic,ip) = budget_local(f_heat_frz,ic,ip) * HFLXtoWFLX + + !------------------------------- + ! from mediator to ocn + !------------------------------- + + ic = c_ocn_send + ip = period_inst + + do n = 1,size(ofrac) + budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*ofrac(n) + end do + + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_lwup' , f_heat_lwup , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_lat' , f_heat_latvap , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_sen' , f_heat_sen , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_evap' , f_watr_evap , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_meltw', f_watr_melt , ic, areas, sfrac, budget_local, rc=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), '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) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Faxa_snow' , f_watr_snow , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_rofl' , f_watr_roff , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_rofi' , f_watr_ioff , ic, areas, sfrac, budget_local, rc=rc) + + call diag_ocn_wiso(is_local%wrap%FBExp(compocn), 'Fioi_meltw_wiso', & + f_watr_melt_16O, f_watr_melt_HDO, f_watr_melt_HDO, ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn_wiso(is_local%wrap%FBExp(compocn), 'Fioi_rain_wiso' , & + f_watr_rain_16O, f_watr_rain_HDO, f_watr_rain_HDO, ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn_wiso(is_local%wrap%FBExp(compocn), 'Fioi_snow_wiso' , & + f_watr_snow_16O, f_watr_snow_HDO, f_watr_snow_HDO, ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn_wiso(is_local%wrap%FBExp(compocn), 'Foxx_rofl_wiso' , & + f_watr_roff_16O, f_watr_roff_HDO, f_watr_roff_HDO, ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn_wiso(is_local%wrap%FBExp(compocn), 'Foxx_rofi_wiso' , & + f_watr_ioff_16O, f_watr_ioff_HDO, f_watr_ioff_HDO, ic, areas, sfrac, budget_local, rc=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 + + !----------- + contains + !----------- + + subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: frac(:) + real(r8) , intent(inout) :: budget(:,:,:) + integer , intent(out) :: rc + ! local variables + integer :: n, ip + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data) + budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*frac(n)*data(n) + end do + end if + end subroutine diag_ocn + + subroutine diag_ocn_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, frac, 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 + integer , intent(in) :: ic + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: frac(:) + real(r8) , intent(inout) :: budget(:,:,:) + integer , intent(out) :: rc + + ! local variables + integer :: n, ip + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1, size(data, dim=2) + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) + areas(n)*frac(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) + areas(n)*frac(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) + areas(n)*frac(n)*data(3,n) + end do + end if + end subroutine diag_ocn_wiso + + end subroutine med_phases_diag_ocn + + !=============================================================================== + + subroutine med_phases_diag_ice_ice2med( gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global ice input/output flux diagnostics + ! ------------------------------------------------------------------ + + use esmFlds, only : compice + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: n,ic,ip + real(r8), pointer :: ofrac(:) + real(r8), pointer :: ifrac(:) + real(r8), pointer :: areas(:) + real(r8), pointer :: lats(:) + character(*), parameter :: subName = '(med_phases_diag_ice_ice2med) ' + ! ------------------------------------------------------------------ + + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + areas => is_local%wrap%mesh_info(compice)%areas + lats => is_local%wrap%mesh_info(compice)%lats + + ip = period_inst + + do n = 1,size(ifrac) + if (lats(n) > 0.0_r8) then + ic = c_inh_recv + else + ic = c_ish_recv + endif + 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, & + areas, lats, ifrac, budget_local, minus=.true., rc=rc) + call diag_ice(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, & + 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, & + areas, lats, ifrac, budget_local, minus=.true., rc=rc) + call diag_ice(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, & + areas, lats, ifrac, budget_local, rc=rc) + call diag_ice(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, & + areas, lats, ifrac, budget_local, rc=rc) + call diag_ice(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', & + 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', & + f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, areas, lats, ifrac, budget_local, rc=rc) + + !----------- + contains + !----------- + + subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, 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) :: 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 + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=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 + else + ic = c_ish_recv + 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 + end do + end if + end subroutine diag_ice + + subroutine diag_ice_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 + 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) :: ifrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + + ! local variables + integer :: n, ip + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=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 + else + ic = c_ish_recv + 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 + end do + end if + end subroutine diag_ice_wiso + + + end subroutine med_phases_diag_ice_ice2med + + !=============================================================================== + + subroutine med_phases_diag_ice_med2ice( gcomp, rc) + + ! ------------------------------------------------------------------ + ! Compute global ice input/output flux diagnostics + ! ------------------------------------------------------------------ + + use esmFlds, only : compice + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(InternalState) :: is_local + integer :: n,ic,ip + real(r8) :: wgt_i, wgt_o + real(r8), pointer :: ofrac(:) + real(r8), pointer :: ifrac(:) + real(r8), pointer :: data(:) + real(r8), pointer :: areas(:) + real(r8), pointer :: lats(:) + character(*), parameter :: subName = '(med_phases_diag_ice_med2ice) ' + ! ------------------------------------------------------------------ + + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + areas => is_local%wrap%mesh_info(compice)%areas + lats => is_local%wrap%mesh_info(compice)%lats + + ip = period_inst + + do n = 1,size(ifrac) + if (lats(n) > 0.0_r8) then + ic = c_inh_send + else + ic = c_ish_send + endif + 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_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 ( 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 (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(data) + wgt_o = areas(n) * ofrac(n) + wgt_i = areas(n) * ifrac(n) + if (lats(n) > 0.0_r8) then + ic = c_inh_send + else + ic = c_ish_send + endif + budget_local(f_heat_frz,ic,ip) = budget_local(f_heat_frz,ic,ip) - (wgt_o + wgt_i)*max(0.0_r8,data(n)) + end do + end if + + ic = c_inh_send + 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 + budget_local(f_watr_frz ,ic,ip) = budget_local(f_heat_frz ,ic,ip)*HFLXtoWFLX + + ic = c_ish_send + 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 + budget_local(f_watr_frz ,ic,ip) = budget_local(f_heat_frz ,ic,ip)*HFLXtoWFLX + + !----------- + contains + !----------- + + subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, 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) :: 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 + real(r8), pointer :: data(:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr1=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 + else + ic = c_ish_recv + 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 + end do + end if + end subroutine diag_ice + + subroutine diag_ice_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 + 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) :: ifrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + logical, optional , intent(in) :: minus + integer , intent(out) :: rc + + ! local variables + integer :: n, ip + real(r8), pointer :: data(:,:) + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + + if ( fldchk(FB, trim(fldname), rc=rc)) then + call FB_GetFldPtr(FB, trim(fldname), fldptr2=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 + else + ic = c_ish_recv + 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 + end do + end if + end subroutine diag_ice_wiso + + end subroutine med_phases_diag_ice_med2ice + + !=============================================================================== + + subroutine med_phases_diag_print(gcomp, rc) + + ! ------------------------------------------------------------------ + ! Print global budget diagnostics. + ! ------------------------------------------------------------------ + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out):: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_Alarm) :: stop_alarm + type(ESMF_Time) :: currTime + integer :: cdate ! coded date, seconds + integer :: curr_year + integer :: curr_mon + integer :: curr_day + integer :: curr_tod + integer :: output_level ! print level + logical :: sumdone ! has a sum been computed yet + character(CS) :: cvalue + integer :: ip + integer :: c_size ! number of component send/recvs + integer :: f_size ! number of fields + integer :: p_size ! number of period types + real(r8), allocatable :: datagpr(:,:,:) + character(*), parameter :: subName = '(med_phases_diag_print) ' + ! ------------------------------------------------------------------ + + rc = ESMF_SUCCESS + + !------------------------------------------------------------------------------- + ! Print budget data if appropriate + !------------------------------------------------------------------------------- + + ! Get clock and alarm info + call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet( clock, currTime=currTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet( currTime, yy=curr_year, mm=curr_mon, dd=curr_day, s=curr_tod, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + cdate = curr_year*10000 + curr_mon*100 + curr_day + + sumdone = .false. + do ip = 1,size(budget_diags%periods) + + ! Determine output level for this period type + output_level = 0 + if (ip == period_inst) then + output_level = max(output_level, budget_print_inst) + endif + if (ip == period_day .and. curr_tod == 0) then + output_level = max(output_level, budget_print_daily) + endif + if (ip == period_mon .and. curr_day == 1 .and. curr_tod == 0) then + output_level = max(output_level, budget_print_month) + endif + if (ip == period_ann .and. curr_mon == 1 .and. curr_day == 1 .and. curr_tod == 0) then + output_level = max(output_level, budget_print_ann) + endif + if (ip == period_inf .and. curr_mon == 1 .and. curr_day == 1 .and. curr_tod == 0) then + output_level = max(output_level, budget_print_ltann) + endif + if (ip == period_inf) then + call ESMF_ClockGetAlarm(clock, alarmname='alarm_stop', alarm=stop_alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ESMF_AlarmIsRinging(stop_alarm, rc=rc)) then + output_level = max(output_level, budget_print_ltend) + endif + endif + + ! Currently output_level is limited to levels of 0,1,2, 3 + ! (see comment for print obtains at top) + + if (output_level > 0) then + if (.not. sumdone) then + ! Some budgets will be printed for this period type + + ! Determine sums if not already done + call med_diag_sum_master(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + sumdone = .true. + end if + + if (mastertask) then + c_size = size(budget_diags%comps) + f_size = size(budget_diags%fields) + p_size = size(budget_diags%periods) + allocate(datagpr(f_size, c_size, p_size)) + datagpr(:,:,:) = budget_global(:,:,:) + + ! budget normalizations (global area and 1e6 for water) + datagpr = datagpr/(4.0_r8*shr_const_pi) + datagpr(f_watr_beg:f_watr_end,:,:) = datagpr(f_watr_beg:f_watr_end,:,:) * 1.0e6_r8 + if ( flds_wiso ) then + datagpr(iso0(1):isof(nisotopes),:,:) = datagpr(iso0(1):isof(nisotopes),:,:) * 1.0e6_r8 + end if + datagpr(:,:,:) = datagpr/budget_counter(:,:,:) + + ! Write diagnostic tables to logunit (mastertask only) + if (output_level >= 3) then + ! detail atm budgets and breakdown into components --- + call med_diag_print_atm(datagpr, ip, cdate, curr_tod) + end if + if (output_level >= 2) then + ! detail lnd/ocn/ice component budgets ---- + call med_diag_print_lnd_ice_ocn(datagpr, ip, cdate, curr_tod) + end if + if (output_level >= 1) then + ! net summary budgets + call med_diag_print_summary(datagpr, ip, cdate, curr_tod) + endif + write(logunit,*) ' ' + + deallocate(datagpr) + endif ! output_level > 0 and mastertask + end if ! if mastertask + enddo ! ip = 1, period_types + + !------------------------------------------------------------------------------- + ! Zero budget data + !------------------------------------------------------------------------------- + + call med_diag_zero(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_phases_diag_print + + !=============================================================================== + + subroutine med_diag_print_atm(data, ip, cdate, curr_tod) + + ! --------------------------------------------------------- + ! detail atm budgets and breakdown into components + ! --------------------------------------------------------- + + ! intput/output variables + real(r8), intent(in) :: data(:,:,:) ! values to print, scaled and such + integer , intent(in) :: ip ! period index + integer , intent(in) :: cdate + integer , intent(in) :: curr_tod + + ! local variables + integer :: ic,nf,is ! data array indicies + integer :: ica,icl + integer :: icn,ics,ico + character(len=40) :: str ! string + character(*), parameter:: subName = '(med_phases_diag_print_level3) ' + ! ------------------------------------------------------------------ + + do ic = 1,2 + if (ic == 1) then ! from atm to mediator + ica = c_atm_recv ! total from atm + icl = c_lnd_arecv ! from land to med on atm grid + icn = c_inh_arecv ! from ice-nh to med on atm grid + ics = c_ish_arecv ! from ice-sh to med on atm grid + ico = c_ocn_arecv ! from ocn to to med on atm grid + str = "ATM_to_CPL" + elseif (ic == 2) then ! from mediator to atm + ica = c_atm_send ! merged to atm + icl = c_lnd_asend ! from land to atm + icn = c_inh_asend ! from ice-nh to atm + ics = c_ish_asend ! from ice-sh to atm + ico = c_ocn_asend ! from ocn to atm + str = "CPL_TO_ATM" + else + call shr_sys_abort(subname//' ERROR in ic index code 411') + endif + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' AREA BUDGET (m2/m2): period = ', & + trim(budget_diags%periods(ip)%name), ': date = ', cdate, curr_tod + write(logunit,FA0) & + budget_diags%comps(ica)%name,& + budget_diags%comps(icl)%name,& + budget_diags%comps(icn)%name,& + budget_diags%comps(ics)%name,& + budget_diags%comps(ico)%name,' *SUM* ' + write(logunit,FA1) budget_diags%fields(f_area)%name,& + data(f_area,ica,ip), & + data(f_area,icl,ip), & + data(f_area,icn,ip), & + data(f_area,ics,ip), & + data(f_area,ico,ip), & + data(f_area,ica,ip) + data(f_area,icl,ip) + & + data(f_area,icn,ip) + data(f_area,ics,ip) + data(f_area,ico,ip) + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' HEAT BUDGET (W/m2): period = ',& + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(ica)%name,& + budget_diags%comps(icl)%name,& + budget_diags%comps(icn)%name,& + budget_diags%comps(ics)%name,& + budget_diags%comps(ico)%name,' *SUM* ' + do nf = f_heat_beg, f_heat_end + write(logunit,FA1) budget_diags%fields(nf)%name,& + data(nf,ica,ip), & + data(nf,icl,ip), & + data(nf,icn,ip), & + data(nf,ics,ip), & + data(nf,ico,ip), & + data(nf,ica,ip) + data(nf,icl,ip) + data(nf,icn,ip) + data(nf,ics,ip) + data(nf,ico,ip) + enddo + write(logunit,FA1) ' *SUM*' ,& + sum(data(f_heat_beg:f_heat_end,ica,ip)), & + sum(data(f_heat_beg:f_heat_end,icl,ip)), & + sum(data(f_heat_beg:f_heat_end,icn,ip)), & + sum(data(f_heat_beg:f_heat_end,ics,ip)), & + sum(data(f_heat_beg:f_heat_end,ico,ip)), & + sum(data(f_heat_beg:f_heat_end,ica,ip)) + sum(data(f_heat_beg:f_heat_end,icl,ip)) + & + sum(data(f_heat_beg:f_heat_end,icn,ip)) + sum(data(f_heat_beg:f_heat_end,ics,ip)) + & + sum(data(f_heat_beg:f_heat_end,ico,ip)) + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' WATER BUDGET (kg/m2s*1e6): period = ',& + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(ica)%name,& + budget_diags%comps(icl)%name,& + budget_diags%comps(icn)%name,& + budget_diags%comps(ics)%name,& + budget_diags%comps(ico)%name,' *SUM* ' + do nf = f_watr_beg, f_watr_end + write(logunit,FA1) budget_diags%fields(nf)%name,& + data(nf,ica,ip), & + data(nf,icl,ip), & + data(nf,icn,ip), & + data(nf,ics,ip), & + data(nf,ico,ip), & + data(nf,ica,ip) + data(nf,icl,ip) + data(nf,icn,ip) + data(nf,ics,ip) + data(nf,ico,ip) + enddo + write(logunit,FA1) ' *SUM*' ,& + sum(data(f_watr_beg:f_watr_end,ica,ip)), & + sum(data(f_watr_beg:f_watr_end,icl,ip)), & + sum(data(f_watr_beg:f_watr_end,icn,ip)), & + sum(data(f_watr_beg:f_watr_end,ics,ip)), & + sum(data(f_watr_beg:f_watr_end,ico,ip)), & + sum(data(f_watr_beg:f_watr_end,ica,ip)) + sum(data(f_watr_beg:f_watr_end,icl,ip)) + & + sum(data(f_watr_beg:f_watr_end,icn,ip)) + sum(data(f_watr_beg:f_watr_end,ics,ip)) + & + sum(data(f_watr_beg:f_watr_end,ico,ip)) + + if ( flds_wiso ) then + do is = 1, nisotopes + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' '//isoname(is)//' WATER BUDGET (kg/m2s*1e6): period = ', & + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(ica)%name,& + budget_diags%comps(icl)%name,& + budget_diags%comps(icn)%name,& + budget_diags%comps(ics)%name,& + budget_diags%comps(ico)%name,' *SUM* ' + do nf = iso0(is), isof(is) + write(logunit,FA1) budget_diags%fields(nf)%name,& + data(nf,ica,ip), & + data(nf,icl,ip), & + data(nf,icn,ip), & + data(nf,ics,ip), & + data(nf,ico,ip), & + data(nf,ica,ip) + data(nf,icl,ip) + data(nf,icn,ip) + data(nf,ics,ip) + data(nf,ico,ip) + enddo + write(logunit,FA1) ' *SUM*', & + sum(data(iso0(is):isof(is),ica,ip)), & + sum(data(iso0(is):isof(is),icl,ip)), & + sum(data(iso0(is):isof(is),icn,ip)), & + sum(data(iso0(is):isof(is),ics,ip)), & + sum(data(iso0(is):isof(is),ico,ip)), & + sum(data(iso0(is):isof(is),ica,ip)) + sum(data(iso0(is):isof(is),icl,ip)) + & + sum(data(iso0(is):isof(is),icn,ip)) + sum(data(iso0(is):isof(is),ics,ip)) + & + sum(data(iso0(is):isof(is),ico,ip)) + end do + end if + + enddo + + end subroutine med_diag_print_atm + + !=============================================================================== + + subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) + + ! --------------------------------------------------------- + ! detail lnd/ocn/ice component budgets + ! --------------------------------------------------------- + + ! intput/output variables + real(r8), intent(in) :: data(:,:,:) ! values to print, scaled and such + integer , intent(in) :: ip + integer , intent(in) :: cdate + integer , intent(in) :: curr_tod + + ! local variables + integer :: ic,nf,is ! data array indicies + integer :: icar,icas + integer :: icxs,icxr + character(len=40) :: str ! string + character(*), parameter :: subName = '(med_diag_print_lnd_ocn_ice) ' + ! ------------------------------------------------------------------ + + do ic = 1,4 + + if (ic == 1) then + icar = c_lnd_arecv + icxs = c_lnd_send + icxr = c_lnd_recv + icas = c_lnd_asend + str = "LND" + elseif (ic == 2) then + icar = c_ocn_arecv + icxs = c_ocn_send + icxr = c_ocn_recv + icas = c_ocn_asend + str = "OCN" + elseif (ic == 3) then + icar = c_inh_arecv + icxs = c_inh_send + icxr = c_inh_recv + icas = c_inh_asend + str = "ICE_NH" + elseif (ic == 4) then + icar = c_ish_arecv + icxs = c_ish_send + icxr = c_ish_recv + icas = c_ish_asend + str = "ICE_SH" + else + call shr_sys_abort(subname//' ERROR in ic index code 412') + endif + + ! heat budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh, + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' HEAT BUDGET (W/m2): period = ',& + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0) budget_diags%comps(icar)%name,& + budget_diags%comps(icxs)%name,& + budget_diags%comps(icxr)%name,& + budget_diags%comps(icas)%name,' *SUM* ' + do nf = f_heat_beg, f_heat_end + write(logunit,FA1) budget_diags%fields(nf)%name,& + -data(nf,icar,ip), & + data(nf,icxs,ip), & + data(nf,icxr,ip), & + -data(nf,icas,ip), & + -data(nf,icar,ip) + data(nf,icxs,ip) + data(nf,icxr,ip) - data(nf,icas,ip) + enddo + write(logunit,FA1)' *SUM*',& + -sum(data(f_heat_beg:f_heat_end,icar,ip)), & + sum(data(f_heat_beg:f_heat_end,icxs,ip)), & + sum(data(f_heat_beg:f_heat_end,icxr,ip)), & + -sum(data(f_heat_beg:f_heat_end,icas,ip)), & + -sum(data(f_heat_beg:f_heat_end,icar,ip)) + sum(data(f_heat_beg:f_heat_end,icxs,ip)) + & + sum(data(f_heat_beg:f_heat_end,icxr,ip)) - sum(data(f_heat_beg:f_heat_end,icas,ip)) + + ! water budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh, + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//' WATER BUDGET (kg/m2s*1e6): period = ',& + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(icar)%name,& + budget_diags%comps(icxs)%name,& + budget_diags%comps(icxr)%name,& + budget_diags%comps(icas)%name,' *SUM* ' + do nf = f_watr_beg, f_watr_end + write(logunit,FA1) budget_diags%fields(nf)%name,& + -data(nf,icar,ip),& + data(nf,icxs,ip), & + data(nf,icxr,ip),& + -data(nf,icas,ip), & + -data(nf,icar,ip) + data(nf,icxs,ip) + data(nf,icxr,ip) - data(nf,icas,ip) + enddo + write(logunit,FA1) ' *SUM*',& + -sum(data(f_watr_beg:f_watr_end,icar,ip)), & + sum(data(f_watr_beg:f_watr_end,icxs,ip)), & + sum(data(f_watr_beg:f_watr_end,icxr,ip)), & + -sum(data(f_watr_beg:f_watr_end,icas,ip)), & + -sum(data(f_watr_beg:f_watr_end,icar,ip)) + sum(data(f_watr_beg:f_watr_end,icxs,ip)) + & + sum(data(f_watr_beg:f_watr_end,icxr,ip)) - sum(data(f_watr_beg:f_watr_end,icas,ip)) + + if ( flds_wiso ) then + do is = 1, nisotopes + + ! heat budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh for water isotopes + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//isoname(is)//' WATER BUDGET (kg/m2s*1e6): period = ',& + trim(budget_diags%periods(ip)%name), & + ': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(icar)%name,& + budget_diags%comps(icxs)%name,& + budget_diags%comps(icxr)%name,& + budget_diags%comps(icas)%name,' *SUM* ' + do nf = iso0(is), isof(is) + write(logunit,FA1) budget_diags%fields(nf)%name,& + -data(nf,icar,ip), & + data(nf,icxs,ip), & + data(nf,icxr,ip), & + -data(nf,icas,ip), & + -data(nf,icar,ip) + data(nf,icxs,ip) + data(nf,icxr,ip) - data(nf,icas,ip) + enddo + write(logunit,FA1) ' *SUM*',& + -sum(data(iso0(is):isof(is),icar,ip)),& + sum(data(iso0(is):isof(is),icxs,ip)), & + sum(data(iso0(is):isof(is),icxr,ip)), & + -sum(data(iso0(is):isof(is),icas,ip)), & + -sum(data(iso0(is):isof(is),icar,ip)) + sum(data(iso0(is):isof(is),icxs,ip)) + & + sum(data(iso0(is):isof(is),icxr,ip)) - sum(data(iso0(is):isof(is),icas,ip)) + + ! water budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh for water isotopes + + write(logunit,*) ' ' + write(logunit,FAH) subname,trim(str)//isoname(is)//' WATER BUDGET (kg/m2s*1e6): period = ',& + trim(budget_diags%periods(ip)%name),& + ': date = ',cdate,curr_tod + write(logunit,FA0) & + budget_diags%comps(icar)%name,& + budget_diags%comps(icxs)%name,& + budget_diags%comps(icxr)%name,& + budget_diags%comps(icas)%name,' *SUM* ' + do nf = iso0(is), isof(is) + write(logunit,FA1) budget_diags%fields(nf)%name,& + -data(nf,icar,ip), & + data(nf,icxs,ip), & + data(nf,icxr,ip), & + -data(nf,icas,ip), & + -data(nf,icar,ip) + data(nf,icxs,ip) + data(nf,icxr,ip) - data(nf,icas,ip) + enddo + write(logunit,FA1) ' *SUM*', & + -sum(data(iso0(is):isof(is), icar, ip)), & + sum(data(iso0(is):isof(is), icxs, ip)), & + sum(data(iso0(is):isof(is), icxr, ip)), & + -sum(data(iso0(is):isof(is), icas, ip)), & + -sum(data(iso0(is):isof(is), icar, ip)) + sum(data(iso0(is):isof(is), icxs, ip)) + & + sum(data(iso0(is):isof(is), icxr, ip)) - sum(data(iso0(is):isof(is), icas, ip)) + end do + end if + enddo + + end subroutine med_diag_print_lnd_ice_ocn + + !=============================================================================== + + subroutine med_diag_print_summary(data, ip, cdate, curr_tod) + + ! --------------------------------------------------------- + ! net summary budgets + ! --------------------------------------------------------- + + ! intput/output variables + real(r8), intent(in) :: data(:,:,:) ! values to print, scaled and such + integer , intent(in) :: ip + integer , intent(in) :: cdate + integer , intent(in) :: curr_tod + + ! local variables + integer :: ic,nf,is ! data array indicies + real(r8) :: atm_area, lnd_area, ocn_area + real(r8) :: ice_area_nh, ice_area_sh + real(r8) :: sum_area, sum_area_tot + real(r8) :: net_water_atm , sum_net_water_atm + real(r8) :: net_water_lnd , sum_net_water_lnd + real(r8) :: net_water_rof , sum_net_water_rof + real(r8) :: net_water_ocn , sum_net_water_ocn + real(r8) :: net_water_glc , sum_net_water_glc + real(r8) :: net_water_ice_nh , sum_net_water_ice_nh + real(r8) :: net_water_ice_sh , sum_net_water_ice_sh + real(r8) :: net_water_tot , sum_net_water_tot + real(r8) :: net_heat_atm , sum_net_heat_atm + real(r8) :: net_heat_lnd , sum_net_heat_lnd + real(r8) :: net_heat_rof , sum_net_heat_rof + real(r8) :: net_heat_ocn , sum_net_heat_ocn + real(r8) :: net_heat_glc , sum_net_heat_glc + real(r8) :: net_heat_ice_nh , sum_net_heat_ice_nh + real(r8) :: net_heat_ice_sh , sum_net_heat_ice_sh + real(r8) :: net_heat_tot , sum_net_heat_tot + character(len=40) :: str + character(*), parameter:: subName = '(med_diag_print_summary) ' + ! ------------------------------------------------------------------ + + ! write out areas + + write(logunit,*) ' ' + write(logunit,FAH) subname,'NET AREA BUDGET (m2/m2): period = ',& + trim(budget_diags%periods(ip)%name),& + ': date = ',cdate,curr_tod + write(logunit,FA0) ' atm',' lnd',' ocn',' ice nh',' ice sh',' *SUM* ' + atm_area = data(f_area,c_atm_recv,ip) + lnd_area = data(f_area,c_lnd_recv,ip) + ocn_area = data(f_area,c_ocn_recv,ip) + ice_area_nh = data(f_area,c_inh_recv,ip) + ice_area_sh = data(f_area,c_ish_recv,ip) + sum_area = atm_area + lnd_area + ocn_area + ice_area_nh + ice_area_sh + write(logunit,FA1) budget_diags%fields(f_area)%name, atm_area, lnd_area, ocn_area, ice_area_nh, ice_area_sh, sum_area + + ! write out net heat budgets + + write(logunit,*) ' ' + write(logunit,FAH) subname,'NET HEAT BUDGET (W/m2): period = ',& + trim(budget_diags%periods(ip)%name), ': date = ',cdate,curr_tod + write(logunit,FA0r) ' atm',' lnd',' rof',' ocn',' ice nh',' ice sh',' glc',' *SUM* ' + do nf = f_heat_beg, f_heat_end + net_heat_atm = data(nf, c_atm_recv, ip) + data(nf, c_atm_send, ip) + net_heat_lnd = data(nf, c_lnd_recv, ip) + data(nf, c_lnd_send, ip) + net_heat_rof = data(nf, c_rof_recv, ip) + data(nf, c_rof_send, ip) + net_heat_ocn = data(nf, c_ocn_recv, ip) + data(nf, c_ocn_send, ip) + net_heat_ice_nh = data(nf, c_inh_recv, ip) + data(nf, c_inh_send, ip) + net_heat_ice_sh = data(nf, c_ish_recv, ip) + data(nf, c_ish_send, ip) + net_heat_glc = data(nf, c_glc_recv, ip) + data(nf, c_glc_send, ip) + net_heat_tot = net_heat_atm + net_heat_lnd + net_heat_rof + net_heat_ocn + & + net_heat_ice_nh + net_heat_ice_sh + net_heat_glc + + write(logunit,FA1r) budget_diags%fields(nf)%name,& + net_heat_atm, net_heat_lnd, net_heat_rof, net_heat_ocn, & + net_heat_ice_nh, net_heat_ice_sh, net_heat_glc, net_heat_tot + end do + + ! Write out sum over all net heat budgets (sum over f_heat_beg -> f_heat_end) + + sum_net_heat_atm = sum(data(f_heat_beg:f_heat_end, c_atm_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_atm_send, ip)) + sum_net_heat_lnd = sum(data(f_heat_beg:f_heat_end, c_lnd_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_lnd_send, ip)) + sum_net_heat_rof = sum(data(f_heat_beg:f_heat_end, c_rof_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_rof_send, ip)) + sum_net_heat_ocn = sum(data(f_heat_beg:f_heat_end, c_ocn_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_ocn_send, ip)) + sum_net_heat_ice_nh = sum(data(f_heat_beg:f_heat_end, c_inh_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_inh_send, ip)) + sum_net_heat_ice_sh = sum(data(f_heat_beg:f_heat_end, c_ish_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_ish_send, ip)) + sum_net_heat_glc = sum(data(f_heat_beg:f_heat_end, c_glc_recv, ip)) + & + sum(data(f_heat_beg:f_heat_end, c_glc_send, ip)) + sum_net_heat_tot = sum_net_heat_atm + sum_net_heat_lnd + sum_net_heat_rof + sum_net_heat_ocn + & + sum_net_heat_ice_nh + sum_net_heat_ice_sh + sum_net_heat_glc + + write(logunit,FA1r)' *SUM*',& + sum_net_heat_atm, sum_net_heat_lnd, sum_net_heat_rof, sum_net_heat_ocn, & + sum_net_heat_ice_nh, sum_net_heat_ice_sh, sum_net_heat_glc, sum_net_heat_tot + + ! write out net water budgets + + write(logunit,*) ' ' + write(logunit,FAH) subname,'NET WATER BUDGET (kg/m2s*1e6): period = ',& + trim(budget_diags%periods(ip)%name), ': date = ',cdate,curr_tod + write(logunit,FA0r) ' atm',' lnd',' rof',' ocn',' ice nh',' ice sh',' glc',' *SUM* ' + do nf = f_watr_beg, f_watr_end + net_water_atm = data(nf, c_atm_recv, ip) + data(nf, c_atm_send, ip) + net_water_lnd = data(nf, c_lnd_recv, ip) + data(nf, c_lnd_send, ip) + net_water_rof = data(nf, c_rof_recv, ip) + data(nf, c_rof_send, ip) + net_water_ocn = data(nf, c_ocn_recv, ip) + data(nf, c_ocn_send, ip) + net_water_ice_nh = data(nf, c_inh_recv, ip) + data(nf, c_inh_send, ip) + net_water_ice_sh = data(nf, c_ish_recv, ip) + data(nf, c_ish_send, ip) + net_water_glc = data(nf, c_glc_recv, ip) + data(nf, c_glc_send, ip) + net_water_tot = net_water_atm + net_water_lnd + net_water_rof + net_water_ocn + & + net_water_ice_nh + net_water_ice_sh + net_water_glc + + write(logunit,FA1r) budget_diags%fields(nf)%name,& + net_water_atm, net_water_lnd, net_water_rof, net_water_ocn, & + net_water_ice_nh, net_water_ice_sh, net_water_glc, net_water_tot + enddo + + ! Write out sum over all net heat budgets (sum over f_watr_beg -> f_watr_end) + + sum_net_water_atm = sum(data(f_watr_beg:f_watr_end, c_atm_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_atm_send, ip)) + sum_net_water_lnd = sum(data(f_watr_beg:f_watr_end, c_lnd_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_lnd_send, ip)) + sum_net_water_rof = sum(data(f_watr_beg:f_watr_end, c_rof_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_rof_send, ip)) + sum_net_water_ocn = sum(data(f_watr_beg:f_watr_end, c_ocn_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_ocn_send, ip)) + sum_net_water_ice_nh = sum(data(f_watr_beg:f_watr_end, c_inh_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_inh_send, ip)) + sum_net_water_ice_sh = sum(data(f_watr_beg:f_watr_end, c_ish_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_ish_send, ip)) + sum_net_water_glc = sum(data(f_watr_beg:f_watr_end, c_glc_recv, ip)) + & + sum(data(f_watr_beg:f_watr_end, c_glc_send, ip)) + sum_net_water_tot = sum_net_water_atm + sum_net_water_lnd + sum_net_water_rof + sum_net_water_ocn + & + sum_net_water_ice_nh + sum_net_water_ice_sh + sum_net_water_glc + + write(logunit,FA1r)' *SUM*',& + sum_net_water_atm, sum_net_water_lnd, sum_net_water_rof, sum_net_water_ocn, & + sum_net_water_ice_nh, sum_net_water_ice_sh, sum_net_water_glc, sum_net_water_tot + + ! write out net water water-isoptope budgets + + if ( flds_wiso ) then + + do is = 1, nisotopes + write(logunit,*) ' ' + write(logunit,FAH) subname,'NET '//isoname(is)//' WATER BUDGET (kg/m2s*1e6): period = ', & + trim(budget_diags%periods(ip)%name),': date = ',cdate,curr_tod + write(logunit,FA0r) ' atm',' lnd',' rof',' ocn',' ice nh',' ice sh',' glc',' *SUM* ' + do nf = iso0(is), isof(is) + net_water_atm = data(nf, c_atm_recv, ip) + data(nf, c_atm_send, ip) + net_water_lnd = data(nf, c_lnd_recv, ip) + data(nf, c_lnd_send, ip) + net_water_rof = data(nf, c_rof_recv, ip) + data(nf, c_rof_send, ip) + net_water_ocn = data(nf, c_ocn_recv, ip) + data(nf, c_ocn_send, ip) + net_water_ice_nh = data(nf, c_inh_recv, ip) + data(nf, c_inh_send, ip) + net_water_ice_sh = data(nf, c_ish_recv, ip) + data(nf, c_ish_send, ip) + net_water_glc = data(nf, c_glc_recv, ip) + data(nf, c_glc_send, ip) + net_water_tot = net_water_atm + net_water_lnd + net_water_rof + net_water_ocn + & + net_water_ice_nh + net_water_ice_sh + net_water_glc + + write(logunit,FA1r) budget_diags%fields(nf)%name,& + net_water_atm, net_water_lnd, net_water_rof, net_water_ocn, & + net_water_ice_nh, net_water_ice_sh, net_water_glc, net_water_tot + enddo + + sum_net_water_atm = sum(data(iso0(is):isof(is), c_atm_recv, ip)) + & + sum(data(iso0(is):isof(is), c_atm_send, ip)) + sum_net_water_lnd = sum(data(iso0(is):isof(is), c_lnd_recv, ip)) + & + sum(data(iso0(is):isof(is), c_lnd_send, ip)) + sum_net_water_rof = sum(data(iso0(is):isof(is), c_rof_recv, ip)) + & + sum(data(iso0(is):isof(is), c_rof_send, ip)) + sum_net_water_ocn = sum(data(iso0(is):isof(is), c_ocn_recv, ip)) + & + sum(data(iso0(is):isof(is), c_ocn_send, ip)) + sum_net_water_ice_nh = sum(data(iso0(is):isof(is), c_inh_recv, ip)) + & + sum(data(iso0(is):isof(is), c_inh_send, ip)) + sum_net_water_ice_sh = sum(data(iso0(is):isof(is), c_ish_recv, ip)) + & + sum(data(iso0(is):isof(is), c_ish_send, ip)) + sum_net_water_glc = sum(data(iso0(is):isof(is), c_glc_recv, ip)) + & + sum(data(iso0(is):isof(is), c_glc_send, ip)) + sum_net_water_tot = sum_net_water_atm + sum_net_water_lnd + sum_net_water_rof + & + sum_net_water_ocn + sum_net_water_ice_nh + sum_net_water_ice_sh + & + sum_net_water_glc + + write(logunit,FA1r)' *SUM*',& + sum_net_water_atm, sum_net_water_lnd, sum_net_water_rof, sum_net_water_ocn, & + sum_net_water_ice_nh, sum_net_water_ice_sh, sum_net_water_glc, sum_net_water_tot + end do + end if + + end subroutine med_diag_print_summary + + !=============================================================================== + + subroutine add_to_budget_diag(entries, index, name) + + ! input/output variablesn + type(budget_diag_type) , pointer :: entries(:) + integer , intent(out) :: index + character(len=*) , intent(in) :: name + + ! local variables + integer :: n + integer :: oldsize + logical :: found + type(budget_diag_type), pointer :: new_entries(:) + character(len=*), parameter :: subname='(add_to_budget_diag)' + !---------------------------------------------------------------------- + + if (associated(entries)) then + oldsize = size(entries) + found = .false. + do n= 1,oldsize + if (trim(name) == trim(entries(n)%name)) then + found = .true. + exit + end if + end do + else + oldsize = 0 + found = .false. + end if + index = oldsize + 1 + + ! create new entry if fldname is not in original list + + if (.not. found) then + + ! 1) allocate newfld to be size (one element larger than input flds) + allocate(new_entries(index)) + + ! 2) copy entries into first N-1 elements of new_entries + do n = 1,oldsize + new_entries(n)%name = entries(n)%name + end do + + ! 3) deallocate / nullify entries + if (oldsize > 0) then + deallocate(entries) + nullify(entries) + end if + entries => new_entries + + ! 4) point entries => new_entries + entries => new_entries + + ! 5) now update entries information for new entry + entries(index)%name = trim(name) + end if + + end subroutine add_to_budget_diag + +end module med_diag_mod diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 8deadfa1a..bbb588604 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -39,9 +39,16 @@ module med_internalstate_mod .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)) + shape(med_coupling_allowed)) ! med atm lnd ocn ice rof wav glc + type, public :: mesh_info_type + real(r8), pointer :: areas(:) + real(r8), pointer :: lats(:) + real(r8), pointer :: lons(:) + end type mesh_info_type + + ! private internal state to keep instance data type InternalStateStruct @@ -57,18 +64,18 @@ module med_internalstate_mod logical :: med_coupling_active(ncomps,ncomps) ! computes the active coupling ! Mediator vm - type(ESMF_VM) :: vm + type(ESMF_VM) :: vm ! Global nx,ny dimensions of input arrays (needed for mediator history output) - integer :: nx(ncomps), ny(ncomps) + integer :: nx(ncomps), ny(ncomps) ! Import/Export Scalars - character(len=CL) :: flds_scalar_name = '' - integer :: flds_scalar_num = 0 - integer :: flds_scalar_index_nx = 0 - integer :: flds_scalar_index_ny = 0 - integer :: flds_scalar_index_nextsw_cday = 0 - integer :: flds_scalar_index_precip_factor = 0 + character(len=CL) :: flds_scalar_name = '' + integer :: flds_scalar_num = 0 + integer :: flds_scalar_index_nx = 0 + integer :: flds_scalar_index_ny = 0 + integer :: flds_scalar_index_nextsw_cday = 0 + integer :: flds_scalar_index_precip_factor = 0 ! Import/export States and field bundles (the field bundles have the scalar fields removed) type(ESMF_State) :: NStateImp(ncomps) ! Import data from various component, on their grid @@ -98,6 +105,9 @@ module med_internalstate_mod type(ESMF_FieldBundle) :: FBImpAccum(ncomps,ncomps) ! Accumulator for various components import integer :: FBImpAccumCnt(ncomps) ! Accumulator counter for each FBImpAccum + ! Component Mesh info + type(mesh_info_type) :: mesh_info(ncomps) + end type InternalStateStruct type, public :: InternalState diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 2b21ac0bc..1763a123a 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -264,6 +264,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) factorList=factorList, & ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else if ((mapindex == mapconsf .or. mapindex == mapnstod_consf) .and. & .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapconsf,rc)) then call ESMF_FieldRegridStore(fldsrc, flddst, & @@ -277,6 +278,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else if ((mapindex == mapconsd .or. mapindex == mapnstod_consd) .and. & .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapconsd,rc)) then call ESMF_FieldRegridStore(fldsrc, flddst, & @@ -290,6 +292,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mappatch) then call ESMF_FieldRegridStore(fldsrc, flddst, & routehandle=is_local%wrap%RH(n1,n2,mapindex), & @@ -301,6 +304,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) factorList=factorList, & ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if ! consd_nstod method requires a second routehandle if ((mapindex == mapnstod .or. mapindex == mapnstod_consd .or. mapindex == mapnstod_consf) .and. & @@ -315,8 +319,8 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) ignoreDegenerate=.true., & unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if - if (chkerr(rc,__LINE__,u_FILE_u)) return if (rhprint_flag .and. mapindex /= mapnstod_consd .and. mapindex /= mapnstod_consf) then call NUOPC_Write(factorList, "array_med_"//trim(string)//"_consf.nc", rc) if (chkerr(rc,__LINE__,u_FILE_u)) return From 861e925985054002aec2b094703cbd2151b0227f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 21 Nov 2019 16:37:23 -0700 Subject: [PATCH 078/206] changes to get budgets working --- mediator/esmFldsExchange_cesm_mod.F90 | 1 - mediator/med.F90 | 3 +- mediator/med_diag_mod.F90 | 50 +++++++++++++++------------ mediator/med_phases_ocnalb_mod.F90 | 1 - mediator/med_phases_prep_glc_mod.F90 | 4 +-- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 2b1bc0997..8282308d3 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -700,7 +700,6 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) end if end if end do - deallocate(suffix) ! --------------------------------------------------------------------- diff --git a/mediator/med.F90 b/mediator/med.F90 index 3bc13cca7..812d8e4b6 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -24,6 +24,7 @@ module MED use med_methods_mod , only : FB_Copy => med_methods_FB_Copy 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 @@ -1757,6 +1758,7 @@ subroutine DataInitialize(gcomp, rc) is_local%wrap%FBExpAccumCnt(n1) = 0 ! Create mesh info data + write(6,*)'DEBUG: calling med_meshinfo_create for ',trim(compname(n1)) call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), is_local%wrap%mesh_info(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif @@ -2288,7 +2290,6 @@ end subroutine med_finalize !----------------------------------------------------------------------------- subroutine med_grid_write(grid, fileName, rc) - use ESMF, only : ESMF_Grid, ESMF_Array, ESMF_ArrayBundle use ESMF, only : ESMF_ArrayBundleCreate, ESMF_GridGet use ESMF, only : ESMF_GridGetCoord, ESMF_ArraySet, ESMF_ArrayBundleAdd diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 5fc59496f..b53a87b7e 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -15,17 +15,23 @@ module med_diag_mod ! salt flux ~ (kg/s)/m^2 !---------------------------------------------------------------------------- - use NUOPC - use ESMF + use NUOPC , only : NUOPC_CompAttributeGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR + 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 use shr_sys_mod , only : shr_sys_abort 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_constants_mod , only : R8, CS, CL + 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 shr_nuopc_methods_mod , only : fldchk => shr_nuopc_methods_FB_FldChk - use shr_nuopc_utils_mod , only : chkerr => shr_nuopc_utils_ChkErr - use shr_nuopc_methods_mod , only : FB_GetFldPtr => shr_nuopc_methods_FB_GetFldPtr - + use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk + use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr + use med_utils_mod , only : chkerr => med_utils_ChkErr + implicit none private @@ -695,7 +701,7 @@ subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, bu real(r8), pointer :: data(:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -733,7 +739,7 @@ subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & real(r8), pointer :: data(:,:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -893,7 +899,7 @@ subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -926,7 +932,7 @@ subroutine diag_lnd_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, lfrac, ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1038,7 +1044,7 @@ subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1071,7 +1077,7 @@ subroutine diag_rof_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, budget, ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1152,7 +1158,7 @@ subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) real(r8), pointer :: data(:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1220,7 +1226,7 @@ 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 ( fldchk(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', rc=rc)) then + 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 (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(ifrac) @@ -1300,7 +1306,7 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) real(r8), pointer :: data(:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1329,7 +1335,7 @@ subroutine diag_ocn_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, frac, b ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1437,7 +1443,7 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r real(r8), pointer :: data(:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1484,7 +1490,7 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1571,7 +1577,7 @@ subroutine med_phases_diag_ice_med2ice( gcomp, 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 ( fldchk(is_local%wrap%FBExp(compice), 'Fioo_q', rc=rc)) then + 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 (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(data) @@ -1617,7 +1623,7 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r real(r8), pointer :: data(:) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst @@ -1664,7 +1670,7 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( fldchk(FB, trim(fldname), rc=rc)) then + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 957641d5e..17d0571d8 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -227,7 +227,6 @@ subroutine med_phases_ocnalb_run(gcomp, rc) character(CL) :: cvalue character(CS) :: starttype ! config start type character(CL) :: runtype ! initial, continue, hybrid, branch - character(CL) :: aoflux_grid logical :: flux_albav ! flux avg option real(R8) :: nextsw_cday ! calendar day of next atm shortwave real(R8), pointer :: ofrac(:) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 4ab32080d..9d08f6465 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -275,7 +275,7 @@ subroutine med_phases_prep_glc_init(gcomp, 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) + call ESMF_MeshGet(lmesh_lnd, elemAreaArray=lArray, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return aream_l(:) = dataptr1d(:) call ESMF_ArrayDestroy(larray, rc=rc) @@ -287,7 +287,7 @@ subroutine med_phases_prep_glc_init(gcomp, 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) + call ESMF_MeshGet(lmesh_glc, elemAreaArray=lArray, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return aream_g(:) = dataptr1d(:) call ESMF_ArrayDestroy(larray, rc=rc) From a74c38918cfd6e96841bb22ba6e1b77caf963d41 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 10 Dec 2019 19:36:45 -0700 Subject: [PATCH 079/206] bug fixes and updates for cism --- cime_config/namelist_definition_drv.xml | 16 ++++++++++++++++ mediator/med_time_mod.F90 | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 02ce42833..a643ffe96 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -2161,6 +2161,22 @@ + + + + + + logical + flds + GLC_attributes + + False => CISM does not evolve but only sends initial information back to CTSM + + + $CISM_EVOLVE + + + diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 99d19cc4c..05ac6442f 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -48,7 +48,6 @@ module med_time_mod !=============================================================================== contains !=============================================================================== - subroutine med_time_alarmInit( clock, alarm, option, & opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc) From cf5da28b37ade1f0ddfecf412b9cf8d1f4247c83 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 5 Aug 2020 09:56:56 -0600 Subject: [PATCH 080/206] update of mvertens/newdiags --- cime_config/namelist_definition_drv.xml | 19 +- cime_config/runseq/runseq_general.py | 12 +- mediator/med.F90 | 82 ++- mediator/med_diag_mod.F90 | 35 +- mediator/med_phases_prep_lnd_mod.F90 | 10 +- mediator/med_phases_prep_ocn_mod.F90 | 2 + mediator/med_phases_prep_rof_mod.F90 | 7 +- mediator/med_time_mod.F90 | 876 +++++++++++++++++++++++- 8 files changed, 981 insertions(+), 62 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index a643ffe96..438e2b49f 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -2148,32 +2148,19 @@ - - logical - flds - ALLCOMP_attributes - - False => CISM does not evolve but only sends initial information back to CTSM - - - .false. - $CISM_EVOLVE - - - - logical flds - GLC_attributes + ALLCOMP_attributes False => CISM does not evolve but only sends initial information back to CTSM - $CISM_EVOLVE + .false. + $CISM_EVOLVE diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 8a7126ab5..06bc1cb23 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -20,6 +20,7 @@ def gen_runseq(case, coupling_times): cpl_seq_option = case.get_value('CPL_SEQ_OPTION') cpl_add_aoflux = case.get_value('ADD_AOFLUX_TO_RUNSEQ') coupling_mode = case.get_value('COUPLING_MODE') + diag_mode = case.get_value('BUDGETS') # It is assumed that if a component will be run it will send information to the mediator # so the flags run_xxx and xxx_to_med are redundant @@ -61,6 +62,7 @@ def gen_runseq(case, coupling_times): 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("MED med_phases_diag_glc" , run_glc and diag_mode) runseq.add_action("GLC -> MED :remapMethod=redist" , run_glc) #------------------ @@ -116,8 +118,12 @@ def gen_runseq(case, coupling_times): 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) runseq.add_action("LND -> MED :remapMethod=redist" , run_lnd) + 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_ice_ice2med" , run_ice and diag_mode) runseq.add_action("ICE -> MED :remapMethod=redist" , run_ice) 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) @@ -126,12 +132,16 @@ def gen_runseq(case, coupling_times): 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_ice_med2ice" , run_ice 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("MED med_phases_diag_ocn" , run_ocn and diag_mode and ocn_outer_loop) if coupling_mode == 'hafs': runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true" , run_ocn and ocn_outer_loop) else: diff --git a/mediator/med.F90 b/mediator/med.F90 index 812d8e4b6..a543afd8a 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -27,6 +27,7 @@ module MED 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_time_mod , only : set_stop_alarm => med_time_set_component_stop_alarm use med_utils_mod , only : memcheck => med_memcheck use med_internalstate_mod , only : InternalState use med_internalstate_mod , only : med_coupling_allowed, logunit, mastertask @@ -1758,8 +1759,9 @@ subroutine DataInitialize(gcomp, rc) is_local%wrap%FBExpAccumCnt(n1) = 0 ! Create mesh info data - write(6,*)'DEBUG: calling med_meshinfo_create for ',trim(compname(n1)) - call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), is_local%wrap%mesh_info(n1), rc=rc) + write(6,*)'DEBUG: calling med_meshinfo_create for ',n1,trim(compname(n1)) + call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), & + is_local%wrap%mesh_info(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif @@ -1792,6 +1794,7 @@ subroutine DataInitialize(gcomp, rc) endif enddo ! loop over n2 + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) enddo ! loop over n1 @@ -1885,7 +1888,6 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- ! Initialize route handles and required normalization field bunds !--------------------------------------- - call med_map_RouteHandles_init(gcomp, logunit, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -2250,6 +2252,9 @@ subroutine SetRunClock(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + call set_stop_alarm(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + first_time = .false. end if @@ -2269,6 +2274,77 @@ subroutine SetRunClock(gcomp, rc) end subroutine SetRunClock + !----------------------------------------------------------------------------- + !----------------------------------------------------------------------------- + + subroutine med_meshinfo_create(FB, mesh_info, rc) + + use ESMF , only : ESMF_Array, ESMF_ArrayCreate, ESMF_ArrayDestroy, ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_DistGrid, ESMF_FieldBundle, ESMF_FieldRegridGetArea, ESMF_FieldBundleGet + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO + use med_internalstate_mod , only : mesh_info_type + + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + type(mesh_info_type) , intent(inout) :: mesh_info + integer , intent(out) :: 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(:) + real(r8), pointer :: dataptr(:) + integer :: n, dimcount, fieldcount + character(len=*),parameter :: subnaame='(module_MED:med_meshinfo_create)' + !------------------------------------------------------------------------------- + + rc= ESMF_SUCCESS + + 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 + 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) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Allocate mesh_info data, we need a copy here because the FB may get reset later + 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 + print *,__FILE__,__LINE__,sum(mesh_info%areas) + + 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 + do n = 1,numOwnedElements + mesh_info%lons(n) = ownedElemCoords(2*n-1) + mesh_info%lats(n) = ownedElemCoords(2*n) + end do + deallocate(ownedElemCoords) + + end subroutine med_meshinfo_create + !----------------------------------------------------------------------------- subroutine med_finalize(gcomp, rc) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index b53a87b7e..ce0f28baf 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -23,6 +23,7 @@ module med_diag_mod use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet use ESMF , only : ESMF_Alarm, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging use ESMF , only : ESMF_FieldBundle + use ESMF , only : operator(==) use shr_sys_mod , only : shr_sys_abort 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 @@ -31,7 +32,7 @@ module med_diag_mod use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_utils_mod , only : chkerr => med_utils_ChkErr - + implicit none private @@ -344,7 +345,6 @@ subroutine med_diag_init(gcomp, rc) allocate(budget_counter (f_size , c_size , p_size)) ! counter, valid only on root pe allocate(budget_local_1d (f_size * c_size * p_size)) ! needed for ESMF_VMReduce call allocate(budget_global_1d(f_size * c_size * p_size)) ! needed for ESMF_VMReduce call - !------------------------------------------------------------------------------- ! Get config variables !------------------------------------------------------------------------------- @@ -593,7 +593,7 @@ subroutine med_phases_diag_atm(gcomp, rc) areas => is_local%wrap%mesh_info(compatm)%areas lats => is_local%wrap%mesh_info(compatm)%lats - + print *,__FILE__,__LINE__,compatm,sum(areas) !------------------------------- ! from atm to mediator !------------------------------- @@ -809,14 +809,13 @@ subroutine med_phases_diag_lnd( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(complnd)%areas - + print *,__FILE__,__LINE__,complnd,sum(areas) !------------------------------- ! from land to mediator !------------------------------- ic = c_lnd_recv ip = period_inst - do n = 1, size(lfrac) budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*lfrac(n) end do @@ -980,7 +979,7 @@ subroutine med_phases_diag_rof( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(comprof)%areas - + print *,__FILE__,__LINE__,comprof,sum(areas) !------------------------------- ! from river to mediator !------------------------------- @@ -1125,7 +1124,8 @@ subroutine med_phases_diag_glc( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compglc)%areas - + print *,__FILE__,__LINE__,compglc,sum(areas) + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) !------------------------------- ! from glc to mediator !------------------------------- @@ -1214,6 +1214,7 @@ subroutine med_phases_diag_ocn( gcomp, rc) sfrac(:) = ifrac(:) + ofrac(:) areas => is_local%wrap%mesh_info(compocn)%areas + print *,__FILE__,__LINE__,compocn,sum(areas) !------------------------------- ! from ocn to mediator @@ -1386,6 +1387,7 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) areas => is_local%wrap%mesh_info(compice)%areas lats => is_local%wrap%mesh_info(compice)%lats + print *,__FILE__,__LINE__,compice,sum(areas) ip = period_inst @@ -1555,6 +1557,7 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) areas => is_local%wrap%mesh_info(compice)%areas lats => is_local%wrap%mesh_info(compice)%lats + print *,__FILE__,__LINE__,compice,sum(areas) ip = period_inst @@ -1724,6 +1727,10 @@ subroutine med_phases_diag_print(gcomp, rc) integer :: f_size ! number of fields integer :: p_size ! number of period types real(r8), allocatable :: datagpr(:,:,:) + character(len=20) :: name + logical, save :: firstcall = .true. + integer :: yr,mon,day,sec ! time units + character(len=64) :: currtimestr character(*), parameter :: subName = '(med_phases_diag_print) ' ! ------------------------------------------------------------------ @@ -1734,7 +1741,7 @@ subroutine med_phases_diag_print(gcomp, rc) !------------------------------------------------------------------------------- ! Get clock and alarm info - call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + call ESMF_GridCompGet(gcomp, clock=clock, name=name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_ClockGet( clock, currTime=currTime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1770,8 +1777,16 @@ subroutine med_phases_diag_print(gcomp, rc) endif endif + if(mastertask) then + call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + + write(logunit,*) 'DEBUG print diags ',output_level, ip, period_inf + write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) + endif ! Currently output_level is limited to levels of 0,1,2, 3 - ! (see comment for print obtains at top) + ! (see comment for print options at top) if (output_level > 0) then if (.not. sumdone) then @@ -2085,7 +2100,7 @@ subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) if ( flds_wiso ) then do is = 1, nisotopes - ! heat budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh for water isotopes + ! heat budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh for water isotopes write(logunit,*) ' ' write(logunit,FAH) subname,trim(str)//isoname(is)//' WATER BUDGET (kg/m2s*1e6): period = ',& diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 203af93f6..c4152568b 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -108,6 +108,8 @@ subroutine med_phases_prep_lnd(gcomp, rc) call FB_getNumFlds(is_local%wrap%FBExp(complnd), trim(subname)//"FBexp(complnd)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,complnd,sum(is_local%wrap%mesh_info(complnd)%areas) + if (ncnt > 0) then !--------------------------------------- @@ -116,7 +118,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,complnd)) then - ! The following will map all atm->lnd, rof->lnd, and + ! The following will map all atm->lnd, rof->lnd, and ! glc->lnd only for Sg_icemask_field and Sg_icemask_coupled_fluxes call med_map_FB_Regrid_Norm( & fldsSrc=fldListFr(n1)%flds, & @@ -135,7 +137,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) !--- auto merges to create FBExp(complnd) !--------------------------------------- - ! The following will merge all fields in fldsSrc + ! The following will merge all fields in fldsSrc ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) call med_merge_auto(trim(compname(complnd)), & is_local%wrap%FBExp(complnd), & @@ -145,7 +147,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - !--- custom calculations + !--- custom calculations !--------------------------------------- ! The following is only done if glc->lnd coupling is active @@ -393,7 +395,7 @@ subroutine med_map_glc2lnd( gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_frac), fldptr1=frac_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(FBglc_ec, 'field_ec', fldptr2=frac_g_ec, rc=rc) + call FB_getFldPtr(FBglc_ec, 'field_ec', fldptr2=frac_g_ec, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! compute frac_g_ec call glc_get_fractional_icecov(ungriddedCount-1, topo_g, frac_g, frac_g_ec, logunit) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 69eab1a42..7e64805ca 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -215,6 +215,7 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -233,6 +234,7 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) end if endif + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index e484bcb26..44c9bf928 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -188,7 +188,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- !--- Count the number of fields outside of scalar data, if zero, then return !--------------------------------------- - + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) ! 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 @@ -252,6 +252,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) dataptr(:) = 0._r8 end if endif + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) !--------------------------------------- !--- auto merges to create FBExp(comprof) @@ -269,6 +270,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) is_local%wrap%FBImpAccum(:,comprof), & fldListTo(comprof), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExp(comprof), & @@ -285,6 +287,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) call FB_reset(is_local%wrap%FBImpAccum(complnd,complnd), value=czero, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) !--------------------------------------- !--- custom calculations !--------------------------------------- @@ -294,7 +297,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- endif - + print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 05ac6442f..681e66fda 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -22,22 +22,35 @@ module med_time_mod implicit none private ! default private + public :: med_time_clockInit ! initialize driver clock (assumes default calendar) public :: med_time_alarmInit ! initialize an alarm + public :: med_time_set_component_stop_alarm + + private :: med_time_timeInit + private :: med_time_date2ymd ! Clock and alarm options character(len=*), private, parameter :: & optNONE = "none" , & optNever = "never" , & optNSteps = "nsteps" , & + optNStep = "nstep" , & optNSeconds = "nseconds" , & + optNSecond = "nsecond" , & optNMinutes = "nminutes" , & + optNMinute = "nminute" , & optNHours = "nhours" , & + optNHour = "nhour" , & optNDays = "ndays" , & + optNDay = "nday" , & optNMonths = "nmonths" , & + optNMonth = "nmonth" , & optNYears = "nyears" , & + optNYear = "nyear" , & optMonthly = "monthly" , & optYearly = "yearly" , & optDate = "date" , & + optIfdays0 = "ifdays0" , & optGLCCouplingPeriod = "glc_coupling_period" ! Module data @@ -48,10 +61,435 @@ module med_time_mod !=============================================================================== contains !=============================================================================== + + subroutine med_time_clockInit(ensemble_driver, esmdriver, logunit, rc) + + ! input/output variables + type(ESMF_GridComp) :: ensemble_driver, esmdriver + integer, intent(in) :: logunit + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_VM) :: vm + type(ESMF_Time) :: StartTime ! Start time + type(ESMF_Time) :: RefTime ! Reference time + type(ESMF_Time) :: CurrTime ! Current time + type(ESMF_Time) :: StopTime ! Stop time + type(ESMF_Time) :: StopTime1 ! Stop time + type(ESMF_Time) :: StopTime2 ! Stop time + type(ESMF_Time) :: Clocktime ! Loop time + type(ESMF_TimeInterval) :: TimeStep ! Clock time-step + type(ESMF_Alarm) :: alarm_stop ! alarm + type(ESMF_Alarm) :: alarm_datestop ! alarm + integer :: ref_ymd ! Reference date (YYYYMMDD) + integer :: ref_tod ! Reference time of day (seconds) + integer :: start_ymd ! Start date (YYYYMMDD) + integer :: start_tod ! Start time of day (seconds) + integer :: curr_ymd ! Current ymd (YYYYMMDD) + integer :: curr_tod ! Current tod (seconds) + integer :: stop_n ! Number until stop + integer :: stop_ymd ! Stop date (YYYYMMDD) + integer :: stop_tod ! Stop time-of-day + character(CS) :: stop_option ! Stop option units + integer :: atm_cpl_dt ! Atmosphere coupling interval + integer :: lnd_cpl_dt ! Land coupling interval + integer :: ice_cpl_dt ! Sea-Ice coupling interval + integer :: ocn_cpl_dt ! Ocean coupling interval + integer :: glc_cpl_dt ! Glc coupling interval + integer :: rof_cpl_dt ! Runoff coupling interval + integer :: wav_cpl_dt ! Wav coupling interval + integer :: esp_cpl_dt ! Esp coupling interval + character(CS) :: glc_avg_period ! Glc avering coupling period + logical :: read_restart + character(len=CL) :: restart_file + character(len=CL) :: restart_pfile + character(len=CL) :: cvalue + integer :: dtime_drv ! time-step to use + integer :: yr, mon, day ! Year, month, day as integers + integer :: localPet ! local pet in esm domain + logical :: mastertask ! true if mastertask in esm domain + integer :: unitn ! unit number + integer :: ierr ! Return code + character(CL) :: tmpstr ! temporary + character(CS) :: inst_suffix + integer :: tmp(6) ! Array for Broadcast + logical :: isPresent + character(len=*), parameter :: subname = '(med_time_clockInit): ' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + + call ESMF_GridCompGet(esmdriver, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! We may want to get the ensemble_driver vm here instead so that + ! files are read on global task 0 only instead of each esm member task 0 + call ESMF_VMGet(vm, localPet=localPet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + mastertask = localPet == 0 + + !--------------------------------------------------------------------------- + ! Determine clock start time, reference time and current time + !--------------------------------------------------------------------------- + + curr_ymd = 0 + curr_tod = 0 + + call NUOPC_CompAttributeGet(esmdriver, name="start_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) start_ymd + call NUOPC_CompAttributeGet(esmdriver, name="start_tod", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) start_tod + + call NUOPC_CompAttributeGet(esmdriver, name="ref_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ref_ymd + call NUOPC_CompAttributeGet(esmdriver, name="ref_tod", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ref_tod + + call NUOPC_CompAttributeGet(esmdriver, name='read_restart', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) read_restart + + if (read_restart) then + + call NUOPC_CompAttributeGet(esmdriver, name='restart_file', value=restart_file, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--- read rpointer if restart_file is set to str_undefined --- + if (trim(restart_file) == 'str_undefined') then + + ! Error check on restart_pfile + call NUOPC_CompAttributeGet(esmdriver, name="restart_pfile", value=restart_pfile, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompAttributeGet(esmdriver, name="inst_suffix", isPresent=isPresent, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if(isPresent) then + call NUOPC_CompAttributeGet(esmdriver, name="inst_suffix", value=inst_suffix, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + inst_suffix = "" + endif + if ( len_trim(restart_pfile) == 0 ) then + call ESMF_LogWrite(trim(subname)//' ERROR restart_pfile must be defined', & + ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) + rc = ESMF_FAILURE + return + end if + restart_pfile = trim(restart_pfile)//inst_suffix + if (mastertask) then + call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), & + ESMF_LOGMSG_INFO) + open(newunit=unitn, file=restart_pfile, form='FORMATTED', status='old',iostat=ierr) + if (ierr < 0) then + rc = ESMF_FAILURE + call ESMF_LogWrite(trim(subname)//' ERROR rpointer file open returns error', & + ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) + return + end if + read(unitn,'(a)', iostat=ierr) restart_file + if (ierr < 0) then + rc = ESMF_FAILURE + call ESMF_LogWrite(trim(subname)//' ERROR rpointer file read returns error', & + ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) + return + end if + close(unitn) + call ESMF_LogWrite(trim(subname)//" read driver restart from file = "//trim(restart_file), & + ESMF_LOGMSG_INFO) + endif + endif + if (mastertask) then + call med_time_read_restart(restart_file, & + start_ymd, start_tod, ref_ymd, ref_tod, curr_ymd, curr_tod, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif + tmp(1) = start_ymd + tmp(2) = start_tod + tmp(3) = ref_ymd + tmp(4) = ref_tod + tmp(5) = curr_ymd + tmp(6) = curr_tod + call ESMF_VMBroadcast(vm, tmp, 6, 0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + start_ymd = tmp(1) + start_tod = tmp(2) + ref_ymd = tmp(3) + ref_tod = tmp(4) + curr_ymd = tmp(5) + curr_tod = tmp(6) + end if + + if ( ref_ymd == 0 ) then + ref_ymd = start_ymd + ref_tod = start_tod + endif + if ( curr_ymd == 0 ) then + curr_ymd = start_ymd + curr_tod = start_tod + endif + + ! Determine start time (THE FOLLOWING ASSUMES THAT THE DEFAULT CALENDAR IS SET in the driver) + + call med_time_date2ymd(start_ymd, yr, mon, day) + call ESMF_TimeSet( StartTime, yy=yr, mm=mon, dd=day, s=start_tod, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if(mastertask .or. dbug_flag > 2) then + write(tmpstr,'(i10)') start_ymd + call ESMF_LogWrite(trim(subname)//': driver start_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver start_ymd: '// trim(tmpstr) + write(tmpstr,'(i10)') start_tod + call ESMF_LogWrite(trim(subname)//': driver start_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver start_tod: '// trim(tmpstr) + endif + + ! Determine reference time + call med_time_date2ymd(ref_ymd, yr, mon, day) + call ESMF_TimeSet( RefTime, yy=yr, mm=mon, dd=day, s=ref_tod, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if(mastertask .or. dbug_flag > 2) then + write(tmpstr,'(i10)') ref_ymd + call ESMF_LogWrite(trim(subname)//': driver ref_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver ref_ymd: '// trim(tmpstr) + write(tmpstr,'(i10)') ref_tod + call ESMF_LogWrite(trim(subname)//': driver ref_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver ref_tod: '// trim(tmpstr) + endif + ! Determine current time + call med_time_date2ymd(curr_ymd, yr, mon, day) + call ESMF_TimeSet( CurrTime, yy=yr, mm=mon, dd=day, s=curr_tod, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if(mastertask .or. dbug_flag > 2) then + write(tmpstr,'(i10)') curr_ymd + call ESMF_LogWrite(trim(subname)//': driver curr_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver curr_ymd: '// trim(tmpstr) + write(tmpstr,'(i10)') curr_tod + call ESMF_LogWrite(trim(subname)//': driver curr_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver curr_tod: '// trim(tmpstr) + endif + + !--------------------------------------------------------------------------- + ! Determine driver clock timestep + ! This is the minimum of all of the component coupling time steps + !--------------------------------------------------------------------------- + + call NUOPC_CompAttributeGet(esmdriver, name="atm_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) atm_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="lnd_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) lnd_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="ice_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ice_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="ocn_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ocn_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="glc_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) glc_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="rof_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) rof_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="wav_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) wav_cpl_dt + + call NUOPC_CompAttributeGet(esmdriver, name="glc_avg_period", value=glc_avg_period, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) glc_avg_period + + ! TODO: for now - this is not in the namelist_definition_drv.xml file + ! call NUOPC_CompAttributeGet(esmdriver, name="esp_cpl_dt", value=cvalue, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! read(cvalue,*) esp_cpl_dt + esp_cpl_dt = 9999 + + dtime_drv = 9999 + dtime_drv = min(dtime_drv, atm_cpl_dt) + dtime_drv = min(dtime_drv, lnd_cpl_dt) + dtime_drv = min(dtime_drv, ocn_cpl_dt) + dtime_drv = min(dtime_drv, ice_cpl_dt) + dtime_drv = min(dtime_drv, glc_cpl_dt) + dtime_drv = min(dtime_drv, rof_cpl_dt) + dtime_drv = min(dtime_drv, wav_cpl_dt) + dtime_drv = min(dtime_drv, esp_cpl_dt) + if(mastertask .or. dbug_flag > 2) then + write(tmpstr,'(i10)') dtime_drv + call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) + write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr) + endif + call ESMF_TimeIntervalSet( TimeStep, s=dtime_drv, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------------------------------------------------- + ! Create the driver clock with an artificial stop time + !--------------------------------------------------------------------------- + + ! Create the clock + clock = ESMF_ClockCreate(TimeStep, StartTime, refTime=RefTime, name='ESMF Driver Clock', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Advance the clock to the current time (in case of a restart) + call ESMF_ClockGet(clock, currTime=clocktime, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do while( clocktime < CurrTime) + call ESMF_ClockAdvance( clock, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet( clock, currTime=clocktime, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + + ! Set the driver gridded component clock to the created clock + call ESMF_GridCompSet(esmdriver, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------------------- + ! Set driver clock stop time + !------------------------------- + + call NUOPC_CompAttributeGet(esmdriver, name="stop_option", value=stop_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(esmdriver, name="stop_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_n + call NUOPC_CompAttributeGet(esmdriver, name="stop_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_ymd + call NUOPC_CompAttributeGet(esmdriver, name="stop_tod", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_tod + if ( stop_ymd < 0) then + stop_ymd = 99990101 + stop_tod = 0 + endif + if(mastertask .or. dbug_flag > 2) then + write(tmpstr,'(i10)') stop_ymd + call ESMF_LogWrite(trim(subname)//': driver stop_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver stop_ymd: '// trim(tmpstr) + write(tmpstr,'(i10)') stop_tod + call ESMF_LogWrite(trim(subname)//': driver stop_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) + write(logunit,*) trim(subname)//': driver stop_tod: '// trim(tmpstr) + endif + call med_time_alarmInit(clock, & + alarm = alarm_stop, & + option = stop_option, & + opt_n = stop_n, & + opt_ymd = stop_ymd, & + opt_tod = stop_tod, & + RefTime = CurrTime, & + alarmname = 'alarm_stop', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call med_time_alarmInit(clock, & + alarm = alarm_datestop, & + option = optDate, & + opt_ymd = stop_ymd, & + opt_tod = stop_tod, & + RefTime = StartTime, & + alarmname = 'alarm_datestop', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_AlarmGet(alarm_stop, RingTime=StopTime1, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_AlarmGet(alarm_datestop, RingTime=StopTime2, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (StopTime2 < StopTime1) then + StopTime = StopTime2 + else + StopTime = StopTime1 + endif + + call ESMF_ClockSet(clock, StopTime=StopTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Create the ensemble driver clock + TimeStep = StopTime-ClockTime + clock = ESMF_ClockCreate(TimeStep, ClockTime, StopTime=StopTime, & + refTime=RefTime, name='ESMF ensemble Driver Clock', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_GridCompSet(ensemble_driver, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + + + end subroutine med_time_clockInit + +!=============================================================================== + + subroutine med_time_set_component_stop_alarm(gcomp, rc) + + use ESMF , only : ESMF_GridComp, ESMF_Alarm, ESMF_Clock, ESMF_ClockGet + use ESMF , only : ESMF_AlarmSet + use NUOPC , only : NUOPC_CompAttributeGet + use NUOPC_Model , only : NUOPC_ModelGet + + ! input/output variables + type(ESMF_gridcomp) :: gcomp + integer, intent(out) :: rc + + ! local variables + character(len=256) :: stop_option ! Stop option units + integer :: stop_n ! Number until stop interval + integer :: stop_ymd ! Stop date (YYYYMMDD) + type(ESMF_ALARM) :: stop_alarm + character(len=256) :: cvalue + type(ESMF_Clock) :: mclock + type(ESMF_Time) :: mCurrTime + !----------------------------------------------------------- + + !---------------- + ! Stop alarm + !---------------- + call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ClockGet(mclock, CurrTime=mCurrTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_n + + call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_ymd + call med_time_alarmInit(mclock, stop_alarm, stop_option, & + opt_n = stop_n, & + opt_ymd = stop_ymd, & + RefTime = mcurrTime, & + alarmname = 'alarm_stop', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_AlarmSet(stop_alarm, clock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end subroutine med_time_set_component_stop_alarm + +!=============================================================================== + subroutine med_time_alarmInit( clock, alarm, option, & opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc) - ! Setup an alarm in a clock + ! !DESCRIPTION: Setup an alarm in a clock ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm ! time. If you send an arbitrary but proper ringtime from the ! past and the ring interval, the alarm will always go off on the @@ -112,8 +550,24 @@ subroutine med_time_alarmInit( clock, alarm, option, & ! Get calendar from clock call ESMF_ClockGet(clock, calendar=cal) - ! Error checks - if (trim(option) == optdate) then + ! Determine inputs for call to create alarm + selectcase (trim(option)) + + case (optNONE) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optNever) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optDate) if (.not. present(opt_ymd)) then call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE @@ -124,49 +578,93 @@ subroutine med_time_alarmInit( clock, alarm, option, & rc = ESMF_FAILURE return end if - else if (trim(option) == optNSteps .or. & - trim(option) == optNSeconds .or. & - trim(option) == optNMinutes .or. & - trim(option) == optNHours .or. & - trim(option) == optNDays .or. & - trim(option) == optNMonths .or. & - trim(option) == optNYears) then + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_time_timeInit(NextAlarm, lymd, cal, tod=ltod, desc="optDate") + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + + case (optIfdays0) + if (.not. present(opt_ymd)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if if (.not.present(opt_n)) then call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if - if (opt_n <= 0) then + if (opt_n <= 0) then call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if - end if - - ! Determine inputs for call to create alarm - selectcase (trim(option)) - - case (optNONE) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=opt_n, s=0, calendar=cal, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. + update_nextalarm = .true. - case (optNever) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + case (optNSteps) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. - case (optNSteps) + case (optNStep) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNSeconds) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNSecond) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -174,22 +672,126 @@ subroutine med_time_alarmInit( clock, alarm, option, & case (optNMinutes) call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNMinute) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNHours) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNHour) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNDays) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNDay) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNMonths) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNMonth) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -203,6 +805,32 @@ subroutine med_time_alarmInit( clock, alarm, option, & update_nextalarm = .true. case (optNYears) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + AlarmInterval = AlarmInterval * opt_n + update_nextalarm = .true. + + case (optNYear) + if (.not.present(opt_n)) then + call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + if (opt_n <= 0) then + call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -242,4 +870,200 @@ subroutine med_time_alarmInit( clock, alarm, option, & end subroutine med_time_alarmInit + !=============================================================================== + + subroutine med_time_timeInit( Time, ymd, cal, tod, desc, logunit ) + + ! Create the ESMF_Time object corresponding to the given input time, given in + ! YMD (Year Month Day) and TOD (Time-of-day) format. + ! Set the time by an integer as YYYYMMDD and integer seconds in the day + + ! input/output parameters: + type(ESMF_Time) , intent(inout) :: Time ! ESMF time + integer , intent(in) :: ymd ! year, month, day YYYYMMDD + type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar + integer , intent(in), optional :: tod ! time of day in seconds + character(len=*) , intent(in), optional :: desc ! description of time to set + integer , intent(in), optional :: logunit + + ! local variables + integer :: yr, mon, day ! Year, month, day as integers + integer :: ltod ! local tod + character(len=256) :: ldesc ! local desc + integer :: rc ! return code + character(len=*), parameter :: subname = '(med_time_m_ETimeInit) ' + !------------------------------------------------------------------------------- + + ltod = 0 + if (present(tod)) ltod = tod + ldesc = '' + if (present(desc)) ldesc = desc + + if ( (ymd < 0) .or. (ltod < 0) .or. (ltod > SecPerDay) )then + if (present(logunit)) then + write(logunit,*) subname//': ERROR yymmdd is a negative number or '// & + 'time-of-day out of bounds', ymd, ltod + end if + call ESMF_LogWrite( subname//'ERROR: Bad input' , ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + + call med_time_date2ymd (ymd,yr,mon,day) + + call ESMF_TimeSet( Time, yy=yr, mm=mon, dd=day, s=ltod, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_time_timeInit + + !=============================================================================== + + subroutine med_time_date2ymd (date, year, month, day) + + ! input/output variables + integer, intent(in) :: date ! coded-date (yyyymmdd) + integer, intent(out) :: year,month,day ! calendar year,month,day + + ! local variables + integer :: tdate ! temporary date + character(*),parameter :: subName = "(med_time_date2ymd)" + !------------------------------------------------------------------------------- + + tdate = abs(date) + year = int(tdate/10000) + if (date < 0) then + year = -year + end if + month = int( mod(tdate,10000)/ 100) + day = mod(tdate, 100) + + end subroutine med_time_date2ymd + + !=============================================================================== + + subroutine med_time_read_restart(restart_file, & + start_ymd, start_tod, ref_ymd, ref_tod, curr_ymd, curr_tod, rc) + + use netcdf , only : nf90_open, nf90_nowrite, nf90_noerr + use netcdf , only : nf90_inq_varid, nf90_get_var, nf90_close + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO + + ! input/output variables + character(len=*), intent(in) :: restart_file + integer, intent(out) :: ref_ymd ! Reference date (YYYYMMDD) + integer, intent(out) :: ref_tod ! Reference time of day (seconds) + integer, intent(out) :: start_ymd ! Start date (YYYYMMDD) + integer, intent(out) :: start_tod ! Start time of day (seconds) + integer, intent(out) :: curr_ymd ! Current ymd (YYYYMMDD) + integer, intent(out) :: curr_tod ! Current tod (seconds) + integer, intent(out) :: rc + + ! local variables + integer :: status, ncid, varid ! netcdf stuff + character(CL) :: tmpstr ! temporary + character(len=*), parameter :: subname = "(med_time_read_restart)" + !---------------------------------------------------------------- + + ! use netcdf here since it's serial + status = nf90_open(restart_file, NF90_NOWRITE, ncid) + if (status /= nf90_NoErr) then + print *,__FILE__,__LINE__,trim(restart_file) + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_open', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + endif + status = nf90_inq_varid(ncid, 'start_ymd', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid start_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, start_ymd) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var start_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_inq_varid(ncid, 'start_tod', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid start_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, start_tod) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var start_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_inq_varid(ncid, 'ref_ymd', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid ref_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, ref_ymd) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var ref_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_inq_varid(ncid, 'ref_tod', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid ref_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, ref_tod) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var ref_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_inq_varid(ncid, 'curr_ymd', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid curr_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, curr_ymd) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var curr_ymd', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_inq_varid(ncid, 'curr_tod', varid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid curr_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_get_var(ncid, varid, curr_tod) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var curr_tod', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + status = nf90_close(ncid) + if (status /= nf90_NoErr) then + call ESMF_LogWrite(trim(subname)//' ERROR: nf90_close', ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return + end if + + write(tmpstr,*) trim(subname)//" read start_ymd = ",start_ymd + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + write(tmpstr,*) trim(subname)//" read start_tod = ",start_tod + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + write(tmpstr,*) trim(subname)//" read ref_ymd = ",ref_ymd + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + write(tmpstr,*) trim(subname)//" read ref_tod = ",ref_tod + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + write(tmpstr,*) trim(subname)//" read curr_ymd = ",curr_ymd + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + write(tmpstr,*) trim(subname)//" read curr_tod = ",curr_tod + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + + end subroutine med_time_read_restart + end module med_time_mod From 9f697d538e81e4057caaa8ebdd5c0760693ad853 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 5 Aug 2020 17:11:53 -0600 Subject: [PATCH 081/206] budget development --- cime_config/runseq/runseq_general.py | 4 +- mediator/med.F90 | 3 -- mediator/med_diag_mod.F90 | 68 ++++++++++++---------------- mediator/med_phases_prep_lnd_mod.F90 | 2 - mediator/med_phases_prep_ocn_mod.F90 | 2 - mediator/med_phases_prep_rof_mod.F90 | 5 -- mediator/med_time_mod.F90 | 1 - 7 files changed, 30 insertions(+), 55 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 06bc1cb23..ebf11cbab 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -134,8 +134,6 @@ def gen_runseq(case, coupling_times): 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_ice_med2ice" , run_ice 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) #------------------ @@ -146,6 +144,8 @@ def gen_runseq(case, coupling_times): 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("MED med_phases_diag_accum" , diag_mode) + runseq.add_action("MED med_phases_diag_print" , diag_mode) #------------------ runseq.leave_time_loop(ocn_outer_loop) diff --git a/mediator/med.F90 b/mediator/med.F90 index a543afd8a..706d3a956 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1759,7 +1759,6 @@ subroutine DataInitialize(gcomp, rc) is_local%wrap%FBExpAccumCnt(n1) = 0 ! Create mesh info data - write(6,*)'DEBUG: calling med_meshinfo_create for ',n1,trim(compname(n1)) call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), & is_local%wrap%mesh_info(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1794,7 +1793,6 @@ subroutine DataInitialize(gcomp, rc) endif enddo ! loop over n2 - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) enddo ! loop over n1 @@ -2328,7 +2326,6 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return mesh_info%areas = dataptr - print *,__FILE__,__LINE__,sum(mesh_info%areas) allocate(mesh_info%lats(numOwnedElements)) allocate(mesh_info%lons(numOwnedElements)) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index ce0f28baf..cfe498463 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -22,7 +22,7 @@ module med_diag_mod 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 + use ESMF , only : ESMF_FieldBundle, ESMF_AlarmRingerOff use ESMF , only : operator(==) use shr_sys_mod , only : shr_sys_abort use shr_const_mod , only : shr_const_rearth, shr_const_pi, shr_const_latice @@ -217,9 +217,8 @@ module med_diag_mod real(r8), allocatable :: budget_local (:,:,:) ! local sum, valid on all pes real(r8), allocatable :: budget_global (:,:,:) ! global sum, valid only on root pe real(r8), allocatable :: budget_counter(:,:,:) ! counter, valid only on root pe - real(r8), allocatable :: budget_local_1d(:) ! needed for ESMF_VMReduce call real(r8), allocatable :: budget_global_1d(:) ! needed for ESMF_VMReduce call - + type(ESMF_Time) :: prevtime ! make sure diags are only printed once in a given model time character(len=*), parameter :: modName = "(med_diag) " character(len=*), parameter :: u_FILE_u = & @@ -244,6 +243,8 @@ subroutine med_diag_init(gcomp, rc) integer :: c_size ! number of component send/recvs integer :: f_size ! number of fields integer :: p_size ! number of period types + type(ESMF_Clock) :: clock + ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -343,7 +344,6 @@ subroutine med_diag_init(gcomp, rc) allocate(budget_local (f_size , c_size , p_size)) ! local sum, valid on all pes allocate(budget_global (f_size , c_size , p_size)) ! global sum, valid only on root pe allocate(budget_counter (f_size , c_size , p_size)) ! counter, valid only on root pe - allocate(budget_local_1d (f_size * c_size * p_size)) ! needed for ESMF_VMReduce call allocate(budget_global_1d(f_size * c_size * p_size)) ! needed for ESMF_VMReduce call !------------------------------------------------------------------------------- ! Get config variables @@ -373,6 +373,13 @@ subroutine med_diag_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) budget_print_ltend + ! Get time info + call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ClockGet( clock, currTime=prevTime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end subroutine med_diag_init !=============================================================================== @@ -485,6 +492,9 @@ subroutine med_phases_diag_accum(gcomp, rc) budget_local(:,:,ip) = budget_local(:,:,ip) + budget_local(:,:,period_inst) enddo budget_counter(:,:,:) = budget_counter(:,:,:) + 1.0_r8 + print *,__FILE__,__LINE__,budget_counter(f_area,:,1) + + write(logunit,*) 'DEBUG diag_accum',budget_counter(1,1,1) end subroutine med_phases_diag_accum @@ -502,7 +512,6 @@ subroutine med_diag_sum_master(gcomp, rc) ! local variables type(ESMF_VM) :: vm - integer :: nf,nc,np,n integer :: count integer :: c_size ! number of component send/recvs integer :: f_size ! number of fields @@ -519,31 +528,12 @@ subroutine med_diag_sum_master(gcomp, rc) c_size = size(budget_diags%comps) p_size = size(budget_diags%periods) - n = 0 - do np = 1,p_size - do nc = 1,c_size - do nf = 1,f_size - n = n + 1 - budget_local_1d(n) = budget_local(nf,nc,np) - end do - end do - end do - !budget_local_1d = reshape(budget_local,(/1/)) - - count = size(budget_global_1d) + count = size(budget_global) budget_global_1d(:) = 0.0_r8 - call ESMF_VMReduce(vm, budget_local_1d, budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) + call ESMF_VMReduce(vm, reshape(budget_local,(/count/)) , budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - n = 0 - do np = 1,p_size - do nc = 1,c_size - do nf = 1,f_size - n = n + 1 - budget_global(nf,nc,np) = budget_global_1d(n) - end do - end do - end do + budget_global = reshape(budget_global_1d,(/f_size,c_size,p_size/)) budget_local(:,:,:) = 0.0_r8 @@ -593,7 +583,7 @@ subroutine med_phases_diag_atm(gcomp, rc) areas => is_local%wrap%mesh_info(compatm)%areas lats => is_local%wrap%mesh_info(compatm)%lats - print *,__FILE__,__LINE__,compatm,sum(areas) + !------------------------------- ! from atm to mediator !------------------------------- @@ -809,7 +799,7 @@ subroutine med_phases_diag_lnd( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(complnd)%areas - print *,__FILE__,__LINE__,complnd,sum(areas) + !------------------------------- ! from land to mediator !------------------------------- @@ -979,7 +969,7 @@ subroutine med_phases_diag_rof( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(comprof)%areas - print *,__FILE__,__LINE__,comprof,sum(areas) + !------------------------------- ! from river to mediator !------------------------------- @@ -1124,8 +1114,7 @@ subroutine med_phases_diag_glc( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compglc)%areas - print *,__FILE__,__LINE__,compglc,sum(areas) - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) + !------------------------------- ! from glc to mediator !------------------------------- @@ -1214,7 +1203,6 @@ subroutine med_phases_diag_ocn( gcomp, rc) sfrac(:) = ifrac(:) + ofrac(:) areas => is_local%wrap%mesh_info(compocn)%areas - print *,__FILE__,__LINE__,compocn,sum(areas) !------------------------------- ! from ocn to mediator @@ -1222,7 +1210,6 @@ subroutine med_phases_diag_ocn( gcomp, rc) ip = period_inst ic = c_ocn_recv - do n = 1,size(ofrac) budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*ofrac(n) end do @@ -1387,7 +1374,6 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) areas => is_local%wrap%mesh_info(compice)%areas lats => is_local%wrap%mesh_info(compice)%lats - print *,__FILE__,__LINE__,compice,sum(areas) ip = period_inst @@ -1557,7 +1543,6 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) areas => is_local%wrap%mesh_info(compice)%areas lats => is_local%wrap%mesh_info(compice)%lats - print *,__FILE__,__LINE__,compice,sum(areas) ip = period_inst @@ -1748,6 +1733,8 @@ subroutine med_phases_diag_print(gcomp, rc) call ESMF_TimeGet( currTime, yy=curr_year, mm=curr_mon, dd=curr_day, s=curr_tod, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return cdate = curr_year*10000 + curr_mon*100 + curr_day + if( currtime == prevtime )return + prevtime = currtime sumdone = .false. do ip = 1,size(budget_diags%periods) @@ -1774,6 +1761,8 @@ subroutine med_phases_diag_print(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ESMF_AlarmIsRinging(stop_alarm, rc=rc)) then output_level = max(output_level, budget_print_ltend) + call ESMF_AlarmRingerOff( stop_alarm, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return endif endif @@ -1781,8 +1770,6 @@ subroutine med_phases_diag_print(gcomp, rc) call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec - - write(logunit,*) 'DEBUG print diags ',output_level, ip, period_inf write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) endif ! Currently output_level is limited to levels of 0,1,2, 3 @@ -1791,7 +1778,6 @@ subroutine med_phases_diag_print(gcomp, rc) if (output_level > 0) then if (.not. sumdone) then ! Some budgets will be printed for this period type - ! Determine sums if not already done call med_diag_sum_master(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1812,7 +1798,9 @@ subroutine med_phases_diag_print(gcomp, rc) if ( flds_wiso ) then datagpr(iso0(1):isof(nisotopes),:,:) = datagpr(iso0(1):isof(nisotopes),:,:) * 1.0e6_r8 end if - datagpr(:,:,:) = datagpr/budget_counter(:,:,:) + datagpr(:,:,:) = datagpr(:,:,:)/budget_counter(:,:,:) + print *,__FILE__,__LINE__,datagpr(f_area,:,1) + print *,__FILE__,__LINE__,budget_counter(f_area,:,1) ! Write diagnostic tables to logunit (mastertask only) if (output_level >= 3) then diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index c4152568b..81a653db3 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -108,8 +108,6 @@ subroutine med_phases_prep_lnd(gcomp, rc) call FB_getNumFlds(is_local%wrap%FBExp(complnd), trim(subname)//"FBexp(complnd)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,complnd,sum(is_local%wrap%mesh_info(complnd)%areas) - if (ncnt > 0) then !--------------------------------------- diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 7e64805ca..69eab1a42 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -215,7 +215,6 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) ! Count the number of fields outside of scalar data, if zero, then return call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -234,7 +233,6 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) end if endif - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 44c9bf928..158765207 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -188,7 +188,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- !--- Count the number of fields outside of scalar data, if zero, then return !--------------------------------------- - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) ! 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 @@ -252,7 +251,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) dataptr(:) = 0._r8 end if endif - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) !--------------------------------------- !--- auto merges to create FBExp(comprof) @@ -270,7 +268,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) is_local%wrap%FBImpAccum(:,comprof), & fldListTo(comprof), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExp(comprof), & @@ -287,7 +284,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) call FB_reset(is_local%wrap%FBImpAccum(complnd,complnd), value=czero, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) !--------------------------------------- !--- custom calculations !--------------------------------------- @@ -297,7 +293,6 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- endif - print *,__FILE__,__LINE__,sum(is_local%wrap%mesh_info(3)%areas) if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 681e66fda..48eec59b0 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -967,7 +967,6 @@ subroutine med_time_read_restart(restart_file, & ! use netcdf here since it's serial status = nf90_open(restart_file, NF90_NOWRITE, ncid) if (status /= nf90_NoErr) then - print *,__FILE__,__LINE__,trim(restart_file) call ESMF_LogWrite(trim(subname)//' ERROR: nf90_open', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return From fb8b42d3ad738d528f40175990bde0725a23181e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 10 Aug 2020 10:00:16 -0600 Subject: [PATCH 082/206] remove unused prevtime --- mediator/med_diag_mod.F90 | 118 +++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 64 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index cfe498463..15061f70d 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -23,7 +23,6 @@ module med_diag_mod 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 : operator(==) use shr_sys_mod , only : shr_sys_abort 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 @@ -218,7 +217,6 @@ module med_diag_mod real(r8), allocatable :: budget_global (:,:,:) ! global sum, valid only on root pe real(r8), allocatable :: budget_counter(:,:,:) ! counter, valid only on root pe real(r8), allocatable :: budget_global_1d(:) ! needed for ESMF_VMReduce call - type(ESMF_Time) :: prevtime ! make sure diags are only printed once in a given model time character(len=*), parameter :: modName = "(med_diag) " character(len=*), parameter :: u_FILE_u = & @@ -243,8 +241,6 @@ subroutine med_diag_init(gcomp, rc) integer :: c_size ! number of component send/recvs integer :: f_size ! number of fields integer :: p_size ! number of period types - type(ESMF_Clock) :: clock - ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -373,13 +369,6 @@ subroutine med_diag_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) budget_print_ltend - ! Get time info - call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ClockGet( clock, currTime=prevTime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end subroutine med_diag_init !=============================================================================== @@ -492,7 +481,6 @@ subroutine med_phases_diag_accum(gcomp, rc) budget_local(:,:,ip) = budget_local(:,:,ip) + budget_local(:,:,period_inst) enddo budget_counter(:,:,:) = budget_counter(:,:,:) + 1.0_r8 - print *,__FILE__,__LINE__,budget_counter(f_area,:,1) write(logunit,*) 'DEBUG diag_accum',budget_counter(1,1,1) @@ -533,7 +521,14 @@ subroutine med_diag_sum_master(gcomp, rc) call ESMF_VMReduce(vm, reshape(budget_local,(/count/)) , budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,budget_local(f_area,c_ocn_asend,period_inst) + print *,__FILE__,__LINE__,budget_local(f_area,c_ocn_asend,:) + budget_global = reshape(budget_global_1d,(/f_size,c_size,p_size/)) + if(mastertask) then + print *,__FILE__,__LINE__,budget_global(f_area,c_ocn_asend,:) + endif + budget_local(:,:,:) = 0.0_r8 @@ -1733,8 +1728,10 @@ subroutine med_phases_diag_print(gcomp, rc) call ESMF_TimeGet( currTime, yy=curr_year, mm=curr_mon, dd=curr_day, s=curr_tod, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return cdate = curr_year*10000 + curr_mon*100 + curr_day - if( currtime == prevtime )return - prevtime = currtime + if(mastertask) then + write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') curr_year,'-',curr_mon,'-',curr_day,'-',curr_tod + write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) + endif sumdone = .false. do ip = 1,size(budget_diags%periods) @@ -1765,62 +1762,55 @@ subroutine med_phases_diag_print(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif endif + if (output_level > 0) exit + enddo ! ip = 1, period_types + + ! Currently output_level is limited to levels of 0,1,2, 3 + ! (see comment for print options at top) - if(mastertask) then - call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (output_level > 0) then + if (.not. sumdone) then + ! Some budgets will be printed for this period type + ! Determine sums if not already done + call med_diag_sum_master(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec - write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) - endif - ! Currently output_level is limited to levels of 0,1,2, 3 - ! (see comment for print options at top) - - if (output_level > 0) then - if (.not. sumdone) then - ! Some budgets will be printed for this period type - ! Determine sums if not already done - call med_diag_sum_master(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - sumdone = .true. + sumdone = .true. + end if + + if (mastertask) then + c_size = size(budget_diags%comps) + f_size = size(budget_diags%fields) + p_size = size(budget_diags%periods) + allocate(datagpr(f_size, c_size, p_size)) + datagpr(:,:,:) = budget_global(:,:,:) + + ! budget normalizations (global area and 1e6 for water) + datagpr = datagpr/(4.0_r8*shr_const_pi) + datagpr(f_watr_beg:f_watr_end,:,:) = datagpr(f_watr_beg:f_watr_end,:,:) * 1.0e6_r8 + if ( flds_wiso ) then + datagpr(iso0(1):isof(nisotopes),:,:) = datagpr(iso0(1):isof(nisotopes),:,:) * 1.0e6_r8 end if + datagpr(:,:,:) = datagpr(:,:,:)/budget_counter(:,:,:) - if (mastertask) then - c_size = size(budget_diags%comps) - f_size = size(budget_diags%fields) - p_size = size(budget_diags%periods) - allocate(datagpr(f_size, c_size, p_size)) - datagpr(:,:,:) = budget_global(:,:,:) - - ! budget normalizations (global area and 1e6 for water) - datagpr = datagpr/(4.0_r8*shr_const_pi) - datagpr(f_watr_beg:f_watr_end,:,:) = datagpr(f_watr_beg:f_watr_end,:,:) * 1.0e6_r8 - if ( flds_wiso ) then - datagpr(iso0(1):isof(nisotopes),:,:) = datagpr(iso0(1):isof(nisotopes),:,:) * 1.0e6_r8 - end if - datagpr(:,:,:) = datagpr(:,:,:)/budget_counter(:,:,:) - print *,__FILE__,__LINE__,datagpr(f_area,:,1) - print *,__FILE__,__LINE__,budget_counter(f_area,:,1) - - ! Write diagnostic tables to logunit (mastertask only) - if (output_level >= 3) then - ! detail atm budgets and breakdown into components --- - call med_diag_print_atm(datagpr, ip, cdate, curr_tod) - end if - if (output_level >= 2) then - ! detail lnd/ocn/ice component budgets ---- - call med_diag_print_lnd_ice_ocn(datagpr, ip, cdate, curr_tod) - end if - if (output_level >= 1) then - ! net summary budgets - call med_diag_print_summary(datagpr, ip, cdate, curr_tod) - endif - write(logunit,*) ' ' + ! Write diagnostic tables to logunit (mastertask only) + if (output_level >= 3) then + ! detail atm budgets and breakdown into components --- + call med_diag_print_atm(datagpr, ip, cdate, curr_tod) + end if + if (output_level >= 2) then + ! detail lnd/ocn/ice component budgets ---- + call med_diag_print_lnd_ice_ocn(datagpr, ip, cdate, curr_tod) + end if + if (output_level >= 1) then + ! net summary budgets + call med_diag_print_summary(datagpr, ip, cdate, curr_tod) + endif + write(logunit,*) ' ' - deallocate(datagpr) - endif ! output_level > 0 and mastertask - end if ! if mastertask - enddo ! ip = 1, period_types + deallocate(datagpr) + endif ! output_level > 0 and mastertask + end if ! if mastertask !------------------------------------------------------------------------------- ! Zero budget data From 3515c71c9b7397d0f7f1da787790ead1610bfee3 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 21 Sep 2020 10:52:29 -0600 Subject: [PATCH 083/206] add ocn budget for A compset --- cime_config/runseq/runseq_general.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index ebf11cbab..d3036651f 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -117,6 +117,7 @@ def gen_runseq(case, coupling_times): 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) + 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("MED med_phases_diag_lnd" , run_lnd and diag_mode) runseq.add_action("MED med_phases_diag_rof" , run_rof and diag_mode) From 91fccdc7dd832d5c3c336e77da751bc2d56eccb1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 29 Sep 2020 16:06:39 -0600 Subject: [PATCH 084/206] budget improvements --- cime_config/runseq/runseq_general.py | 18 ++++++----- mediator/med.F90 | 10 ++++-- mediator/med_diag_mod.F90 | 48 +++++++++------------------- mediator/med_fraction_mod.F90 | 30 ++++++++++++----- mediator/med_map_mod.F90 | 3 +- 5 files changed, 56 insertions(+), 53 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index d3036651f..983c3f701 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -62,7 +62,6 @@ def gen_runseq(case, coupling_times): 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("MED med_phases_diag_glc" , run_glc and diag_mode) runseq.add_action("GLC -> MED :remapMethod=redist" , run_glc) #------------------ @@ -95,6 +94,7 @@ def gen_runseq(case, coupling_times): 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) @@ -119,10 +119,8 @@ def gen_runseq(case, coupling_times): runseq.add_action("MED med_phases_ocnalb_run" , run_ocn and run_atm) 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("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_ice_ice2med" , run_ice and diag_mode) 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) @@ -134,19 +132,23 @@ def gen_runseq(case, coupling_times): 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_ice_med2ice" , run_ice 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_ocn" , run_ocn 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("MED med_phases_diag_ocn" , run_ocn and diag_mode and ocn_outer_loop) + if coupling_mode == 'hafs': 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("MED med_phases_diag_accum" , diag_mode) - runseq.add_action("MED med_phases_diag_print" , diag_mode) + #------------------ runseq.leave_time_loop(ocn_outer_loop) diff --git a/mediator/med.F90 b/mediator/med.F90 index 706d3a956..5de359a5e 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -705,6 +705,12 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) if (trim(cvalue) /= 'sglc') glc_present = "true" end if + call NUOPC_CompAttributeGet(gcomp, name='mediator_present', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + med_present = trim(cvalue) + end if + call NUOPC_CompAttributeSet(gcomp, name="atm_present", value=atm_present, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompAttributeSet(gcomp, name="lnd_present", value=lnd_present, rc=rc) @@ -2282,7 +2288,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO use med_internalstate_mod , only : mesh_info_type - + use shr_sys_mod, only : shr_sys_abort ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB type(mesh_info_type) , intent(inout) :: mesh_info @@ -2298,7 +2304,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) real(r8), allocatable :: ownedElemCoords(:) real(r8), pointer :: dataptr(:) integer :: n, dimcount, fieldcount - character(len=*),parameter :: subnaame='(module_MED:med_meshinfo_create)' + character(len=*),parameter :: subname='(module_MED:med_meshinfo_create)' !------------------------------------------------------------------------------- rc= ESMF_SUCCESS diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 15061f70d..9a930e86a 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -220,7 +220,7 @@ module med_diag_mod character(len=*), parameter :: modName = "(med_diag) " character(len=*), parameter :: u_FILE_u = & - __FILE__ + __FILE__ !=============================================================================== contains @@ -455,7 +455,6 @@ subroutine med_diag_zero( gcomp, mode, rc) endif enddo end if - end subroutine med_diag_zero !=============================================================================== @@ -471,19 +470,15 @@ subroutine med_phases_diag_accum(gcomp, rc) integer, intent(out) :: rc ! local variables - integer :: ip + integer :: ip, ic character(*), parameter :: subName = '(med_diag_accum) ' ! ------------------------------------------------------------------ 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 - - write(logunit,*) 'DEBUG diag_accum',budget_counter(1,1,1) - end subroutine med_phases_diag_accum !=============================================================================== @@ -518,18 +513,11 @@ subroutine med_diag_sum_master(gcomp, rc) count = size(budget_global) budget_global_1d(:) = 0.0_r8 - call ESMF_VMReduce(vm, reshape(budget_local,(/count/)) , budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,budget_local(f_area,c_ocn_asend,period_inst) - print *,__FILE__,__LINE__,budget_local(f_area,c_ocn_asend,:) + call ESMF_VMReduce(vm, reshape(budget_local,(/count/)) , budget_global_1d, count, ESMF_REDUCE_SUM, 0, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return budget_global = reshape(budget_global_1d,(/f_size,c_size,p_size/)) - if(mastertask) then - print *,__FILE__,__LINE__,budget_global(f_area,c_ocn_asend,:) - endif - - budget_local(:,:,:) = 0.0_r8 end subroutine med_diag_sum_master @@ -567,8 +555,6 @@ 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), 'afrac', fldptr1=afrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', fldptr1=lfrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', fldptr1=ifrac, rc=rc) @@ -578,7 +564,8 @@ subroutine med_phases_diag_atm(gcomp, rc) 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 !------------------------------- @@ -621,7 +608,6 @@ subroutine med_phases_diag_atm(gcomp, rc) call diag_atm_wiso(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 - ! heat implied by snow flux 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 @@ -841,7 +827,6 @@ subroutine med_phases_diag_lnd( gcomp, rc) do n = 1,size(lfrac) budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*lfrac(n) end do - call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_lwdn' , f_heat_lwdn, ic, areas, lfrac, budget_local, rc=rc) call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_rainc', f_watr_rain, ic, areas, lfrac, budget_local, rc=rc) call diag_lnd(is_local%wrap%FBExp(complnd), 'Faxa_rainl', f_watr_rain, ic, areas, lfrac, budget_local, rc=rc) @@ -860,8 +845,9 @@ subroutine med_phases_diag_lnd( gcomp, rc) call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Flrl_flood_wiso', & f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, lfrac, budget_local, minus=.true., rc=rc) + print *,__FILE__,__LINE__,budget_local(f_watr_ioff, c_lnd_recv, period_inst), budget_local(f_watr_ioff, c_lnd_send, period_inst) + 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 !----------- @@ -889,9 +875,9 @@ subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) ip = period_inst do n = 1, size(data) if (present(minus)) then - budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*lfrac(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) - areas(n)*lfrac(n)*data(n) else - budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*lfrac(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*lfrac(n)*data(n) end if end do end if @@ -1006,7 +992,6 @@ 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 !----------- @@ -1034,9 +1019,9 @@ subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ip = period_inst do n = 1, size(data) if (present(minus)) then - budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) - areas(n)*data(n) else - budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*data(n) end if end do end if @@ -1148,9 +1133,9 @@ subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) ip = period_inst do n = 1, size(data) if (present(minus)) then - budget(nf,ic,ip) = budget_local(nf,ic,ip) - areas(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) - areas(n)*data(n) else - budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*data(n) end if end do end if @@ -1269,7 +1254,6 @@ 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 - !----------- contains !----------- @@ -1294,7 +1278,7 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) - budget(nf,ic,ip) = budget_local(nf,ic,ip) + areas(n)*frac(n)*data(n) + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*frac(n)*data(n) end do end if end subroutine diag_ocn @@ -1404,7 +1388,6 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) 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', & f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, areas, lats, ifrac, budget_local, rc=rc) - !----------- contains !----------- @@ -1811,7 +1794,6 @@ subroutine med_phases_diag_print(gcomp, rc) deallocate(datagpr) endif ! output_level > 0 and mastertask end if ! if mastertask - !------------------------------------------------------------------------------- ! Zero budget data !------------------------------------------------------------------------------- diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 839cc9422..bcd442958 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -108,6 +108,7 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps + use ESMF , only : ESMF_RouteHandle implicit none private @@ -131,6 +132,8 @@ module med_fraction_mod character(*), parameter :: u_FILE_u = & __FILE__ + type(ESMF_RouteHandle) :: rh_ice2atm + !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -152,6 +155,16 @@ subroutine med_fraction_init(gcomp, rc) use med_internalstate_mod , only : InternalState, logunit, mastertask use perf_mod , only : t_startf, t_stopf + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR + use ESMF , only : ESMF_Field, ESMF_FieldRegrid + use ESMF , only : ESMF_FieldRegridStore, ESMF_FieldRegridRelease + use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRedistRelease + use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL, ESMF_REGION_SELECT + use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA + use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint + use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -170,6 +183,10 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: So_omask(:) integer :: i,j,n,n1 integer :: maptype + type(ESMF_RouteHandle) :: rh_ocn2atm + type(ESMF_RouteHandle) :: rh_lnd2atm + type(ESMF_RouteHandle) :: rh_atm2lnd + integer :: srcTermProcessing_Value = 0 logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' !--------------------------------------- @@ -327,7 +344,7 @@ subroutine med_fraction_init(gcomp, rc) ! Reset 'lfrac' in FBFrac(complnd) by mapping the Frac ! If lnd -> atm coupling is active - map 'lfrac' from FBFrac(compatm) to FBFrac(complnd) - + if (med_map_RH_is_created(is_local%wrap%RH(compatm,complnd,:),mapfcopy, rc=rc)) then maptype = mapfcopy else @@ -346,21 +363,15 @@ subroutine med_fraction_init(gcomp, rc) 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) ! --------------------------------------- - ! These should actually be mapo2a of ofrac and lfrac but we can't - ! map lfrac from o2a due to masked mapping weights. So we have to - ! settle for a residual calculation that is truncated to zero to - ! try to preserve "all ocean" cells. - if (is_local%wrap%comp_present(compatm)) then if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then - ! Ocean is present + ! Ocean is present call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) @@ -566,6 +577,7 @@ subroutine med_fraction_set(gcomp, rc) use med_internalstate_mod , only : InternalState use med_map_mod , only : med_map_RH_is_created use perf_mod , only : t_startf, t_stopf + use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName ! input/output variables type(ESMF_GridComp) :: gcomp @@ -573,6 +585,8 @@ subroutine med_fraction_set(gcomp, rc) ! local variables type(InternalState) :: is_local + type(ESMF_Field) :: fldsrc + type(ESMF_Field) :: flddst real(r8), pointer :: lfrac(:) real(r8), pointer :: ifrac(:) real(r8), pointer :: ofrac(:) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 1763a123a..1d20c737f 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -105,6 +105,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) use ESMF , only : ESMF_REGRIDMETHOD_NEAREST_STOD use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint use NUOPC , only : NUOPC_Write + use shr_sys_mod, only : shr_sys_abort ! input/output variables type(ESMF_GridComp) :: gcomp @@ -193,7 +194,6 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) !--- given field bundle source and destination grids if (n1 /= n2) then - ! Determine route handle names rhname = trim(compname(n1))//"2"//trim(compname(n2)) @@ -220,7 +220,6 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (.not. mapexists) then - mapname = trim(mapnames(mapindex)) mapfile = trim(fldListFr(n1)%flds(nf)%mapfile(n2)) string = trim(rhname)//'_weights' From ee63d5c07a3da2e95cafac3c90772cdfdb4adee7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 30 Sep 2020 08:04:56 -0600 Subject: [PATCH 085/206] remove debug print statement --- mediator/med_diag_mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 9a930e86a..025b72bff 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -845,7 +845,6 @@ subroutine med_phases_diag_lnd( gcomp, rc) call diag_lnd_wiso(is_local%wrap%FBExp(complnd), 'Flrl_flood_wiso', & f_watr_roff_16O, f_watr_roff_18O, f_watr_roff_HDO, ic, areas, lfrac, budget_local, minus=.true., rc=rc) - print *,__FILE__,__LINE__,budget_local(f_watr_ioff, c_lnd_recv, period_inst), budget_local(f_watr_ioff, c_lnd_send, period_inst) 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 !----------- From 04cf4d5aafeb2cbc95a9bfeed4c5ab3f57c90fa4 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 09:49:22 -0600 Subject: [PATCH 086/206] add netcdf to required for cmake --- CMakeLists.txt | 2 + cmake/FindNetCDF.cmake | 143 ++++++++++++++++++++++++++++++++++++++++ mediator/CMakeLists.txt | 3 +- 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 cmake/FindNetCDF.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 14e0ef046..7365b51ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,8 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") find_package(ESMF REQUIRED) +find_package(NETCDF REQUIRED COMPONENT Fortran) + if (DEFINED PIO) set(PIO_PATH ${PIO}) else() diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake new file mode 100644 index 000000000..344714b18 --- /dev/null +++ b/cmake/FindNetCDF.cmake @@ -0,0 +1,143 @@ +# - Try to find NetCDF +# +# This can be controlled by setting the NetCDF_PATH (or, equivalently, the +# NETCDF environment variable), or NetCDF__PATH CMake variables, where +# is the COMPONENT language one needs. +# +# Once done, this will define: +# +# NetCDF__FOUND (BOOL) - system has NetCDF +# NetCDF__IS_SHARED (BOOL) - whether library is shared/dynamic +# NetCDF__INCLUDE_DIR (PATH) - Location of the C header file +# NetCDF__INCLUDE_DIRS (LIST) - the NetCDF include directories +# NetCDF__LIBRARY (FILE) - Path to the C library file +# NetCDF__LIBRARIES (LIST) - link these to use NetCDF +# +# The available COMPONENTS are: C Fortran +# If no components are specified, it assumes only C +include (LibFind) +include (LibCheck) + +# Define NetCDF C Component +define_package_component (NetCDF DEFAULT + COMPONENT C + INCLUDE_NAMES netcdf.h + LIBRARY_NAMES netcdf) + +# Define NetCDF Fortran Component +define_package_component (NetCDF + COMPONENT Fortran + INCLUDE_NAMES netcdf.mod netcdf.inc + LIBRARY_NAMES netcdff) + +# Search for list of valid components requested +find_valid_components (NetCDF) + +#============================================================================== +# SEARCH FOR VALIDATED COMPONENTS +foreach (NCDFcomp IN LISTS NetCDF_FIND_VALID_COMPONENTS) + + # If not found already, search... + if (NOT NetCDF_${NCDFcomp}_FOUND) + + # Manually add the MPI include and library dirs to search paths + # and search for the package component + if (MPI_${NCDFcomp}_FOUND) + initialize_paths (NetCDF_${NCDFcomp}_PATHS + INCLUDE_DIRECTORIES ${MPI_${NCDFcomp}_INCLUDE_PATH} + LIBRARIES ${MPI_${NCDFcomp}_LIBRARIES}) + find_package_component(NetCDF COMPONENT ${NCDFcomp} + PATHS ${NetCDF_${NCDFcomp}_PATHS}) + else () + find_package_component(NetCDF COMPONENT ${NCDFcomp}) + endif () + + # Continue only if component found + if (NetCDF_${NCDFcomp}_FOUND) + + # Checks + if (NCDFcomp STREQUAL C) + + # Check version + check_version (NetCDF + NAME "netcdf_meta.h" + HINTS ${NetCDF_C_INCLUDE_DIRS} + MACRO_REGEX "NC_VERSION_") + + # Check for parallel support + check_macro (NetCDF_C_HAS_PARALLEL + NAME TryNetCDF_PARALLEL.c + HINTS ${CMAKE_MODULE_PATH} + DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} + COMMENT "whether NetCDF has parallel support") + + # Check if logging enabled + set(CMAKE_REQUIRED_INCLUDES ${NetCDF_C_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${NetCDF_C_LIBRARIES}) + CHECK_FUNCTION_EXISTS(nc_set_log_level NetCDF_C_LOGGING_ENABLED) + + endif () + + # Dependencies + if (NCDFcomp STREQUAL C AND NOT NetCDF_C_IS_SHARED) + + # DEPENDENCY: PnetCDF (if PnetCDF enabled) + check_macro (NetCDF_C_HAS_PNETCDF + NAME TryNetCDF_PNETCDF.c + HINTS ${CMAKE_MODULE_PATH} + DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} + COMMENT "whether NetCDF has PnetCDF support") + if (NetCDF_C_HAS_PNETCDF) + find_package (PnetCDF COMPONENTS C) + if (CURL_FOUND) + list (APPEND NetCDF_C_INCLUDE_DIRS ${PnetCDF_C_INCLUDE_DIRS}) + list (APPEND NetCDF_C_LIBRARIES ${PnetCDF_C_LIBRARIES}) + endif () + endif () + + # DEPENDENCY: CURL (If DAP enabled) + check_macro (NetCDF_C_HAS_DAP + NAME TryNetCDF_DAP.c + HINTS ${CMAKE_MODULE_PATH} + DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} + COMMENT "whether NetCDF has DAP support") + if (NetCDF_C_HAS_DAP) + find_package (CURL) + if (CURL_FOUND) + list (APPEND NetCDF_C_INCLUDE_DIRS ${CURL_INCLUDE_DIRS}) + list (APPEND NetCDF_C_LIBRARIES ${CURL_LIBRARIES}) + endif () + endif () + + # DEPENDENCY: HDF5 + find_package (HDF5 COMPONENTS HL C) + if (HDF5_C_FOUND) + list (APPEND NetCDF_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS} + ${HDF5_HL_INCLUDE_DIRS}) + list (APPEND NetCDF_C_LIBRARIES ${HDF5_C_LIBRARIES} + ${HDF5_HL_LIBRARIES}) + endif () + + # DEPENDENCY: LIBDL Math + list (APPEND NetCDF_C_LIBRARIES -ldl -lm) + + elseif (NCDFcomp STREQUAL Fortran AND NOT NetCDF_Fortran_IS_SHARED) + + # DEPENDENCY: NetCDF + set (orig_comp ${NCDFcomp}) + set (orig_comps ${NetCDF_FIND_VALID_COMPONENTS}) + find_package (NetCDF COMPONENTS C) + set (NetCDF_FIND_VALID_COMPONENTS ${orig_comps}) + set (NCDFcomp ${orig_comp}) + if (NetCDF_C_FOUND) + list (APPEND NetCDF_Fortran_INCLUDE_DIRS ${NetCDF_C_INCLUDE_DIRS}) + list (APPEND NetCDF_Fortran_LIBRARIES ${NetCDF_C_LIBRARIES}) + endif () + + endif () + + endif () + + endif () + +endforeach () diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index 77fb16829..82ddf6a25 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -21,6 +21,7 @@ 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}") +target_include_directories (cmeps PUBLIC ${PIO_Fortran_INCLUDE_DIR}) +target_include_directories (cmeps PUBLIC ${NetCDF_Fortran_INCLUDE_DIR}) install(TARGETS cmeps LIBRARY DESTINATION lib) From 1fec2df8a9b539886d4cef72828cdb17a3d707ed Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 10:15:15 -0600 Subject: [PATCH 087/206] fix netcdf case in cmake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7365b51ad..195f14a7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") find_package(ESMF REQUIRED) -find_package(NETCDF REQUIRED COMPONENT Fortran) +find_package(NetCDF REQUIRED COMPONENT Fortran) if (DEFINED PIO) set(PIO_PATH ${PIO}) From 2b9a741ab921cf420dc8392eb0ba33bae53542fc Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 10:25:30 -0600 Subject: [PATCH 088/206] fix github build --- .github/workflows/extbuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 0c086e380..78297310d 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -101,6 +101,6 @@ jobs: export PIO=$HOME/pio mkdir build-cmeps pushd build-cmeps - cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ + cmake -DNetCDF_Fortran_LIBRARY=$HOME/netcdf-fortran/lib/libnetcdff.a -DNetCDF_Fortran_INCLUDE_DIR=$HOME/netcdf-fortran/include -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ make VERBOSE=1 popd From c9a6b4e71fa2742f283f78ffbb6bcdbb9cb22e6d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 10:31:12 -0600 Subject: [PATCH 089/206] fix github build --- .github/workflows/extbuild.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 78297310d..34541ff4d 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -101,6 +101,11 @@ jobs: export PIO=$HOME/pio mkdir build-cmeps pushd build-cmeps - cmake -DNetCDF_Fortran_LIBRARY=$HOME/netcdf-fortran/lib/libnetcdff.a -DNetCDF_Fortran_INCLUDE_DIR=$HOME/netcdf-fortran/include -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ + cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" \ + -DNetCDF_Fortran_LIBRARY=$HOME/netcdf-fortran/lib/libnetcdff.a \ + -DNetCDF_Fortran_INCLUDE_DIR=$HOME/netcdf-fortran/include \ + -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so \ + -DNetCDF_C_INCLUDE_DIR=/usr/include \ + ../ make VERBOSE=1 popd From 9e59f18374ada6d800c2857cdad3dd164c2f9ab9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 10:46:18 -0600 Subject: [PATCH 090/206] fix github build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 195f14a7c..988646fcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") find_package(ESMF REQUIRED) -find_package(NetCDF REQUIRED COMPONENT Fortran) +find_package(NetCDF REQUIRED COMPONENT C Fortran) if (DEFINED PIO) set(PIO_PATH ${PIO}) From 263870ee72f1910d14fe73294b4b3331f1c26c24 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 11:03:08 -0600 Subject: [PATCH 091/206] fix github build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 988646fcf..b9d615d44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ else() set(BLD_STANDALONE TRUE) endif() -project(CMEPS LANGUAGES Fortran VERSION 0.1) +project(CMEPS LANGUAGES C Fortran VERSION 0.1) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) From a9fc73a73ab506ffa69f82e284dc8f15d4380e5c Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 11:07:54 -0600 Subject: [PATCH 092/206] fix github build --- mediator/CMakeLists.txt | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index 82ddf6a25..e52861d70 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -1,10 +1,18 @@ 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) + +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) foreach(FILE ${SRCFILES}) if(EXISTS "${CASEROOT}/SourceMods/src.cmeps/${FILE}") From 6d1ebac8aea629bdecc262ee2fb0ea2e9fa8971e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 15:23:38 -0600 Subject: [PATCH 093/206] use master med_time_mod, remove shr_sys_abort --- cime_config/namelist_definition_drv.xml | 41 +- mediator/med.F90 | 2 +- mediator/med_diag_mod.F90 | 11 +- mediator/med_map_mod.F90 | 1 - mediator/med_time_mod.F90 | 874 +----------------------- 5 files changed, 65 insertions(+), 864 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 438e2b49f..4ba2a6dde 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -855,11 +855,11 @@ 'on': always do this renormalization 'off': never do this renormalization (see WARNING below) 'on_if_glc_coupled_fluxes': Determine at runtime whether to do this renormalization. - Does the renormalization if we're running a two-way-coupled glc that sends fluxes - to other components (which is the case where we need conservation). - Does NOT do the renormalization if we're running a one-way-coupled glc, or if - we're running a glc-only compset (T compsets). - (In these cases, conservation is not important.) + Does the renormalization if we're running a two-way-coupled glc that sends fluxes + to other components (which is the case where we need conservation). + Does NOT do the renormalization if we're running a one-way-coupled glc, or if + we're running a glc-only compset (T compsets). + (In these cases, conservation is not important.) Only used if running with a prognostic GLC component. @@ -1094,6 +1094,31 @@ $CPL_ALBAV + + char + mapping + MED_attributes + ocn,atm,exch + + Grid for atm ocn flux calc (untested) + default: ocn + + + ocn + + + + + real + control + MED_attributes + + wind gustiness factor + + + 0.0D0 + + logical @@ -1248,7 +1273,7 @@ - + @@ -3301,9 +3326,9 @@ PELAYOUT_attributes Determines what ESMF log files (if any) are generated when - USE_ESMF_LIB is TRUE. + USE_ESMF_LIB is TRUE. ESMF_LOGKIND_SINGLE: Use a single log file, combining messages from - all of the PETs. Not supported on some platforms. + all of the PETs. Not supported on some platforms. ESMF_LOGKIND_MULTI: Use multiple log files — one per PET. ESMF_LOGKIND_NONE: Do not issue messages to a log file. By default, no ESMF log files are generated. diff --git a/mediator/med.F90 b/mediator/med.F90 index 5de359a5e..aefea0a4c 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -2288,7 +2288,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO use med_internalstate_mod , only : mesh_info_type - use shr_sys_mod, only : shr_sys_abort + ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB type(mesh_info_type) , intent(inout) :: mesh_info diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 025b72bff..ca00eb38a 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -23,7 +23,6 @@ module med_diag_mod 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 shr_sys_mod , only : shr_sys_abort 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 @@ -419,7 +418,11 @@ subroutine med_diag_zero( gcomp, mode, rc) budget_global(:,:,:) = 0.0_r8 budget_counter(:,:,:) = 0.0_r8 else - call shr_sys_abort(subname//' ERROR in mode '//trim(mode)) + call ESMF_LogWrite(trim(subname)//' mode '//trim(mode)//& + ' not recognized', & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return endif else @@ -1839,8 +1842,6 @@ subroutine med_diag_print_atm(data, ip, cdate, curr_tod) ics = c_ish_asend ! from ice-sh to atm ico = c_ocn_asend ! from ocn to atm str = "CPL_TO_ATM" - else - call shr_sys_abort(subname//' ERROR in ic index code 411') endif write(logunit,*) ' ' @@ -2001,8 +2002,6 @@ subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) icxr = c_ish_recv icas = c_ish_asend str = "ICE_SH" - else - call shr_sys_abort(subname//' ERROR in ic index code 412') endif ! heat budgets atm<->lnd, atm<->ocn, atm<->ice_nh, atm<->ice_sh, diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 1d20c737f..91b5fdb9e 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -105,7 +105,6 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) use ESMF , only : ESMF_REGRIDMETHOD_NEAREST_STOD use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint use NUOPC , only : NUOPC_Write - use shr_sys_mod, only : shr_sys_abort ! input/output variables type(ESMF_GridComp) :: gcomp diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 48eec59b0..99d19cc4c 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -22,35 +22,22 @@ module med_time_mod implicit none private ! default private - public :: med_time_clockInit ! initialize driver clock (assumes default calendar) public :: med_time_alarmInit ! initialize an alarm - public :: med_time_set_component_stop_alarm - - private :: med_time_timeInit - private :: med_time_date2ymd ! Clock and alarm options character(len=*), private, parameter :: & optNONE = "none" , & optNever = "never" , & optNSteps = "nsteps" , & - optNStep = "nstep" , & optNSeconds = "nseconds" , & - optNSecond = "nsecond" , & optNMinutes = "nminutes" , & - optNMinute = "nminute" , & optNHours = "nhours" , & - optNHour = "nhour" , & optNDays = "ndays" , & - optNDay = "nday" , & optNMonths = "nmonths" , & - optNMonth = "nmonth" , & optNYears = "nyears" , & - optNYear = "nyear" , & optMonthly = "monthly" , & optYearly = "yearly" , & optDate = "date" , & - optIfdays0 = "ifdays0" , & optGLCCouplingPeriod = "glc_coupling_period" ! Module data @@ -60,436 +47,12 @@ module med_time_mod !=============================================================================== contains -!=============================================================================== - - subroutine med_time_clockInit(ensemble_driver, esmdriver, logunit, rc) - - ! input/output variables - type(ESMF_GridComp) :: ensemble_driver, esmdriver - integer, intent(in) :: logunit - integer, intent(out) :: rc - - ! local variables - type(ESMF_Clock) :: clock - type(ESMF_VM) :: vm - type(ESMF_Time) :: StartTime ! Start time - type(ESMF_Time) :: RefTime ! Reference time - type(ESMF_Time) :: CurrTime ! Current time - type(ESMF_Time) :: StopTime ! Stop time - type(ESMF_Time) :: StopTime1 ! Stop time - type(ESMF_Time) :: StopTime2 ! Stop time - type(ESMF_Time) :: Clocktime ! Loop time - type(ESMF_TimeInterval) :: TimeStep ! Clock time-step - type(ESMF_Alarm) :: alarm_stop ! alarm - type(ESMF_Alarm) :: alarm_datestop ! alarm - integer :: ref_ymd ! Reference date (YYYYMMDD) - integer :: ref_tod ! Reference time of day (seconds) - integer :: start_ymd ! Start date (YYYYMMDD) - integer :: start_tod ! Start time of day (seconds) - integer :: curr_ymd ! Current ymd (YYYYMMDD) - integer :: curr_tod ! Current tod (seconds) - integer :: stop_n ! Number until stop - integer :: stop_ymd ! Stop date (YYYYMMDD) - integer :: stop_tod ! Stop time-of-day - character(CS) :: stop_option ! Stop option units - integer :: atm_cpl_dt ! Atmosphere coupling interval - integer :: lnd_cpl_dt ! Land coupling interval - integer :: ice_cpl_dt ! Sea-Ice coupling interval - integer :: ocn_cpl_dt ! Ocean coupling interval - integer :: glc_cpl_dt ! Glc coupling interval - integer :: rof_cpl_dt ! Runoff coupling interval - integer :: wav_cpl_dt ! Wav coupling interval - integer :: esp_cpl_dt ! Esp coupling interval - character(CS) :: glc_avg_period ! Glc avering coupling period - logical :: read_restart - character(len=CL) :: restart_file - character(len=CL) :: restart_pfile - character(len=CL) :: cvalue - integer :: dtime_drv ! time-step to use - integer :: yr, mon, day ! Year, month, day as integers - integer :: localPet ! local pet in esm domain - logical :: mastertask ! true if mastertask in esm domain - integer :: unitn ! unit number - integer :: ierr ! Return code - character(CL) :: tmpstr ! temporary - character(CS) :: inst_suffix - integer :: tmp(6) ! Array for Broadcast - logical :: isPresent - character(len=*), parameter :: subname = '(med_time_clockInit): ' - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - - call ESMF_GridCompGet(esmdriver, vm=vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! We may want to get the ensemble_driver vm here instead so that - ! files are read on global task 0 only instead of each esm member task 0 - call ESMF_VMGet(vm, localPet=localPet, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - mastertask = localPet == 0 - - !--------------------------------------------------------------------------- - ! Determine clock start time, reference time and current time - !--------------------------------------------------------------------------- - - curr_ymd = 0 - curr_tod = 0 - - call NUOPC_CompAttributeGet(esmdriver, name="start_ymd", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) start_ymd - call NUOPC_CompAttributeGet(esmdriver, name="start_tod", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) start_tod - - call NUOPC_CompAttributeGet(esmdriver, name="ref_ymd", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ref_ymd - call NUOPC_CompAttributeGet(esmdriver, name="ref_tod", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ref_tod - - call NUOPC_CompAttributeGet(esmdriver, name='read_restart', value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) read_restart - - if (read_restart) then - - call NUOPC_CompAttributeGet(esmdriver, name='restart_file', value=restart_file, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--- read rpointer if restart_file is set to str_undefined --- - if (trim(restart_file) == 'str_undefined') then - - ! Error check on restart_pfile - call NUOPC_CompAttributeGet(esmdriver, name="restart_pfile", value=restart_pfile, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call NUOPC_CompAttributeGet(esmdriver, name="inst_suffix", isPresent=isPresent, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if(isPresent) then - call NUOPC_CompAttributeGet(esmdriver, name="inst_suffix", value=inst_suffix, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - inst_suffix = "" - endif - if ( len_trim(restart_pfile) == 0 ) then - call ESMF_LogWrite(trim(subname)//' ERROR restart_pfile must be defined', & - ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) - rc = ESMF_FAILURE - return - end if - restart_pfile = trim(restart_pfile)//inst_suffix - if (mastertask) then - call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), & - ESMF_LOGMSG_INFO) - open(newunit=unitn, file=restart_pfile, form='FORMATTED', status='old',iostat=ierr) - if (ierr < 0) then - rc = ESMF_FAILURE - call ESMF_LogWrite(trim(subname)//' ERROR rpointer file open returns error', & - ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) - return - end if - read(unitn,'(a)', iostat=ierr) restart_file - if (ierr < 0) then - rc = ESMF_FAILURE - call ESMF_LogWrite(trim(subname)//' ERROR rpointer file read returns error', & - ESMF_LOGMSG_INFO, line=__LINE__, file=__FILE__) - return - end if - close(unitn) - call ESMF_LogWrite(trim(subname)//" read driver restart from file = "//trim(restart_file), & - ESMF_LOGMSG_INFO) - endif - endif - if (mastertask) then - call med_time_read_restart(restart_file, & - start_ymd, start_tod, ref_ymd, ref_tod, curr_ymd, curr_tod, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - tmp(1) = start_ymd - tmp(2) = start_tod - tmp(3) = ref_ymd - tmp(4) = ref_tod - tmp(5) = curr_ymd - tmp(6) = curr_tod - call ESMF_VMBroadcast(vm, tmp, 6, 0, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - start_ymd = tmp(1) - start_tod = tmp(2) - ref_ymd = tmp(3) - ref_tod = tmp(4) - curr_ymd = tmp(5) - curr_tod = tmp(6) - end if - - if ( ref_ymd == 0 ) then - ref_ymd = start_ymd - ref_tod = start_tod - endif - if ( curr_ymd == 0 ) then - curr_ymd = start_ymd - curr_tod = start_tod - endif - - ! Determine start time (THE FOLLOWING ASSUMES THAT THE DEFAULT CALENDAR IS SET in the driver) - - call med_time_date2ymd(start_ymd, yr, mon, day) - call ESMF_TimeSet( StartTime, yy=yr, mm=mon, dd=day, s=start_tod, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if(mastertask .or. dbug_flag > 2) then - write(tmpstr,'(i10)') start_ymd - call ESMF_LogWrite(trim(subname)//': driver start_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver start_ymd: '// trim(tmpstr) - write(tmpstr,'(i10)') start_tod - call ESMF_LogWrite(trim(subname)//': driver start_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver start_tod: '// trim(tmpstr) - endif - - ! Determine reference time - call med_time_date2ymd(ref_ymd, yr, mon, day) - call ESMF_TimeSet( RefTime, yy=yr, mm=mon, dd=day, s=ref_tod, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if(mastertask .or. dbug_flag > 2) then - write(tmpstr,'(i10)') ref_ymd - call ESMF_LogWrite(trim(subname)//': driver ref_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver ref_ymd: '// trim(tmpstr) - write(tmpstr,'(i10)') ref_tod - call ESMF_LogWrite(trim(subname)//': driver ref_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver ref_tod: '// trim(tmpstr) - endif - ! Determine current time - call med_time_date2ymd(curr_ymd, yr, mon, day) - call ESMF_TimeSet( CurrTime, yy=yr, mm=mon, dd=day, s=curr_tod, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if(mastertask .or. dbug_flag > 2) then - write(tmpstr,'(i10)') curr_ymd - call ESMF_LogWrite(trim(subname)//': driver curr_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver curr_ymd: '// trim(tmpstr) - write(tmpstr,'(i10)') curr_tod - call ESMF_LogWrite(trim(subname)//': driver curr_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver curr_tod: '// trim(tmpstr) - endif - - !--------------------------------------------------------------------------- - ! Determine driver clock timestep - ! This is the minimum of all of the component coupling time steps - !--------------------------------------------------------------------------- - - call NUOPC_CompAttributeGet(esmdriver, name="atm_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) atm_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="lnd_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) lnd_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="ice_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ice_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="ocn_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ocn_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="glc_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) glc_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="rof_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) rof_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="wav_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) wav_cpl_dt - - call NUOPC_CompAttributeGet(esmdriver, name="glc_avg_period", value=glc_avg_period, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) glc_avg_period - - ! TODO: for now - this is not in the namelist_definition_drv.xml file - ! call NUOPC_CompAttributeGet(esmdriver, name="esp_cpl_dt", value=cvalue, rc=rc) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! read(cvalue,*) esp_cpl_dt - esp_cpl_dt = 9999 - - dtime_drv = 9999 - dtime_drv = min(dtime_drv, atm_cpl_dt) - dtime_drv = min(dtime_drv, lnd_cpl_dt) - dtime_drv = min(dtime_drv, ocn_cpl_dt) - dtime_drv = min(dtime_drv, ice_cpl_dt) - dtime_drv = min(dtime_drv, glc_cpl_dt) - dtime_drv = min(dtime_drv, rof_cpl_dt) - dtime_drv = min(dtime_drv, wav_cpl_dt) - dtime_drv = min(dtime_drv, esp_cpl_dt) - if(mastertask .or. dbug_flag > 2) then - write(tmpstr,'(i10)') dtime_drv - call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc) - write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr) - endif - call ESMF_TimeIntervalSet( TimeStep, s=dtime_drv, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------------------------------------------- - ! Create the driver clock with an artificial stop time - !--------------------------------------------------------------------------- - - ! Create the clock - clock = ESMF_ClockCreate(TimeStep, StartTime, refTime=RefTime, name='ESMF Driver Clock', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Advance the clock to the current time (in case of a restart) - call ESMF_ClockGet(clock, currTime=clocktime, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do while( clocktime < CurrTime) - call ESMF_ClockAdvance( clock, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGet( clock, currTime=clocktime, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end do - - ! Set the driver gridded component clock to the created clock - call ESMF_GridCompSet(esmdriver, clock=clock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !------------------------------- - ! Set driver clock stop time - !------------------------------- - - call NUOPC_CompAttributeGet(esmdriver, name="stop_option", value=stop_option, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(esmdriver, name="stop_n", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_n - call NUOPC_CompAttributeGet(esmdriver, name="stop_ymd", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_ymd - call NUOPC_CompAttributeGet(esmdriver, name="stop_tod", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_tod - if ( stop_ymd < 0) then - stop_ymd = 99990101 - stop_tod = 0 - endif - if(mastertask .or. dbug_flag > 2) then - write(tmpstr,'(i10)') stop_ymd - call ESMF_LogWrite(trim(subname)//': driver stop_ymd: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver stop_ymd: '// trim(tmpstr) - write(tmpstr,'(i10)') stop_tod - call ESMF_LogWrite(trim(subname)//': driver stop_tod: '// trim(tmpstr), ESMF_LOGMSG_INFO) - write(logunit,*) trim(subname)//': driver stop_tod: '// trim(tmpstr) - endif - call med_time_alarmInit(clock, & - alarm = alarm_stop, & - option = stop_option, & - opt_n = stop_n, & - opt_ymd = stop_ymd, & - opt_tod = stop_tod, & - RefTime = CurrTime, & - alarmname = 'alarm_stop', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call med_time_alarmInit(clock, & - alarm = alarm_datestop, & - option = optDate, & - opt_ymd = stop_ymd, & - opt_tod = stop_tod, & - RefTime = StartTime, & - alarmname = 'alarm_datestop', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_AlarmGet(alarm_stop, RingTime=StopTime1, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_AlarmGet(alarm_datestop, RingTime=StopTime2, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (StopTime2 < StopTime1) then - StopTime = StopTime2 - else - StopTime = StopTime1 - endif - - call ESMF_ClockSet(clock, StopTime=StopTime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Create the ensemble driver clock - TimeStep = StopTime-ClockTime - clock = ESMF_ClockCreate(TimeStep, ClockTime, StopTime=StopTime, & - refTime=RefTime, name='ESMF ensemble Driver Clock', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_GridCompSet(ensemble_driver, clock=clock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - - - end subroutine med_time_clockInit - -!=============================================================================== - - subroutine med_time_set_component_stop_alarm(gcomp, rc) - - use ESMF , only : ESMF_GridComp, ESMF_Alarm, ESMF_Clock, ESMF_ClockGet - use ESMF , only : ESMF_AlarmSet - use NUOPC , only : NUOPC_CompAttributeGet - use NUOPC_Model , only : NUOPC_ModelGet - - ! input/output variables - type(ESMF_gridcomp) :: gcomp - integer, intent(out) :: rc - - ! local variables - character(len=256) :: stop_option ! Stop option units - integer :: stop_n ! Number until stop interval - integer :: stop_ymd ! Stop date (YYYYMMDD) - type(ESMF_ALARM) :: stop_alarm - character(len=256) :: cvalue - type(ESMF_Clock) :: mclock - type(ESMF_Time) :: mCurrTime - !----------------------------------------------------------- - - !---------------- - ! Stop alarm - !---------------- - call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ClockGet(mclock, CurrTime=mCurrTime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_n - - call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_ymd - call med_time_alarmInit(mclock, stop_alarm, stop_option, & - opt_n = stop_n, & - opt_ymd = stop_ymd, & - RefTime = mcurrTime, & - alarmname = 'alarm_stop', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_AlarmSet(stop_alarm, clock=mclock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end subroutine med_time_set_component_stop_alarm - !=============================================================================== subroutine med_time_alarmInit( clock, alarm, option, & opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc) - ! !DESCRIPTION: Setup an alarm in a clock + ! Setup an alarm in a clock ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm ! time. If you send an arbitrary but proper ringtime from the ! past and the ring interval, the alarm will always go off on the @@ -550,24 +113,8 @@ subroutine med_time_alarmInit( clock, alarm, option, & ! Get calendar from clock call ESMF_ClockGet(clock, calendar=cal) - ! Determine inputs for call to create alarm - selectcase (trim(option)) - - case (optNONE) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. - - case (optNever) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. - - case (optDate) + ! Error checks + if (trim(option) == optdate) then if (.not. present(opt_ymd)) then call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE @@ -578,93 +125,49 @@ subroutine med_time_alarmInit( clock, alarm, option, & rc = ESMF_FAILURE return end if - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_time_timeInit(NextAlarm, lymd, cal, tod=ltod, desc="optDate") - if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. - - case (optIfdays0) - if (.not. present(opt_ymd)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if + else if (trim(option) == optNSteps .or. & + trim(option) == optNSeconds .or. & + trim(option) == optNMinutes .or. & + trim(option) == optNHours .or. & + trim(option) == optNDays .or. & + trim(option) == optNMonths .or. & + trim(option) == optNYears) then if (.not.present(opt_n)) then call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if - if (opt_n <= 0) then + if (opt_n <= 0) then call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return end if - call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) + end if + + ! Determine inputs for call to create alarm + selectcase (trim(option)) + + case (optNONE) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=opt_n, s=0, calendar=cal, rc=rc ) + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .true. + update_nextalarm = .false. - case (optNSteps) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc) + case (optNever) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. + call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. - case (optNStep) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if + case (optNSteps) call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNSeconds) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNSecond) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -672,126 +175,22 @@ subroutine med_time_alarmInit( clock, alarm, option, & case (optNMinutes) call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNMinute) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNHours) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNHour) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNDays) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNDay) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. case (optNMonths) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNMonth) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -805,32 +204,6 @@ subroutine med_time_alarmInit( clock, alarm, option, & update_nextalarm = .true. case (optNYears) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNYear) - if (.not.present(opt_n)) then - call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - if (opt_n <= 0) then - call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n @@ -870,199 +243,4 @@ subroutine med_time_alarmInit( clock, alarm, option, & end subroutine med_time_alarmInit - !=============================================================================== - - subroutine med_time_timeInit( Time, ymd, cal, tod, desc, logunit ) - - ! Create the ESMF_Time object corresponding to the given input time, given in - ! YMD (Year Month Day) and TOD (Time-of-day) format. - ! Set the time by an integer as YYYYMMDD and integer seconds in the day - - ! input/output parameters: - type(ESMF_Time) , intent(inout) :: Time ! ESMF time - integer , intent(in) :: ymd ! year, month, day YYYYMMDD - type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar - integer , intent(in), optional :: tod ! time of day in seconds - character(len=*) , intent(in), optional :: desc ! description of time to set - integer , intent(in), optional :: logunit - - ! local variables - integer :: yr, mon, day ! Year, month, day as integers - integer :: ltod ! local tod - character(len=256) :: ldesc ! local desc - integer :: rc ! return code - character(len=*), parameter :: subname = '(med_time_m_ETimeInit) ' - !------------------------------------------------------------------------------- - - ltod = 0 - if (present(tod)) ltod = tod - ldesc = '' - if (present(desc)) ldesc = desc - - if ( (ymd < 0) .or. (ltod < 0) .or. (ltod > SecPerDay) )then - if (present(logunit)) then - write(logunit,*) subname//': ERROR yymmdd is a negative number or '// & - 'time-of-day out of bounds', ymd, ltod - end if - call ESMF_LogWrite( subname//'ERROR: Bad input' , ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - - call med_time_date2ymd (ymd,yr,mon,day) - - call ESMF_TimeSet( Time, yy=yr, mm=mon, dd=day, s=ltod, calendar=cal, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - end subroutine med_time_timeInit - - !=============================================================================== - - subroutine med_time_date2ymd (date, year, month, day) - - ! input/output variables - integer, intent(in) :: date ! coded-date (yyyymmdd) - integer, intent(out) :: year,month,day ! calendar year,month,day - - ! local variables - integer :: tdate ! temporary date - character(*),parameter :: subName = "(med_time_date2ymd)" - !------------------------------------------------------------------------------- - - tdate = abs(date) - year = int(tdate/10000) - if (date < 0) then - year = -year - end if - month = int( mod(tdate,10000)/ 100) - day = mod(tdate, 100) - - end subroutine med_time_date2ymd - - !=============================================================================== - - subroutine med_time_read_restart(restart_file, & - start_ymd, start_tod, ref_ymd, ref_tod, curr_ymd, curr_tod, rc) - - use netcdf , only : nf90_open, nf90_nowrite, nf90_noerr - use netcdf , only : nf90_inq_varid, nf90_get_var, nf90_close - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO - - ! input/output variables - character(len=*), intent(in) :: restart_file - integer, intent(out) :: ref_ymd ! Reference date (YYYYMMDD) - integer, intent(out) :: ref_tod ! Reference time of day (seconds) - integer, intent(out) :: start_ymd ! Start date (YYYYMMDD) - integer, intent(out) :: start_tod ! Start time of day (seconds) - integer, intent(out) :: curr_ymd ! Current ymd (YYYYMMDD) - integer, intent(out) :: curr_tod ! Current tod (seconds) - integer, intent(out) :: rc - - ! local variables - integer :: status, ncid, varid ! netcdf stuff - character(CL) :: tmpstr ! temporary - character(len=*), parameter :: subname = "(med_time_read_restart)" - !---------------------------------------------------------------- - - ! use netcdf here since it's serial - status = nf90_open(restart_file, NF90_NOWRITE, ncid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_open', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - endif - status = nf90_inq_varid(ncid, 'start_ymd', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid start_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, start_ymd) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var start_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_inq_varid(ncid, 'start_tod', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid start_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, start_tod) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var start_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_inq_varid(ncid, 'ref_ymd', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid ref_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, ref_ymd) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var ref_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_inq_varid(ncid, 'ref_tod', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid ref_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, ref_tod) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var ref_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_inq_varid(ncid, 'curr_ymd', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid curr_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, curr_ymd) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var curr_ymd', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_inq_varid(ncid, 'curr_tod', varid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_inq_varid curr_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_get_var(ncid, varid, curr_tod) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_get_var curr_tod', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - status = nf90_close(ncid) - if (status /= nf90_NoErr) then - call ESMF_LogWrite(trim(subname)//' ERROR: nf90_close', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - - write(tmpstr,*) trim(subname)//" read start_ymd = ",start_ymd - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - write(tmpstr,*) trim(subname)//" read start_tod = ",start_tod - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - write(tmpstr,*) trim(subname)//" read ref_ymd = ",ref_ymd - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - write(tmpstr,*) trim(subname)//" read ref_tod = ",ref_tod - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - write(tmpstr,*) trim(subname)//" read curr_ymd = ",curr_ymd - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - write(tmpstr,*) trim(subname)//" read curr_tod = ",curr_tod - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - - end subroutine med_time_read_restart - end module med_time_mod From 0a282730e3b790bf006d09e370d4050d76bb70ce Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 15:28:02 -0600 Subject: [PATCH 094/206] remove netcdf requirement from cmake build --- .github/workflows/extbuild.yml | 7 +- CMakeLists.txt | 1 - cmake/FindNetCDF.cmake | 143 --------------------------------- mediator/CMakeLists.txt | 2 +- 4 files changed, 2 insertions(+), 151 deletions(-) delete mode 100644 cmake/FindNetCDF.cmake diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml index 34541ff4d..0c086e380 100644 --- a/.github/workflows/extbuild.yml +++ b/.github/workflows/extbuild.yml @@ -101,11 +101,6 @@ jobs: export PIO=$HOME/pio mkdir build-cmeps pushd build-cmeps - cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" \ - -DNetCDF_Fortran_LIBRARY=$HOME/netcdf-fortran/lib/libnetcdff.a \ - -DNetCDF_Fortran_INCLUDE_DIR=$HOME/netcdf-fortran/include \ - -DNetCDF_C_LIBRARY=/usr/lib/x86_64-linux-gnu/libnetcdf.so \ - -DNetCDF_C_INCLUDE_DIR=/usr/include \ - ../ + cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_Fortran_FLAGS="-g -Wall -ffree-form -ffree-line-length-none" ../ make VERBOSE=1 popd diff --git a/CMakeLists.txt b/CMakeLists.txt index b9d615d44..1d4d7026d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") find_package(ESMF REQUIRED) -find_package(NetCDF REQUIRED COMPONENT C Fortran) if (DEFINED PIO) set(PIO_PATH ${PIO}) diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake deleted file mode 100644 index 344714b18..000000000 --- a/cmake/FindNetCDF.cmake +++ /dev/null @@ -1,143 +0,0 @@ -# - Try to find NetCDF -# -# This can be controlled by setting the NetCDF_PATH (or, equivalently, the -# NETCDF environment variable), or NetCDF__PATH CMake variables, where -# is the COMPONENT language one needs. -# -# Once done, this will define: -# -# NetCDF__FOUND (BOOL) - system has NetCDF -# NetCDF__IS_SHARED (BOOL) - whether library is shared/dynamic -# NetCDF__INCLUDE_DIR (PATH) - Location of the C header file -# NetCDF__INCLUDE_DIRS (LIST) - the NetCDF include directories -# NetCDF__LIBRARY (FILE) - Path to the C library file -# NetCDF__LIBRARIES (LIST) - link these to use NetCDF -# -# The available COMPONENTS are: C Fortran -# If no components are specified, it assumes only C -include (LibFind) -include (LibCheck) - -# Define NetCDF C Component -define_package_component (NetCDF DEFAULT - COMPONENT C - INCLUDE_NAMES netcdf.h - LIBRARY_NAMES netcdf) - -# Define NetCDF Fortran Component -define_package_component (NetCDF - COMPONENT Fortran - INCLUDE_NAMES netcdf.mod netcdf.inc - LIBRARY_NAMES netcdff) - -# Search for list of valid components requested -find_valid_components (NetCDF) - -#============================================================================== -# SEARCH FOR VALIDATED COMPONENTS -foreach (NCDFcomp IN LISTS NetCDF_FIND_VALID_COMPONENTS) - - # If not found already, search... - if (NOT NetCDF_${NCDFcomp}_FOUND) - - # Manually add the MPI include and library dirs to search paths - # and search for the package component - if (MPI_${NCDFcomp}_FOUND) - initialize_paths (NetCDF_${NCDFcomp}_PATHS - INCLUDE_DIRECTORIES ${MPI_${NCDFcomp}_INCLUDE_PATH} - LIBRARIES ${MPI_${NCDFcomp}_LIBRARIES}) - find_package_component(NetCDF COMPONENT ${NCDFcomp} - PATHS ${NetCDF_${NCDFcomp}_PATHS}) - else () - find_package_component(NetCDF COMPONENT ${NCDFcomp}) - endif () - - # Continue only if component found - if (NetCDF_${NCDFcomp}_FOUND) - - # Checks - if (NCDFcomp STREQUAL C) - - # Check version - check_version (NetCDF - NAME "netcdf_meta.h" - HINTS ${NetCDF_C_INCLUDE_DIRS} - MACRO_REGEX "NC_VERSION_") - - # Check for parallel support - check_macro (NetCDF_C_HAS_PARALLEL - NAME TryNetCDF_PARALLEL.c - HINTS ${CMAKE_MODULE_PATH} - DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} - COMMENT "whether NetCDF has parallel support") - - # Check if logging enabled - set(CMAKE_REQUIRED_INCLUDES ${NetCDF_C_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${NetCDF_C_LIBRARIES}) - CHECK_FUNCTION_EXISTS(nc_set_log_level NetCDF_C_LOGGING_ENABLED) - - endif () - - # Dependencies - if (NCDFcomp STREQUAL C AND NOT NetCDF_C_IS_SHARED) - - # DEPENDENCY: PnetCDF (if PnetCDF enabled) - check_macro (NetCDF_C_HAS_PNETCDF - NAME TryNetCDF_PNETCDF.c - HINTS ${CMAKE_MODULE_PATH} - DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} - COMMENT "whether NetCDF has PnetCDF support") - if (NetCDF_C_HAS_PNETCDF) - find_package (PnetCDF COMPONENTS C) - if (CURL_FOUND) - list (APPEND NetCDF_C_INCLUDE_DIRS ${PnetCDF_C_INCLUDE_DIRS}) - list (APPEND NetCDF_C_LIBRARIES ${PnetCDF_C_LIBRARIES}) - endif () - endif () - - # DEPENDENCY: CURL (If DAP enabled) - check_macro (NetCDF_C_HAS_DAP - NAME TryNetCDF_DAP.c - HINTS ${CMAKE_MODULE_PATH} - DEFINITIONS -I${NetCDF_C_INCLUDE_DIR} - COMMENT "whether NetCDF has DAP support") - if (NetCDF_C_HAS_DAP) - find_package (CURL) - if (CURL_FOUND) - list (APPEND NetCDF_C_INCLUDE_DIRS ${CURL_INCLUDE_DIRS}) - list (APPEND NetCDF_C_LIBRARIES ${CURL_LIBRARIES}) - endif () - endif () - - # DEPENDENCY: HDF5 - find_package (HDF5 COMPONENTS HL C) - if (HDF5_C_FOUND) - list (APPEND NetCDF_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS} - ${HDF5_HL_INCLUDE_DIRS}) - list (APPEND NetCDF_C_LIBRARIES ${HDF5_C_LIBRARIES} - ${HDF5_HL_LIBRARIES}) - endif () - - # DEPENDENCY: LIBDL Math - list (APPEND NetCDF_C_LIBRARIES -ldl -lm) - - elseif (NCDFcomp STREQUAL Fortran AND NOT NetCDF_Fortran_IS_SHARED) - - # DEPENDENCY: NetCDF - set (orig_comp ${NCDFcomp}) - set (orig_comps ${NetCDF_FIND_VALID_COMPONENTS}) - find_package (NetCDF COMPONENTS C) - set (NetCDF_FIND_VALID_COMPONENTS ${orig_comps}) - set (NCDFcomp ${orig_comp}) - if (NetCDF_C_FOUND) - list (APPEND NetCDF_Fortran_INCLUDE_DIRS ${NetCDF_C_INCLUDE_DIRS}) - list (APPEND NetCDF_Fortran_LIBRARIES ${NetCDF_C_LIBRARIES}) - endif () - - endif () - - endif () - - endif () - -endforeach () diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index e52861d70..be5b89670 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -30,6 +30,6 @@ 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}) -target_include_directories (cmeps PUBLIC ${NetCDF_Fortran_INCLUDE_DIR}) + install(TARGETS cmeps LIBRARY DESTINATION lib) From c70410f002df1a9baa59332f109287b5015f3bd0 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 15:51:30 -0600 Subject: [PATCH 095/206] clean up wrt master --- CMakeLists.txt | 3 +- cime_config/namelist_definition_drv.xml | 26 ++++---- cime_config/runseq/runseq_general.py | 2 +- mediator/med.F90 | 86 ++----------------------- mediator/med_fraction_mod.F90 | 24 ++----- mediator/med_internalstate_mod.F90 | 12 +--- 6 files changed, 25 insertions(+), 128 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d4d7026d..14e0ef046 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,14 +21,13 @@ else() set(BLD_STANDALONE TRUE) endif() -project(CMEPS LANGUAGES C Fortran VERSION 0.1) +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() diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 4ba2a6dde..3bbc58483 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -855,11 +855,11 @@ 'on': always do this renormalization 'off': never do this renormalization (see WARNING below) 'on_if_glc_coupled_fluxes': Determine at runtime whether to do this renormalization. - Does the renormalization if we're running a two-way-coupled glc that sends fluxes - to other components (which is the case where we need conservation). - Does NOT do the renormalization if we're running a one-way-coupled glc, or if - we're running a glc-only compset (T compsets). - (In these cases, conservation is not important.) + Does the renormalization if we're running a two-way-coupled glc that sends fluxes + to other components (which is the case where we need conservation). + Does NOT do the renormalization if we're running a one-way-coupled glc, or if + we're running a glc-only compset (T compsets). + (In these cases, conservation is not important.) Only used if running with a prognostic GLC component. @@ -868,7 +868,7 @@ on_if_glc_coupled_fluxes - off + off @@ -901,7 +901,7 @@ mapping ATM_attributes - DOMAIN description of atm grid + DOMAIN description of atm grid $ATM_DOMAIN_PATH/$ATM_DOMAIN_FILE @@ -925,7 +925,7 @@ mapping LND_attributes - DOMAIN description of lnd grid + DOMAIN description of lnd grid $LND_DOMAIN_PATH/$LND_DOMAIN_FILE @@ -1094,6 +1094,7 @@ $CPL_ALBAV + char mapping @@ -1273,7 +1274,7 @@ - + @@ -2173,9 +2174,6 @@ - - - logical flds @@ -3326,9 +3324,9 @@ PELAYOUT_attributes Determines what ESMF log files (if any) are generated when - USE_ESMF_LIB is TRUE. + USE_ESMF_LIB is TRUE. ESMF_LOGKIND_SINGLE: Use a single log file, combining messages from - all of the PETs. Not supported on some platforms. + all of the PETs. Not supported on some platforms. ESMF_LOGKIND_MULTI: Use multiple log files — one per PET. ESMF_LOGKIND_NONE: Do not issue messages to a log file. By default, no ESMF log files are generated. diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 983c3f701..1bca91532 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -135,7 +135,7 @@ def gen_runseq(case, coupling_times): 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_ocn" , run_ocn and diag_mode) - runseq.add_action("MED med_phases_diag_glc" , run_glc 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) #------------------ diff --git a/mediator/med.F90 b/mediator/med.F90 index aefea0a4c..5e917e4f0 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -99,14 +99,17 @@ subroutine SetServices(gcomp, rc) use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum_avg 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 + use med_diag_mod , only: med_phases_diag_accum + use med_diag_mod , only: med_phases_diag_print use med_diag_mod , only: med_phases_diag_atm use med_diag_mod , only: med_phases_diag_lnd use med_diag_mod , only: med_phases_diag_rof use med_diag_mod , only: med_phases_diag_glc use med_diag_mod , only: med_phases_diag_ocn - use med_diag_mod , only: med_phases_diag_ice_ice2med, med_phases_diag_ice_med2ice - use med_fraction_mod , only: med_fraction_init, med_fraction_set + use med_diag_mod , only: med_phases_diag_ice_ice2med + use med_diag_mod , only: med_phases_diag_ice_med2ice + use med_fraction_mod , only: med_fraction_init + use med_fraction_mod , only: med_fraction_set use med_phases_profile_mod , only: med_phases_profile type(ESMF_GridComp) :: gcomp @@ -1764,10 +1767,6 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return is_local%wrap%FBExpAccumCnt(n1) = 0 - ! Create mesh info data - call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), & - is_local%wrap%mesh_info(n1), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return endif ! The following are FBImp and FBImpAccum mapped to different grids. @@ -2256,9 +2255,6 @@ subroutine SetRunClock(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call set_stop_alarm(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - first_time = .false. end if @@ -2278,76 +2274,6 @@ subroutine SetRunClock(gcomp, rc) end subroutine SetRunClock - !----------------------------------------------------------------------------- - !----------------------------------------------------------------------------- - - subroutine med_meshinfo_create(FB, mesh_info, rc) - - use ESMF , only : ESMF_Array, ESMF_ArrayCreate, ESMF_ArrayDestroy, ESMF_Field, ESMF_FieldGet - use ESMF , only : ESMF_DistGrid, ESMF_FieldBundle, ESMF_FieldRegridGetArea, ESMF_FieldBundleGet - use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO - use med_internalstate_mod , only : mesh_info_type - - ! input/output variables - type(ESMF_FieldBundle) , intent(in) :: FB - type(mesh_info_type) , intent(inout) :: mesh_info - integer , intent(out) :: 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(:) - real(r8), pointer :: dataptr(:) - integer :: n, dimcount, fieldcount - character(len=*),parameter :: subname='(module_MED:med_meshinfo_create)' - !------------------------------------------------------------------------------- - - rc= ESMF_SUCCESS - - 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 - 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) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Allocate mesh_info data, we need a copy here because the FB may get reset later - 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 - - 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 - do n = 1,numOwnedElements - mesh_info%lons(n) = ownedElemCoords(2*n-1) - mesh_info%lats(n) = ownedElemCoords(2*n) - end do - deallocate(ownedElemCoords) - - end subroutine med_meshinfo_create - !----------------------------------------------------------------------------- subroutine med_finalize(gcomp, rc) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index bcd442958..88431f867 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -108,7 +108,6 @@ module med_fraction_mod use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid use esmFlds , only : ncomps - use ESMF , only : ESMF_RouteHandle implicit none private @@ -132,8 +131,6 @@ module med_fraction_mod character(*), parameter :: u_FILE_u = & __FILE__ - type(ESMF_RouteHandle) :: rh_ice2atm - !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -155,16 +152,6 @@ subroutine med_fraction_init(gcomp, rc) use med_internalstate_mod , only : InternalState, logunit, mastertask use perf_mod , only : t_startf, t_stopf - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR - use ESMF , only : ESMF_Field, ESMF_FieldRegrid - use ESMF , only : ESMF_FieldRegridStore, ESMF_FieldRegridRelease - use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRedistRelease - use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL, ESMF_REGION_SELECT - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA - use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint - use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName - ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -183,10 +170,6 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: So_omask(:) integer :: i,j,n,n1 integer :: maptype - type(ESMF_RouteHandle) :: rh_ocn2atm - type(ESMF_RouteHandle) :: rh_lnd2atm - type(ESMF_RouteHandle) :: rh_atm2lnd - integer :: srcTermProcessing_Value = 0 logical, save :: first_call = .true. character(len=*),parameter :: subname='(med_fraction_init)' !--------------------------------------- @@ -366,6 +349,10 @@ subroutine med_fraction_init(gcomp, rc) !--------------------------------------- ! Set 'lfrac' in FBFrac(compatm) and correct 'ofrac' in FBFrac(compatm) ! --------------------------------------- + ! These should actually be mapo2a of ofrac and lfrac but we can't + ! map lfrac from o2a due to masked mapping weights. So we have to + ! settle for a residual calculation that is truncated to zero to + ! try to preserve "all ocean" cells. if (is_local%wrap%comp_present(compatm)) then @@ -577,7 +564,6 @@ subroutine med_fraction_set(gcomp, rc) use med_internalstate_mod , only : InternalState use med_map_mod , only : med_map_RH_is_created use perf_mod , only : t_startf, t_stopf - use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName ! input/output variables type(ESMF_GridComp) :: gcomp @@ -585,8 +571,6 @@ subroutine med_fraction_set(gcomp, rc) ! local variables type(InternalState) :: is_local - type(ESMF_Field) :: fldsrc - type(ESMF_Field) :: flddst real(r8), pointer :: lfrac(:) real(r8), pointer :: ifrac(:) real(r8), pointer :: ofrac(:) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index bbb588604..4a4ebde2a 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -40,14 +40,7 @@ module med_internalstate_mod .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 - - type, public :: mesh_info_type - real(r8), pointer :: areas(:) - real(r8), pointer :: lats(:) - real(r8), pointer :: lons(:) - end type mesh_info_type - + ! med atm lnd ocn ice rof wav glc ! private internal state to keep instance data type InternalStateStruct @@ -105,9 +98,6 @@ module med_internalstate_mod type(ESMF_FieldBundle) :: FBImpAccum(ncomps,ncomps) ! Accumulator for various components import integer :: FBImpAccumCnt(ncomps) ! Accumulator counter for each FBImpAccum - ! Component Mesh info - type(mesh_info_type) :: mesh_info(ncomps) - end type InternalStateStruct type, public :: InternalState From 88bd1f73e4a8d6135783eed005570573d1ae69c3 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 16:03:54 -0600 Subject: [PATCH 096/206] add back mesh_info --- mediator/med.F90 | 86 +++++++++++++++++++++++++++--- mediator/med_internalstate_mod.F90 | 12 ++++- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 5e917e4f0..aefea0a4c 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -99,17 +99,14 @@ subroutine SetServices(gcomp, rc) use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum_avg 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 - use med_diag_mod , only: med_phases_diag_print + use med_diag_mod , only: med_phases_diag_accum, med_phases_diag_print use med_diag_mod , only: med_phases_diag_atm use med_diag_mod , only: med_phases_diag_lnd use med_diag_mod , only: med_phases_diag_rof use med_diag_mod , only: med_phases_diag_glc use med_diag_mod , only: med_phases_diag_ocn - use med_diag_mod , only: med_phases_diag_ice_ice2med - use med_diag_mod , only: med_phases_diag_ice_med2ice - use med_fraction_mod , only: med_fraction_init - use med_fraction_mod , only: med_fraction_set + use med_diag_mod , only: med_phases_diag_ice_ice2med, med_phases_diag_ice_med2ice + use med_fraction_mod , only: med_fraction_init, med_fraction_set use med_phases_profile_mod , only: med_phases_profile type(ESMF_GridComp) :: gcomp @@ -1767,6 +1764,10 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return is_local%wrap%FBExpAccumCnt(n1) = 0 + ! Create mesh info data + call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), & + is_local%wrap%mesh_info(n1), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return endif ! The following are FBImp and FBImpAccum mapped to different grids. @@ -2255,6 +2256,9 @@ subroutine SetRunClock(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + call set_stop_alarm(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + first_time = .false. end if @@ -2274,6 +2278,76 @@ subroutine SetRunClock(gcomp, rc) end subroutine SetRunClock + !----------------------------------------------------------------------------- + !----------------------------------------------------------------------------- + + subroutine med_meshinfo_create(FB, mesh_info, rc) + + use ESMF , only : ESMF_Array, ESMF_ArrayCreate, ESMF_ArrayDestroy, ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_DistGrid, ESMF_FieldBundle, ESMF_FieldRegridGetArea, ESMF_FieldBundleGet + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO + use med_internalstate_mod , only : mesh_info_type + + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + type(mesh_info_type) , intent(inout) :: mesh_info + integer , intent(out) :: 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(:) + real(r8), pointer :: dataptr(:) + integer :: n, dimcount, fieldcount + character(len=*),parameter :: subname='(module_MED:med_meshinfo_create)' + !------------------------------------------------------------------------------- + + rc= ESMF_SUCCESS + + 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 + 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) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Allocate mesh_info data, we need a copy here because the FB may get reset later + 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 + + 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 + do n = 1,numOwnedElements + mesh_info%lons(n) = ownedElemCoords(2*n-1) + mesh_info%lats(n) = ownedElemCoords(2*n) + end do + deallocate(ownedElemCoords) + + end subroutine med_meshinfo_create + !----------------------------------------------------------------------------- subroutine med_finalize(gcomp, rc) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 4a4ebde2a..bbb588604 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -40,7 +40,14 @@ module med_internalstate_mod .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 + ! med atm lnd ocn ice rof wav glc + + type, public :: mesh_info_type + real(r8), pointer :: areas(:) + real(r8), pointer :: lats(:) + real(r8), pointer :: lons(:) + end type mesh_info_type + ! private internal state to keep instance data type InternalStateStruct @@ -98,6 +105,9 @@ module med_internalstate_mod type(ESMF_FieldBundle) :: FBImpAccum(ncomps,ncomps) ! Accumulator for various components import integer :: FBImpAccumCnt(ncomps) ! Accumulator counter for each FBImpAccum + ! Component Mesh info + type(mesh_info_type) :: mesh_info(ncomps) + end type InternalStateStruct type, public :: InternalState From c7cdf6aef89e90e459ab13b96fc669ace1cdaf70 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 16:06:23 -0600 Subject: [PATCH 097/206] add back mesh_info --- mediator/med.F90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index aefea0a4c..fbf50312a 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -27,7 +27,6 @@ module MED 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_time_mod , only : set_stop_alarm => med_time_set_component_stop_alarm use med_utils_mod , only : memcheck => med_memcheck use med_internalstate_mod , only : InternalState use med_internalstate_mod , only : med_coupling_allowed, logunit, mastertask @@ -2255,10 +2254,6 @@ subroutine SetRunClock(gcomp, rc) call ESMF_AlarmSet(glc_avg_alarm, clock=mediatorclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - - call set_stop_alarm(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - first_time = .false. end if From 9067ce03a01d0ddc20990c961dc7e6507d1499f0 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 7 Oct 2020 16:14:12 -0600 Subject: [PATCH 098/206] more cleanup wrt master --- mediator/med.F90 | 2 +- mediator/med_phases_prep_glc_mod.F90 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index fbf50312a..d281f5e9d 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1764,7 +1764,7 @@ subroutine DataInitialize(gcomp, rc) is_local%wrap%FBExpAccumCnt(n1) = 0 ! Create mesh info data - call med_meshinfo_create(is_local%wrap%FBImpAccum(n1,n1), & + 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 diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 9d08f6465..4ab32080d 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -275,7 +275,7 @@ subroutine med_phases_prep_glc_init(gcomp, 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, elemAreaArray=lArray, 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) @@ -287,7 +287,7 @@ subroutine med_phases_prep_glc_init(gcomp, 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, elemAreaArray=lArray, 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) From 118db688c5273e54527ac5042f43923644d51cb5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 8 Oct 2020 13:14:19 -0600 Subject: [PATCH 099/206] fixed problem with stop alarm initialization --- mediator/med.F90 | 6 +----- mediator/med_diag_mod.F90 | 40 ++++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index d281f5e9d..12a289d81 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -2174,15 +2174,10 @@ subroutine SetRunClock(gcomp, rc) type(ESMF_Time) :: currTime type(ESMF_TimeInterval) :: timeStep character(len=CL) :: cvalue - character(len=CL) :: restart_option ! Restart option units - integer :: restart_n ! Number until restart interval - integer :: restart_ymd ! Restart date (YYYYMMDD) - type(ESMF_ALARM) :: restart_alarm type(ESMF_ALARM) :: glc_avg_alarm logical :: glc_present character(len=CS) :: glc_avg_period integer :: glc_cpl_dt - type(ESMF_ALARM) :: alarm logical :: first_time = .true. character(len=*),parameter :: subname='(module_MED:SetRunClock)' !----------------------------------------------------------- @@ -2222,6 +2217,7 @@ subroutine SetRunClock(gcomp, rc) !-------------------------------- 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 diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index ca00eb38a..e7963e7e1 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -16,6 +16,7 @@ module med_diag_mod !---------------------------------------------------------------------------- use NUOPC , only : NUOPC_CompAttributeGet + use NUOPC_Mediator , only : NUOPC_MediatorGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR use ESMF , only : ESMF_GridComp, ESMF_Clock, ESMF_Time @@ -29,6 +30,7 @@ module med_diag_mod 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 implicit none @@ -236,10 +238,15 @@ subroutine med_diag_init(gcomp, rc) integer , intent(out) :: rc ! local variables - character(CS) :: cvalue - integer :: c_size ! number of component send/recvs - integer :: f_size ! number of fields - integer :: p_size ! number of period types + character(CS) :: cvalue + integer :: c_size ! number of component send/recvs + integer :: f_size ! number of fields + integer :: p_size ! number of period types + type(ESMF_Clock) :: mediatorClock + character(CS) :: stop_option + integer :: stop_n ! Number until restart interval + integer :: stop_ymd ! Restart date (YYYYMMDD) + type(ESMF_ALARM) :: stop_alarm ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -368,6 +375,21 @@ subroutine med_diag_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) budget_print_ltend + ! Set stop alarm (needed for budgets) + call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_n + call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_ymd + call NUOPC_MediatorGet(gcomp, mediatorClock=mediatorClock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call alarmInit(mediatorclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & + alarmname='alarm_stop', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end subroutine med_diag_init !=============================================================================== @@ -1725,19 +1747,19 @@ subroutine med_phases_diag_print(gcomp, rc) output_level = 0 if (ip == period_inst) then output_level = max(output_level, budget_print_inst) - endif + end if if (ip == period_day .and. curr_tod == 0) then output_level = max(output_level, budget_print_daily) - endif + end if if (ip == period_mon .and. curr_day == 1 .and. curr_tod == 0) then output_level = max(output_level, budget_print_month) - endif + end if if (ip == period_ann .and. curr_mon == 1 .and. curr_day == 1 .and. curr_tod == 0) then output_level = max(output_level, budget_print_ann) - endif + end if if (ip == period_inf .and. curr_mon == 1 .and. curr_day == 1 .and. curr_tod == 0) then output_level = max(output_level, budget_print_ltann) - endif + end if if (ip == period_inf) then call ESMF_ClockGetAlarm(clock, alarmname='alarm_stop', alarm=stop_alarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 71658481194759c86988043d03f293d2f4bd2762 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 9 Oct 2020 11:19:38 -0600 Subject: [PATCH 100/206] add B1850 test, list SourceMods dir first in build --- cime_config/buildexe | 3 ++- cime_config/testdefs/testlist_drv.xml | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cime_config/buildexe b/cime_config/buildexe index 0d336d9a8..ed5b04459 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -83,9 +83,10 @@ def _main_func(): with open(os.path.join(bld_root,'Filepath'), 'w') as out: cmeps_dir = os.path.join(os.path.dirname(__file__), os.pardir) + # SourceMods dir needs to be first listed + out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") if not skip_mediator: out.write(os.path.join(cmeps_dir, "mediator") + "\n") - out.write(os.path.join(caseroot, "SourceMods", "src.drv") + "\n") out.write(os.path.join(cmeps_dir, "drivers", "cime") + "\n") # build model executable diff --git a/cime_config/testdefs/testlist_drv.xml b/cime_config/testdefs/testlist_drv.xml index 01b4a9691..ad1d2514d 100644 --- a/cime_config/testdefs/testlist_drv.xml +++ b/cime_config/testdefs/testlist_drv.xml @@ -165,6 +165,14 @@ + + + + + + + + @@ -464,18 +472,18 @@ - - - + + + - - - + + + From 3c1249a49a2972b7ad746ebb701262917538f29f Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 24 Aug 2020 20:01:33 +0000 Subject: [PATCH 101/206] Split esmFldsExchange_hafs_mod.F90 into advertise and initialize phases. --- mediator/esmFldsExchange_hafs_mod.F90 | 851 ++++++++++++++++---------- 1 file changed, 534 insertions(+), 317 deletions(-) diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index 92b90d16c..eb8181635 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -1,5 +1,21 @@ module esmFldsExchange_hafs_mod + use ESMF + use NUOPC + use med_utils_mod, only : chkerr => med_utils_chkerr + use med_kind_mod, only : CX=>SHR_KIND_CX + use med_kind_mod, only : CS=>SHR_KIND_CS + use med_kind_mod, only : CL=>SHR_KIND_CL + use med_kind_mod, only : R8=>SHR_KIND_R8 + use esmflds, only : compmed + use esmflds, only : compatm + use esmflds, only : compocn + use esmflds, only : compice + use esmflds, only : ncomps + use esmflds, only : fldListTo + use esmflds, only : fldListFr + use esmFlds, only : coupling_mode + !--------------------------------------------------------------------- ! This is a mediator specific routine that determines ALL possible ! fields exchanged between components and their associated routing, @@ -14,28 +30,272 @@ module esmFldsExchange_hafs_mod character(*), parameter :: u_FILE_u = & __FILE__ -!================================================================================ + type gcomp_attr + character(len=CX) :: atm2ice_fmap='unset' + character(len=CX) :: atm2ice_smap='unset' + character(len=CX) :: atm2ice_vmap='unset' + character(len=CX) :: atm2ocn_fmap='unset' + character(len=CX) :: atm2ocn_smap='unset' + character(len=CX) :: atm2ocn_vmap='unset' + character(len=CX) :: ice2atm_fmap='unset' + character(len=CX) :: ice2atm_smap='unset' + character(len=CX) :: ocn2atm_fmap='unset' + character(len=CX) :: ocn2atm_smap='unset' + end type + +!=============================================================================== contains -!================================================================================ +!=============================================================================== subroutine esmFldsExchange_hafs(gcomp, phase, rc) - use ESMF - use NUOPC - 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 + ! input/output parameters: + type(ESMF_GridComp) :: gcomp + character(len=*) , intent(in) :: phase + integer , intent(inout) :: rc + + ! local variables: + !-------------------------------------- + + rc = ESMF_SUCCESS + + if (phase == 'advertise') then + call esmFldsExchange_hafs_advt(gcomp, phase, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call esmFldsExchange_hafs_init(gcomp, phase, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + end subroutine esmFldsExchange_hafs + + !----------------------------------------------------------------------------- + + subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc) + + use esmFlds , only : addfld => med_fldList_AddFld + + ! input/output parameters: + type(ESMF_GridComp) :: gcomp + character(len=*) , intent(in) :: phase + integer , intent(inout) :: rc + + ! local variables: + integer :: num, i, n + logical :: isPresent + !character(len=5) :: iso(2) + character(len=CL) :: cvalue + character(len=CS) :: name, fldname + character(len=CS), allocatable :: flds(:) + character(len=CS), allocatable :: suffix(:) + character(len=*) , parameter :: subname='(esmFldsExchange_hafs_advt)' + !-------------------------------------- + + rc = ESMF_SUCCESS + + !===================================================================== + ! scalar information + !===================================================================== + call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldName", value=cvalue, & + rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,ncomps + call addfld(fldListFr(n)%flds, trim(cvalue)) + call addfld(fldListTo(n)%flds, trim(cvalue)) + end do + + !===================================================================== + ! FIELDS TO MEDIATOR component (for fractions and atm/ocn flux calculation) + !===================================================================== + + !---------------------------------------------------------- + ! to med: masks from components + !---------------------------------------------------------- + call addfld(fldListFr(compocn)%flds, 'So_omask') + call addfld(fldListFr(compice)%flds, 'Si_imask') + + ! --------------------------------------------------------------------- + ! to med: swnet fluxes used for budget calculation + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') + + !===================================================================== + ! FIELDS TO ATMOSPHERE + !===================================================================== + + !---------------------------------------------------------- + ! to atm: Fractions + !---------------------------------------------------------- + ! the following are computed in med_phases_prep_atm + call addfld(fldListTo(compatm)%flds, 'Si_ifrac') + call addfld(fldListTo(compatm)%flds, 'So_ofrac') + + !===================================================================== + ! FIELDS TO OCEAN (compocn) + !===================================================================== + + !---------------------------------------------------------- + ! to ocn: req. fields to satisfy mediator (can be removed later) + !---------------------------------------------------------- + allocate(flds(2)) + flds = (/'Faxa_snowc', 'Faxa_snowl'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + end do + deallocate(flds) + + allocate(flds(4)) + flds = (/'Sa_topo', 'Sa_z ', 'Sa_ptem', 'Sa_pbot'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + end do + deallocate(flds) + + !---------------------------------------------------------- + ! to ocn: fractional ice coverage wrt ocean from ice + !---------------------------------------------------------- + call addfld(fldListFr(compice)%flds, 'Si_ifrac') + call addfld(fldListTo(compocn)%flds, 'Si_ifrac') + + ! --------------------------------------------------------------------- + ! to ocn: downward longwave heat flux from atm + ! to ocn: downward direct near-infrared incident solar radiation from atm + ! to ocn: downward diffuse near-infrared incident solar radiation from atm + ! to ocn: downward dirrect visible incident solar radiation from atm + ! to ocn: downward diffuse visible incident solar radiation from atm + ! --------------------------------------------------------------------- + allocate(flds(5)) + flds = (/'Faxa_lwdn ', 'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', & + 'Faxa_swvdf'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ocn: longwave net heat flux + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds, 'Faxa_lwnet') + call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') + + ! --------------------------------------------------------------------- + ! to ocn: downward shortwave heat flux + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds, 'Faxa_swdn') + call addfld(fldListTo(compocn)%flds, 'Faxa_swdn') + + ! --------------------------------------------------------------------- + ! to ocn: net shortwave radiation from atm + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet') + + ! --------------------------------------------------------------------- + ! to ocn: precipitation rate from atm + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') + call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') + call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) + call addfld(fldListTo(compocn)%flds, 'Faxa_rain' ) + + ! --------------------------------------------------------------------- + ! to ocn: sensible heat flux from atm + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds , 'Faxa_sen') + call addfld(fldListTo(compocn)%flds , 'Foxx_sen') + + ! --------------------------------------------------------------------- + ! to ocn: surface latent heat flux and evaporation water flux + ! --------------------------------------------------------------------- + call addfld(fldListFr(compatm)%flds , 'Faxa_lat') + call addfld(fldListTo(compocn)%flds , 'Foxx_lat') + + ! --------------------------------------------------------------------- + ! to ocn: sea level pressure from atm + ! to ocn: zonal wind at the lowest model level from atm + ! to ocn: meridional wind at the lowest model level from atm + ! to ocn: wind speed at the lowest model level from atm + ! to ocn: temperature at the lowest model level from atm + ! to ocn: sea surface skin temperature + ! 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', & + 'Sa_shum'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ocn: zonal and meridional surface stress from atm + ! --------------------------------------------------------------------- + allocate(suffix(2)) + suffix = (/'taux', 'tauy'/) + + do n = 1,size(suffix) + call addfld(fldListFr(compatm)%flds , 'Faxa_'//trim(suffix(n))) + call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) + end do + deallocate(suffix) + + !===================================================================== + ! FIELDS TO ICE (compice) + !===================================================================== + + ! --------------------------------------------------------------------- + ! to ice: density at the lowest model level from atm + ! --------------------------------------------------------------------- + allocate(flds(1)) + flds = (/'Sa_dens'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compice)%flds, trim(fldname)) + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ice: zonal sea water velocity from ocn + ! --------------------------------------------------------------------- + allocate(flds(2)) + flds = (/'So_u ', 'So_v '/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + call addfld(fldListFr(compocn)%flds, trim(fldname)) + call addfld(fldListTo(compice)%flds, trim(fldname)) + end do + deallocate(flds) + + end subroutine esmFldsExchange_hafs_advt + + !----------------------------------------------------------------------------- + + subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) + use med_methods_mod , only : fldchk => med_methods_FB_FldChk use med_internalstate_mod , only : InternalState use esmFlds , only : med_fldList_type - use esmFlds , only : addfld => med_fldList_AddFld use esmFlds , only : addmap => med_fldList_AddMap use esmFlds , only : addmrg => med_fldList_AddMrg - use esmflds , only : compmed, compatm, compocn, compice, ncomps use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch - use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf + use esmflds , only : mapfcopy, mapnstod, mapnstod_consd + use esmflds , only : mapnstod_consf use esmflds , only : mapuv_with_cart3d - use esmflds , only : fldListTo, fldListFr - use esmFlds , only : coupling_mode ! input/output parameters: type(ESMF_GridComp) :: gcomp @@ -44,20 +304,16 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! local variables: type(InternalState) :: is_local - integer :: dbrc integer :: num, i, n integer :: n1, n2, n3, n4 logical :: isPresent !character(len=5) :: iso(2) character(len=CL) :: cvalue character(len=CS) :: name, fldname - character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' - character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' - character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' - character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' + type(gcomp_attr) :: hafs_attr character(len=CS), allocatable :: flds(:) character(len=CS), allocatable :: suffix(:) - character(len=*) , parameter :: subname='(esmFldsExchange_hafs)' + character(len=*) , parameter :: subname='(esmFldsExchange_hafs_init)' !-------------------------------------- rc = ESMF_SUCCESS @@ -65,117 +321,36 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) !--------------------------------------- ! Get the internal state !--------------------------------------- - - if (phase /= 'advertise') then - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return !-------------------------------------- ! Merging arguments: ! mrg_fromN = source component index that for the field to be merged ! mrg_fldN = souce field name to be merged - ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', 'sum_with_weights', 'merge') + ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', + ! 'sum_with_weights', 'merge') ! NOTE: - ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn fluxes or for ocn albedos + ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn + ! fluxes or for ocn albedos ! ! NOTE: - ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in the - ! atm/ocn flux calculations. Input fields required from either the atm or the ocn for - ! these computation will use the logical 'use_med_aoflux' below. This is used to determine - ! mappings between the atm and ocn needed for these computations. + ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in + ! the atm/ocn flux calculations. Input fields required from either the atm + ! or the ocn for these computation will use the logical 'use_med_aoflux' + ! below. This is used to determine mappings between the atm and ocn needed + ! for these computations. !-------------------------------------- - !---------------------------------------------------------- - ! Initialize mapping file names - !---------------------------------------------------------- - - ! to atm - - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', value=ice2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_fmapname = '// trim(ice2atm_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', value=ice2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_smapname = '// trim(ice2atm_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', value=ocn2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_smapname = '// trim(ocn2atm_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', value=ocn2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_fmapname = '// trim(ocn2atm_fmap), ESMF_LOGMSG_INFO) - end if - - ! to ice - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_fmapname = '// trim(atm2ice_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, isPresent=isPresent, rc=rc) + call esmFldsExchange_hafs_attr(gcomp, hafs_attr, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_smapname = '// trim(atm2ice_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_vmapname = '// trim(atm2ice_vmap), ESMF_LOGMSG_INFO) - end if - - ! to ocn - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_fmapname = '// trim(atm2ocn_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_smapname = '// trim(atm2ocn_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_vmapname = '// trim(atm2ocn_vmap), ESMF_LOGMSG_INFO) - end if !---------------------------------------------------------- ! Initialize if use 3d cartesian mapping for u,v !---------------------------------------------------------- - mapuv_with_cart3d = .false. - !===================================================================== - ! scalar information - !===================================================================== - - if (phase == 'advertise') then - call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldName", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1,ncomps - call addfld(fldListFr(n)%flds, trim(cvalue)) - call addfld(fldListTo(n)%flds, trim(cvalue)) - end do - end if - !===================================================================== ! FIELDS TO MEDIATOR component (for fractions and atm/ocn flux calculation) !===================================================================== @@ -183,90 +358,66 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) !---------------------------------------------------------- ! to med: masks from components !---------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, 'So_omask') - call addfld(fldListFr(compice)%flds, 'Si_imask') - else - call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') - end if + call addmap(fldListFr(compocn)%flds, 'So_omask', compice, & + mapfcopy, 'unset', 'unset') ! --------------------------------------------------------------------- ! to med: atm and ocn fields required for atm/ocn flux calculation ! --------------------------------------------------------------------- - if (phase /= 'advertise') then - allocate(flds(6)) - flds = (/'Sa_u ', 'Sa_v ', 'Sa_z ', 'Sa_tbot', 'Sa_pbot', 'Sa_shum'/) - do n = 1,size(flds) - fldname = trim(flds(n)) - call addfld(fldListFr(compatm)%flds, trim(fldname)) - if (trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v') then - !call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mappatch, 'one', atm2ocn_vmap) - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapbilnr, 'one', atm2ocn_smap) - else - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapbilnr, 'one', atm2ocn_smap) - end if - end do - deallocate(flds) - end if + allocate(flds(6)) + flds = (/'Sa_u ', 'Sa_v ', 'Sa_z ', 'Sa_tbot', 'Sa_pbot', 'Sa_shum'/) + do n = 1,size(flds) + fldname = trim(flds(n)) + if (trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v') then + !call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & + ! mappatch, 'one', hafs_attr%atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + else + call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + end if + end do + deallocate(flds) ! --------------------------------------------------------------------- ! to med: unused fields needed by the atm/ocn flux computation ! --------------------------------------------------------------------- - - if (phase /= 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_u') - !call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch, 'one', atm2ocn_vmap) - call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mapbilnr, 'one', atm2ocn_vmap) - - call addfld(fldListFr(compatm)%flds, 'Sa_v') - !call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch, 'one', atm2ocn_vmap) - call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mapbilnr, 'one', atm2ocn_vmap) - - call addfld(fldListFr(compatm)%flds, 'Sa_z') - call addmap(fldListFr(compatm)%flds, 'Sa_z' , compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_tbot') - call addmap(fldListFr(compatm)%flds, 'Sa_tbot', compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_pbot') - call addmap(fldListFr(compatm)%flds, 'Sa_pbot', compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_shum') - call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, mapbilnr, 'one', atm2ocn_smap) - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_ptem', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_ptem') - call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_dens', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_dens') - call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, mapbilnr, 'one', atm2ocn_smap) - end if + !call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, & + ! mappatch, 'one', hafs_attr%atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_vmap) + !call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, & + ! mappatch, 'one', hafs_attr%atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, 'Sa_z' , compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + call addmap(fldListFr(compatm)%flds, 'Sa_tbot', compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + call addmap(fldListFr(compatm)%flds, 'Sa_pbot', compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + if (fldchk(is_local%wrap%FBImp(compatm,compatm),'Sa_ptem',rc=rc)) then + call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + end if + if (fldchk(is_local%wrap%FBImp(compatm,compatm),'Sa_dens',rc=rc)) then + call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) end if ! --------------------------------------------------------------------- ! to med: swnet fluxes used for budget calculation ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one', atm2ocn_fmap) - end if + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, & + mapconsf, 'one', hafs_attr%atm2ocn_fmap) !===================================================================== ! FIELDS TO ATMOSPHERE !===================================================================== - !---------------------------------------------------------- - ! to atm: Fractions - !---------------------------------------------------------- - if (phase == 'advertise') then - ! the following are computed in med_phases_prep_atm - call addfld(fldListTo(compatm)%flds, 'Si_ifrac') - call addfld(fldListTo(compatm)%flds, 'So_ofrac') - end if - !===================================================================== ! FIELDS TO OCEAN (compocn) !===================================================================== @@ -279,16 +430,13 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) do n = 1,size(flds) fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - 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') - end if + 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', hafs_attr%atm2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') end if end do deallocate(flds) @@ -298,16 +446,13 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) do n = 1,size(flds) fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - 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, mapbilnr, 'one', atm2ocn_smap) - call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') - end if + 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, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + call addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') end if end do deallocate(flds) @@ -315,13 +460,10 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) !---------------------------------------------------------- ! to ocn: fractional ice coverage wrt ocean from ice !---------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds, 'Si_ifrac') - 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') - end if + 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') ! --------------------------------------------------------------------- ! to ocn: downward longwave heat flux from atm @@ -331,20 +473,19 @@ subroutine esmFldsExchange_hafs(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)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - 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') - end if + 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', 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') end if end do deallocate(flds) @@ -352,90 +493,69 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) ! --------------------------------------------------------------------- ! to ocn: longwave net heat flux ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_lwnet') - call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_lwnet', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy') - end if + 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') ! --------------------------------------------------------------------- ! to ocn: downward shortwave heat flux ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swdn') - call addfld(fldListTo(compocn)%flds, 'Faxa_swdn') - else - if (fldchk(is_local%wrap%FBImp(compatm, compatm), 'Faxa_swdn', rc=rc) .and. & - 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') - end if + if (fldchk(is_local%wrap%FBImp(compatm,compatm),'Faxa_swdn',rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn),'Faxa_swdn',rc=rc) & + ) then + 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') end if ! --------------------------------------------------------------------- ! to ocn: net shortwave radiation from atm ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_swnet', & - mrg_from1=compatm, mrg_fld1='Faxa_swnet', mrg_type1='copy') - end if + 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') ! --------------------------------------------------------------------- ! to ocn: precipitation rate from atm ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') - call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') - call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) - call addfld(fldListTo(compocn)%flds, 'Faxa_rain' ) - else - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_rain' , rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_rainl', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_rainc', compocn, mapconsf, 'one', 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') - 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', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Faxa_rain', mrg_from1=compatm, mrg_fld1='Faxa_rain', & - mrg_type1='copy') - end if + if (fldchk(is_local%wrap%FBImp(compatm,compatm),'Faxa_rainl',rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm),'Faxa_rainc',rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn),'Faxa_rain',rc=rc) & + ) then + call addmap(fldListFr(compatm)%flds, 'Faxa_rainl', compocn, & + mapconsf, 'one', hafs_attr%atm2ocn_fmap) + 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') + 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') end if ! --------------------------------------------------------------------- ! to ocn: sensible heat flux from atm ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_sen') - call addfld(fldListTo(compocn)%flds , 'Foxx_sen') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_sen', & - mrg_from1=compatm, mrg_fld1='Faxa_sen', mrg_type1='copy') - end if + 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') ! --------------------------------------------------------------------- ! to ocn: surface latent heat flux and evaporation water flux ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_lat') - call addfld(fldListTo(compocn)%flds , 'Foxx_lat') - else - call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_lat', & - mrg_from1=compatm, mrg_fld1='Faxa_lat', mrg_type1='copy') - end if + 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') ! --------------------------------------------------------------------- ! to ocn: sea level pressure from atm @@ -447,20 +567,18 @@ subroutine esmFldsExchange_hafs(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', 'Sa_shum'/) + flds = (/'Sa_pslv', 'Sa_u ', 'Sa_v ', 'Sa_wspd', 'Sa_tbot', 'Sa_tskn', & + 'Sa_shum'/) do n = 1,size(flds) fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - if (fldchk(is_local%wrap%FBImp(compatm, compatm), trim(fldname), rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc)) then - call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapbilnr, 'one', atm2ocn_smap) - call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') - end if + 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, & + mapbilnr, 'one', hafs_attr%atm2ocn_smap) + call addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') end if end do deallocate(flds) @@ -472,14 +590,11 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) suffix = (/'taux', 'tauy'/) do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_'//trim(suffix(n))) - call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) - else - call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n)), compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & - mrg_from1=compatm, mrg_fld1='Faxa_'//trim(suffix(n)), mrg_type1='copy') - end if + 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') end do deallocate(suffix) @@ -495,16 +610,13 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) do n = 1,size(flds) fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compice)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapbilnr, 'one', atm2ice_smap) - call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') - end if + if (fldchk(is_local%wrap%FBexp(compice),trim(fldname),rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm),trim(fldname),rc=rc) & + ) then + 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') end if end do deallocate(flds) @@ -517,20 +629,125 @@ subroutine esmFldsExchange_hafs(gcomp, phase, rc) do n = 1,size(flds) fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, trim(fldname)) - call addfld(fldListTo(compice)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & - 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') - end if + if (fldchk(is_local%wrap%FBexp(compice),trim(fldname),rc=rc) .and. & + 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') end if end do deallocate(flds) - end subroutine esmFldsExchange_hafs + end subroutine esmFldsExchange_hafs_init + + !----------------------------------------------------------------------------- + + subroutine esmFldsExchange_hafs_attr(gcomp, hafs_attr, rc) + + ! input/output parameters: + type(ESMF_GridComp) :: gcomp + type(gcomp_attr) , intent(inout) :: hafs_attr + integer , intent(inout) :: rc + + ! local variables: + logical :: isPresent + character(len=*) , parameter :: subname='(esmFldsExchange_hafs_attr)' + !-------------------------------------- + + rc = ESMF_SUCCESS + + !---------------------------------------------------------- + ! Initialize mapping file names + !---------------------------------------------------------- + + ! to atm + + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', & + value=hafs_attr%ice2atm_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ice2atm_fmapname = '//trim(hafs_attr%ice2atm_fmap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', & + value=hafs_attr%ice2atm_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ice2atm_smapname = '//trim(hafs_attr%ice2atm_smap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', & + value=hafs_attr%ocn2atm_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ocn2atm_smapname = '//trim(hafs_attr%ocn2atm_smap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', & + value=hafs_attr%ocn2atm_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ocn2atm_fmapname = '//trim(hafs_attr%ocn2atm_fmap), & + ESMF_LOGMSG_INFO) + end if + + ! to ice + + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', & + value=hafs_attr%atm2ice_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ice_fmapname = '//trim(hafs_attr%atm2ice_fmap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', & + value=hafs_attr%atm2ice_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ice_smapname = '//trim(hafs_attr%atm2ice_smap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', & + value=hafs_attr%atm2ice_vmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ice_vmapname = '//trim(hafs_attr%atm2ice_vmap), & + ESMF_LOGMSG_INFO) + end if + + ! to ocn + + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', & + value=hafs_attr%atm2ocn_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ocn_fmapname = '//trim(hafs_attr%atm2ocn_fmap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', & + value=hafs_attr%atm2ocn_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ocn_smapname = '//trim(hafs_attr%atm2ocn_smap), & + ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', & + value=hafs_attr%atm2ocn_vmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ocn_vmapname = '//trim(hafs_attr%atm2ocn_vmap), & + ESMF_LOGMSG_INFO) + end if + + end subroutine esmFldsExchange_hafs_attr end module esmFldsExchange_hafs_mod From d390f6cdea19195d5219062ac2759b704f12d339 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 14 Oct 2020 15:45:28 -0600 Subject: [PATCH 102/206] fix diags for c case --- cime_config/runseq/runseq_general.py | 1 - mediator/med_diag_mod.F90 | 7 +++++- mediator/med_methods_mod.F90 | 37 ++++++++++++++-------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 1bca91532..df8002825 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -134,7 +134,6 @@ def gen_runseq(case, coupling_times): 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_ocn" , run_ocn 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) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index e7963e7e1..30ca014b6 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -1735,11 +1735,16 @@ subroutine med_phases_diag_print(gcomp, rc) call ESMF_TimeGet( currTime, yy=curr_year, mm=curr_mon, dd=curr_day, s=curr_tod, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return cdate = curr_year*10000 + curr_mon*100 + curr_day +#ifdef DEBUG if(mastertask) then write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') curr_year,'-',curr_mon,'-',curr_day,'-',curr_tod write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) endif - +#endif + if(firstcall) then + firstcall = .false. + return + endif sumdone = .false. do ip = 1,size(budget_diags%periods) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index f63638b46..9ec6500a7 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -163,7 +163,7 @@ subroutine med_methods_FB_RWFields(mode,fname,FB,flag,rc) enddo call med_methods_FB_diagnose(FB, 'read '//trim(fname), rc) - if (present(flag)) flag = .true. + if (present(flag)) flag = .true. endif else @@ -185,19 +185,19 @@ subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, r ! ---------------------------------------------- use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleAdd, ESMF_FieldBundleCreate + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleAdd, ESMF_FieldBundleCreate use ESMF , only : ESMF_State, ESMF_StateGet, ESMF_Mesh, ESMF_MeshLoc use ESMF , only : ESMF_AttributeGet, ESMF_INDEX_DELOCAL ! input/output variables type(ESMF_State) , intent(in) :: StateIn ! input state - type(ESMF_FieldBundle), intent(inout) :: FBout ! output field bundle + type(ESMF_FieldBundle), intent(inout) :: FBout ! output field bundle character(len=*) , intent(in) :: flds_scalar_name ! name of scalar fields character(len=*) , intent(in) :: name integer , intent(out) :: rc ! local variables - logical :: isPresent + logical :: isPresent integer :: n,n1 type(ESMF_Field) :: lfield type(ESMF_Field) :: newfield @@ -294,7 +294,7 @@ subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, r call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! create new field without an ungridded dimension + ! create new field without an ungridded dimension newfield = ESMF_FieldCreate(lmesh, dataptr1d, ESMF_INDEX_DELOCAL, & meshloc=meshloc, name=lfieldNameList(n), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -338,7 +338,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S use ESMF , only : ESMF_TYPEKIND_R8, ESMF_FIELDSTATUS_EMPTY, ESMF_AttributeGet ! input/output variables - type(ESMF_FieldBundle), intent(inout) :: FBout ! output field bundle + type(ESMF_FieldBundle), intent(inout) :: FBout ! output field bundle character(len=*) , intent(in) :: flds_scalar_name ! name of scalar fields character(len=*) , intent(in), optional :: fieldNameList(:) ! names of fields to use in output field bundle type(ESMF_FieldBundle), intent(in), optional :: FBgeom ! input field bundle geometry to use @@ -541,7 +541,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S do n = 1, fieldCount ! Note that input fields come from ONE of FBFlds, STflds, or fieldNamelist input argument - if (present(FBFlds) .or. present(STflds)) then + if (present(FBFlds) .or. present(STflds)) then ! ungridded dimensions might be present in the input states or field bundles if (present(FBflds)) then @@ -587,14 +587,14 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S if (chkerr(rc,__LINE__,u_FILE_u)) return end if - else if (present(fieldNameList)) then - + else if (present(fieldNameList)) then + ! Assume no ungridded dimensions if just the field name list is give field = ESMF_FieldCreate(lmesh, ESMF_TYPEKIND_R8, meshloc=meshloc, name=lfieldNameList(n), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - + end if - + ! Add the created field bundle FBout if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" adding field "//trim(lfieldNameList(n)), & @@ -602,7 +602,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S end if call ESMF_FieldBundleAdd(FBout, (/field/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - + enddo ! fieldCount endif ! fieldcountgeom @@ -1680,7 +1680,7 @@ logical function med_methods_FB_FldChk(FB, fldname, rc) call ESMF_FieldBundleGet(FB, fieldName=trim(fldname), isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) then - call ESMF_LogWrite(trim(subname)//" Error checking field: "//trim(fldname), & + call ESMF_LogWrite(trim(subname)//" Error checking field: "//trim(fldname), & ESMF_LOGMSG_ERROR) return endif @@ -1771,7 +1771,7 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (nnodes == 0 .and. nelements == 0) lrank = 0 - else + else call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & ESMF_LOGMSG_INFO) rc = ESMF_FAILURE @@ -3129,7 +3129,7 @@ subroutine med_methods_State_GetScalar(state, scalar_id, scalar_value, flds_scal else scalar_value = 0.0_R8 call ESMF_LogWrite(trim(subname)//": no ESMF_Field found named: "//trim(flds_scalar_name), ESMF_LOGMSG_INFO) - end if + end if end subroutine med_methods_State_GetScalar @@ -3345,7 +3345,7 @@ end subroutine med_methods_State_FldDebug subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) - ! ---------------------------------------------- + ! ---------------------------------------------- ! Determine if fieldbundle is created and if so, the number of non-scalar ! fields in the field bundle ! ---------------------------------------------- @@ -3363,7 +3363,7 @@ subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) if (.not. ESMF_FieldBundleIsCreated(FB)) then call ESMF_LogWrite(trim(string)//": has not been created, returning", ESMF_LOGMSG_INFO) - nflds = 0 + nflds = 0 else ! 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 @@ -3381,7 +3381,7 @@ end subroutine med_methods_FB_getNumFlds subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fldnames_shared, rc) - ! ---------------------------------------------- + ! ---------------------------------------------- ! Get shared Fld names between State1 and State2 and ! allocate the return array fldnames_shared ! ---------------------------------------------- @@ -3447,4 +3447,3 @@ subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fl end subroutine med_methods_States_GetSharedFlds end module med_methods_mod - From cc634da8ce76cc31122ed0b01984a003275500e4 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 19 Oct 2020 16:02:26 -0600 Subject: [PATCH 103/206] add med_diag to Makefile --- mediator/Makefile | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/mediator/Makefile b/mediator/Makefile index d40272a19..524fa581c 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -22,13 +22,13 @@ all default: $(LIBRARY) $(LIBRARY): $(OBJ) $(AR) $(ARFLAGS) $@ $? -%.o: %.F90 +%.o: %.F90 $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.F90 clean: $(RM) -f $(LIBRARY) *.i90 *.o *.mod -med_kind_mod.o : +med_kind_mod.o : med_constants_mod.o : med_kind_mod.o esmFlds.o : med_kind_mod.o esmFldsExchange_cesm_mod.o : med_kind_mod.o med_methods_mod.o esmFlds.o med_internalstate_mod.o med_utils_mod.o @@ -39,23 +39,24 @@ med.o : med_kind_mod.o med_phases_profile_mod.o med_utils_mod.o med_phases_prep_ 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 -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 -med_map_mod.o : med_kind_mod.o med_internalstate_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o med_utils_mod.o -med_merge_mod.o : med_kind_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o med_utils_mod.o -med_methods_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o -med_phases_aofluxes_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o -med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_time_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o -med_phases_ocnalb_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o -med_phases_prep_atm_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_merge_mod.o med_map_mod.o med_constants_mod.o med_phases_ocnalb_mod.o med_internalstate_mod.o med_utils_mod.o -med_phases_prep_glc_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_map_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o -med_phases_prep_ice_mod.o : med_kind_mod.o med_utils_mod.o med_methods_mod.o med_merge_mod.o esmFlds.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o -med_phases_prep_lnd_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_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_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 +med_map_mod.o : med_kind_mod.o med_internalstate_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o med_utils_mod.o +med_merge_mod.o : med_kind_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o med_utils_mod.o +med_methods_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o +med_phases_aofluxes_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o +med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_time_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o +med_phases_ocnalb_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o +med_phases_prep_atm_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_merge_mod.o med_map_mod.o med_constants_mod.o med_phases_ocnalb_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_prep_glc_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_map_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o +med_phases_prep_ice_mod.o : med_kind_mod.o med_utils_mod.o med_methods_mod.o med_merge_mod.o esmFlds.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o +med_phases_prep_lnd_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_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_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 -med_utils_mod.o : med_kind_mod.o med_utils_mod.F90 +med_time_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o +med_utils_mod.o : med_kind_mod.o med_utils_mod.F90 +med_diag_mod.o : med_kind_mod.o med_time_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o med_diag_mod.F90 From 026a6e7100e3ac46a6e31d88894a2e4ca1253fbf Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Oct 2020 14:49:31 -0600 Subject: [PATCH 104/206] make diags optional in the config file --- mediator/med_diag_mod.F90 | 52 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 30ca014b6..635bcb112 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -238,7 +238,7 @@ subroutine med_diag_init(gcomp, rc) integer , intent(out) :: rc ! local variables - character(CS) :: cvalue + integer :: c_size ! number of component send/recvs integer :: f_size ! number of fields integer :: p_size ! number of period types @@ -351,29 +351,12 @@ subroutine med_diag_init(gcomp, rc) ! Get config variables !------------------------------------------------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='budget_inst', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_inst - - call NUOPC_CompAttributeGet(gcomp, name='budget_daily', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_daily - - call NUOPC_CompAttributeGet(gcomp, name='budget_month', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_month - - call NUOPC_CompAttributeGet(gcomp, name='budget_ann', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_ann - - call NUOPC_CompAttributeGet(gcomp, name='budget_ltann', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_ltann - - call NUOPC_CompAttributeGet(gcomp, name='budget_ltend', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) budget_print_ltend + budget_print_inst = get_diag_attribute(gcomp, 'budget_inst') + budget_print_daily = get_diag_attribute(gcomp, 'budget_daily') + budget_print_month = get_diag_attribute(gcomp, 'budget_month') + budget_print_ann = get_diag_attribute(gcomp, 'budget_ann') + budget_print_ltann = get_diag_attribute(gcomp, 'budget_ltann') + budget_print_ltend = get_diag_attribute(gcomp, 'budget_ltend') ! Set stop alarm (needed for budgets) call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) @@ -389,6 +372,27 @@ subroutine med_diag_init(gcomp, rc) call alarmInit(mediatorclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & alarmname='alarm_stop', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + contains + integer function get_diag_attribute(gcomp, name, rc) + type(ESMF_GridComp) , intent(inout) :: gcomp + character(len=*), intent(in) :: name + integer, intent(out) :: rc + + character(CS) :: cvalue + + rc = ESMF_SUCCESS + get_diag_attribute = 0 + call NUOPC_CompAttributeGet(gcomp, name=name, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name=name, value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) get_diag_attribute + else + call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) + endif + + end function get_diag_attribute end subroutine med_diag_init From 549616a3ac345e7b09caaf063817f488312cbba9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Oct 2020 16:17:37 -0600 Subject: [PATCH 105/206] add error handling --- mediator/med_diag_mod.F90 | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 635bcb112..b71c4b7d0 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -15,7 +15,7 @@ module med_diag_mod ! salt flux ~ (kg/s)/m^2 !---------------------------------------------------------------------------- - use NUOPC , only : NUOPC_CompAttributeGet + use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet use NUOPC_Mediator , only : NUOPC_MediatorGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR @@ -247,6 +247,7 @@ subroutine med_diag_init(gcomp, rc) integer :: stop_n ! Number until restart interval integer :: stop_ymd ! Restart date (YYYYMMDD) type(ESMF_ALARM) :: stop_alarm + character(CS) :: cvalue ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -351,12 +352,18 @@ subroutine med_diag_init(gcomp, rc) ! Get config variables !------------------------------------------------------------------------------- - budget_print_inst = get_diag_attribute(gcomp, 'budget_inst') - budget_print_daily = get_diag_attribute(gcomp, 'budget_daily') - budget_print_month = get_diag_attribute(gcomp, 'budget_month') - budget_print_ann = get_diag_attribute(gcomp, 'budget_ann') - budget_print_ltann = get_diag_attribute(gcomp, 'budget_ltann') - budget_print_ltend = get_diag_attribute(gcomp, 'budget_ltend') + budget_print_inst = get_diag_attribute(gcomp, 'budget_inst', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + budget_print_daily = get_diag_attribute(gcomp, 'budget_daily', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + budget_print_month = get_diag_attribute(gcomp, 'budget_month', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + budget_print_ann = get_diag_attribute(gcomp, 'budget_ann', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + budget_print_ltann = get_diag_attribute(gcomp, 'budget_ltann', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + budget_print_ltend = get_diag_attribute(gcomp, 'budget_ltend', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Set stop alarm (needed for budgets) call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) @@ -379,6 +386,7 @@ integer function get_diag_attribute(gcomp, name, rc) integer, intent(out) :: rc character(CS) :: cvalue + logical :: isPresent rc = ESMF_SUCCESS get_diag_attribute = 0 @@ -391,7 +399,6 @@ integer function get_diag_attribute(gcomp, name, rc) else call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) endif - end function get_diag_attribute end subroutine med_diag_init From 60b23976119fd9f4d4c3e825e405bb8d20daa4b6 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Oct 2020 09:53:28 -0600 Subject: [PATCH 106/206] remove set part --- mediator/med_diag_mod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index b71c4b7d0..26787dcea 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -396,8 +396,10 @@ integer function get_diag_attribute(gcomp, name, rc) call NUOPC_CompAttributeGet(gcomp, name=name, value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) get_diag_attribute - else - call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) + ! the following gave an error in esmf 8.1.0b: Operation not yet supported +! else +! call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) +! if (ChkErr(rc,__LINE__,u_FILE_u)) return endif end function get_diag_attribute From 176872c0553c9f94d987f2db06f07af46732e9a8 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Oct 2020 10:39:01 -0600 Subject: [PATCH 107/206] dont get alarm options unless diags are set --- mediator/med_diag_mod.F90 | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 26787dcea..07b87c183 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -364,21 +364,22 @@ subroutine med_diag_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return budget_print_ltend = get_diag_attribute(gcomp, 'budget_ltend', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Set stop alarm (needed for budgets) - call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_n - call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) stop_ymd - call NUOPC_MediatorGet(gcomp, mediatorClock=mediatorClock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call alarmInit(mediatorclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & - alarmname='alarm_stop', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (budget_print_inst + budget_print_daily + budget_print_month + budget_print_ann + budget_print_ltann + budget_print_ltend > 0) then + ! Set stop alarm (needed for budgets) + call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_n + call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) stop_ymd + call NUOPC_MediatorGet(gcomp, mediatorClock=mediatorClock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call alarmInit(mediatorclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & + 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 From 5c3bd48a452920b88dadd535126e50af98b30367 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Oct 2020 11:05:29 -0600 Subject: [PATCH 108/206] makefile fix --- mediator/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediator/Makefile b/mediator/Makefile index 524fa581c..8562fbc40 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -58,5 +58,5 @@ med_phases_prep_wav_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod 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 -med_utils_mod.o : med_kind_mod.o med_utils_mod.F90 -med_diag_mod.o : med_kind_mod.o med_time_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o med_diag_mod.F90 +med_utils_mod.o : med_kind_mod.o +med_diag_mod.o : med_kind_mod.o med_time_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o From 91fd48c7467a2461f6a0706bc58ffe6e7fce2e32 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Oct 2020 12:27:14 -0600 Subject: [PATCH 109/206] try this instead --- mediator/med_diag_mod.F90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 07b87c183..c59e98232 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -397,10 +397,11 @@ integer function get_diag_attribute(gcomp, name, rc) call NUOPC_CompAttributeGet(gcomp, name=name, value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) get_diag_attribute - ! the following gave an error in esmf 8.1.0b: Operation not yet supported -! else -! call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) -! if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call NUOPC_CompAttributeAdd(gcomp, (/name/), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeSet(gcomp, name=name, value='0', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return endif end function get_diag_attribute From db1869afcd576e96bd1504a28e713680d434d730 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Oct 2020 12:34:02 -0600 Subject: [PATCH 110/206] add interface --- mediator/med_diag_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index c59e98232..90c931dc5 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -15,7 +15,7 @@ module med_diag_mod ! salt flux ~ (kg/s)/m^2 !---------------------------------------------------------------------------- - use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet + use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd use NUOPC_Mediator , only : NUOPC_MediatorGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR From 61c7fde86716491e33f669cede4cfe4430c1ffc7 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 26 Oct 2020 09:03:34 -0600 Subject: [PATCH 111/206] fixed bug in mapping for flooding to ocn from river --- mediator/esmFldsExchange_cesm_mod.F90 | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 8282308d3..4062cd390 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1339,16 +1339,26 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) end do else do n = 1,size(iso) - ! from both rof and glc to con + ! 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, mapconsf, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n), compocn, mapconsf, 'one' , glc2ocn_liq_rmap) + call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n) , compocn, mapconsf, 'none', rof2ocn_liq_rmap) + call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n) , compocn, mapconsf, 'one' , glc2ocn_liq_rmap) + call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_fmap) 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. & + 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 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=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. & @@ -1357,14 +1367,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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: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)) 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 ( 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 @@ -1382,14 +1390,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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, mapconsf, '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 From bc6ced197a143aa0d795d0f971f86d38c9a71b4c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 26 Oct 2020 10:55:37 -0600 Subject: [PATCH 112/206] bug fixes --- mediator/esmFldsExchange_cesm_mod.F90 | 37 ++++++++++++++++++--------- mediator/med_fraction_mod.F90 | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 4062cd390..e4ee68190 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1340,42 +1340,55 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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. & + 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 + write(6,*)'DEBUG: i am here1' call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n) , compocn, mapconsf, 'none', rof2ocn_liq_rmap) call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n) , compocn, mapconsf, 'one' , glc2ocn_liq_rmap) - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_fmap) + call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, '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', & 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. & - 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(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 + write(6,*)'DEBUG: i am here2' call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) 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=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)) then - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_fmap) + 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 + write(6,*)'DEBUG: i am here3' + call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) 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: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)) then + 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 + write(6,*)'DEBUG: i am here4' 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 + write(6,*)'DEBUG: i am here5' 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') diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 88431f867..ee2593d08 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -674,7 +674,7 @@ subroutine med_fraction_set(gcomp, rc) ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compocn,compatm)) then call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & + is_local%wrap%FBfrac(compice), 'ofrac', & is_local%wrap%FBfrac(compatm), 'ofrac', & is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 6aa22a164338030c6befc119c723d751f78e460b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 26 Oct 2020 20:37:53 -0600 Subject: [PATCH 113/206] fixed bug that was just introduced --- mediator/esmFlds.F90 | 28 +++++++++++++-------- mediator/esmFldsExchange_cesm_mod.F90 | 36 ++++++++++++++------------- mediator/med_fraction_mod.F90 | 2 +- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index cf3afec5a..9234db892 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -26,19 +26,25 @@ module esmflds ! Set mappers !----------------------------------------------- - integer , public, parameter :: mapunset = 0 - integer , public, parameter :: mapbilnr = 1 - integer , public, parameter :: mapconsf = 2 - integer , public, parameter :: mapconsd = 3 - integer , public, parameter :: mappatch = 4 - integer , public, parameter :: mapfcopy = 5 - integer , public, parameter :: mapnstod = 6 ! nearest source to destination - 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 :: nmappers = 8 + integer , public, parameter :: mapunset = 0 + integer , public, parameter :: mapbilnr = 1 + integer , public, parameter :: mapconsf = 2 + integer , public, parameter :: mapconsd = 3 + integer , public, parameter :: mappatch = 4 + integer , public, parameter :: mapfcopy = 5 + integer , public, parameter :: mapnstod = 6 ! nearest source to destination + 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 :: map_glc2ocn_ice = 9 ! custom smoothing map to map ice from glc->ocn (cesm only) + integer , public, parameter :: map_glc2ocn_liq = 10 ! custom smoothing map to map liq from glc->ocn (cesm only) + integer , public, parameter :: map_rof2ocn_ice = 11 ! custom smoothing map to map ice from rof->ocn (cesm only) + integer , public, parameter :: map_rof2ocn_liq = 12 ! custom smoothing map to map liq from rof->ocn (cesm only) + integer , public, parameter :: nmappers = 12 character(len=*) , public, parameter :: mapnames(nmappers) = & - (/'bilnr ','consf ','consd ','patch ','fcopy ','nstod ','nstod_consd','nstod_consf'/) + (/'bilnr ','consf ','consd ','patch ','fcopy ',& + 'nstod ','nstod_consd','nstod_consf', & + 'glc2ocn_ice','glc2ocn_liq','rof2ocn_ice','rof2ocn_liq'/) logical, public :: mapuv_with_cart3d ! rotate u,v to 3d cartesian space, map from src->dest, then rotate back diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index e4ee68190..9d0f81ae8 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -34,6 +34,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) use esmflds , only : compice, comprof, compwav, compglc, ncomps use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf + use esmflds , only : map_glc2ocn_ice, map_glc2ocn_liq, map_rof2ocn_ice, map_rof2ocn_liq use esmflds , only : mapuv_with_cart3d use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb use esmFlds , only : coupling_mode @@ -1330,12 +1331,17 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if (phase == 'advertise') then do n = 1,size(iso) + ! 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)) 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)) end do else do n = 1,size(iso) @@ -1343,12 +1349,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 - write(6,*)'DEBUG: i am here1' - call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n) , compocn, mapconsf, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n) , compocn, mapconsf, 'one' , glc2ocn_liq_rmap) - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) + 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' , mrg_type1='sum', & 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 @@ -1356,9 +1362,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 - write(6,*)'DEBUG: i am here2' - call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n), compocn, mapconsf, 'one' , glc2ocn_liq_rmap) + 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') @@ -1367,9 +1372,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 - write(6,*)'DEBUG: i am here3' - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(comprof)%flds, 'Forr_rofl' //iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) + 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 @@ -1377,7 +1381,6 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 - write(6,*)'DEBUG: i am here4' 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') @@ -1388,7 +1391,6 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 - write(6,*)'DEBUG: i am here5' 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') @@ -1398,21 +1400,21 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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, mapconsf, 'none', rof2ocn_ice_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofi'//iso(n), compocn, mapconsf, 'one' , glc2ocn_ice_rmap) + 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, mapconsf, 'none', rof2ocn_ice_rmap) + 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, mapconsf, 'one', glc2ocn_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=compglc, mrg_fld1='Fogg_rofi'//iso(n), mrg_type1='copy') end if diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index ee2593d08..67b2b060b 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -676,7 +676,7 @@ subroutine med_fraction_set(gcomp, rc) call FB_FieldRegrid(& is_local%wrap%FBfrac(compice), 'ofrac', & is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if ! end of if present compatm From a3790d5fda894db8fe25ca0f0eb1cbf020ad9467 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 27 Oct 2020 14:46:32 -0600 Subject: [PATCH 114/206] remove albedo from the X compset --- cime_config/config_component.xml | 8 +-- cime_config/runseq/runseq_general.py | 8 ++- mediator/med_phases_aofluxes_mod.F90 | 83 ++++++++++++++-------------- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index aa7ab6510..dbffe661f 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -987,9 +987,9 @@ env_run.xml Determines what ESMF log files (if any) are generated when - USE_ESMF_LIB is TRUE. + USE_ESMF_LIB is TRUE. ESMF_LOGKIND_SINGLE: Use a single log file, combining messages from - all of the PETs. Not supported on some platforms. + all of the PETs. Not supported on some platforms. ESMF_LOGKIND_MULTI: Use multiple log files -- one per PET. ESMF_LOGKIND_NONE: Do not issue messages to a log file. By default, no ESMF log files are generated. @@ -2018,7 +2018,7 @@ pio rearranger communication max pending requests (io2comp) : -2 implies that CIME internally calculates the value ( = 64), -1 implies no bound on max pending requests - 0 implies that MPI_ALLTOALL will be used + 0 implies that MPI_ALLTOALL will be used @@ -2600,7 +2600,7 @@ - + diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index df8002825..e0a4cfb36 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -18,9 +18,10 @@ def gen_runseq(case, coupling_times): rundir = case.get_value("RUNDIR") caseroot = case.get_value("CASEROOT") cpl_seq_option = case.get_value('CPL_SEQ_OPTION') - cpl_add_aoflux = case.get_value('ADD_AOFLUX_TO_RUNSEQ') coupling_mode = case.get_value('COUPLING_MODE') diag_mode = case.get_value('BUDGETS') + xcompset = case.get_value("COMP_ATM") == 'xatm' + cpl_add_aoflux = not xcompset and case.get_value('ADD_AOFLUX_TO_RUNSEQ') # It is assumed that if a component will be run it will send information to the mediator # so the flags run_xxx and xxx_to_med are redundant @@ -34,6 +35,7 @@ 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'] + # Note: assume that atm_cpl_dt, lnd_cpl_dt, ice_cpl_dt and wav_cpl_dt are the same if lnd_cpl_time != atm_cpl_time: @@ -89,7 +91,7 @@ def gen_runseq(case, coupling_times): 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)) + 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) @@ -116,7 +118,7 @@ def gen_runseq(case, coupling_times): 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) + 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) diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 6a303da80..198ef4908 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -94,6 +94,7 @@ subroutine med_phases_aofluxes_run(gcomp, rc) use NUOPC , only : NUOPC_IsConnected, NUOPC_CompAttributeGet use esmFlds , only : med_fldList_GetNumFlds, med_fldList_GetFldNames use esmFlds , only : fldListFr, fldListMed_aoflux, compatm, compocn, compname + use NUOPC , only : NUOPC_CompAttributeGet !----------------------------------------------------------------------- ! Compute atm/ocn fluxes @@ -189,7 +190,7 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_VM use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldBundle, ESMF_VMGet use NUOPC , only : NUOPC_CompAttributeGet - + use shr_flux_mod , only : shr_flux_adjust_constants !----------------------------------------------------------------------- ! Initialize pointers to the module variables !----------------------------------------------------------------------- @@ -212,6 +213,10 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, character(CL) :: cvalue logical :: flds_wiso ! use case character(len=CX) :: tmpstr + real(R8) :: flux_convergence ! convergence criteria for imlicit flux computation + 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) ' !----------------------------------------------------------------------- @@ -381,6 +386,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) @@ -397,7 +436,7 @@ subroutine med_aofluxes_run(gcomp, aoflux, rc) use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet, ESMF_TimeIntervalGet use ESMF , only : ESMF_LogWrite, ESMF_LogMsg_Info use NUOPC , only : NUOPC_CompAttributeGet - use shr_flux_mod , only : shr_flux_atmocn, shr_flux_adjust_constants + use shr_flux_mod , only : shr_flux_atmocn !----------------------------------------------------------------------- ! Determine atm/ocn fluxes eother on atm or on ocean grid @@ -414,53 +453,13 @@ subroutine med_aofluxes_run(gcomp, aoflux, rc) character(CL) :: cvalue integer :: n,i ! indices integer :: lsize ! local size - real(R8) :: flux_convergence ! convergence criteria for imlicit flux computation - integer :: flux_max_iteration ! maximum number of iterations for convergence - logical :: coldair_outbreak_mod ! cold air outbreak adjustment (Mahrt & Sun 1995,MWR) character(len=CX) :: tmpstr logical :: isPresent, isSet - logical,save :: first_call = .true. character(*),parameter :: subName = '(med_aofluxes_run) ' !----------------------------------------------------------------------- call t_startf('MED:'//subname) - !---------------------------------- - ! Get config variables on first call - !---------------------------------- - - if (first_call) then - 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) - - first_call = .false. - end if !---------------------------------- ! Determine the compute mask From ac043a7fb0d9f9bad3829f6589103f40d236208b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 27 Oct 2020 15:56:42 -0600 Subject: [PATCH 115/206] removed unneeded commented line --- mediator/esmFldsExchange_cesm_mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 9d0f81ae8..43a06c286 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1354,7 +1354,6 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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' , mrg_type1='sum', & 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 From 5e6fcef95421dbcb8a25e0c9e14d77914bb19d0e Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Wed, 7 Oct 2020 12:45:40 -0500 Subject: [PATCH 116/206] update PIO and genf90 to support CDEPS --- nems/lib/ParallelIO | 2 +- nems/lib/genf90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nems/lib/ParallelIO b/nems/lib/ParallelIO index 86ad4463a..6f9fb5e1b 160000 --- a/nems/lib/ParallelIO +++ b/nems/lib/ParallelIO @@ -1 +1 @@ -Subproject commit 86ad4463ab46e706aca632c2c4c2ffd48854113b +Subproject commit 6f9fb5e1b9b8adb3fb6e531f6296b2abf9d58a7f diff --git a/nems/lib/genf90 b/nems/lib/genf90 index acb24bb13..4816965ba 160000 --- a/nems/lib/genf90 +++ b/nems/lib/genf90 @@ -1 +1 @@ -Subproject commit acb24bb13b54db505163f683ed5a0e6271bf5e79 +Subproject commit 4816965ba946731352bad195b7d946a5fe682ff5 From 2ba14ea7acf104b6f4250af455115a51b88449bd Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Wed, 7 Oct 2020 14:55:01 -0500 Subject: [PATCH 117/206] make internal PIO initialization optional for different UFS apps --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1ddc4f357..e778090f3 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,11 @@ ifndef CXX $(error CXX not defined) endif +ifndef INTERNAL_PIO_INIT +INTERNAL_PIO_INIT := 1 +endif +$(info INTERNAL_PIO_INIT is set to $(INTERNAL_PIO_INIT)) + MEDIATOR_DIR := $(BASE_DIR)/mediator LIBRARY_MEDIATOR := $(MEDIATOR_DIR)/libcmeps.a LIBRARY_UTIL := $(BASE_DIR)/nems/util/libcmeps_util.a @@ -53,7 +58,7 @@ endif $(LIBRARY_MEDIATOR): $(LIBRARY_UTIL) .FORCE cd mediator ;\ - exec $(MAKE) PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) INTERNAL_PIO_INIT=1 + exec $(MAKE) PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) INTERNAL_PIO_INIT=$(INTERNAL_PIO_INIT) $(LIBRARY_UTIL): $(PIO_INSTALL_LIBS) .FORCE cd nems/util ;\ From c9e4ecb5aa1f2dc0ca0ff310860259544e7b925a Mon Sep 17 00:00:00 2001 From: Ufuk Turuncoglu Date: Mon, 12 Oct 2020 11:18:14 -0500 Subject: [PATCH 118/206] fix GTPL issue and optional internal PIO initialization --- mediator/Makefile | 2 +- mediator/med_utils_mod.F90 | 2 ++ nuopc_cap_share/nuopc_shr_methods.F90 | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mediator/Makefile b/mediator/Makefile index 8562fbc40..574d19357 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -9,7 +9,7 @@ ifndef PIO_INCLUDE_DIR $(error PIO_INCLUDE_DIR not set) endif -ifdef INTERNAL_PIO_INIT +ifeq ($(INTERNAL_PIO_INIT),1) CPPDEFS += -DINTERNAL_PIO_INIT endif diff --git a/mediator/med_utils_mod.F90 b/mediator/med_utils_mod.F90 index 9aef4cff9..12a846466 100644 --- a/mediator/med_utils_mod.F90 +++ b/mediator/med_utils_mod.F90 @@ -23,10 +23,12 @@ subroutine med_memcheck(string, level, mastertask) logical, intent(in) :: mastertask integer :: ierr #ifndef INTERNAL_PIO_INIT +#ifdef CESMCOUPLED integer, external :: GPTLprint_memusage if((mastertask .and. memdebug_level > level) .or. memdebug_level > level+1) then ierr = GPTLprint_memusage(string) endif +#endif #endif end subroutine med_memcheck diff --git a/nuopc_cap_share/nuopc_shr_methods.F90 b/nuopc_cap_share/nuopc_shr_methods.F90 index 44ead6c8f..8d3283a4f 100644 --- a/nuopc_cap_share/nuopc_shr_methods.F90 +++ b/nuopc_cap_share/nuopc_shr_methods.F90 @@ -83,12 +83,16 @@ subroutine memcheck(string, level, mastertask) ! local variables integer :: ierr +#ifdef CESMCOUPLED integer, external :: GPTLprint_memusage +#endif !----------------------------------------------------------------------- +#ifdef CESMCOUPLED if ((mastertask .and. memdebug_level > level) .or. memdebug_level > level+1) then ierr = GPTLprint_memusage(string) endif +#endif end subroutine memcheck From 4c2316088773c75af73a8e721bd9b704c447618a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 12 Oct 2020 19:56:05 -0600 Subject: [PATCH 119/206] performance upgrade - primarily to med_merge_mod - on top of jedwards/newdiag --- mediator/med_map_mod.F90 | 75 +++-- mediator/med_merge_mod.F90 | 447 +++++++++++++++------------ mediator/med_phases_prep_atm_mod.F90 | 18 +- mediator/med_phases_prep_ice_mod.F90 | 9 +- mediator/med_phases_prep_lnd_mod.F90 | 3 +- mediator/med_phases_prep_ocn_mod.F90 | 18 +- mediator/med_phases_prep_rof_mod.F90 | 3 +- mediator/med_phases_prep_wav_mod.F90 | 3 +- 8 files changed, 333 insertions(+), 243 deletions(-) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 91b5fdb9e..d29c6c0fc 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -704,7 +704,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & use ESMF , only: ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR use ESMF , only: ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use ESMF , only: ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet - use ESMF , only: ESMF_RouteHandle + use ESMF , only: ESMF_RouteHandle, ESMF_FieldRegrid use ESMF , only: ESMF_REGION_SELECT, ESMF_REGION_TOTAL use ESMF , only: ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated use ESMF , only: ESMF_FieldDestroy, ESMF_FieldCreate @@ -775,20 +775,22 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & ! First - reset the field bundle on the destination grid to zero !--------------------------------------- - call FB_reset(FBDst, value=czero, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! call FB_reset(FBDst, value=czero, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- ! Loop over all fields in the source field bundle and map them to ! the destination field bundle accordingly !--------------------------------------- - call ESMF_LogWrite(trim(subname)//" *** mapping from "//trim(compname(srccomp))//" to "//& - trim(compname(destcomp))//" ***", ESMF_LOGMSG_INFO) + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//" *** mapping from "//trim(compname(srccomp))//" to "//& + trim(compname(destcomp))//" ***", ESMF_LOGMSG_INFO) + end if - frac_field_created = .false. used_cart3d_for_uvmapping = .false. do n = 1,size(fldsSrc) + ! Determine if field is a scalar - and if so go to next iternation fldname = fldsSrc(n)%shortname if (fldname == flds_scalar_name) CYCLE @@ -798,7 +800,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & if (mapindex == 0) CYCLE mapnorm = fldsSrc(n)%mapnorm(destcomp) - ! Determine if field is FBSrc or FBDst or connected - and if not go to next iteration + !Determine if field is FBSrc or FBDst or connected - and if not go to next iteration if (.not. FB_FldChk(FBSrc, trim(fldname), rc=rc)) then if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//" field not found in FBSrc: "//trim(fldname), ESMF_LOGMSG_INFO) @@ -815,16 +817,18 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & ! Error checks ! ------------------- - if (.not. FB_FldChk(FBSrc, fldname, rc=rc)) then - call ESMF_LogWrite(trim(subname)//" field not found in FBSrc: "//trim(fldname), ESMF_LOGMSG_INFO) - else if (.not. FB_FldChk(FBDst, fldname, rc=rc)) then - call ESMF_LogWrite(trim(subname)//" field not found in FBDst: "//trim(fldname), ESMF_LOGMSG_INFO) - else if (.not. med_map_RH_is_created(RouteHandles,mapindex,rc=rc)) then - call ESMF_LogWrite(trim(subname)//trim(lstring)//& - ": ERROR RH not available for "//mapnames(mapindex)//": fld="//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return + if (dbug_flag > 2) then + if (.not. FB_FldChk(FBSrc, fldname, rc=rc)) then + call ESMF_LogWrite(trim(subname)//" field not found in FBSrc: "//trim(fldname), ESMF_LOGMSG_INFO) + else if (.not. FB_FldChk(FBDst, fldname, rc=rc)) then + call ESMF_LogWrite(trim(subname)//" field not found in FBDst: "//trim(fldname), ESMF_LOGMSG_INFO) + else if (.not. med_map_RH_is_created(RouteHandles,mapindex,rc=rc)) then + call ESMF_LogWrite(trim(subname)//trim(lstring)//& + ": ERROR RH not available for "//mapnames(mapindex)//": fld="//trim(fldname), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + end if end if ! ------------------- @@ -861,31 +865,38 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & ! Get the source and destination fields ! ------------------- - call ESMF_LogWrite(trim(subname)//" --> remapping "//trim(fldname)//" with "//trim(mapnames(mapindex)), & - ESMF_LOGMSG_INFO) + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//" --> remapping "//trim(fldname)//" with "//trim(mapnames(mapindex)), & + ESMF_LOGMSG_INFO) + end if + + ! ------------------- + ! Do the mapping + ! ------------------- + call t_startf('MED:'//subname//'time1') call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=srcfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleGet(FBDst, fieldName=trim(fldname), field=dstfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! ------------------- - ! Do the mapping - ! ------------------- + call t_stopf('MED:'//subname//'time1') if (mapindex == mapfcopy) then - call med_map_FB_Field_Regrid(FBSrc, fldname, FBDst, fldname, RouteHandles, mapindex, rc=rc) + + call t_startf('MED:'//subname//'time2') + call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapfcopy), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//subname//'time2') else + ! Determine the normalization for the map mapnorm = fldsSrc(n)%mapnorm(destcomp) if ( trim(mapnorm) /= 'unset' .and. trim(mapnorm) /= 'one' .and. trim(mapnorm) /= 'none') then - call FB_getFieldByName(FBSrc, fldname, lfield, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + call ESMF_FieldGet(srcfield, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! get a pointer to source field data in FBSrc @@ -966,9 +977,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! create fraction field on destination mesh - call ESMF_FieldBundleGet(FBDst, fldname, field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh, rc=rc) + call ESMF_FieldGet(dstfield, mesh=lmesh, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return frac_field_dst = ESMF_FieldCreate(lmesh, ESMF_TYPEKIND_R8, name=mapnorm, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1010,6 +1019,7 @@ subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & end if ! mapnorm is 'one' end if ! mapnorm is 'one' or 'nne' + end if ! mapindex is not mapfcopy and field exists if (dbug_flag > 1) then @@ -1065,8 +1075,9 @@ subroutine med_map_FB_Field_Regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex lfldname=trim(fldin)//'->'//trim(fldout) - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if if (FB_FldChk(FBin , trim(fldin) , rc=rc) .and. & FB_FldChk(FBout, trim(fldout), rc=rc)) then diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index 9b32f4ff0..cb91f1bd9 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -12,8 +12,6 @@ module med_merge_mod use med_constants_mod , only : czero => med_constants_czero use med_utils_mod , only : ChkErr => med_utils_ChkErr use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk - use med_methods_mod , only : FB_GetNameN => med_methods_FB_GetNameN - use med_methods_mod , only : FB_Reset => med_methods_FB_reset use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FieldPtr_Compare => med_methods_FieldPtr_Compare use esmFlds , only : compmed, compname @@ -41,8 +39,9 @@ module med_merge_mod !=============================================================================== contains !=============================================================================== - - subroutine med_merge_auto(compout_name, FBOut, FBfrac, FBImp, fldListTo, FBMed1, FBMed2, rc) + + subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldListTo, & + FBMed1, FBMed2, rc) use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet use ESMF , only : ESMF_Field, ESMF_FieldGet @@ -55,162 +54,278 @@ subroutine med_merge_auto(compout_name, FBOut, FBfrac, FBImp, fldListTo, FBMed1, ! ---------------------------------------------- ! input/output variables - character(len=*) , intent(in) :: compout_name ! component name for FBOut - type(ESMF_FieldBundle) , intent(inout) :: FBOut ! Merged output field bundle - type(ESMF_FieldBundle) , intent(inout) :: FBfrac ! Fraction data for FBOut - type(ESMF_FieldBundle) , intent(in) :: FBImp(:) ! Array of field bundles each mapping to the FBOut mesh - type(med_fldList_type) , intent(in) :: fldListTo ! Information for merging - type(ESMF_FieldBundle) , intent(in) , optional :: FBMed1 ! mediator field bundle - type(ESMF_FieldBundle) , intent(in) , optional :: FBMed2 ! mediator field bundle - integer , intent(out) :: rc + integer , intent(in) :: compout ! component index for FBOut + logical , intent(in) :: coupling_active(:) ! true => coupling is active + type(ESMF_FieldBundle) , intent(inout) :: FBOut ! Merged output field bundle + type(ESMF_FieldBundle) , intent(inout) :: FBfrac ! Fraction data for FBOut + type(ESMF_FieldBundle) , intent(in) :: FBImp(:) ! Array of field bundles each mapping to the FBOut mesh + type(med_fldList_type) , intent(in) :: fldListTo ! Information for merging + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed1 ! mediator field bundle + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed2 ! mediator field bundle + integer , intent(out) :: rc ! local variables - integer :: cnt - integer :: n,nf,nm,compsrc - character(CX) :: fldname, stdname - character(CX) :: merge_fields - character(CX) :: merge_field - character(CS) :: merge_type - character(CS) :: merge_fracname + integer :: nfld_out,nfld_in,nm + integer :: compsrc + integer :: num_merge_fields + integer :: num_merge_colon_fields + character(CL) :: fldname_out + character(CL) :: merge_fields + character(CL) :: merge_field + character(CS) :: merge_type + character(CS) :: merge_fracname + character(CS), allocatable :: merge_field_names(:) + integer :: rank_out + type(ESMF_Field) :: field_out + real(r8), pointer :: dataptr1d(:) + real(r8), pointer :: dataptr2d(:,:) + logical :: error_check = .false. ! TODO: make this an input argument + integer :: ungriddedUBound_out(1) ! currently the size must equal 1 for rank 2 fieldds + integer :: gridToFieldMap_out(1) ! currently the size must equal 1 for rank 2 fieldds + integer :: fieldnamecount + character(CL), pointer :: fieldnamelist(:) + character(CL) :: msg character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_auto)' !--------------------------------------- call t_startf('MED:'//subname) - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - rc = ESMF_SUCCESS + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + rc = ESMF_SUCCESS + end if - call FB_reset(FBOut, value=czero, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBOut, fieldCount=fieldnamecount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fieldnamelist(fieldnamecount)) + call ESMF_FieldBundleGet(FBOut, fieldNameList=fieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + num_merge_fields = med_fldList_GetNumFlds(fldListTo) + allocate(merge_field_names(num_merge_fields)) + do nfld_in = 1,num_merge_fields + call med_fldList_GetFldInfo(fldListTo, nfld_in, merge_field_names(nfld_in)) + end do ! Want to loop over all of the fields in FBout here - and find the corresponding index in fldListTo(compxxx) ! for that field name - then call the corresponding merge routine below appropriately - call ESMF_FieldBundleGet(FBOut, fieldCount=cnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Loop over all fields in field bundle FBOut - do n = 1,cnt + do nfld_out = 1,fieldnamecount - ! Get the nth field name in FBexp - call FB_getNameN(FBOut, n, fldname, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the nth field in FBOut + fldname_out = trim(fieldnamelist(nfld_out)) + call ESMF_FieldBundleGet(FBOut, trim(fldname_out), field=field_out, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Loop over the field in fldListTo - do nf = 1,med_fldList_GetNumFlds(fldListTo) + ! Set nth field data to zero + call ESMF_FieldGet(field_out, rank=rank_out, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + write(msg,*)trim(subname),'output field ',trim(fldname_out),' has rank ',rank_out + call ESMF_LogWrite(msg, ESMF_LOGMSG_INFO) + end if - ! Determine if if there is a match of the fldList field name with the FBOut field name - call med_fldList_GetFldInfo(fldListTo, nf, stdname) + if (rank_out == 1) then + call ESMF_FieldGet(field_out, farrayPtr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + else if (rank_out == 2) then + call ESMF_FieldGet(field_out, farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + call ESMF_FieldGet(field_out, ungriddedUBound=ungriddedUBound_out, & + gridToFieldMap=gridToFieldMap_out, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + ! Loop over the field in fldListTo + do nfld_in = 1,med_fldList_GetNumFlds(fldListTo) - if (trim(stdname) == trim(fldname)) then + if (trim(merge_field_names(nfld_in)) == trim(fldname_out)) then ! Loop over all possible source components in the merging arrays returned from the above call ! If the merge field name from the source components is not set, then simply go to the next component do compsrc = 1,size(FBImp) - ! Determine the merge information for the import field - call med_fldList_GetFldInfo(fldListTo, nf, compsrc, merge_fields, merge_type, merge_fracname) - - ! If merge_field is a colon delimited string then cycle through every field - otherwise by default nm - ! will only equal 1 - do nm = 1,merge_listGetNum(merge_fields) - - call merge_listGetName(merge_fields, nm, merge_field, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Cycle if coupling is not active or mediator input is not present and compsrc is mediator + if (compsrc == compmed) then + if (.not. present(FBMed1) .and. .not. present(FBMed2)) then + CYCLE + end if + else if (.not. coupling_active(compsrc)) then + CYCLE + end if - if (merge_type /= 'unset' .and. merge_field /= 'unset') then + ! Determine the merge information for the import field + call med_fldList_GetFldInfo(fldListTo, nfld_in, compsrc, merge_fields, merge_type, merge_fracname) + + if (merge_type /= 'unset' .and. merge_field /= 'unset') then + + ! If merge_field is a colon delimited string then cycle through every field - otherwise by default nm + ! will only equal 1 + num_merge_colon_fields = merge_listGetNum(merge_fields) + do nm = 1,num_merge_colon_fields + + ! Determine merge field name from source field + if (num_merge_fields == 1) then + merge_field = trim(merge_fields) + else + call merge_listGetName(merge_fields, nm, merge_field, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Perform error checks + if (error_check) then + call med_merge_errcheck(compsrc, fldname_out, field_out, rank_out, & + ungriddedUBound_out, gridToFieldMap_out, trim(merge_field), & + FBImp(compsrc), FBMed1=FBMed1, FBMed2=FBMed2, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if ! end of error check ! Perform merge - if (compsrc == compmed) then - - if (present(FBMed1) .and. present(FBMed2)) then - if (.not. ESMF_FieldBundleIsCreated(FBMed1)) then - call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, & - msg="Field bundle FBMed1 not created.", & - line=__LINE__, file=u_FILE_u, rcToReturn=rc) - return - endif - if (.not. ESMF_FieldBundleIsCreated(FBMed2)) then - call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, & - msg="Field bundle FBMed2 not created.", & - line=__LINE__, file=u_FILE_u, rcToReturn=rc) - return - endif - if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), & - FBOut, fldname, FB=FBMed1, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - else if (FB_FldChk(FBMed2, trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), & - FBOut, fldname, FB=FBMed2, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - else - call ESMF_LogWrite(trim(subname)//": ERROR merge_field = "//trim(merge_field)//" not found", & - ESMF_LOGMSG_ERROR, rc=rc) - rc = ESMF_FAILURE - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - elseif (present(FBMed1)) then - if (.not. ESMF_FieldBundleIsCreated(FBMed1)) then - call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, & - msg="Field bundle FBMed1 not created.", & - line=__LINE__, file=u_FILE_u, rcToReturn=rc) - return - endif - if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), & - FBOut, fldname, FB=FBMed1, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - else - call ESMF_LogWrite(trim(subname)//": ERROR merge_field = "//trim(merge_field)//"not found", & - ESMF_LOGMSG_ERROR, rc=rc) - rc = ESMF_FAILURE - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - - else if (ESMF_FieldBundleIsCreated(FBImp(compsrc), rc=rc)) then - if (FB_FldChk(FBImp(compsrc), trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), & - FBOut, fldname, FB=FBImp(compsrc), FBFld=merge_field, & - FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) + if ((present(FBMed1) .or. present(FBMed2)) .and. compsrc == compmed) then + if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then + call med_merge_auto_field(trim(merge_type), field_out, & + rank_out, ungriddedUBound_out, gridToFieldMap_out, & + FB=FBMed1, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (FB_FldChk(FBMed2, trim(merge_field), rc=rc)) then + call med_merge_auto_field(trim(merge_type), field_out, & + rank_out, ungriddedUBound_out, gridToFieldMap_out, & + FB=FBMed2, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - - end if ! end of single merge - - end if ! end of check of merge_type and merge_field not unset - end do ! end of nmerges loop + else + call med_merge_auto_field(trim(merge_type), field_out, & + rank_out, ungriddedUBound_out, gridToFieldMap_out, & + FB=FBImp(compsrc), FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + end do ! end of nm loop + end if ! end of check of merge_type and merge_field not unset end do ! end of compsrc loop end if ! end of check if stdname and fldname are the same end do ! end of loop over fldsListTo end do ! end of loop over fields in FBOut - !--------------------------------------- - !--- clean up - !--------------------------------------- + deallocate(fieldnamelist) + + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + end if - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) call t_stopf('MED:'//subname) end subroutine med_merge_auto !=============================================================================== + subroutine med_merge_errcheck(compsrc, fldname_out, field_out, rank_out, & + ungriddedUBound_out, gridToFieldMap_out, merge_fldname, FBImp, FBMed1, FBMed2, rc) - subroutine med_merge_auto_field(merge_type, FBout, FBoutfld, FB, FBfld, FBw, fldw, rc) + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR + use ESMF , only : ESMF_LogSetError, ESMF_RC_OBJ_NOT_CREATED + + ! input/output variables + integer , intent(in) :: compsrc ! source component index + character(len=*) , intent(in) :: fldname_out ! output field name + type(ESMF_Field) , intent(in) :: field_out ! output field + integer , intent(in) :: rank_out ! rank of output field + integer , intent(in) :: ungriddedUBound_out(1) ! currently the size must equal 1 for rank 2 fields + integer , intent(in) :: gridToFieldMap_out(1) ! currently the size must equal 1 for rank 2 fields + character(len=*) , intent(in) :: merge_fldname ! source merge fieldname + type(ESMF_FieldBundle) , intent(in) :: FBImp ! source field bundle + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed1 ! mediator field bundle + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed2 ! mediator field bundle + integer , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: field_in + integer :: rank_in + integer :: ungriddedUBound_in(1) ! currently the size must equal 1 for rank 2 fieldds + integer :: gridToFieldMap_in(1) ! currently the size must equal 1 for rank 2 fieldds + character(len=CL) :: errmsg + character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_errcheck)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + if (compsrc == compmed) then + if (present(FBMed1) .and. present(FBMed2)) then + if (.not. ESMF_FieldBundleIsCreated(FBMed1)) then + call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed1 not created.", & + line=__LINE__, file=u_FILE_u, rcToReturn=rc) + return + endif + if (.not. ESMF_FieldBundleIsCreated(FBMed2)) then + call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed2 not created.", & + line=__LINE__, file=u_FILE_u, rcToReturn=rc) + return + endif + if (FB_FldChk(FBMed1, trim(merge_fldname), rc=rc)) then + call ESMF_FieldBundleGet(FBMed1, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (FB_FldChk(FBMed2, trim(merge_fldname), rc=rc)) then + call ESMF_FieldBundleGet(FBMed2, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//": ERROR merge_fldname = "//trim(merge_fldname)//" not found", & + ESMF_LOGMSG_ERROR, rc=rc) + rc = ESMF_FAILURE + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + endif + call ESMF_FieldBundleGet(FBImp, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_in, rank=rank_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (rank_in /= rank_out) then + write(errmsg,*) trim(subname),' input field rank ',rank_in,' for '//trim(merge_fldname), & + ' not equal to output field rank ',rank_out,' for '//trim(fldname_out) + call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + else if (rank_out == 2) then + call ESMF_FieldGet(field_in, ungriddedUBound=ungriddedUBound_in, & + gridToFieldMap=gridToFieldMap_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound_out(1) /= ungriddedUBound_in(1)) then + write(errmsg,*) trim(subname),"ungriddedUBound_in (",ungriddedUBound_in(1),& + ") not equal to ungriddedUBound_out (",ungriddedUBound_out(1),") for "//trim(fldname_out) + call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + else if (gridToFieldMap_in(1) /= gridToFieldMap_out(1)) then + write(errmsg,*) trim(subname),"gridtofieldmap_in (",gridtofieldmap_in(1),& + ") not equal to gridtofieldmap_out (",gridtofieldmap_out(1),") for "//trim(fldname_out) + call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + endif + + end subroutine med_merge_errcheck + + !=============================================================================== + subroutine med_merge_auto_field(merge_type, field_out, & + rank_out, ungriddedUBound_out, gridToFieldMap_out, & + FB, FBfld, FBw, fldw, rc) use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogMsg_Error - use ESMF , only : ESMF_LogWrite, ESMF_LogMsg_Info use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only : ESMF_LogWrite, ESMF_LogMsg_Info use ESMF , only : ESMF_FieldGet, ESMF_Field ! input/output variables + integer ,intent(in) :: rank_out ! rank of output array character(len=*) ,intent(in) :: merge_type - type(ESMF_FieldBundle),intent(inout) :: FBout - character(len=*) ,intent(in) :: FBoutfld + type(ESMF_Field) ,intent(inout) :: field_out + integer ,intent(in) :: ungriddedUBound_out(1) + integer ,intent(in) :: gridToFieldMap_out(1) type(ESMF_FieldBundle),intent(in) :: FB character(len=*) ,intent(in) :: FBfld type(ESMF_FieldBundle),intent(inout) :: FBw ! field bundle with weights @@ -219,18 +334,11 @@ subroutine med_merge_auto_field(merge_type, FBout, FBoutfld, FB, FBfld, FBw, fld ! local variables integer :: n - type(ESMF_Field) :: lfield + type(ESMF_Field) :: field_wgt + type(ESMF_Field) :: field_in real(R8), pointer :: dp1 (:), dp2(:,:) ! output pointers to 1d and 2d fields real(R8), pointer :: dpf1(:), dpf2(:,:) ! intput pointers to 1d and 2d fields real(R8), pointer :: dpw1(:) ! weight pointer - integer :: lrank_input ! rank of input array - integer :: lrank_output ! rank of output array - integer :: ungriddedUBound_output(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: ungriddedUBound_input(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: gridToFieldMap_output(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: gridToFieldMap_input(1) ! currently the size must equal 1 for rank 2 fieldds - character(len=CL) :: errmsg - character(len=CL) :: msg character(len=*),parameter :: subname=' (med_merge_mod: med_merge)' !--------------------------------------- @@ -259,112 +367,65 @@ subroutine med_merge_auto_field(merge_type, FBout, FBoutfld, FB, FBfld, FBw, fld ! Get appropriate field pointers !------------------------- - ! Get field pointer to output field - call ESMF_FieldBundleGet(FBout, trim(FBoutfld), field=lfield, rc=rc) + ! Get input field + call ESMF_FieldBundleGet(FB, FBfld, field=field_in, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank_output, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - write(msg,*)trim(subname),'output field ',trim(FBoutfld),' has rank ',lrank_output - call ESMF_LogWrite(msg, ESMF_LOGMSG_INFO) - end if - if (lrank_output == 1) then - call ESMF_FieldGet(lfield, farrayPtr=dp1, rc=rc) + ! Get field pointer to output and input fields + ! Assume that input and output ranks are the same - this is checked in error check + if (rank_out == 1) then + call ESMF_FieldGet(field_in, farrayPtr=dpf1, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (lrank_output == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, & - gridToFieldMap=gridToFieldMap_output, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dp2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - ! Get field pointer to input field used in the merge - call ESMF_FieldBundleGet(FB, FBfld, field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank_input, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - write(msg,*)trim(subname),'input field ',trim(FBfld),' has rank ',lrank_input - call ESMF_LogWrite(msg, ESMF_LOGMSG_INFO) - end if - - if (lrank_input == 1) then - call ESMF_FieldGet(lfield, farrayPtr=dpf1, rc=rc) + call ESMF_FieldGet(field_out, farrayPtr=dp1, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (lrank_input == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_input, & - gridToFieldMap=gridToFieldMap_input, rc=rc) + else if (rank_out == 2) then + call ESMF_FieldGet(field_in, farrayPtr=dpf2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dpf2, rc=rc) + call ESMF_FieldGet(field_out, farrayPtr=dp2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - ! error checks - if (lrank_input /= lrank_output) then - write(errmsg,*) trim(subname),' input field rank ',lrank_input,' for '//trim(FBfld), & - ' not equal to output field rank ',lrank_output,' for '//trim(FBoutfld) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - else if (lrank_output == 2) then - if (ungriddedUBound_output(1) /= ungriddedUBound_input(1)) then - write(errmsg,*) trim(subname),"ungriddedUBound_input (",ungriddedUBound_input(1),& - ") not equal to ungriddedUBound_output (",ungriddedUBound_output(1),") for "//trim(FBoutfld) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - else if (gridToFieldMap_input(1) /= gridToFieldMap_output(1)) then - write(errmsg,*) trim(subname),"gridtofieldmap_input (",gridtofieldmap_input(1),& - ") not equal to gridtofieldmap_output (",gridtofieldmap_output(1),") for "//trim(FBoutfld) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - end if - endif - ! Get pointer to weights that weights are only rank 1 if (merge_type == 'copy_with_weights' .or. merge_type == 'merge' .or. merge_type == 'sum_with_weights') then - call ESMF_FieldBundleGet(FBw, fieldName=trim(fldw), field=lfield, rc=rc) + call ESMF_FieldBundleGet(FBw, fieldName=trim(fldw), field=field_wgt, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dpw1, rc=rc) + call ESMF_FieldGet(field_wgt, farrayPtr=dpw1, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return endif ! Do supported merges if (trim(merge_type) == 'copy') then - if (lrank_output == 1) then + if (rank_out == 1) then dp1(:) = dpf1(:) else dp2(:,:) = dpf2(:,:) endif else if (trim(merge_type) == 'copy_with_weights') then - if (lrank_output == 1) then + if (rank_out == 1) then dp1(:) = dpf1(:)*dpw1(:) else - do n = 1,ungriddedUBound_input(1) - if (gridToFieldMap_input(1) == 1) then + do n = 1,ungriddedUBound_out(1) + if (gridToFieldMap_out(1) == 1) then dp2(:,n) = dpf2(:,n)*dpw1(:) - else if (gridToFieldMap_input(1) == 2) then + else if (gridToFieldMap_out(1) == 2) then dp2(n,:) = dpf2(n,:)*dpw1(:) end if end do endif else if (trim(merge_type) == 'merge' .or. trim(merge_type) == 'sum_with_weights') then - if (lrank_output == 1) then + if (rank_out == 1) then dp1(:) = dp1(:) + dpf1(:)*dpw1(:) else - do n = 1,ungriddedUBound_input(1) - if (gridToFieldMap_input(1) == 1) then + do n = 1,ungriddedUBound_out(1) + if (gridToFieldMap_out(1) == 1) then dp2(:,n) = dp2(:,n) + dpf2(:,n)*dpw1(:) - else if (gridToFieldMap_input(1) == 2) then + else if (gridToFieldMap_out(1) == 2) then dp2(n,:) = dp2(n,:) + dpf2(n,:)*dpw1(:) end if end do endif else if (trim(merge_type) == 'sum') then - if (lrank_output == 1) then + if (rank_out == 1) then dp1(:) = dp1(:) + dpf1(:) else dp2(:,:) = dp2(:,:) + dpf2(:,:) diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index 95994d30f..b071c1a9c 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -154,16 +154,22 @@ subroutine med_phases_prep_atm(gcomp, rc) !--- merge all fields to atm !--------------------------------------- if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - call med_merge_auto(trim(compname(compatm)), & - is_local%wrap%FBExp(compatm), is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), fldListTo(compatm), & + 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(trim(compname(compatm)), & - is_local%wrap%FBExp(compatm), is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), fldListTo(compatm), rc=rc) + 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 diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 3aabc5691..fbf1a46e0 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -121,9 +121,12 @@ subroutine med_phases_prep_ice(gcomp, rc) !--- auto merges to create FBExp(compice) !--------------------------------------- - call med_merge_auto(trim(compname(compice)), & - is_local%wrap%FBExp(compice), is_local%wrap%FBFrac(compice), & - is_local%wrap%FBImp(:,compice), fldListTo(compice), rc=rc) + 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 !--------------------------------------- diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 81a653db3..47e293c50 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -137,7 +137,8 @@ subroutine med_phases_prep_lnd(gcomp, rc) ! The following will merge all fields in fldsSrc ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) - call med_merge_auto(trim(compname(complnd)), & + call med_merge_auto(complnd, & + is_local%wrap%med_coupling_active(:,complnd), & is_local%wrap%FBExp(complnd), & is_local%wrap%FBFrac(complnd), & is_local%wrap%FBImp(:,complnd), & diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 69eab1a42..c48846c6c 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -147,15 +147,21 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) if (trim(coupling_mode) == 'cesm' .or. & trim(coupling_mode) == 'nems_orig_data' .or. & trim(coupling_mode) == 'hafs') then - call med_merge_auto(trim(compname(compocn)), & - is_local%wrap%FBExp(compocn), is_local%wrap%FBFrac(compocn), & - is_local%wrap%FBImp(:,compocn), fldListTo(compocn), & + 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(trim(compname(compocn)), & - is_local%wrap%FBExp(compocn), is_local%wrap%FBFrac(compocn), & - is_local%wrap%FBImp(:,compocn), fldListTo(compocn), rc=rc) + 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 diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 158765207..3a39e6538 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -262,7 +262,8 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - call med_merge_auto(trim(compname(comprof)), & + 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), & diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index bee6ad614..6cc4e6658 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -94,7 +94,8 @@ subroutine med_phases_prep_wav(gcomp, rc) !--- auto merges to create FBExp(compwav) !--------------------------------------- - call med_merge_auto(trim(compname(compwav)), & + call med_merge_auto(compwav, & + is_local%wrap%med_coupling_active(:,compwav), & is_local%wrap%FBExp(compwav), & is_local%wrap%FBFrac(compwav), & is_local%wrap%FBImp(:,compwav), & From 16962cdd83c242add6a254522d0ccd12fbca6f8a Mon Sep 17 00:00:00 2001 From: mvertens Date: Wed, 14 Oct 2020 16:36:15 -0600 Subject: [PATCH 120/206] updates to mapping to handle packed field bundles --- mediator/med_internalstate_mod.F90 | 1 + mediator/med_map_packed_mod.F90 | 294 ++++++++++++++++++++++ mediator/med_phases_history_mod.F90 | 9 + mediator/med_phases_prep_lnd_mod.F90 | 354 ++++++++++++--------------- 4 files changed, 457 insertions(+), 201 deletions(-) create mode 100644 mediator/med_map_packed_mod.F90 diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index bbb588604..8848958c7 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -92,6 +92,7 @@ module med_internalstate_mod ! Mapping type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers type(ESMF_FieldBundle) :: FBNormOne(ncomps,ncomps,nmappers) ! Unity static normalization + type(ESMF_FieldBundle) :: FBImp_packed(ncomps,ncomps,nmappers) ! Fractions type(ESMF_FieldBundle) :: FBfrac(ncomps) ! Fraction data for various components, on their grid diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 new file mode 100644 index 000000000..04aba7e38 --- /dev/null +++ b/mediator/med_map_packed_mod.F90 @@ -0,0 +1,294 @@ +module med_map_packed_mod + + !------------------------------------------ + ! Create packed field bundles needed for mapping + ! and map the packed field bundles + !------------------------------------------ + + use med_kind_mod , only : cx=>shr_kind_cx, cs=>shr_kind_cs, cl=>shr_kind_cl, i8=>shr_kind_i8, r8=>shr_kind_r8 + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + + implicit none + private + + public :: med_map_packed_fieldbundles_create + public :: med_map_packed_fieldbundles + + integer , parameter :: number_strlen = 2 + character(*),parameter :: u_FILE_u = & + __FILE__ + +!=============================================================================== +contains +!=============================================================================== + + subroutine med_map_packed_fieldbundles_create(flds_scalar_name, fldsSrc, & + FBSrc, FBSrc_packed, FBDst_packed, FBDst, rc) + + use ESMF + use esmFlds , only : mapfcopy, med_fldList_entry_type + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + + ! input/output variables + character(len=*) , intent(in) :: flds_scalar_name + type(med_fldList_entry_type) , pointer :: fldsSrc(:) + type(ESMF_FieldBundle) , intent(in) :: FBSrc + type(ESMF_FieldBundle) , intent(inout) :: FBSrc_packed(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(inout) :: FBDst_packed(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(in) :: FBDst + integer , intent(out) :: rc + + ! local variables + integer :: n, n1, nf, nu + integer :: npacked + integer :: fieldcount + integer :: lrank + type(ESMF_Field) :: lfield + character(CL) :: fldname + 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 + character(CL), allocatable :: lfieldnamelist(:) + character(CL), allocatable :: lfieldnamelist_packed(:) + real(r8), pointer :: ptrsrc_packed(:,:) + real(r8), pointer :: ptrdst_packed(:,:) + integer :: lsize_src + integer :: lsize_dst + type(ESMF_Mesh) :: lmesh_src + type(ESMF_Mesh) :: lmesh_dst + integer :: mapindex + character(len=number_strlen) :: cnumber + character(len=*), parameter :: subname=' (med_packed_fieldbundles_create) ' + !----------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used + mapindex = mapfcopy + + ! determine field list in source field bundle + call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, fieldCount + if (trim(lfieldnamelist(n)) == trim(flds_scalar_name) .or. trim(lfieldnamelist(n)) == '') then + do n1 = n, fieldCount-1 + lfieldnamelist(n1) = lfieldnamelist(n1+1) + enddo + fieldCount = fieldCount - 1 + endif + enddo ! n + + ! Reset fieldcount based on the fact that some fields have ungridded dimensions and + ! need to unwrap them into separate fields for the purposes of packing + npacked = 0 + do nf = 1, fieldCount + fldname = trim(lfieldnamelist(nf)) + call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 2) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + npacked = npacked + ungriddedUBound(1) + else + npacked = npacked + 1 + end if + end do + + ! Get list of fields in including new field names for each ungridded dimension + npacked = 0 + allocate(lfieldnamelist_packed(npacked)) + do nf = 1, fieldCount + fldname = trim(lfieldnamelist(nf)) + call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 2) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + npacked = npacked + 1 + write(cnumber,'(i0)') nu + lfieldnamelist_packed(npacked) = trim(fldname)//trim(cnumber) + end do + else + npacked = npacked + 1 + lfieldnamelist_packed(npacked) = trim(fldname) + end if + end do + + ! Determine local size and mesh of source fields + ! Allocate a source fortran pointer for the new packed field bundle + ! Create the packed source field bundle + call FB_getFieldN(FBSrc, 1, lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, mesh=lmesh_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(ptrsrc_packed(npacked, lsize_src)) + FBSrc_packed(mapindex) = ESMF_FieldBundleCreate(lfieldnamelist_packed, & + ptrsrc_packed, lmesh_src, lsize_src, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + + ! Determine local size of destination fields + ! Allocate a destination fortran pointer for the new packed field bundle + ! Create the packed source field bundle + call FB_getFieldN(FBDst, 1, lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, mesh=lmesh_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(ptrdst_packed(npacked, lsize_dst)) + FBDst_packed(mapindex) = ESMF_FieldBundleCreate(lfieldnamelist_packed, & + ptrdst_packed, lmesh_dst, lsize_dst, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + + deallocate(lfieldnamelist) + deallocate(lfieldnamelist_packed) + + end subroutine med_map_packed_fieldbundles_create + + !================================================================================ + subroutine med_map_packed_fieldbundles(flds_scalar_name, FBSrc, FBSrc_packed, FBDst_packed, FBDst, & + RouteHandles, rc) + + ! ----------------------------------------------- + ! Do the redistribution on the packed field bundles + ! ----------------------------------------------- + + use ESMF + use esmFlds , only : mapfcopy + use med_methods_mod , only : FB_getFieldByName => med_methods_FB_getFieldByName + + ! input/output variables + character(len=*) , intent(in) :: flds_scalar_name + type(ESMF_FieldBundle) , intent(in) :: FBSrc + type(ESMF_FieldBundle) , intent(inout) :: FBSrc_packed(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(inout) :: FBDst_packed(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(inout) :: FBDst + type(ESMF_RouteHandle) , intent(inout) :: RouteHandles(:) + integer , intent(out) :: rc + + ! local variables + integer :: n, n1, nf, nu + integer :: npacked + integer :: fieldcount + character(CL), allocatable :: lfieldnamelist(:) + integer :: lrank + type(ESMF_Field) :: lfield + type(ESMF_Field) :: lfield_packed + character(CL) :: fldname + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + real(r8), pointer :: dataptr1d(:) + real(r8), pointer :: dataptr2d(:,:) + real(r8), pointer :: dataptr1d_packed(:) + integer :: lsize_src + integer :: lsize_dst + integer :: mapindex + character(len=number_strlen) :: cnumber + character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + !----------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used + mapindex = mapfcopy + + ! determine field list in source field bundle + call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, fieldCount + if (trim(lfieldnamelist(n)) == trim(flds_scalar_name) .or. trim(lfieldnamelist(n)) == '') then + do n1 = n, fieldCount-1 + lfieldnamelist(n1) = lfieldnamelist(n1+1) + enddo + fieldCount = fieldCount - 1 + endif + enddo ! n + + ! copy the src fields into the packed field bundle + do n = 1,fieldcount + fldname = lfieldnamelist(n) + call FB_getFieldByName(FBSrc, trim(fldname), lfield, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 2) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + ! Name of packed field is same as name of src field with + ! the ungridded dimension appended + write(cnumber,'(i0)') nu + call FB_getFieldByName(FbSrc_packed(mapindex), trim(fldname)//trim(cnumber), lfield_packed, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, 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 + dataptr1d_packed(:) = dataptr2d(nu,:) + end do + else + ! Name of packed field is same as name of src field + call FB_getFieldByName(FBSrc_packed(mapindex), trim(fldname), lfield_packed, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, 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_packed(:) = dataptr1d(:) + end if + end do + + ! Do the mapping + call ESMF_FieldBundleRedist(FBSrc_packed(mapindex), FBDst_packed(mapindex), Routehandles(mapindex), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Copy the destination packed field bundle into the destination unpacked field bundle + do n = 1,fieldcount + fldname = lfieldnamelist(n) + call FB_getFieldByName(FBDst, trim(fldname), lfield, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 2) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + ! Name of packed field is same as name of field with + ! the ungridded dimension appended + write(cnumber,'(i0)') nu + call FB_getFieldByName(FBDst_packed(mapindex), & + trim(fldname)//trim(cnumber), lfield_packed, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_packed, farrayptr=dataPtr1d_packed, 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(nu,:) = dataptr1d_packed(:) + end do + else + ! Name of packed field is same as name of src field + call FB_getFieldByName(FBDst_packed(mapindex), trim(fldname), lfield_packed, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, 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_packed(:) + end if + end do + + deallocate(lfieldnamelist) + + end subroutine med_map_packed_fieldbundles + +end module med_map_packed_mod diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index f4f60f09f..f7e9f90ea 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -427,6 +427,15 @@ subroutine med_phases_history_write(gcomp, rc) call med_io_write(hist_file, iam, is_local%wrap%FBMed_ocnalb_o, & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_alb_ocn', rc=rc) end if + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc) .and. & + ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(compatm,compocn))) then + ! This provides the atm input on the ocn mesh needed for that atm/ocn calculation + ! that currently is restricted to the ocn mesh + nx = is_local%wrap%nx(compocn) + ny = is_local%wrap%ny(compocn) + call med_io_write(hist_file, iam, is_local%wrap%FBImp(compatm,compocn), & + nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='AtmImp_ocn', rc=rc) + end if if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc)) then nx = is_local%wrap%nx(compocn) ny = is_local%wrap%ny(compocn) diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 47e293c50..90bbb61b4 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -8,29 +8,22 @@ module med_phases_prep_lnd_mod 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_FieldBundleCreate, ESMF_FieldBundleAdd - use ESMF , only : ESMF_RouteHandle 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 + 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_TYPEKIND_R8 + use ESMF , only : ESMF_RouteHandle use esmFlds , only : complnd, compatm, compglc, ncomps, compname, mapconsd - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : med_fldlist_type - 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_getNumFlds => med_methods_FB_getNumFlds - use med_methods_mod , only : FB_init => med_methods_FB_init + 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 : 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, logunit - use med_map_mod , only : med_map_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_routehandles_init + use med_internalstate_mod , only : InternalState, mastertask, logunit + use med_map_mod , only : med_map_rh_is_created + 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 @@ -42,8 +35,8 @@ module med_phases_prep_lnd_mod public :: med_phases_prep_lnd - private :: med_map_glc2lnd_init - private :: med_map_glc2lnd + private :: map_glc2lnd_init + private :: map_glc2lnd ! private module variables character(len =*), parameter :: Sg_icemask = 'Sg_icemask' @@ -52,11 +45,14 @@ module med_phases_prep_lnd_mod character(len =*), parameter :: Sg_topo = 'Sg_topo' character(len =*), parameter :: Flgg_hflx = 'Flgg_hflx' - type(ESMF_FieldBundle) :: FBglc_icemask ! no elevation classes - type(ESMF_FieldBundle) :: FBglc_frac_x_icemask ! elevation classes - type(ESMF_FieldBundle) :: FBlnd_frac_x_icemask ! elevation classes - type(ESMF_FieldBundle) :: FBglc_ec - type(ESMF_FieldBundle) :: FBlnd_ec + 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) @@ -90,49 +86,39 @@ subroutine med_phases_prep_lnd(gcomp, rc) call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if - !--------------------------------------- - ! --- 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 - !--------------------------------------- - + ! 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 FB_getNumFlds(is_local%wrap%FBExp(complnd), trim(subname)//"FBexp(complnd)", ncnt, rc) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldCount=ncnt, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then !--------------------------------------- - !--- map to create FBimp(:,complnd) + ! map to create FBimp(:,complnd) !--------------------------------------- do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,complnd)) then - ! The following will map all atm->lnd, rof->lnd, and - ! glc->lnd only for Sg_icemask_field and Sg_icemask_coupled_fluxes - call med_map_FB_Regrid_Norm( & - fldsSrc=fldListFr(n1)%flds, & - srccomp=n1, destcomp=complnd, & + 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), & - FBNormOne=is_local%wrap%FBNormOne(n1,complnd,:), & - RouteHandles=is_local%wrap%RH(n1,complnd,:), & - string=trim(compname(n1))//'2'//trim(compname(complnd)), rc=rc) + 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 - enddo + end do !--------------------------------------- - !--- auto merges to create FBExp(complnd) + ! auto merges to create FBExp(complnd) !--------------------------------------- ! The following will merge all fields in fldsSrc @@ -146,26 +132,23 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - !--- custom calculations + ! 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 med_map_glc2lnd_init(gcomp, rc=rc) + call map_glc2lnd_init(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - first_call = .false. end if - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call med_map_glc2lnd(gcomp, rc=rc) + call map_glc2lnd(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if !--------------------------------------- - !--- update scalar data + ! update scalar data !--------------------------------------- - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then @@ -186,22 +169,15 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - !--- diagnose - !--------------------------------------- - + ! diagnose if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExp(complnd), & string=trim(subname)//' FBexp(complnd) ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - - !--------------------------------------- - !--- clean up - !--------------------------------------- - end if + first_call = .false. if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) @@ -212,19 +188,21 @@ end subroutine med_phases_prep_lnd !================================================================================================ - subroutine med_map_glc2lnd_init(gcomp, rc) + 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) ! currently the size must equal 1 for rank 2 fieldds - character(len=*) , parameter :: subname='(med_map_glc2lnd_mod:med_map_glc2lnd_init)' + 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 @@ -242,7 +220,7 @@ subroutine med_map_glc2lnd_init(gcomp, rc) !--------------------------------------- ! 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, rc=rc) + 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 @@ -253,74 +231,63 @@ subroutine med_map_glc2lnd_init(gcomp, rc) ! Get the glc and land meshes !--------------------------------------- - call FB_getFieldN(is_local%wrap%FBExp(complnd), 1, field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_lnd, rc=rc) + 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 FB_getFieldN(is_local%wrap%FBImp(compglc,compglc), 1, field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_glc, rc=rc) + 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 ! ------------------------------- - FBglc_icemask = ESMF_FieldBundleCreate(rc=rc) + field_icemask_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, name=trim(Sg_icemask), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBglc_icemask, (/lfield/), rc=rc) + field_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - FBglc_frac_x_icemask = ESMF_FieldBundleCreate(rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, name=trim(Sg_frac_x_icemask), meshloc=ESMF_MESHLOC_ELEMENT, & + 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 - call ESMF_FieldBundleAdd(FBglc_frac_x_icemask, (/lfield/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - FBlnd_frac_x_icemask = ESMF_FieldBundleCreate(rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, name=trim(Sg_frac_x_icemask), meshloc=ESMF_MESHLOC_ELEMENT, & + 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 - call ESMF_FieldBundleAdd(FBlnd_frac_x_icemask, (/lfield/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - FBglc_ec = ESMF_FieldBundleCreate(rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, name='field_ec', meshloc=ESMF_MESHLOC_ELEMENT, & + 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 - call ESMF_FieldBundleAdd(FBglc_ec, (/lfield/), rc=rc) + 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 - FBlnd_ec = ESMF_FieldBundleCreate(rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, name='field_ec', meshloc=ESMF_MESHLOC_ELEMENT, & + 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 - call ESMF_FieldBundleAdd(FBlnd_ec, (/lfield/), rc=rc) + 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 - ! ------------------------------- - + ! Verify that route handle has been created if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:), mapconsd,rc=rc)) then - call med_map_routehandles_init( compglc, complnd, & - FBSrc=FBglc_ec, FBDst=FBlnd_ec, & - mapindex=mapconsd, RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for glc->lnd mapping", & + ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + 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__) @@ -328,11 +295,10 @@ subroutine med_map_glc2lnd_init(gcomp, rc) return end if - end subroutine med_map_glc2lnd_init + end subroutine map_glc2lnd_init !================================================================================================ - - subroutine med_map_glc2lnd( gcomp, rc) + subroutine map_glc2lnd( gcomp, rc) !------------------ ! Maps fields from the GLC grid to the LND grid. @@ -346,23 +312,22 @@ subroutine med_map_glc2lnd( gcomp, rc) ! local variables type(InternalState) :: is_local - type(med_fldlist_type) :: fldlist - integer :: ec, nfld, n, l, g + type(ESMF_Field) :: lfield + integer :: ec, l, g real(r8) :: topo_virtual - real(r8), pointer :: icemask_g(:) ! glc ice mask field on glc grid - real(r8), pointer :: frac_g(:) ! total ice fraction in each glc cell - real(r8), pointer :: frac_g_ec(:,:) ! glc fractions on the glc grid - real(r8), pointer :: frac_l_ec(:,:) ! glc fractions on the land grid - real(r8), pointer :: frac_x_icemask_g_ec(:,:) ! (glc fraction) x (icemask), on the glc grid - real(r8), pointer :: topo_g(:) ! topographic height of each glc cell (no elevation classes) - real(r8), pointer :: topo_l_ec(:,:) ! topographic height in each land gridcell for each elevation class - real(r8), pointer :: topo_x_icemask_g(:,:) - real(r8), pointer :: topo_x_icemask_l(:,:) - real(r8), pointer :: frac_x_icemask_g(:,:) - real(r8), pointer :: frac_x_icemask_l(:,:) - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d_exp(:,:) - character(len=*), parameter :: subname = 'med_map_glc2lnd' + 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) @@ -390,55 +355,58 @@ subroutine med_map_glc2lnd( gcomp, rc) ! 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 FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_topo), fldptr1=topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_frac), fldptr1=frac_g, rc=rc) + 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 FB_getFldPtr(FBglc_ec, 'field_ec', fldptr2=frac_g_ec, rc=rc) + 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) - ! Set the contents of FBglc_icemask - call FB_getFldPtr(FBglc_icemask, trim(Sg_icemask), fldptr1=icemask_g, rc=rc) + ! 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 FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_icemask), fldptr1=dataptr1d, rc=rc) + 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(:) - ! Only include grid cells that are both (a) within the icemask and (b) in this elevation class - call FB_getFldPtr(FBglc_frac_x_icemask, trim(Sg_frac_x_icemask), fldptr2=frac_x_icemask_g_ec, rc=rc) + ! 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 to lnd and normalize by Sg_icemask_field + ! 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 - allocate(fldlist%flds(1)) - fldlist%flds(1)%shortname = 'field_ec' - fldlist%flds(1)%mapindex(complnd) = mapconsd - fldlist%flds(1)%mapnorm(complnd) = trim(Sg_icemask) - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList%flds, & - srccomp=compglc, & - destcomp=complnd, & - FBSrc=FBglc_ec, & ! this has multiple elevation classes - FBDst=FBlnd_ec, & ! this has multiple elvation classes - FBFracSrc=FBglc_icemask, & ! this is used with a mapnorm of Sg_icemask_field - FBNormOne=is_local%wrap%FBNormOne(compglc,complnd,:), & ! this will not be used - RouteHandles=is_local%wrap%RH(compglc,complnd,:), & - string='mapping elevation class fractions from glc to land ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fldlist%flds) - call FB_getFldPtr(FBlnd_ec, 'field_ec', fldptr2=frac_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBExp(complnd), trim(Sg_frac)//'_elev', fldptr2=dataptr2d_exp, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d_exp(:,:) = frac_l_ec(:,:) + 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) @@ -450,60 +418,42 @@ subroutine med_map_glc2lnd( gcomp, rc) ! land grid (with elevation classes) ! Note that bare land values are mapped in the same way as ice-covered values - call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_topo), fldptr1=topo_g, rc=rc) + 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 FB_getFldPtr(FBglc_ec, 'field_ec', fldptr2=topo_x_icemask_g, rc=rc) + 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,l) = topo_g(l) * frac_x_icemask_g_ec(ec,l) + topo_x_icemask_g_ec(ec,l) = topo_g(l) * frac_x_icemask_g_ec(ec,l) end do end do - ! map FBglc_topo_x_icemask from glc to land (with multiple elevation classes) - no normalization + ! 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 - allocate(fldlist%flds(1)) - fldlist%flds(1)%shortname = 'field_ec' - fldlist%flds(1)%mapindex(complnd) = mapconsd - fldlist%flds(1)%mapnorm(complnd) = 'none' - call med_map_FB_Regrid_Norm( & - fldsSrc=fldlist%flds, & - srccomp=compglc, & - destcomp=complnd, & - FBSrc=FBglc_ec, & - FBDst=FBlnd_ec, & - FBFracSrc=is_local%wrap%FBFrac(compglc), & ! this will not be used - FBNormOne=is_local%wrap%FBNormOne(compglc,complnd,:), & ! this will not be used - RouteHandles=is_local%wrap%RH(compglc,complnd,:), & - string='mapping topo from glc to land (with elevation classes)', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fldlist%flds) - call FB_getFldPtr(FBlnd_ec, 'field_ec', fldptr2=topo_l_ec , rc=rc) + 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 - allocate(fldlist%flds(1)) - fldlist%flds(1)%shortname = trim(Sg_frac_x_icemask) - fldlist%flds(1)%mapindex(complnd) = mapconsd - fldlist%flds(1)%mapnorm(complnd) = 'none' - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList%flds, & - srccomp=compglc, & - destcomp=complnd, & - FBSrc=FBglc_frac_x_icemask, & - FBDst=FBlnd_frac_x_icemask, & - FBFracSrc=is_local%wrap%FBFrac(compglc), & ! this will not be used - FBNormOne=is_local%wrap%FBNormOne(compglc,complnd,:), & ! this will not be used - RouteHandles=is_local%wrap%RH(compglc,complnd,:), & - string='mapping frac_x_icemask from glc to land (with elevation classes)', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fldlist%flds) - call FB_getFldPtr(FBlnd_frac_x_icemask, trim(Sg_frac_x_icemask), fldptr2=frac_x_icemask_l , rc=rc) + 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) @@ -511,18 +461,20 @@ subroutine med_map_glc2lnd( gcomp, rc) ! 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 FB_getFldPtr(is_local%wrap%FBExp(complnd), trim(Sg_topo)//'_elev', fldptr2=dataptr2d_exp, rc=rc) + 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, dim=2) + do l = 1,size(frac_x_icemask_l_ec, dim=2) if (frac_l_ec(ec,l) <= 0._r8) then - dataptr2d_exp(ec,l) = topo_virtual + dataptr2d(ec,l) = topo_virtual else - if (frac_x_icemask_l(ec,l) == 0.0_r8) then - dataptr2d_exp(ec,l) = 0.0_r8 + if (frac_x_icemask_l_ec(ec,l) == 0.0_r8) then + dataptr2d(ec,l) = 0.0_r8 else - dataptr2d_exp(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l(ec,l) + dataptr2d(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) end if end if end do @@ -533,6 +485,6 @@ subroutine med_map_glc2lnd( gcomp, rc) end if call t_stopf('MED:'//subname) - end subroutine med_map_glc2lnd + end subroutine map_glc2lnd end module med_phases_prep_lnd_mod From 237fd0f62ffb658b6d0c36dafe94a054edda4e11 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 15 Oct 2020 13:48:02 -0600 Subject: [PATCH 121/206] major performance boosts for hard-wired packed redist --- mediator/med_internalstate_mod.F90 | 5 +- mediator/med_map_packed_mod.F90 | 246 +++++++++++------------------ 2 files changed, 93 insertions(+), 158 deletions(-) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 8848958c7..eeef9bda7 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -4,7 +4,7 @@ module med_internalstate_mod ! Mediator Internal State Datatype. !----------------------------------------------------------------------------- - use ESMF , only : ESMF_RouteHandle, ESMF_FieldBundle, ESMF_State + use ESMF , only : ESMF_RouteHandle, ESMF_FieldBundle, ESMF_State, ESMF_Field use ESMF , only : ESMF_VM use esmFlds , only : ncomps, nmappers use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 @@ -92,7 +92,8 @@ module med_internalstate_mod ! Mapping type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers type(ESMF_FieldBundle) :: FBNormOne(ncomps,ncomps,nmappers) ! Unity static normalization - type(ESMF_FieldBundle) :: FBImp_packed(ncomps,ncomps,nmappers) + type(ESMF_Field) :: fieldsrc_packed(ncomps,ncomps,nmappers) + type(ESMF_Field) :: fielddst_packed(ncomps,ncomps,nmappers) ! Fractions type(ESMF_FieldBundle) :: FBfrac(ncomps) ! Fraction data for various components, on their grid diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 04aba7e38..3c253b2a8 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -8,6 +8,7 @@ module med_map_packed_mod use med_kind_mod , only : cx=>shr_kind_cx, cs=>shr_kind_cs, cl=>shr_kind_cl, i8=>shr_kind_i8, r8=>shr_kind_r8 use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_utils_mod , only : chkerr => med_utils_ChkErr + use perf_mod , only : t_startf, t_stopf implicit none private @@ -15,7 +16,6 @@ module med_map_packed_mod public :: med_map_packed_fieldbundles_create public :: med_map_packed_fieldbundles - integer , parameter :: number_strlen = 2 character(*),parameter :: u_FILE_u = & __FILE__ @@ -23,33 +23,25 @@ module med_map_packed_mod contains !=============================================================================== - subroutine med_map_packed_fieldbundles_create(flds_scalar_name, fldsSrc, & - FBSrc, FBSrc_packed, FBDst_packed, FBDst, rc) + subroutine med_map_packed_fieldbundles_create(fldsSrc, FBSrc, FBDst, fieldsrc_packed, fielddst_packed, rc) use ESMF - use esmFlds , only : mapfcopy, med_fldList_entry_type - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use esmFlds, only : mapfcopy, med_fldList_entry_type ! input/output variables - character(len=*) , intent(in) :: flds_scalar_name type(med_fldList_entry_type) , pointer :: fldsSrc(:) type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBSrc_packed(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(inout) :: FBDst_packed(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(in) :: FBDst + type(ESMF_FieldBundle) , intent(inout) :: FBDst + type(ESMF_Field) , intent(inout) :: fieldsrc_packed(:) ! array over mapping types + type(ESMF_Field) , intent(inout) :: fielddst_packed(:) ! array over mapping types integer , intent(out) :: rc ! local variables - integer :: n, n1, nf, nu + integer :: nf, nu integer :: npacked integer :: fieldcount - integer :: lrank type(ESMF_Field) :: lfield - character(CL) :: fldname 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 - character(CL), allocatable :: lfieldnamelist(:) - character(CL), allocatable :: lfieldnamelist_packed(:) real(r8), pointer :: ptrsrc_packed(:,:) real(r8), pointer :: ptrdst_packed(:,:) integer :: lsize_src @@ -57,7 +49,8 @@ subroutine med_map_packed_fieldbundles_create(flds_scalar_name, fldsSrc, & type(ESMF_Mesh) :: lmesh_src type(ESMF_Mesh) :: lmesh_dst integer :: mapindex - character(len=number_strlen) :: cnumber + type(ESMF_Field), pointer :: fieldlist_src(:) + type(ESMF_Field), pointer :: fieldlist_dst(:) character(len=*), parameter :: subname=' (med_packed_fieldbundles_create) ' !----------------------------------------------------------- @@ -66,96 +59,62 @@ subroutine med_map_packed_fieldbundles_create(flds_scalar_name, fldsSrc, & ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used mapindex = mapfcopy - ! determine field list in source field bundle + ! Get field count for both FBsrc and FBdst call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldcount)) - call ESMF_FieldBundleGet(FBsrc, fieldNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - if (trim(lfieldnamelist(n)) == trim(flds_scalar_name) .or. trim(lfieldnamelist(n)) == '') then - do n1 = n, fieldCount-1 - lfieldnamelist(n1) = lfieldnamelist(n1+1) - enddo - fieldCount = fieldCount - 1 - endif - enddo ! n - - ! Reset fieldcount based on the fact that some fields have ungridded dimensions and + allocate(fieldlist_src(fieldcount)) + allocate(fieldlist_dst(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Calculated size of packed field based on the fact that some fields have ungridded dimensions and ! need to unwrap them into separate fields for the purposes of packing npacked = 0 do nf = 1, fieldCount - fldname = trim(lfieldnamelist(nf)) - call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=lfield, rc=rc) + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - npacked = npacked + ungriddedUBound(1) - else - npacked = npacked + 1 - end if - end do - - ! Get list of fields in including new field names for each ungridded dimension - npacked = 0 - allocate(lfieldnamelist_packed(npacked)) - do nf = 1, fieldCount - fldname = trim(lfieldnamelist(nf)) - call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then do nu = 1,ungriddedUBound(1) npacked = npacked + 1 - write(cnumber,'(i0)') nu - lfieldnamelist_packed(npacked) = trim(fldname)//trim(cnumber) end do else npacked = npacked + 1 - lfieldnamelist_packed(npacked) = trim(fldname) end if end do ! Determine local size and mesh of source fields ! Allocate a source fortran pointer for the new packed field bundle ! Create the packed source field bundle - call FB_getFieldN(FBSrc, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_src, rc=rc) + call ESMF_FieldGet(fieldlist_src(1), mesh=lmesh_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(ptrsrc_packed(npacked, lsize_src)) - FBSrc_packed(mapindex) = ESMF_FieldBundleCreate(lfieldnamelist_packed, & - ptrsrc_packed, lmesh_src, lsize_src, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + fieldsrc_packed(mapindex) = ESMF_FieldCreate(lmesh_src, & + ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) ! Determine local size of destination fields ! Allocate a destination fortran pointer for the new packed field bundle ! Create the packed source field bundle - call FB_getFieldN(FBDst, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_dst, rc=rc) + call ESMF_FieldGet(fieldlist_dst(1), mesh=lmesh_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(ptrdst_packed(npacked, lsize_dst)) - FBDst_packed(mapindex) = ESMF_FieldBundleCreate(lfieldnamelist_packed, & - ptrdst_packed, lmesh_dst, lsize_dst, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + fielddst_packed(mapindex) = ESMF_FieldCreate(lmesh_dst, & + ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(lfieldnamelist) - deallocate(lfieldnamelist_packed) + deallocate(fieldlist_src) + deallocate(fieldlist_dst) end subroutine med_map_packed_fieldbundles_create !================================================================================ - subroutine med_map_packed_fieldbundles(flds_scalar_name, FBSrc, FBSrc_packed, FBDst_packed, FBDst, & - RouteHandles, rc) + subroutine med_map_packed_fieldbundles(FBSrc, FBDst, fieldsrc_packed, fielddst_packed, & + routehandles, rc) ! ----------------------------------------------- ! Do the redistribution on the packed field bundles @@ -163,34 +122,28 @@ subroutine med_map_packed_fieldbundles(flds_scalar_name, FBSrc, FBSrc_packed, FB use ESMF use esmFlds , only : mapfcopy - use med_methods_mod , only : FB_getFieldByName => med_methods_FB_getFieldByName + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN ! input/output variables - character(len=*) , intent(in) :: flds_scalar_name type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBSrc_packed(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(inout) :: FBDst_packed(:) ! array over mapping types type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_RouteHandle) , intent(inout) :: RouteHandles(:) + type(ESMF_Field) , intent(inout) :: fieldsrc_packed(:) ! array over mapping types + type(ESMF_Field) , intent(inout) :: fielddst_packed(:) ! array over mapping types + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) integer , intent(out) :: rc ! local variables - integer :: n, n1, nf, nu - integer :: npacked - integer :: fieldcount - character(CL), allocatable :: lfieldnamelist(:) - integer :: lrank - type(ESMF_Field) :: lfield - type(ESMF_Field) :: lfield_packed - character(CL) :: fldname - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d(:,:) - real(r8), pointer :: dataptr1d_packed(:) - integer :: lsize_src - integer :: lsize_dst - integer :: mapindex - character(len=number_strlen) :: cnumber + integer :: nf, nu + integer :: npacked + integer :: fieldcount + type(ESMF_Field) :: lfield + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + real(r8), pointer :: dataptr1d(:) + real(r8), pointer :: dataptr2d(:,:) + real(r8), pointer :: dataptr2d_packed(:,:) + integer :: mapindex + type(ESMF_Field), pointer :: fieldlist_src(:) + type(ESMF_Field), pointer :: fieldlist_dst(:) character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- @@ -199,95 +152,76 @@ subroutine med_map_packed_fieldbundles(flds_scalar_name, FBSrc, FBSrc_packed, FB ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used mapindex = mapfcopy - ! determine field list in source field bundle + ! Get field count for both FBsrc and FBdst call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldcount)) - call ESMF_FieldBundleGet(FBsrc, fieldNameList=lfieldnamelist, rc=rc) + allocate(fieldlist_src(fieldcount)) + allocate(fieldlist_dst(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the pointer for the packed source data + call ESMF_FieldGet(fieldsrc_packed(mapindex), farrayptr=dataptr2d_packed, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - if (trim(lfieldnamelist(n)) == trim(flds_scalar_name) .or. trim(lfieldnamelist(n)) == '') then - do n1 = n, fieldCount-1 - lfieldnamelist(n1) = lfieldnamelist(n1+1) - enddo - fieldCount = fieldCount - 1 - endif - enddo ! n - ! copy the src fields into the packed field bundle - do n = 1,fieldcount - fldname = lfieldnamelist(n) - call FB_getFieldByName(FBSrc, trim(fldname), lfield, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + ! Copy the src fields into the packed field bundle + call t_startf('MED:'//trim(subname)//' copy from src') + npacked = 0 + do nf = 1,fieldcount + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr2d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do nu = 1,ungriddedUBound(1) - ! Name of packed field is same as name of src field with - ! the ungridded dimension appended - write(cnumber,'(i0)') nu - call FB_getFieldByName(FbSrc_packed(mapindex), trim(fldname)//trim(cnumber), lfield_packed, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, 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 - dataptr1d_packed(:) = dataptr2d(nu,:) + npacked = npacked + 1 + dataptr2d_packed(npacked,:) = dataptr2d(nu,:) end do else - ! Name of packed field is same as name of src field - call FB_getFieldByName(FBSrc_packed(mapindex), trim(fldname), lfield_packed, rc) + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, 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_packed(:) = dataptr1d(:) + npacked = npacked + 1 + dataptr2d_packed(npacked,:) = dataptr1d(:) end if end do + call t_stopf('MED:'//trim(subname)//' copy from src') ! Do the mapping - call ESMF_FieldBundleRedist(FBSrc_packed(mapindex), FBDst_packed(mapindex), Routehandles(mapindex), rc=rc) + call t_startf('MED:'//trim(subname)//' map') + call ESMF_FieldRedist(fieldsrc_packed(mapindex), fielddst_packed(mapindex), routehandles(mapindex), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map') + + ! Get the pointer for the packed destination data + call ESMF_FieldGet(fielddst_packed(mapindex), farrayptr=dataptr2d_packed, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Copy the destination packed field bundle into the destination unpacked field bundle - do n = 1,fieldcount - fldname = lfieldnamelist(n) - call FB_getFieldByName(FBDst, trim(fldname), lfield, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, rank=lrank, rc=rc) + call t_startf('MED:'//trim(subname)//' copy to dest') + npacked = 0 + do nf = 1,fieldcount + call ESMF_FieldGet(fieldlist_dst(nf), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 2) then - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr2d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do nu = 1,ungriddedUBound(1) - ! Name of packed field is same as name of field with - ! the ungridded dimension appended - write(cnumber,'(i0)') nu - call FB_getFieldByName(FBDst_packed(mapindex), & - trim(fldname)//trim(cnumber), lfield_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_packed, farrayptr=dataPtr1d_packed, 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(nu,:) = dataptr1d_packed(:) + npacked = npacked + 1 + dataptr2d(nu,:) = dataptr2d_packed(npacked,:) end do else - ! Name of packed field is same as name of src field - call FB_getFieldByName(FBDst_packed(mapindex), trim(fldname), lfield_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_packed, farrayptr=dataptr1d_packed, rc=rc) + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr1d, 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_packed(:) + npacked = npacked + 1 + dataptr1d(:) = dataptr2d_packed(npacked,:) end if end do + call t_stopf('MED:'//trim(subname)//' copy to dest') - deallocate(lfieldnamelist) + deallocate(fieldlist_src) + deallocate(fieldlist_dst) end subroutine med_map_packed_fieldbundles From a05a7bb05b29ef6f162761d8295855bc322e6e7b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 18 Oct 2020 17:32:02 -0600 Subject: [PATCH 122/206] updates to get packed field bundles for other mappings --- mediator/med_internalstate_mod.F90 | 11 +- mediator/med_map_packed_mod.F90 | 406 ++++++++++++++++++++--------- 2 files changed, 297 insertions(+), 120 deletions(-) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index eeef9bda7..172d3384e 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -48,6 +48,14 @@ module med_internalstate_mod real(r8), pointer :: lons(:) end type mesh_info_type + type, public :: packed_data_type + integer, allocatable :: fldindex(:) ! size of number of packed fields + character(len=CS) :: mapnorm ! normalization for packed field + type(ESMF_Field) :: field_src ! packed sourced field + type(ESMF_Field) :: field_dst ! packed destination field + type(ESMF_Field) :: field_fracsrc + type(ESMF_Field) :: field_fracdst + end type packed_data_type ! private internal state to keep instance data type InternalStateStruct @@ -92,8 +100,7 @@ module med_internalstate_mod ! Mapping type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers type(ESMF_FieldBundle) :: FBNormOne(ncomps,ncomps,nmappers) ! Unity static normalization - type(ESMF_Field) :: fieldsrc_packed(ncomps,ncomps,nmappers) - type(ESMF_Field) :: fielddst_packed(ncomps,ncomps,nmappers) + type(packed_data_type) :: packed_data(ncomps,ncomps,nmappers) ! Fractions type(ESMF_FieldBundle) :: FBfrac(ncomps) ! Fraction data for various components, on their grid diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 3c253b2a8..7acc2a773 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -2,87 +2,83 @@ module med_map_packed_mod !------------------------------------------ ! Create packed field bundles needed for mapping - ! and map the packed field bundles + ! and map the packed field bundles !------------------------------------------ use med_kind_mod , only : cx=>shr_kind_cx, cs=>shr_kind_cs, cl=>shr_kind_cl, i8=>shr_kind_i8, r8=>shr_kind_r8 use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_utils_mod , only : chkerr => med_utils_ChkErr use perf_mod , only : t_startf, t_stopf + use med_internalstate_mod, only : mastertask, logunit + + use shr_sys_mod, only : shr_sys_flush implicit none private - public :: med_map_packed_fieldbundles_create - public :: med_map_packed_fieldbundles + public :: med_map_packed_field_create + public :: med_map_packed_field_map character(*),parameter :: u_FILE_u = & __FILE__ !=============================================================================== -contains +contains !=============================================================================== - subroutine med_map_packed_fieldbundles_create(fldsSrc, FBSrc, FBDst, fieldsrc_packed, fielddst_packed, rc) - + subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & + fldsSrc, FBSrc, FBDst, packed_data, rc) + use ESMF - use esmFlds, only : mapfcopy, med_fldList_entry_type + use esmFlds , only : med_fldList_entry_type, nmappers + use med_internalstate_mod , only : packed_data_type ! input/output variables - type(med_fldList_entry_type) , pointer :: fldsSrc(:) + integer , intent(in) :: destcomp + character(len=*) , intent(in) :: flds_scalar_name + type(med_fldList_entry_type) , pointer :: fldsSrc(:) ! array over mapping types type(ESMF_FieldBundle) , intent(in) :: FBSrc type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_Field) , intent(inout) :: fieldsrc_packed(:) ! array over mapping types - type(ESMF_Field) , intent(inout) :: fielddst_packed(:) ! array over mapping types + type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types integer , intent(out) :: rc ! local variables - integer :: nf, nu - integer :: npacked + integer :: nf, nu, ns + integer, allocatable :: npacked(:) integer :: fieldcount type(ESMF_Field) :: lfield integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: ptrsrc_packed(:,:) - real(r8), pointer :: ptrdst_packed(:,:) + real(r8), pointer :: ptrsrc_packed(:,:) => null() + real(r8), pointer :: ptrdst_packed(:,:) => null() integer :: lsize_src integer :: lsize_dst type(ESMF_Mesh) :: lmesh_src type(ESMF_Mesh) :: lmesh_dst integer :: mapindex - type(ESMF_Field), pointer :: fieldlist_src(:) - type(ESMF_Field), pointer :: fieldlist_dst(:) + type(ESMF_Field), pointer :: fieldlist_src(:) => null() + type(ESMF_Field), pointer :: fieldlist_dst(:) => null() + character(CL), allocatable :: fieldNameList(:) character(len=*), parameter :: subname=' (med_packed_fieldbundles_create) ' !----------------------------------------------------------- rc = ESMF_SUCCESS - ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used - mapindex = mapfcopy - ! Get field count for both FBsrc and FBdst call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! get fields in source and destination field bundles allocate(fieldlist_src(fieldcount)) - allocate(fieldlist_dst(fieldcount)) call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist_dst(fieldcount)) call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Calculated size of packed field based on the fact that some fields have ungridded dimensions and - ! need to unwrap them into separate fields for the purposes of packing - npacked = 0 - do nf = 1, fieldCount - call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - do nu = 1,ungriddedUBound(1) - npacked = npacked + 1 - end do - else - npacked = npacked + 1 - end if - end do + + ! field names are the same for the source and destination field bundles + allocate(fieldnamelist(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldnamelist=fieldnamelist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Determine local size and mesh of source fields ! Allocate a source fortran pointer for the new packed field bundle @@ -91,9 +87,6 @@ subroutine med_map_packed_fieldbundles_create(fldsSrc, FBSrc, FBDst, fieldsrc_pa if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(ptrsrc_packed(npacked, lsize_src)) - fieldsrc_packed(mapindex) = ESMF_FieldCreate(lmesh_src, & - ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) ! Determine local size of destination fields ! Allocate a destination fortran pointer for the new packed field bundle @@ -102,127 +95,304 @@ subroutine med_map_packed_fieldbundles_create(fldsSrc, FBSrc, FBDst, fieldsrc_pa if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(ptrdst_packed(npacked, lsize_dst)) - fielddst_packed(mapindex) = ESMF_FieldCreate(lmesh_dst, & - ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Gather all fields that will be mapped with a target map index into a packed field + ! Calculated size of packed field based on the fact that + ! some fields have ungridded dimensions and need to unwrap + ! them into separate fields for the purposes of packing + ! Looper over each mapping type + + ! TODO: What happens if you have a field in FBSrc that is not going to be mapped + + allocate(npacked(nmappers)) + npacked(:) = 0 + + ! Loop over mapping types + do mapindex = 1,nmappers + + ! Allocate the fldindex attribute of packed_indices if needed + if (.not. allocated(packed_data(mapindex)%fldindex)) then + allocate(packed_data(mapindex)%fldindex(fieldcount)) + packed_data(mapindex)%fldindex(:) = -999 + end if + + ! Loop over the fields in FBSrc + do nf = 1, fieldCount + + ! Loop over the fldsSrc types + do ns = 1,size(fldsSrc) + + if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & + fldsSrc(ns)%shortname /= flds_scalar_name .and. & + trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then + + ! Determine mapnorm - the assumption is that there is only one + ! mapnorm type for a source packed field bundle + if (npacked(mapindex) == 0) then + packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) + else + if (fldsSrc(ns)%mapnorm(destcomp) /= packed_data(mapindex)%mapnorm) then + call ESMF_LogWrite(trim(subname)//& + ": ERROR mapnorm "//trim(fldsSrc(ns)%mapnorm(destcomp))//" is not equal to "// & + trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & + ESMF_LOGMSG_ERROR, rc=rc) + rc = ESMF_FAILURE + return + end if + end if + + ! Determine mapping of indices into packed field bundle + ! Get source field + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + do nu = 1,ungriddedUBound(1) + npacked(mapindex) = npacked(mapindex) + 1 + if (nu == 1) then + packed_data(mapindex)%fldindex(nf) = npacked(mapindex) + end if + end do + else + npacked(mapindex) = npacked(mapindex) + 1 + packed_data(mapindex)%fldindex(nf) = npacked(mapindex) + end if + end if! end if source field is mapped to destination field with mapindex + end do ! end loop over FBSrc fields + end do ! end loop over fldSrc elements + + ! Create the source and destination packed fields for mapindex + if (npacked(mapindex) > 0) then + allocate(ptrsrc_packed(npacked(mapindex), lsize_src)) + packed_data(mapindex)%field_src = ESMF_FieldCreate(lmesh_src, & + ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + allocate(ptrdst_packed(npacked(mapindex), lsize_dst)) + packed_data(mapindex)%field_dst = ESMF_FieldCreate(lmesh_dst, & + ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + packed_data(mapindex)%field_fracsrc = ESMF_FieldCreate(lmesh_src, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + packed_data(mapindex)%field_fracdst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + end if + + end do ! end loop over mapindex + + deallocate(npacked) deallocate(fieldlist_src) deallocate(fieldlist_dst) - end subroutine med_map_packed_fieldbundles_create + end subroutine med_map_packed_field_create !================================================================================ - subroutine med_map_packed_fieldbundles(FBSrc, FBDst, fieldsrc_packed, fielddst_packed, & - routehandles, rc) - + subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & + packed_data, routehandles, rc) + ! ----------------------------------------------- ! Do the redistribution on the packed field bundles ! ----------------------------------------------- use ESMF - use esmFlds , only : mapfcopy - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use esmFlds , only : mapunset, mapnames, nmappers + use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd + use esmFlds , only : ncomps, compatm, compice, compocn, compname + use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod + use med_map_mod , only : med_map_field_regrid + use med_internalstate_mod , only : packed_data_type ! input/output variables - type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_Field) , intent(inout) :: fieldsrc_packed(:) ! array over mapping types - type(ESMF_Field) , intent(inout) :: fielddst_packed(:) ! array over mapping types - type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) - integer , intent(out) :: rc + type(ESMF_FieldBundle) , intent(in) :: FBSrc + type(ESMF_FieldBundle) , intent(inout) :: FBDst + type(ESMF_FieldBundle) , intent(in) :: FBNormOne(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(in) :: FBFracSrc ! fraction field bundle for source + type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(out) :: rc ! local variables - integer :: nf, nu - integer :: npacked - integer :: fieldcount - type(ESMF_Field) :: lfield - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d(:,:) - real(r8), pointer :: dataptr2d_packed(:,:) - integer :: mapindex - type(ESMF_Field), pointer :: fieldlist_src(:) - type(ESMF_Field), pointer :: fieldlist_dst(:) + integer :: nf, nu, np, n + integer :: fieldcount + integer :: mapindex + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + real(r8), pointer :: dataptr1d(:) + real(r8), pointer :: dataptr2d(:,:) + real(r8), pointer :: dataptr2d_packed(:,:) + type(ESMF_Field) :: lfield + type(ESMF_Field) :: frac_field_src + type(ESMF_Field), pointer :: fieldlist_src(:) + type(ESMF_Field), pointer :: fieldlist_dst(:) + character(CL), allocatable :: fieldNameList(:) + real(r8), pointer :: data_src(:,:) + real(r8), pointer :: data_srctmp(:,:) + real(r8), pointer :: data_dst(:,:) + real(r8), pointer :: data_fracsrc(:) + real(r8), pointer :: data_fracdst(:) character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- rc = ESMF_SUCCESS - ! TODO: Just for now assume redistribution, need to leverage fldssrc which is simply not being used - mapindex = mapfcopy - ! Get field count for both FBsrc and FBdst call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist_src(fieldcount)) - allocate(fieldlist_dst(fieldcount)) call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + allocate(fieldlist_dst(fieldcount)) call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Get the pointer for the packed source data - call ESMF_FieldGet(fieldsrc_packed(mapindex), farrayptr=dataptr2d_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Loop over mapping types + do mapindex = 1,nmappers + + ! If packed field is created + if (ESMF_FieldIsCreated(packed_data(mapindex)%field_src)) then + + ! ----------------------------------- + ! Copy the src fields into the packed field bundle + ! ----------------------------------- - ! Copy the src fields into the packed field bundle - call t_startf('MED:'//trim(subname)//' copy from src') - npacked = 0 - do nf = 1,fieldcount - call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr2d, rc=rc) + call t_startf('MED:'//trim(subname)//' copy from src') + + ! First get the pointer for the packed source data + call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayptr=dataptr2d_packed, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do nu = 1,ungriddedUBound(1) - npacked = npacked + 1 - dataptr2d_packed(npacked,:) = dataptr2d(nu,:) + + ! Now do the copy + do nf = 1,fieldcount + ! Get the indices into the packed data structure + np = packed_data(mapindex)%fldindex(nf) + if (np > 0) then + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + dataptr2d_packed(np+nu-1,:) = dataptr2d(nu,:) + end do + else + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d_packed(np,:) = dataptr1d(:) + end if + end if end do - else - call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - npacked = npacked + 1 - dataptr2d_packed(npacked,:) = dataptr1d(:) - end if - end do - call t_stopf('MED:'//trim(subname)//' copy from src') + call t_stopf('MED:'//trim(subname)//' copy from src') - ! Do the mapping - call t_startf('MED:'//trim(subname)//' map') - call ESMF_FieldRedist(fieldsrc_packed(mapindex), fielddst_packed(mapindex), routehandles(mapindex), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' map') + ! ----------------------------------- + ! Do the mapping + ! ----------------------------------- - ! Get the pointer for the packed destination data - call ESMF_FieldGet(fielddst_packed(mapindex), farrayptr=dataptr2d_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call t_startf('MED:'//trim(subname)//' map') + if (mapindex == mapfcopy) then + + ! Redistributing mapfcopy + call ESMF_FieldRedist(packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & + routehandles(mapindex), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + else - ! Copy the destination packed field bundle into the destination unpacked field bundle - call t_startf('MED:'//trim(subname)//' copy to dest') - npacked = 0 - do nf = 1,fieldcount - call ESMF_FieldGet(fieldlist_dst(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr2d, rc=rc) + ! ASSUME that each packed field has only one normalization type + ! TODO: set this in the initialization + if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'none') then + + ! get a pointer to the array of the normalization on the source grid + call ESMF_FieldBundleGet(FBFracSrc, fieldName=packed_data(mapindex)%mapnorm, & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=data_fracsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! get a pointer to source field data in FBSrc + call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayPtr=data_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! copy data_src to data_srctmp then multiply ungridded dimension in data_src by fraction + allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) + data_srctmp(:,:) = data_src(:,:) + do n = 1,size(data_fracsrc) + data_src(:,n) = data_src(:,n) * data_fracsrc(n) + end do + + ! regrid normalized packed source field + call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & + routehandles, mapindex, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! get fraction fields on both source and destination mesh + call ESMF_FieldBundleGet(FBFracSrc, fieldname=trim(packed_data(mapindex)%mapnorm), & + field=frac_field_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! regrid fraction field from source to destination + call med_map_field_regrid(frac_field_src, packed_data(mapindex)%field_fracdst, & + routehandles, mapindex, rc=rc) + + ! get pointer to mapped fraction + call ESMF_FieldGet(packed_data(mapindex)%field_fracdst, farrayPtr=data_fracdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! normalize destination mapped values by the reciprocal of the mapped fraction + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_fracdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1,size(data_dst,dim=2) + if (data_fracdst(n) == 0.0_r8) then + data_dst(:,n) = 0.0_r8 + else + data_dst(:,n) = data_dst(:,n)/data_fracdst(n) + end if + end do + end if + end if + call t_stopf('MED:'//trim(subname)//' map') + + ! ----------------------------------- + ! Copy the destination packed field bundle into the destination unpacked field bundle + ! ----------------------------------- + + call t_startf('MED:'//trim(subname)//' copy to dest') + + ! First get the pointer for the packed destination data + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayptr=dataptr2d_packed, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do nu = 1,ungriddedUBound(1) - npacked = npacked + 1 - dataptr2d(nu,:) = dataptr2d_packed(npacked,:) + + ! Now do the copy back to FBDst + do nf = 1,fieldcount + ! Get the indices into the packed data structure + np = packed_data(mapindex)%fldindex(nf) + if (np > 0) then + call ESMF_FieldGet(fieldlist_dst(nf), ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + dataptr2d(nu,:) = dataptr2d_packed(np+nu-1,:) + end do + else + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = dataptr2d_packed(np,:) + end if + end if end do - else - call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - npacked = npacked + 1 - dataptr1d(:) = dataptr2d_packed(npacked,:) + call t_stopf('MED:'//trim(subname)//' copy to dest') + end if - end do - call t_stopf('MED:'//trim(subname)//' copy to dest') + end do ! end of loop over mapindex deallocate(fieldlist_src) deallocate(fieldlist_dst) - end subroutine med_map_packed_fieldbundles + end subroutine med_map_packed_field_map end module med_map_packed_mod From 2dac7b78964e2fee72ffce2fe69a12782b6ea0d6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 18 Oct 2020 20:24:46 -0600 Subject: [PATCH 123/206] significantly improved the performance of the auto merge --- mediator/med_merge_mod.F90 | 303 ++++++++++++++++--------------------- 1 file changed, 128 insertions(+), 175 deletions(-) diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index cb91f1bd9..e5868cb7e 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -39,7 +39,7 @@ module med_merge_mod !=============================================================================== contains !=============================================================================== - + subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldListTo, & FBMed1, FBMed2, rc) @@ -68,36 +68,37 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis integer :: nfld_out,nfld_in,nm integer :: compsrc integer :: num_merge_fields - integer :: num_merge_colon_fields - character(CL) :: fldname_out + integer :: num_merge_colon_fields character(CL) :: merge_fields character(CL) :: merge_field character(CS) :: merge_type character(CS) :: merge_fracname character(CS), allocatable :: merge_field_names(:) - integer :: rank_out - type(ESMF_Field) :: field_out - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d(:,:) - logical :: error_check = .false. ! TODO: make this an input argument - integer :: ungriddedUBound_out(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: gridToFieldMap_out(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: fieldnamecount - character(CL), pointer :: fieldnamelist(:) + logical :: error_check = .false. ! TODO: make this an input argument + integer :: ungriddedUBound_out(1) ! size of ungridded dimension + integer :: fieldcount + character(CL) , pointer :: fieldnamelist(:) => null() + type(ESMF_Field), pointer :: fieldlist(:) => null() + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() character(CL) :: msg character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_auto)' !--------------------------------------- + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) rc = ESMF_SUCCESS end if - call ESMF_FieldBundleGet(FBOut, fieldCount=fieldnamecount, rc=rc) + call ESMF_FieldBundleGet(FBOut, fieldCount=fieldcount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fieldnamelist(fieldnamecount)) - call ESMF_FieldBundleGet(FBOut, fieldNameList=fieldnamelist, rc=rc) + allocate(fieldnamelist(fieldcount)) + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(FBOut, fieldnamelist=fieldnamelist, fieldlist=fieldlist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return num_merge_fields = med_fldList_GetNumFlds(fldListTo) @@ -110,38 +111,25 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis ! for that field name - then call the corresponding merge routine below appropriately ! Loop over all fields in field bundle FBOut - do nfld_out = 1,fieldnamecount - - ! Get the nth field in FBOut - fldname_out = trim(fieldnamelist(nfld_out)) - call ESMF_FieldBundleGet(FBOut, trim(fldname_out), field=field_out, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + do nfld_out = 1,fieldcount - ! Set nth field data to zero - call ESMF_FieldGet(field_out, rank=rank_out, rc=rc) + ! 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 (dbug_flag > 1) then - write(msg,*)trim(subname),'output field ',trim(fldname_out),' has rank ',rank_out - call ESMF_LogWrite(msg, ESMF_LOGMSG_INFO) - end if - - if (rank_out == 1) then - call ESMF_FieldGet(field_out, farrayPtr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = czero - else if (rank_out == 2) then - call ESMF_FieldGet(field_out, farrayptr=dataptr2d, rc=rc) + 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 - call ESMF_FieldGet(field_out, ungriddedUBound=ungriddedUBound_out, & - gridToFieldMap=gridToFieldMap_out, rc=rc) + else + call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero end if ! Loop over the field in fldListTo do nfld_in = 1,med_fldList_GetNumFlds(fldListTo) - if (trim(merge_field_names(nfld_in)) == trim(fldname_out)) then + if (trim(merge_field_names(nfld_in)) == trim(fieldnamelist(nfld_out))) then ! Loop over all possible source components in the merging arrays returned from the above call ! If the merge field name from the source components is not set, then simply go to the next component @@ -174,30 +162,27 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - ! Perform error checks + ! Perform error checks if (error_check) then - call med_merge_errcheck(compsrc, fldname_out, field_out, rank_out, & - ungriddedUBound_out, gridToFieldMap_out, trim(merge_field), & - FBImp(compsrc), FBMed1=FBMed1, FBMed2=FBMed2, rc=rc) + call med_merge_auto_errcheck(compsrc, fieldnamelist(nfld_out), fieldlist(nfld_out), & + ungriddedUBound_out, trim(merge_field), FBImp(compsrc), & + FBMed1=FBMed1, FBMed2=FBMed2, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! end of error check ! Perform merge if ((present(FBMed1) .or. present(FBMed2)) .and. compsrc == compmed) then if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), field_out, & - rank_out, ungriddedUBound_out, gridToFieldMap_out, & + call med_merge_auto_field(trim(merge_type), fieldlist(nfld_out), ungriddedUBound_out, & FB=FBMed1, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return else if (FB_FldChk(FBMed2, trim(merge_field), rc=rc)) then - call med_merge_auto_field(trim(merge_type), field_out, & - rank_out, ungriddedUBound_out, gridToFieldMap_out, & + call med_merge_auto_field(trim(merge_type), fieldlist(nfld_out), ungriddedUBound_out, & FB=FBMed2, FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if else - call med_merge_auto_field(trim(merge_type), field_out, & - rank_out, ungriddedUBound_out, gridToFieldMap_out, & + call med_merge_auto_field(trim(merge_type), fieldlist(nfld_out), ungriddedUBound_out, & FB=FBImp(compsrc), FBFld=merge_field, FBw=FBfrac, fldw=trim(merge_fracname), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -210,6 +195,7 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis end do ! end of loop over fields in FBOut deallocate(fieldnamelist) + deallocate(fieldlist) if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) @@ -220,99 +206,7 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis end subroutine med_merge_auto !=============================================================================== - subroutine med_merge_errcheck(compsrc, fldname_out, field_out, rank_out, & - ungriddedUBound_out, gridToFieldMap_out, merge_fldname, FBImp, FBMed1, FBMed2, rc) - - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet - use ESMF , only : ESMF_Field, ESMF_FieldGet - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_LogSetError, ESMF_RC_OBJ_NOT_CREATED - - ! input/output variables - integer , intent(in) :: compsrc ! source component index - character(len=*) , intent(in) :: fldname_out ! output field name - type(ESMF_Field) , intent(in) :: field_out ! output field - integer , intent(in) :: rank_out ! rank of output field - integer , intent(in) :: ungriddedUBound_out(1) ! currently the size must equal 1 for rank 2 fields - integer , intent(in) :: gridToFieldMap_out(1) ! currently the size must equal 1 for rank 2 fields - character(len=*) , intent(in) :: merge_fldname ! source merge fieldname - type(ESMF_FieldBundle) , intent(in) :: FBImp ! source field bundle - type(ESMF_FieldBundle) , intent(in) , optional :: FBMed1 ! mediator field bundle - type(ESMF_FieldBundle) , intent(in) , optional :: FBMed2 ! mediator field bundle - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: field_in - integer :: rank_in - integer :: ungriddedUBound_in(1) ! currently the size must equal 1 for rank 2 fieldds - integer :: gridToFieldMap_in(1) ! currently the size must equal 1 for rank 2 fieldds - character(len=CL) :: errmsg - character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_errcheck)' - !--------------------------------------- - - rc = ESMF_SUCCESS - - if (compsrc == compmed) then - if (present(FBMed1) .and. present(FBMed2)) then - if (.not. ESMF_FieldBundleIsCreated(FBMed1)) then - call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed1 not created.", & - line=__LINE__, file=u_FILE_u, rcToReturn=rc) - return - endif - if (.not. ESMF_FieldBundleIsCreated(FBMed2)) then - call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed2 not created.", & - line=__LINE__, file=u_FILE_u, rcToReturn=rc) - return - endif - if (FB_FldChk(FBMed1, trim(merge_fldname), rc=rc)) then - call ESMF_FieldBundleGet(FBMed1, trim(merge_fldname), field=field_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (FB_FldChk(FBMed2, trim(merge_fldname), rc=rc)) then - call ESMF_FieldBundleGet(FBMed2, trim(merge_fldname), field=field_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//": ERROR merge_fldname = "//trim(merge_fldname)//" not found", & - ESMF_LOGMSG_ERROR, rc=rc) - rc = ESMF_FAILURE - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - endif - call ESMF_FieldBundleGet(FBImp, trim(merge_fldname), field=field_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_in, rank=rank_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (rank_in /= rank_out) then - write(errmsg,*) trim(subname),' input field rank ',rank_in,' for '//trim(merge_fldname), & - ' not equal to output field rank ',rank_out,' for '//trim(fldname_out) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - else if (rank_out == 2) then - call ESMF_FieldGet(field_in, ungriddedUBound=ungriddedUBound_in, & - gridToFieldMap=gridToFieldMap_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound_out(1) /= ungriddedUBound_in(1)) then - write(errmsg,*) trim(subname),"ungriddedUBound_in (",ungriddedUBound_in(1),& - ") not equal to ungriddedUBound_out (",ungriddedUBound_out(1),") for "//trim(fldname_out) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - else if (gridToFieldMap_in(1) /= gridToFieldMap_out(1)) then - write(errmsg,*) trim(subname),"gridtofieldmap_in (",gridtofieldmap_in(1),& - ") not equal to gridtofieldmap_out (",gridtofieldmap_out(1),") for "//trim(fldname_out) - call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - end if - endif - - end subroutine med_merge_errcheck - - !=============================================================================== - subroutine med_merge_auto_field(merge_type, field_out, & - rank_out, ungriddedUBound_out, gridToFieldMap_out, & + subroutine med_merge_auto_field(merge_type, field_out, ungriddedUBound_out, & FB, FBfld, FBw, fldw, rc) use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogMsg_Error @@ -321,11 +215,9 @@ subroutine med_merge_auto_field(merge_type, field_out, & use ESMF , only : ESMF_FieldGet, ESMF_Field ! input/output variables - integer ,intent(in) :: rank_out ! rank of output array character(len=*) ,intent(in) :: merge_type type(ESMF_Field) ,intent(inout) :: field_out integer ,intent(in) :: ungriddedUBound_out(1) - integer ,intent(in) :: gridToFieldMap_out(1) type(ESMF_FieldBundle),intent(in) :: FB character(len=*) ,intent(in) :: FBfld type(ESMF_FieldBundle),intent(inout) :: FBw ! field bundle with weights @@ -372,20 +264,20 @@ subroutine med_merge_auto_field(merge_type, field_out, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get field pointer to output and input fields - ! Assume that input and output ranks are the same - this is checked in error check - if (rank_out == 1) then - call ESMF_FieldGet(field_in, farrayPtr=dpf1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_out, farrayPtr=dp1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (rank_out == 2) then + ! Assume that input and output ungridded upper bounds are the same - this is checked in error check + if (ungriddedUBound_out(1) > 0) then call ESMF_FieldGet(field_in, farrayPtr=dpf2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(field_out, farrayPtr=dp2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_FieldGet(field_in, farrayPtr=dpf1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_out, farrayPtr=dp1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if - ! Get pointer to weights that weights are only rank 1 + ! Get pointer to weights that weights have no ungridded dimensions if (merge_type == 'copy_with_weights' .or. merge_type == 'merge' .or. merge_type == 'sum_with_weights') then call ESMF_FieldBundleGet(FBw, fieldName=trim(fldw), field=field_wgt, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -395,40 +287,32 @@ subroutine med_merge_auto_field(merge_type, field_out, & ! Do supported merges if (trim(merge_type) == 'copy') then - if (rank_out == 1) then - dp1(:) = dpf1(:) - else + if (ungriddedUBound_out(1) > 0) then dp2(:,:) = dpf2(:,:) + else + dp1(:) = dpf1(:) endif else if (trim(merge_type) == 'copy_with_weights') then - if (rank_out == 1) then - dp1(:) = dpf1(:)*dpw1(:) - else + if (ungriddedUBound_out(1) > 0) then do n = 1,ungriddedUBound_out(1) - if (gridToFieldMap_out(1) == 1) then - dp2(:,n) = dpf2(:,n)*dpw1(:) - else if (gridToFieldMap_out(1) == 2) then - dp2(n,:) = dpf2(n,:)*dpw1(:) - end if + dp2(n,:) = dpf2(n,:)*dpw1(:) end do + else + dp1(:) = dpf1(:)*dpw1(:) endif else if (trim(merge_type) == 'merge' .or. trim(merge_type) == 'sum_with_weights') then - if (rank_out == 1) then - dp1(:) = dp1(:) + dpf1(:)*dpw1(:) - else + if (ungriddedUBound_out(1) > 0) then do n = 1,ungriddedUBound_out(1) - if (gridToFieldMap_out(1) == 1) then - dp2(:,n) = dp2(:,n) + dpf2(:,n)*dpw1(:) - else if (gridToFieldMap_out(1) == 2) then - dp2(n,:) = dp2(n,:) + dpf2(n,:)*dpw1(:) - end if + dp2(n,:) = dp2(n,:) + dpf2(n,:)*dpw1(:) end do + else + dp1(:) = dp1(:) + dpf1(:)*dpw1(:) endif else if (trim(merge_type) == 'sum') then - if (rank_out == 1) then - dp1(:) = dp1(:) + dpf1(:) - else + if (ungriddedUBound_out(1) > 0) then dp2(:,:) = dp2(:,:) + dpf2(:,:) + else + dp1(:) = dp1(:) + dpf1(:) endif else call ESMF_LogWrite(trim(subname)//": merge type "//trim(merge_type)//" not supported", & @@ -440,7 +324,79 @@ subroutine med_merge_auto_field(merge_type, field_out, & end subroutine med_merge_auto_field !=============================================================================== + subroutine med_merge_auto_errcheck(compsrc, fldname_out, field_out, & + ungriddedUBound_out, merge_fldname, FBImp, FBMed1, FBMed2, rc) + + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR + use ESMF , only : ESMF_LogSetError, ESMF_RC_OBJ_NOT_CREATED + + ! input/output variables + integer , intent(in) :: compsrc ! source component index + character(len=*) , intent(in) :: fldname_out ! output field name + type(ESMF_Field) , intent(in) :: field_out ! output field + integer , intent(in) :: ungriddedUBound_out(1) ! ungridded upper bound + character(len=*) , intent(in) :: merge_fldname ! source merge fieldname + type(ESMF_FieldBundle) , intent(in) :: FBImp ! source field bundle + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed1 ! mediator field bundle + type(ESMF_FieldBundle) , intent(in) , optional :: FBMed2 ! mediator field bundle + integer , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: field_in + integer :: ungriddedUBound_in(1) ! size of ungridded dimension, if any + character(len=CL) :: errmsg + character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_errcheck)' + !--------------------------------------- + + rc = ESMF_SUCCESS + if (compsrc == compmed) then + if (present(FBMed1) .and. present(FBMed2)) then + if (.not. ESMF_FieldBundleIsCreated(FBMed1)) then + call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed1 not created.", & + line=__LINE__, file=u_FILE_u, rcToReturn=rc) + return + endif + if (.not. ESMF_FieldBundleIsCreated(FBMed2)) then + call ESMF_LogSetError(ESMF_RC_OBJ_NOT_CREATED, msg="Field bundle FBMed2 not created.", & + line=__LINE__, file=u_FILE_u, rcToReturn=rc) + return + endif + if (FB_FldChk(FBMed1, trim(merge_fldname), rc=rc)) then + call ESMF_FieldBundleGet(FBMed1, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (FB_FldChk(FBMed2, trim(merge_fldname), rc=rc)) then + call ESMF_FieldBundleGet(FBMed2, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//": ERROR merge_fldname = "//trim(merge_fldname)//" not found", & + ESMF_LOGMSG_ERROR, rc=rc) + rc = ESMF_FAILURE + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + endif + + call ESMF_FieldBundleGet(FBImp, trim(merge_fldname), field=field_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_in, ungriddedUBound=ungriddedUBound_in, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (ungriddedUbound_in(1) /= UngriddedUbound_out(1)) then + write(errmsg,*) trim(subname),' input field ungriddedUbound ',ungriddedUbound_in(1),& + ' for '//trim(merge_fldname), & + ' not equal to output field ungriddedUbound ',ungriddedUbound_out,' for '//trim(fldname_out) + call ESMF_LogWrite(errmsg, ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + + end subroutine med_merge_auto_errcheck + + !=============================================================================== subroutine med_merge_field_1D(FBout, fnameout, & FBinA, fnameA, wgtA, & FBinB, fnameB, wgtB, & @@ -620,7 +576,6 @@ subroutine med_merge_field_1D(FBout, fnameout, & end subroutine med_merge_field_1D !=============================================================================== - subroutine med_merge_field_2D(FBout, fnameout, & FBinA, fnameA, wgtA, & FBinB, fnameB, wgtB, & @@ -805,7 +760,6 @@ subroutine med_merge_field_2D(FBout, fnameout, & end subroutine med_merge_field_2D !=============================================================================== - integer function merge_listGetNum(str) ! return number of fields in a colon delimited string list @@ -831,7 +785,6 @@ integer function merge_listGetNum(str) end function merge_listGetNum !=============================================================================== - subroutine merge_listGetName(list, k, name, rc) ! Get name of k-th field in colon deliminted list From 2b820028b8ad73874869290b3f6c39f4210a37e7 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 19 Oct 2020 16:54:45 -0600 Subject: [PATCH 124/206] updates to have packed field bundles working in F compsets --- mediator/med.F90 | 42 +++- mediator/med_internalstate_mod.F90 | 2 + mediator/med_io_mod.F90 | 359 ++++++++++++--------------- mediator/med_map_packed_mod.F90 | 30 ++- mediator/med_phases_aofluxes_mod.F90 | 13 +- mediator/med_phases_history_mod.F90 | 2 - mediator/med_phases_ocnalb_mod.F90 | 50 ---- mediator/med_phases_prep_atm_mod.F90 | 124 ++++----- mediator/med_phases_prep_ice_mod.F90 | 24 +- mediator/med_phases_prep_ocn_mod.F90 | 63 +++-- mediator/med_phases_prep_rof_mod.F90 | 1 - mediator/med_phases_prep_wav_mod.F90 | 21 +- 12 files changed, 323 insertions(+), 408 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 12a289d81..eb5e341a1 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1578,6 +1578,7 @@ subroutine DataInitialize(gcomp, rc) use med_phases_profile_mod , only : med_phases_profile use med_diag_mod , only : med_diag_zero, med_diag_init use med_map_mod , only : med_map_MapNorm_init, med_map_RouteHandles_init + use med_map_packed_mod , only : med_map_packed_field_create use med_io_mod , only : med_io_init ! input/output variables @@ -1594,6 +1595,7 @@ subroutine DataInitialize(gcomp, rc) type(ESMF_StateItem_Flag) :: itemType logical :: atCorrectTime, connected integer :: n1,n2,n + integer :: nsrc,ndst integer :: cntn1, cntn2 integer :: fieldCount character(ESMF_MAXSTR),allocatable :: fieldNameList(:) @@ -1890,13 +1892,49 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- ! Initialize route handles and required normalization field bunds + ! Initialized packed field data structures !--------------------------------------- + call med_map_RouteHandles_init(gcomp, logunit, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_map_MapNorm_init(gcomp, logunit, rc) + call med_map_mapnorm_init(gcomp, logunit, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + do ndst = 1,ncomps + do nsrc = 1,ncomps + if (is_local%wrap%med_coupling_active(nsrc,ndst)) then + call med_map_packed_field_create(ndst, & + is_local%wrap%flds_scalar_name, & + fldsSrc=fldListFr(nsrc)%flds, & + FBSrc=is_local%wrap%FBImp(nsrc,nsrc), & + FBDst=is_local%wrap%FBImp(nsrc,ndst), & + packed_data=is_local%wrap%packed_data(nsrc,ndst,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + end do + fieldCount = med_fldList_GetNumFlds(fldListMed_aoflux) + if (fieldCount > 0) then + call med_map_packed_field_create(compatm, & + is_local%wrap%flds_scalar_name, & + fldsSrc=fldListMed_aoflux%flds, & + FBSrc=is_local%wrap%FBMed_aoflux_o, & + FBDst=is_local%wrap%FBMed_aoflux_a, & + packed_data=is_local%wrap%packed_data_aoflux_o2a(:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + fieldCount = med_fldList_GetNumFlds(fldListMed_ocnalb) + if (fieldCount > 0) then + call med_map_packed_field_create(compatm, & + is_local%wrap%flds_scalar_name, & + fldsSrc=fldListMed_ocnalb%flds, & + FBSrc=is_local%wrap%FBMed_ocnalb_o, & + FBDst=is_local%wrap%FBMed_ocnalb_a, & + packed_data=is_local%wrap%packed_data_ocnalb_o2a(:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + !--------------------------------------- ! Set the data initialize flag to false !--------------------------------------- @@ -1974,7 +2012,7 @@ subroutine DataInitialize(gcomp, rc) allocate(fieldNameList(fieldCount)) call ESMF_StateGet(is_local%wrap%NStateImp(n1), itemNameList=fieldNameList, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n=1, fieldCount + do n = 1,fieldCount call ESMF_StateGet(is_local%wrap%NStateImp(n1), itemName=fieldNameList(n), field=field, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return atCorrectTime = NUOPC_IsAtTime(field, time, rc=rc) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 172d3384e..23c53ce03 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -94,8 +94,10 @@ module med_internalstate_mod ! Mediator field bundles type(ESMF_FieldBundle) :: FBMed_ocnalb_o ! Ocn albedo on ocn grid type(ESMF_FieldBundle) :: FBMed_ocnalb_a ! Ocn albedo on atm grid + type(packed_data_type) :: packed_data_ocnalb_o2a(nmappers) ! packed data for mapping ocn->atm type(ESMF_FieldBundle) :: FBMed_aoflux_o ! Ocn/Atm flux fields on ocn grid type(ESMF_FieldBundle) :: FBMed_aoflux_a ! Ocn/Atm flux fields on atm grid + type(packed_data_type) :: packed_data_aoflux_o2a(nmappers) ! packed data for mapping ocn->atm ! Mapping type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index 0a4fa7753..492a50849 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -14,11 +14,9 @@ module med_io_mod use NUOPC , only : NUOPC_FieldDictionaryHasEntry use pio , only : file_desc_t, iosystem_desc_t 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 + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use perf_mod , only : t_startf, t_stopf implicit none private @@ -439,7 +437,6 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & 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 @@ -464,6 +461,8 @@ 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) ' !------------------------------------------------------------------------------- @@ -506,11 +505,16 @@ 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 @@ -522,18 +526,12 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & return endif - call FB_getFieldN(FB, 1, field, rc=rc) + call ESMF_FieldGet(fieldlist(1), mesh=mesh, 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) @@ -541,17 +539,14 @@ 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 @@ -601,72 +596,64 @@ 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 - call FB_getNameN(FB, k, itemc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (trim(fieldnamelist(k)) == "hgt") then + CYCLE + end if - ! Determine rank of field with name itemc - 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) + call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, 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 + 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 - 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") + 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 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 @@ -698,7 +685,6 @@ 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 @@ -708,51 +694,36 @@ 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 - call FB_getNameN(FB, k, itemc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call FB_getFldPtr(FB, itemc, & - fldptr1=fldptr1, fldptr2=fldptr2, rank=rank, rc=rc) + if (trim(fieldnamelist(k)) == "hgt") then + CYCLE + end if + call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, 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) + 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) 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 if rank is 2 or 1 - - end if ! end if not "hgt" - end do ! end loop over fields in FB + 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 ! Fill coordinate variables name1 = trim(lpre)//'_lon' @@ -769,6 +740,9 @@ 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 @@ -1243,41 +1217,34 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) integer ,intent(out) :: rc ! local variables - type(ESMF_Field) :: lfield integer :: rcode - integer :: nf,ns,ng + integer :: nf integer :: k,n,l 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(:), fldptr1_tmp(:) - real(r8), pointer :: fldptr2(:,:) + integer :: lsize + real(r8), pointer :: fldptr1(:) => null() + real(r8), pointer :: fldptr1tmp(:) => null() + real(r8), pointer :: fldptr2(:,:) => null() character(CL) :: tmpstr character(len=16) :: cnumber integer(kind=Pio_Offset_Kind) :: lframe - 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) ' + integer :: ungriddedUBound(1) + character(CL) , pointer :: fieldnamelist(:) => null() + type(ESMF_Field), pointer :: fieldlist(:) => null() + character(*), parameter :: subName = '(med_io_read_FB) ' !------------------------------------------------------------------------------- rc = ESMF_Success - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lpre = ' ' - if (present(pre)) then - lpre = trim(pre) - endif - if (present(frame)) then - lframe = frame - else - lframe = 1 - endif + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + 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 @@ -1288,19 +1255,31 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) return endif + lpre = ' ' + if (present(pre)) lpre = trim(pre) + lframe = 1 + if (present(frame)) lframe = frame + 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) + allocate(fieldnamelist(nf)) + allocate(fieldlist(nf)) + call ESMF_FieldBundleGet(FB, fieldnamelist=fieldnamelist, fieldlist=fieldlist, rc=rc) 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 (dbug_flag > 1) then + 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 (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + if (nf < 1) then + call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" empty", ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - 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 + end if endif if (med_io_file_exists(vm, iam, trim(filename))) then @@ -1315,87 +1294,58 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) endif call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) - do k = 1,nf - ! Get name of field - call FB_getNameN(FB, k, itemc, rc=rc) + call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, 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 - 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) + if (ungriddedUbound(1) > 0) then + name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//'1' + else + name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) 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(itemc), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//' reading field '//trim(fieldnamelist(k)), ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get pointer to field bundle field - ! 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 - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc) + if (ungriddedUbound(1) > 0) then + ! Ungridded dimension is present in field + call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr2, 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)) - + lsize = size(fldptr2, dim=2) + allocate(fldptr1tmp(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(itemc)//trim(cnumber) - + name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//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) if (chkerr(rc,__LINE__,u_FILE_u)) return call pio_setframe(pioid, varid, lframe) - call pio_read_darray(pioid, varid, iodesc, fldptr1_tmp, rcode) + call pio_read_darray(pioid, varid, iodesc, fldptr1tmp, rcode) rcode = pio_get_att(pioid, varid, "_FillValue", lfillvalue) if (rcode /= pio_noerr) then lfillvalue = fillvalue endif - do l = 1,size(fldptr1_tmp) - if (fldptr1_tmp(l) == lfillvalue) fldptr1_tmp(l) = 0.0_r8 + do l = 1,size(fldptr1tmp) + if (fldptr1tmp(l) == lfillvalue) fldptr1tmp(l) = 0.0_r8 enddo else - fldptr1_tmp = 0.0_r8 + fldptr1tmp = 0.0_r8 endif - if (gridToFieldMap(1) == 1) then - fldptr2(:,n) = fldptr1_tmp(:) - else if (gridToFieldMap(1) == 2) then - fldptr2(n,:) = fldptr1_tmp(:) - end if + fldptr2(n,:) = fldptr1tmp(:) end do - - deallocate(fldptr1_tmp) - - else if (rank == 1) then - name1 = trim(lpre)//'_'//trim(itemc) - + deallocate(fldptr1tmp) + else + ! No ungridded dimensions + name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) 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) @@ -1420,6 +1370,9 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) call pio_freedecomp(pioid, iodesc) call pio_closefile(pioid) + deallocate(fieldlist) + deallocate(fieldnamelist) + if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif @@ -1461,7 +1414,8 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) integer :: dimCount, tileCount integer, pointer :: Dof(:) character(CL) :: tmpstr - integer :: rank + integer :: fieldcount + type(ESMF_Field), pointer :: fieldlist(:) => null() character(*),parameter :: subName = '(med_io_read_init_iodesc) ' !------------------------------------------------------------------------------- @@ -1490,18 +1444,18 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) ng = lnx * lny - call FB_getFieldN(FB, 1, field, rc=rc) + call ESMF_FieldBundleGet(FB, fieldCount=fieldcount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_FieldGet(field, mesh=mesh, rc=rc) + 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 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) @@ -1519,16 +1473,15 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) call ESMF_DistGridGet(distgrid, localDE=0, elementCount=ns, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(dof(ns)) 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_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 7acc2a773..08f13d3ca 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -97,13 +97,11 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Gather all fields that will be mapped with a target map index into a packed field - ! Calculated size of packed field based on the fact that - ! some fields have ungridded dimensions and need to unwrap - ! them into separate fields for the purposes of packing - ! Looper over each mapping type - - ! TODO: What happens if you have a field in FBSrc that is not going to be mapped + ! Calculated size of packed field based on the fact that some fields have + ! ungridded dimensions and need to unwrap them into separate fields for the + ! purposes of packing + ! Allocate memory to keep tracked of packing index for each mapping type allocate(npacked(nmappers)) npacked(:) = 0 @@ -216,19 +214,19 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & integer :: fieldcount integer :: mapindex integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d(:,:) - real(r8), pointer :: dataptr2d_packed(:,:) + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: dataptr2d_packed(:,:) => null() type(ESMF_Field) :: lfield type(ESMF_Field) :: frac_field_src - type(ESMF_Field), pointer :: fieldlist_src(:) - type(ESMF_Field), pointer :: fieldlist_dst(:) + type(ESMF_Field), pointer :: fieldlist_src(:) => null() + type(ESMF_Field), pointer :: fieldlist_dst(:) => null() character(CL), allocatable :: fieldNameList(:) - real(r8), pointer :: data_src(:,:) - real(r8), pointer :: data_srctmp(:,:) - real(r8), pointer :: data_dst(:,:) - real(r8), pointer :: data_fracsrc(:) - real(r8), pointer :: data_fracdst(:) + real(r8), pointer :: data_src(:,:) => null() + real(r8), pointer :: data_srctmp(:,:) => null() + real(r8), pointer :: data_dst(:,:) => null() + real(r8), pointer :: data_fracsrc(:) => null() + real(r8), pointer :: data_fracdst(:) => null() character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 198ef4908..8a91293d1 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -10,7 +10,7 @@ module med_phases_aofluxes_mod use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_init => med_methods_FB_init - use med_map_mod , only : med_map_FB_Regrid_Norm + use med_map_packed_mod , only : med_map_packed_field_map use perf_mod , only : t_startf, t_stopf implicit none @@ -154,18 +154,15 @@ 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_FB_Regrid_Norm( & - fldsSrc=fldListFr(compatm)%flds, & - srccomp=compatm, destcomp=compocn, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImp(compatm,compatm), & FBDst=is_local%wrap%FBImp(compatm,compocn), & FBFracSrc=is_local%wrap%FBFrac(compatm), & FBNormOne=is_local%wrap%FBNormOne(compatm,compocn,:), & - RouteHandles=is_local%wrap%RH(compatm,compocn,:), & - string=trim(compname(compatm))//'2'//trim(compname(compocn)), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + 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) diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index f7e9f90ea..ec57c94dc 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -256,7 +256,6 @@ subroutine med_phases_history_write(gcomp, rc) call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMGet(vm, localPet=iam, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -267,7 +266,6 @@ subroutine med_phases_history_write(gcomp, rc) nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 17d0571d8..540caf8f4 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -24,7 +24,6 @@ module med_phases_ocnalb_mod !-------------------------------------------------------------------------- public med_phases_ocnalb_run - public med_phases_ocnalb_mapo2a !-------------------------------------------------------------------------- ! Private interfaces @@ -430,55 +429,6 @@ subroutine med_phases_ocnalb_run(gcomp, rc) end subroutine med_phases_ocnalb_run - !=============================================================================== - - subroutine med_phases_ocnalb_mapo2a(gcomp, rc) - - !---------------------------------------------------------- - ! Map ocean albedos from ocn to atm grid - !---------------------------------------------------------- - - use ESMF , only : ESMF_GridComp - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use med_map_mod , only : med_map_FB_Regrid_Norm - use esmFlds , only : fldListMed_ocnalb - use esmFlds , only : compatm, compocn - - ! Arguments - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - ! Local variables - type(InternalState) :: is_local - character(*), parameter :: subName = '(med_ocnalb_mapo2a) ' - !----------------------------------------------------------------------- - 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 from gcomp - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Map the field bundle from the ocean to the atm grid - call med_map_FB_Regrid_Norm( & - fldsSrc=fldListMed_ocnalb%flds, & - srccomp=compocn, destcomp=compatm, & - FBSrc=is_local%wrap%FBMed_ocnalb_o, & - FBDst=is_local%wrap%FBMed_ocnalb_a, & - FBFracSrc=is_local%wrap%FBFrac(compocn), & - FBNormOne=is_local%wrap%FBNormOne(compocn,compatm,:), & - RouteHandles=is_local%wrap%RH(compocn,compatm,:), & - string='FBMed_ocnalb_o_To_FBMed_ocnalb_a', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//subname) - - end subroutine med_phases_ocnalb_mapo2a - !=============================================================================== subroutine med_phases_ocnalb_orbital_init(gcomp, logunit, mastertask, rc) diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index b071c1a9c..5774dd8af 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -6,26 +6,18 @@ module med_phases_prep_atm_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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet, ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet - use ESMF , only : ESMF_GridComp, ESMF_Clock, ESMF_Time, ESMF_ClockPrint - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_utils_mod , only : memcheck => med_memcheck - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk - use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_init => med_methods_FB_init - use med_methods_mod , only : FB_rest => med_methods_FB_reset - use med_methods_mod , only : FB_getNumFlds => med_methods_FB_getNumFlds - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar - use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldBundleGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : memcheck => med_memcheck + 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_fldchk => med_methods_FB_FldChk use med_merge_mod , only : med_merge_auto - use med_map_mod , only : med_map_FB_Regrid_Norm + use med_map_packed_mod , only : med_map_packed_field_map use med_internalstate_mod , only : InternalState, mastertask - use med_phases_ocnalb_mod , only : med_phases_ocnalb_mapo2a use esmFlds , only : compatm, compocn, compice, ncomps, compname - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : fldListMed_aoflux + use esmFlds , only : fldListFr, fldListTo, fldListMed_aoflux use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -48,8 +40,7 @@ subroutine med_phases_prep_atm(gcomp, rc) integer, intent(out) :: rc ! local variables - type(ESMF_Clock) :: clock - type(ESMF_Time) :: time + type(ESMF_Field) :: lfield character(len=64) :: timestr type(InternalState) :: is_local real(R8), pointer :: dataPtr1(:),dataPtr2(:) @@ -82,71 +73,53 @@ subroutine med_phases_prep_atm(gcomp, rc) 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 - !--------------------------------------- - !--- Get the current time from the clock - !--------------------------------------- - call ESMF_GridCompGet(gcomp, clock=clock) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGet(clock,currtime=time,rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeGet(time,timestring=timestr) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": time = "//trim(timestr), ESMF_LOGMSG_INFO) - if (dbug_flag > 1) then - if (mastertask) then - call ESMF_ClockPrint(clock, options="currTime", & - preString="-------->"//trim(subname)//" mediating for: ", rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - !--------------------------------------- !--- 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_FB_Regrid_Norm( & - fldsSrc=fldListFr(n1)%flds, & - srccomp=n1, destcomp=compatm, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compatm), & FBFracSrc=is_local%wrap%FBFrac(n1), & FBNormOne=is_local%wrap%FBNormOne(n1,compatm,:), & - RouteHandles=is_local%wrap%RH(n1,compatm,:), & - string=trim(compname(n1))//'2'//trim(compname(compatm)), rc=rc) + 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 - endif - enddo + end if + end do !--------------------------------------- !--- map ocean albedos from ocn to atm grid if appropriate !--------------------------------------- if (trim(coupling_mode) == 'cesm') then - call med_phases_ocnalb_mapo2a(gcomp, rc) + call med_map_packed_field_map( & + FBSrc=is_local%wrap%FBMed_ocnalb_o, & + FBDst=is_local%wrap%FBMed_ocnalb_a, & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + FBNormOne=is_local%wrap%FBNormOne(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 !--------------------------------------- - ! Assumption here is that fluxes are computed on the ocean grid - - if (trim(coupling_mode) == 'cesm' .or. & - trim(coupling_mode) == 'hafs') then - call med_map_FB_Regrid_Norm(& - fldsSrc=fldListMed_aoflux%flds, & - srccomp=compocn, destcomp=compatm, & + 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_packed_field_map( & FBSrc=is_local%wrap%FBMed_aoflux_o, & FBDst=is_local%wrap%FBMed_aoflux_a, & FBFracSrc=is_local%wrap%FBFrac(compocn), & FBNormOne=is_local%wrap%FBNormOne(compocn,compatm,:), & - RouteHandles=is_local%wrap%RH(compocn,compatm,:), & - string='FBMed_aoflux_o_To_FBMEd_aoflux_a', rc=rc) + 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 @@ -174,8 +147,7 @@ subroutine med_phases_prep_atm(gcomp, rc) end if if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compatm), & - string=trim(subname)//' FBexp(compatm) ', rc=rc) + 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 @@ -185,28 +157,40 @@ subroutine med_phases_prep_atm(gcomp, rc) ! set fractions to send back to atm if (FB_FldChk(is_local%wrap%FBExp(compatm), 'So_ofrac', rc=rc)) then - call FB_GetFldPtr(is_local%wrap%FBExp(compatm), 'So_ofrac', dataptr1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBFrac(compatm), 'ofrac', dataptr2, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + 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 FB_GetFldPtr(is_local%wrap%FBExp(compatm), 'Si_ifrac', dataptr1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBFrac(compatm), 'ifrac', dataptr2, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + 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 FB_GetFldPtr(is_local%wrap%FBExp(compatm), 'Sl_lfrac', dataptr1, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBFrac(compatm), 'lfrac', dataptr2, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + 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 @@ -216,8 +200,6 @@ subroutine med_phases_prep_atm(gcomp, rc) !--- update local scalar data !--------------------------------------- - !is_local%wrap%scalar_data(1) = - !--------------------------------------- !--- clean up !--------------------------------------- diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index fbf1a46e0..701568296 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -9,13 +9,11 @@ module med_phases_prep_ice_mod use med_methods_mod , only : fldchk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_getNumFlds => med_methods_FB_getNumFlds 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_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_FB_Field_Regrid + use med_map_packed_mod , only : med_map_packed_field_map use med_internalstate_mod , only : InternalState, logunit, mastertask use esmFlds , only : compatm, compice, comprof, compglc, ncomps, compname use esmFlds , only : fldListFr, fldListTo @@ -68,6 +66,7 @@ subroutine med_phases_prep_ice(gcomp, rc) character(len=64), allocatable :: fldnames(:) real(r8) :: nextsw_cday logical :: first_precip_fact_call = .true. + logical :: first_call = .true. character(len=*),parameter :: subname='(med_phases_prep_ice)' !--------------------------------------- @@ -93,29 +92,24 @@ subroutine med_phases_prep_ice(gcomp, rc) ! 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 FB_getNumFlds(is_local%wrap%FBExp(compice), trim(subname)//"FBexp(compice)", ncnt, rc) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), fieldCount=ncnt, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - !--------------------------------------- - !--- map to create FBImp(:,compice) - !--------------------------------------- - + ! 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_FB_Regrid_Norm( & - fldsSrc=fldListFr(n1)%flds, & - srccomp=n1, destcomp=compice, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compice), & FBFracSrc=is_local%wrap%FBFrac(n1), & FBNormOne=is_local%wrap%FBNormOne(n1,compice,:), & - RouteHandles=is_local%wrap%RH(n1,compice,:), & - string=trim(compname(n1))//'2'//trim(compname(compice)), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + 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 end if - enddo + end do !--------------------------------------- !--- auto merges to create FBExp(compice) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index c48846c6c..c72745dcb 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -9,11 +9,11 @@ module med_phases_prep_ocn_mod 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_FB_Regrid_Norm + use med_map_packed_mod , only : med_map_packed_field_create + use med_map_packed_mod , only : med_map_packed_field_map use med_utils_mod , only : memcheck => med_memcheck 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_getNumFlds => med_methods_FB_getNumFlds use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_accum => med_methods_FB_accum @@ -49,7 +49,7 @@ 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 + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_FieldBundleGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS ! input/output variables @@ -57,8 +57,9 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - integer :: n1, ncnt + type(InternalState) :: is_local + integer :: n1, ncnt + logical :: first_call = .true. character(len=*), parameter :: subname='(med_phases_prep_ocn_map)' !------------------------------------------------------------------------------- @@ -76,26 +77,37 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Count the number of fields outside of scalar data, if zero, then return - call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) 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 - - ! map all fields in FBImp that have active ocean coupling to the ocean grid + if (first_call) then + do n1 = 1,ncomps + if (is_local%wrap%med_coupling_active(n1,compocn)) then + call med_map_packed_field_create(compocn, & + is_local%wrap%flds_scalar_name, & + fldsSrc=fldListFr(n1)%flds, & + FBSrc=is_local%wrap%FBImp(n1,n1), & + FBDst=is_local%wrap%FBImp(n1,compocn), & + packed_data=is_local%wrap%packed_data(n1,compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + first_call = .false. + end if do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compocn)) then - call med_map_FB_Regrid_Norm( & - fldsSrc=fldListFr(n1)%flds,& - srccomp=n1, destcomp=compocn, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compocn), & FBFracSrc=is_local%wrap%FBFrac(n1), & FBNormOne=is_local%wrap%FBNormOne(n1,compocn,:), & - RouteHandles=is_local%wrap%RH(n1,compocn,:), & - string=trim(compname(n1))//'2'//trim(compname(compocn)), rc=rc) + 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 - endif - enddo + end if + end do endif call t_stopf('MED:'//subname) @@ -108,7 +120,8 @@ end subroutine med_phases_prep_ocn_map !----------------------------------------------------------------------------- subroutine med_phases_prep_ocn_merge(gcomp, rc) - use ESMF , only : ESMF_GridComp, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp, ESMF_FieldBundleGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_FAILURE, ESMF_LOGMSG_ERROR ! input/output variables @@ -134,8 +147,8 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Count the number of fields outside of scalar data, if zero, then return - call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) 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 @@ -194,7 +207,8 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) ! Carry out fast accumulation for the ocean - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_Clock, ESMF_Time + 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 @@ -222,8 +236,8 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Count the number of fields outside of scalar data, if zero, then return - call FB_getNumFlds(is_local%wrap%FBExp(compocn), trim(subname)//"FBexp(compocn)", ncnt, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) 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 @@ -252,6 +266,7 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) ! Prepare the OCN import Fields. use ESMF , only : ESMF_GridComp, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FieldBundleGet ! input/output variables type(ESMF_GridComp) :: gcomp @@ -276,8 +291,8 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Count the number of fields outside of scalar data, if zero, then return - call FB_getNumFlds(is_local%wrap%FBExpAccum(compocn), trim(subname)//"FBExpAccum(compocn)", ncnt, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBExpAccum(compocn), fieldCount=ncnt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 3a39e6538..a9e5b9521 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -21,7 +21,6 @@ module med_phases_prep_rof_mod 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_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_getNumFlds => med_methods_FB_getNumFlds use med_methods_mod , only : FB_accum => med_methods_FB_accum use med_methods_mod , only : FB_getFldPtr => med_methods_FB_getFldPtr use med_methods_mod , only : FB_average => med_methods_FB_average diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index 6cc4e6658..48fe8a116 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -8,7 +8,6 @@ module med_phases_prep_wav_mod 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_methods_mod , only : FB_getNumFlds => med_methods_FB_getNumFlds use med_merge_mod , only : med_merge_auto use med_map_mod , only : med_map_FB_Regrid_Norm use med_internalstate_mod , only : InternalState, mastertask @@ -59,22 +58,15 @@ subroutine med_phases_prep_wav(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 - !--------------------------------------- - + ! 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 FB_getNumFlds(is_local%wrap%FBExp(compwav), trim(subname)//"FBexp(compwav)", ncnt, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compwav), fieldCount=ncnt, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - !--------------------------------------- - !--- map to create FBimp(:,compwav) - !--------------------------------------- - + ! map to create FBimp(:,compwav) do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compwav)) then call med_map_FB_Regrid_Norm( & @@ -90,10 +82,7 @@ subroutine med_phases_prep_wav(gcomp, rc) endif enddo - !--------------------------------------- - !--- auto merges to create FBExp(compwav) - !--------------------------------------- - + ! auto merges to create FBExp(compwav) call med_merge_auto(compwav, & is_local%wrap%med_coupling_active(:,compwav), & is_local%wrap%FBExp(compwav), & From 6d0ccb63f1860448e846461b8383c55606fcc557 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 19 Oct 2020 22:03:39 -0600 Subject: [PATCH 125/206] fixes for f19_g17 F2000 tests --- mediator/med_constants_mod.F90 | 2 +- mediator/med_map_packed_mod.F90 | 121 +++++++++++++++++---------- mediator/med_phases_prep_ice_mod.F90 | 6 -- 3 files changed, 78 insertions(+), 51 deletions(-) diff --git a/mediator/med_constants_mod.F90 b/mediator/med_constants_mod.F90 index 4cc96f4f7..015101575 100644 --- a/mediator/med_constants_mod.F90 +++ b/mediator/med_constants_mod.F90 @@ -11,6 +11,6 @@ module med_constants_mod real(R8), parameter :: med_constants_czero = 0.0_R8 ! spval integer, parameter :: med_constants_ispval_mask = -987987 ! spval for RH mask values integer, parameter :: med_constants_SecPerDay = 86400 ! Seconds per day - integer :: med_constants_dbug_flag = 0 + integer :: med_constants_dbug_flag = 2 end module med_constants_mod diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 08f13d3ca..fa9e07370 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -31,6 +31,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & use ESMF use esmFlds , only : med_fldList_entry_type, nmappers + use esmFlds , only : ncomps, compatm, compice, compocn, compname, mapnames use med_internalstate_mod , only : packed_data_type ! input/output variables @@ -154,6 +155,16 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & npacked(mapindex) = npacked(mapindex) + 1 packed_data(mapindex)%fldindex(nf) = npacked(mapindex) end if + + ! if (mastertask) then + ! write(logunit,*)'------------------------------' + ! write(logunit,*)'DEBUG: destcomp, mapping, mapnorm, = '// & + ! trim(compname(destcomp))//' '//& + ! trim(mapnames(mapindex))//' '//& + ! trim(fldsSrc(ns)%mapnorm(destcomp)) + ! write(logunit,*)'DEBUG: fldname, index = ',trim(fieldnamelist(nf)),packed_data(mapindex)%fldindex(nf) + ! end if + end if! end if source field is mapped to destination field with mapindex end do ! end loop over FBSrc fields end do ! end loop over fldSrc elements @@ -175,7 +186,6 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & packed_data(mapindex)%field_fracdst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, & meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) end if - end do ! end loop over mapindex deallocate(npacked) @@ -227,6 +237,7 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & real(r8), pointer :: data_dst(:,:) => null() real(r8), pointer :: data_fracsrc(:) => null() real(r8), pointer :: data_fracdst(:) => null() + real(r8), pointer :: data_norm(:) => null() character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- @@ -289,68 +300,90 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & call t_startf('MED:'//trim(subname)//' map') if (mapindex == mapfcopy) then - ! Redistributing mapfcopy + ! Mapping is redistribution call ESMF_FieldRedist(packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & routehandles(mapindex), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else - + else if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'none') then + + ! Mapping is not redistribution ! ASSUME that each packed field has only one normalization type - ! TODO: set this in the initialization - if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & - trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & - trim(packed_data(mapindex)%mapnorm) /= 'none') then - - ! get a pointer to the array of the normalization on the source grid - call ESMF_FieldBundleGet(FBFracSrc, fieldName=packed_data(mapindex)%mapnorm, & - field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=data_fracsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! normalize packed source data + ! - get a pointer (data_fracsrc) to the normalization array + ! - get a pointer (data_src) to source field data in FBSrc + ! - copy data_src to data_srctmp + ! - normalize data_src by data_fracsrc + call ESMF_FieldBundleGet(FBFracSrc, fieldName=packed_data(mapindex)%mapnorm, field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=data_fracsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayPtr=data_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) + data_srctmp(:,:) = data_src(:,:) + do n = 1,size(data_fracsrc) + data_src(:,n) = data_src(:,n) * data_fracsrc(n) + end do + + ! regrid normalized packed source field + call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & + routehandles, mapindex, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get a pointer to source field data in FBSrc - call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayPtr=data_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! restore original value to packed source field + data_src(:,:) = data_srctmp(:,:) + deallocate(data_srctmp) - ! copy data_src to data_srctmp then multiply ungridded dimension in data_src by fraction - allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) - data_srctmp(:,:) = data_src(:,:) - do n = 1,size(data_fracsrc) - data_src(:,n) = data_src(:,n) * data_fracsrc(n) - end do + ! regrid fraction field from source to destination + call ESMF_FieldBundleGet(FBFracSrc, fieldname=trim(packed_data(mapindex)%mapnorm), & + field=frac_field_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field_regrid(frac_field_src, packed_data(mapindex)%field_fracdst, & + routehandles, mapindex, rc=rc) - ! regrid normalized packed source field - call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & - routehandles, mapindex, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! get pointer to mapped fraction and normalize + ! destination mapped values by the reciprocal of the mapped fraction + call ESMF_FieldGet(packed_data(mapindex)%field_fracdst, farrayPtr=data_fracdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(data_dst,dim=2) + if (data_fracdst(n) == 0.0_r8) then + data_dst(:,n) = 0.0_r8 + else + data_dst(:,n) = data_dst(:,n)/data_fracdst(n) + end if + end do - ! get fraction fields on both source and destination mesh - call ESMF_FieldBundleGet(FBFracSrc, fieldname=trim(packed_data(mapindex)%mapnorm), & - field=frac_field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + else if ( trim(packed_data(mapindex)%mapnorm) == 'one' .or. trim(packed_data(mapindex)%mapnorm) == 'none') then - ! regrid fraction field from source to destination - call med_map_field_regrid(frac_field_src, packed_data(mapindex)%field_fracdst, & - routehandles, mapindex, rc=rc) + ! Mapping is not redistribution + call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & + routehandles, mapindex, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get pointer to mapped fraction - call ESMF_FieldGet(packed_data(mapindex)%field_fracdst, farrayPtr=data_fracdst, rc=rc) + ! obtain unity normalization factor and multiply + ! interpolated field by reciprocal of normalization factor + if (trim(packed_data(mapindex)%mapnorm) == 'one') then + call ESMF_FieldBundleGet(FBNormOne(mapindex), fieldName='one', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! normalize destination mapped values by the reciprocal of the mapped fraction - call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_fracdst, rc=rc) + call ESMF_FieldGet(lfield, farrayPtr=data_norm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(data_dst,dim=2) - if (data_fracdst(n) == 0.0_r8) then + if (data_norm(n) == 0.0_r8) then data_dst(:,n) = 0.0_r8 else - data_dst(:,n) = data_dst(:,n)/data_fracdst(n) + data_dst(:,n) = data_dst(:,n)/data_norm(n) end if end do end if - end if + + end if call t_stopf('MED:'//trim(subname)//' map') ! ----------------------------------- diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 701568296..8eee9f7dc 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -56,17 +56,11 @@ subroutine med_phases_prep_ice(gcomp, rc) integer :: fldnum integer :: mapindex real(R8), pointer :: dataptr(:) - real(R8), pointer :: temperature(:) - real(R8), pointer :: pressure(:) - real(R8), pointer :: humidity(:) - real(R8), pointer :: air_density(:) - real(R8), pointer :: pot_temp(:) real(R8) :: precip_fact character(len=CS) :: cvalue character(len=64), allocatable :: fldnames(:) real(r8) :: nextsw_cday logical :: first_precip_fact_call = .true. - logical :: first_call = .true. character(len=*),parameter :: subname='(med_phases_prep_ice)' !--------------------------------------- From c3be8c62b9479cbc49edfe0362dfdf846978ba3a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 20 Oct 2020 13:24:55 -0600 Subject: [PATCH 126/206] more performance updates --- mediator/esmFldsExchange_cesm_mod.F90 | 6 +- mediator/med.F90 | 12 +- mediator/med_fraction_mod.F90 | 261 ++++++++++++++++---------- mediator/med_map_mod.F90 | 43 ++--- mediator/med_map_packed_mod.F90 | 22 ++- 5 files changed, 204 insertions(+), 140 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 43a06c286..e626d6833 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -398,8 +398,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') else if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsf, 'one' , atm2ice_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one' , atm2ocn_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsd, 'one' , atm2ice_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsd, 'one' , atm2ocn_fmap) end if if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', rc=rc)) then call addmap(fldListFr(compice)%flds, 'Faii_swnet', compocn, mapfcopy, 'unset', 'unset') @@ -480,7 +480,7 @@ 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, mapconsf, 'one', atm2lnd_fmap) + call addmap(fldListFr(compatm)%flds, trim(fldname), complnd, mapconsd, 'one', atm2lnd_fmap) call addmrg(fldListTo(complnd)%flds, trim(fldname), & mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') end if diff --git a/mediator/med.F90 b/mediator/med.F90 index eb5e341a1..b3c02d36c 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -450,7 +450,7 @@ end subroutine SetServices subroutine InitializeP0(gcomp, importState, exportState, clock, rc) use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_VM, ESMF_SUCCESS - use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_AttributeGet + use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_AttributeGet, ESMF_AttributeSet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE use NUOPC , only : NUOPC_CompFilterPhaseMap, NUOPC_CompAttributeGet use med_internalstate_mod, only : mastertask, logunit @@ -503,7 +503,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(cvalue), ESMF_LOGMSG_INFO) - call ESMF_AttributeGet(gcomp, name="Verbosity", value=cvalue, & + call ESMF_AttributeSet(gcomp, name="Verbosity", value='65535', & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is set to "//trim(cvalue), ESMF_LOGMSG_INFO) @@ -1914,8 +1914,8 @@ subroutine DataInitialize(gcomp, rc) end if end do end do - fieldCount = med_fldList_GetNumFlds(fldListMed_aoflux) - if (fieldCount > 0) then + if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o) .and. & + ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a)) then call med_map_packed_field_create(compatm, & is_local%wrap%flds_scalar_name, & fldsSrc=fldListMed_aoflux%flds, & @@ -1924,8 +1924,8 @@ subroutine DataInitialize(gcomp, rc) packed_data=is_local%wrap%packed_data_aoflux_o2a(:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - fieldCount = med_fldList_GetNumFlds(fldListMed_ocnalb) - if (fieldCount > 0) then + if ( ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o) .and. & + ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a)) then call med_map_packed_field_create(compatm, & is_local%wrap%flds_scalar_name, & fldsSrc=fldListMed_ocnalb%flds, & diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 67b2b060b..8cc6152d7 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -103,10 +103,9 @@ module med_fraction_mod 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_getFldPtr => med_methods_FB_getFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk - use med_map_mod , only : FB_FieldRegrid => med_map_FB_Field_Regrid + use med_map_mod , only : med_map_field use esmFlds , only : ncomps implicit none @@ -131,19 +130,20 @@ module med_fraction_mod character(*), parameter :: u_FILE_u = & __FILE__ -!----------------------------------------------------------------------------- +!================================================================================================ contains -!----------------------------------------------------------------------------- +!================================================================================================ subroutine med_fraction_init(gcomp, rc) ! Initialize FBFrac(:) field bundles - use ESMF , only : ESMF_GridComp, ESMF_Field use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_GridCompGet, ESMF_StateIsCreated + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_StateIsCreated use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleDestroy + use ESMF , only : ESMF_FieldBundleGet + use ESMF , only : ESMF_Field, ESMF_FieldGet use esmFlds , only : coupling_mode use esmFlds , only : compatm, compocn, compice, complnd use esmFlds , only : comprof, compglc, compwav, compname @@ -157,25 +157,27 @@ subroutine med_fraction_init(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - real(R8), pointer :: frac(:) - real(R8), pointer :: ofrac(:) - real(R8), pointer :: lfrac(:) - real(R8), pointer :: ifrac(:) - real(R8), pointer :: gfrac(:) - real(R8), pointer :: rfrac(:) - real(R8), pointer :: wfrac(:) - real(R8), pointer :: Sl_lfrin(:) - real(R8), pointer :: Si_imask(:) - real(R8), pointer :: So_omask(:) - integer :: i,j,n,n1 - integer :: maptype + type(InternalState) :: is_local + type(ESMF_Field) :: field_src + type(ESMF_Field) :: field_dst + type(ESMF_Field) :: lfield + real(R8), pointer :: frac(:) => null() + real(R8), pointer :: ofrac(:) => null() + real(R8), pointer :: lfrac(:) => null() + real(R8), pointer :: ifrac(:) => null() + real(R8), pointer :: gfrac(:) => null() + real(R8), pointer :: rfrac(:) => null() + real(R8), pointer :: wfrac(:) => null() + real(R8), pointer :: Sl_lfrin(:) => null() + real(R8), pointer :: Si_imask(:) => null() + real(R8), pointer :: So_omask(:) => null() + integer :: i,j,n,n1 + integer :: maptype logical, save :: first_call = .true. - character(len=*),parameter :: subname='(med_fraction_init)' + character(len=*),parameter :: subname=' (med_fraction_init)' !--------------------------------------- call t_startf('MED:'//subname) - if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if @@ -227,9 +229,15 @@ subroutine med_fraction_init(gcomp, rc) !--------------------------------------- if (is_local%wrap%comp_present(complnd)) then - call FB_getFldPtr(is_local%wrap%FBImp(complnd,complnd) , 'Sl_lfrin' , Sl_lfrin, rc=rc) + 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) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) + 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 lfrac(:) = Sl_lfrin(:) end if @@ -241,9 +249,15 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compice)) then ! Set 'ifrac' FBFrac(compice) - call FB_getFldPtr(is_local%wrap%FBImp(compice,compice) , 'Si_imask' , Si_imask, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ifrac', ifrac, rc=rc) + 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 ifrac(:) = Si_imask(:) @@ -268,10 +282,11 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), 'ifrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ifrac', 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(compice,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -283,9 +298,13 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compocn)) then ! Set 'ofrac' in FBFrac(compocn) - call FB_getFldPtr(is_local%wrap%FBImp(compocn,compocn) , 'So_omask', So_omask, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ofrac', ofrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldName='ofrac', field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ofrac(:) = So_omask(:) @@ -310,12 +329,12 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compocn,compatm,:), maptype, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), fieldname='ofrac', field=field_src, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), fieldname='ofrac', 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(compocn,compatm,:), maptype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if end if @@ -340,10 +359,11 @@ subroutine med_fraction_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compatm), 'lfrac', & - is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%RH(compatm,complnd,:),maptype, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'lfrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), '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(compatm,complnd,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if !--------------------------------------- @@ -359,9 +379,14 @@ 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 FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) - + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (is_local%wrap%comp_present(complnd)) then do n = 1,size(lfrac) lfrac(n) = 1.0_R8 - ofrac(n) @@ -390,14 +415,21 @@ subroutine med_fraction_init(gcomp, rc) end if end if end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%FBfrac(compatm), 'lfrac', & - is_local%wrap%RH(complnd,compatm,:),maptype, rc=rc) + 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(compatm), '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,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(lfrac) ofrac(n) = 1.0_R8 - lfrac(n) if (abs(ofrac(n)) < eps_fraclim) then @@ -417,12 +449,20 @@ subroutine med_fraction_init(gcomp, rc) ! 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 FB_getFldPtr(is_local%wrap%FBfrac(comprof) , 'rfrac', rfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBImp(comprof,comprof), 'frac' , frac, rc=rc) + 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 (ChkErr(rc,__LINE__,u_FILE_u)) return rfrac(:) = frac(:) else ! Set 'rfrac' in FBfrac(comprof) to 1. - call FB_getFldPtr(is_local%wrap%FBfrac(comprof), 'rfrac', rfrac, rc=rc) + 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 (ChkErr(rc,__LINE__,u_FILE_u)) return rfrac(:) = 1.0_R8 endif @@ -437,10 +477,11 @@ subroutine med_fraction_init(gcomp, rc) mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%FBfrac(comprof), 'lfrac', & - is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc) + 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(comprof), '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,comprof,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif endif @@ -453,12 +494,21 @@ subroutine med_fraction_init(gcomp, rc) ! 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 FB_getFldPtr(is_local%wrap%FBfrac(compglc) , 'gfrac', gfrac, rc=rc) - call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), 'frac' , frac, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBfrac(compglc), 'gfrac', gfrac, rc=rc) + 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 @@ -473,10 +523,11 @@ subroutine med_fraction_init(gcomp, rc) mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call FB_FieldRegrid(& - is_local%wrap%FBfrac(complnd), 'lfrac', & - is_local%wrap%FBfrac(compglc), 'lfrac', & - is_local%wrap%RH(complnd,compglc,:),maptype, rc=rc) + 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 endif endif @@ -487,7 +538,9 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compwav)) then ! Set 'wfrac' in FBfrac(compwav) to 1. - call FB_getFldPtr(is_local%wrap%FBfrac(compwav), 'wfrac', wfrac, rc=rc) + 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) if (ChkErr(rc,__LINE__,u_FILE_u)) return wfrac(:) = 1.0_R8 endif @@ -549,14 +602,14 @@ subroutine med_fraction_init(gcomp, rc) end subroutine med_fraction_init - !----------------------------------------------------------------------------- - + !================================================================================================ subroutine med_fraction_set(gcomp, rc) ! Update time varying fractions use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_Field, ESMF_FieldBundleIsCreated + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use esmFlds , only : compatm, compocn, compice, compname use esmFlds , only : mapfcopy, mapconsd, mapnstod_consd @@ -571,14 +624,17 @@ subroutine med_fraction_set(gcomp, rc) ! local variables type(InternalState) :: is_local - real(r8), pointer :: lfrac(:) - real(r8), pointer :: ifrac(:) - real(r8), pointer :: ofrac(:) - real(r8), pointer :: Si_ifrac(:) - real(r8), pointer :: Si_imask(:) + real(r8), pointer :: lfrac(:) => null() + real(r8), pointer :: ifrac(:) => null() + real(r8), pointer :: ofrac(:) => null() + real(r8), pointer :: Si_ifrac(:) => null() + real(r8), pointer :: Si_imask(:) => null() + type(ESMF_Field) :: lfield + type(ESMF_Field) :: field_src + type(ESMF_Field) :: field_dst integer :: n integer :: maptype - character(len=*),parameter :: subname='(med_fraction_set)' + character(len=*),parameter :: subname=' (med_fraction_set)' !--------------------------------------- rc = ESMF_SUCCESS @@ -607,14 +663,23 @@ 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 FB_getFldPtr(is_local%wrap%FBImp(compice,compice) , 'Si_ifrac', Si_ifrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compice,compice), fieldName='Si_ifrac', field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=Si_ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBImp(compice,compice) , 'Si_imask' , Si_imask, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ifrac', ifrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), fieldName='ifrac', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', ofrac, rc=rc) + 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) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! set ifrac = Si_ifrac * Si_imask @@ -629,21 +694,25 @@ subroutine med_fraction_set(gcomp, rc) ! The following is just a redistribution from FBFrac(compice) + call t_startf('MED:'//trim(subname)//' fbfrac(compocn)') if (is_local%wrap%comp_present(compocn)) then ! Map 'ifrac' from FBfrac(compice) to FBfrac(compocn) - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compocn), 'ifrac', & - is_local%wrap%RH(compice,compocn,:),mapfcopy, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), 'ifrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), 'ifrac', 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(compice,compocn,:), mapfcopy, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Map 'ofrac' from FBfrac(compice) to FBfrac(compocn) - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ofrac', & - is_local%wrap%FBfrac(compocn), 'ofrac', & - is_local%wrap%RH(compice,compocn,:),mapfcopy, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), 'ofrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), 'ofrac', 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(compice,compocn,:), mapfcopy, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif + call t_stopf('MED:'//trim(subname)//' fbfrac(compocn)') ! ------------------------------------------- ! Set FBfrac(compatm) @@ -651,6 +720,7 @@ subroutine med_fraction_set(gcomp, rc) if (is_local%wrap%comp_present(compatm)) then + call t_startf('MED:'//trim(subname)//' fbfrac(compatm)') ! Determine maptype if (trim(coupling_mode) == 'nems_orig' ) then maptype = mapnstod_consd @@ -664,24 +734,27 @@ subroutine med_fraction_set(gcomp, rc) ! Map 'ifrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compice,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ifrac', & - is_local%wrap%FBfrac(compatm), 'ifrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), 'ifrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ifrac', 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(compice,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! Map 'ofrac' from FBfrac(compice) to FBfrac(compatm) if (is_local%wrap%med_coupling_active(compocn,compatm)) then - call FB_FieldRegrid(& - is_local%wrap%FBfrac(compice), 'ofrac', & - is_local%wrap%FBfrac(compatm), 'ofrac', & - is_local%wrap%RH(compice,compatm,:), maptype, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), 'ofrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ofrac', 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(compice,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if ! end of if present compatm + call t_stopf('MED:'//trim(subname)//' fbfrac(compatm)') - end if ! end of if present compice + end if ! end of if present compatm !--------------------------------------- ! Diagnostic output diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index d29c6c0fc..0743d3241 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -1197,20 +1197,29 @@ subroutine norm_field_dest (fldname, dstfield, frac, rc) ! local variables integer :: i,n - integer :: lrank real(R8), pointer :: data1d(:) real(R8), pointer :: data2d(:,:) 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 - ! ------------------------------------------------ rc = ESMF_SUCCESS - call ESMF_FieldGet(dstfield, rank=lrank, rc=rc) + call ESMF_FieldGet(dstfield, ungriddedUBound=ungriddedUbound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 1) then + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(dstfield, farrayPtr=data2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,ungriddedUbound(1) + do i = 1,size(data2d,dim=2) + if (frac(i) == 0.0_r8) then + data2d(n,i) = 0.0_r8 + else + data2d(n,i) = data2d(n,i)/frac(i) + end if + end do + end do + else call ESMF_FieldGet(dstfield, farrayPtr=data1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do i= 1,size(data1d) @@ -1219,30 +1228,6 @@ subroutine norm_field_dest (fldname, dstfield, frac, rc) else data1d(i) = data1d(i)/frac(i) endif - enddo - else if (lrank == 2) then - call ESMF_FieldGet(dstfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(dstfield, farrayPtr=data2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,ungriddedUbound(1) - if (gridToFieldMap(1) == 1) then - do i = 1,size(data2d,dim=1) - if (frac(i) == 0.0_r8) then - data2d(i,n) = 0.0_r8 - else - data2d(i,n) = data2d(i,n)/frac(i) - end if - end do - else if (gridToFieldMap(1) == 2) then - do i = 1,size(data2d,dim=2) - if (frac(i) == 0.0_r8) then - data2d(n,i) = 0.0_r8 - else - data2d(n,i) = data2d(n,i)/frac(i) - end if - end do - end if end do end if diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index fa9e07370..14919436c 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -106,6 +106,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & allocate(npacked(nmappers)) npacked(:) = 0 + if (mastertask) write(logunit,*) ! Loop over mapping types do mapindex = 1,nmappers @@ -156,14 +157,15 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & packed_data(mapindex)%fldindex(nf) = npacked(mapindex) end if - ! if (mastertask) then - ! write(logunit,*)'------------------------------' - ! write(logunit,*)'DEBUG: destcomp, mapping, mapnorm, = '// & - ! trim(compname(destcomp))//' '//& - ! trim(mapnames(mapindex))//' '//& - ! trim(fldsSrc(ns)%mapnorm(destcomp)) - ! write(logunit,*)'DEBUG: fldname, index = ',trim(fieldnamelist(nf)),packed_data(mapindex)%fldindex(nf) - ! end if + if (mastertask) then + write(logunit,'(5(a,2x),2x,i4)') trim(subname)//& + 'Packed field: destcomp,mapping,mapnorm,fldname,index: ', & + trim(compname(destcomp)), & + trim(mapnames(mapindex)), & + trim(fldsSrc(ns)%mapnorm(destcomp)), & + trim(fieldnamelist(nf)), & + packed_data(mapindex)%fldindex(nf) + end if end if! end if source field is mapped to destination field with mapindex end do ! end loop over FBSrc fields @@ -337,13 +339,16 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & data_src(:,:) = data_srctmp(:,:) deallocate(data_srctmp) + call t_startf('MED:'//trim(subname)//' map_nofrac') ! regrid fraction field from source to destination call ESMF_FieldBundleGet(FBFracSrc, fieldname=trim(packed_data(mapindex)%mapnorm), & field=frac_field_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call med_map_field_regrid(frac_field_src, packed_data(mapindex)%field_fracdst, & routehandles, mapindex, rc=rc) + call t_stopf('MED:'//trim(subname)//' map_nofrac') + call t_startf('MED:'//trim(subname)//' norm one') ! get pointer to mapped fraction and normalize ! destination mapped values by the reciprocal of the mapped fraction call ESMF_FieldGet(packed_data(mapindex)%field_fracdst, farrayPtr=data_fracdst, rc=rc) @@ -357,6 +362,7 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & data_dst(:,n) = data_dst(:,n)/data_fracdst(n) end if end do + call t_stopf('MED:'//trim(subname)//' norm one') else if ( trim(packed_data(mapindex)%mapnorm) == 'one' .or. trim(packed_data(mapindex)%mapnorm) == 'none') then From bca5c056d7965b6a966e565f95357dbdead10e9c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 20 Oct 2020 18:44:53 -0600 Subject: [PATCH 127/206] introduced normalization routine that can also be reused in med_map_packed_mod --- mediator/med_map_packed_mod.F90 | 164 ++++++++++++++++----------- mediator/med_phases_prep_wav_mod.F90 | 15 +-- 2 files changed, 104 insertions(+), 75 deletions(-) diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 14919436c..832e08672 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -18,6 +18,7 @@ module med_map_packed_mod public :: med_map_packed_field_create public :: med_map_packed_field_map + public :: med_map_normalized_field character(*),parameter :: u_FILE_u = & __FILE__ @@ -205,10 +206,7 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & ! ----------------------------------------------- use ESMF - use esmFlds , only : mapunset, mapnames, nmappers - use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd - use esmFlds , only : ncomps, compatm, compice, compocn, compname - use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod + use esmFlds , only : nmappers, mapfcopy use med_map_mod , only : med_map_field_regrid use med_internalstate_mod , only : packed_data_type @@ -230,16 +228,12 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & real(r8), pointer :: dataptr2d(:,:) => null() real(r8), pointer :: dataptr2d_packed(:,:) => null() type(ESMF_Field) :: lfield - type(ESMF_Field) :: frac_field_src + type(ESMF_Field) :: field_fracsrc type(ESMF_Field), pointer :: fieldlist_src(:) => null() type(ESMF_Field), pointer :: fieldlist_dst(:) => null() character(CL), allocatable :: fieldNameList(:) - real(r8), pointer :: data_src(:,:) => null() - real(r8), pointer :: data_srctmp(:,:) => null() - real(r8), pointer :: data_dst(:,:) => null() - real(r8), pointer :: data_fracsrc(:) => null() - real(r8), pointer :: data_fracdst(:) => null() real(r8), pointer :: data_norm(:) => null() + real(r8), pointer :: data_dst(:,:) => null() character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- @@ -303,7 +297,9 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & if (mapindex == mapfcopy) then ! Mapping is redistribution - call ESMF_FieldRedist(packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & + call ESMF_FieldRedist(& + packed_data(mapindex)%field_src, & + packed_data(mapindex)%field_dst, & routehandles(mapindex), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -311,67 +307,28 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & trim(packed_data(mapindex)%mapnorm) /= 'none') then - ! Mapping is not redistribution - ! ASSUME that each packed field has only one normalization type - ! normalize packed source data - ! - get a pointer (data_fracsrc) to the normalization array - ! - get a pointer (data_src) to source field data in FBSrc - ! - copy data_src to data_srctmp - ! - normalize data_src by data_fracsrc - call ESMF_FieldBundleGet(FBFracSrc, fieldName=packed_data(mapindex)%mapnorm, field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=data_fracsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayPtr=data_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) - data_srctmp(:,:) = data_src(:,:) - do n = 1,size(data_fracsrc) - data_src(:,n) = data_src(:,n) * data_fracsrc(n) - end do - - ! regrid normalized packed source field - call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & - routehandles, mapindex, rc=rc) + ! Normalized mapping - assume that each packed field has only one normalization type + call ESMF_FieldBundleGet(FBFracSrc, packed_data(mapindex)%mapnorm, field=field_fracsrc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! restore original value to packed source field - data_src(:,:) = data_srctmp(:,:) - deallocate(data_srctmp) - - call t_startf('MED:'//trim(subname)//' map_nofrac') - ! regrid fraction field from source to destination - call ESMF_FieldBundleGet(FBFracSrc, fieldname=trim(packed_data(mapindex)%mapnorm), & - field=frac_field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field_regrid(frac_field_src, packed_data(mapindex)%field_fracdst, & - routehandles, mapindex, rc=rc) - call t_stopf('MED:'//trim(subname)//' map_nofrac') - - call t_startf('MED:'//trim(subname)//' norm one') - ! get pointer to mapped fraction and normalize - ! destination mapped values by the reciprocal of the mapped fraction - call ESMF_FieldGet(packed_data(mapindex)%field_fracdst, farrayPtr=data_fracdst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(data_dst,dim=2) - if (data_fracdst(n) == 0.0_r8) then - data_dst(:,n) = 0.0_r8 - else - data_dst(:,n) = data_dst(:,n)/data_fracdst(n) - end if - end do - call t_stopf('MED:'//trim(subname)//' norm one') + call med_map_normalized_field(& + field_src=packed_data(mapindex)%field_src, & + field_dst=packed_data(mapindex)%field_dst, & + routehandles=routehandles, & + maptype=mapindex, & + field_normsrc=field_fracsrc, & + field_normdst=packed_data(mapindex)%field_fracdst, rc=rc) else if ( trim(packed_data(mapindex)%mapnorm) == 'one' .or. trim(packed_data(mapindex)%mapnorm) == 'none') then - ! Mapping is not redistribution - call med_map_field_regrid (packed_data(mapindex)%field_src, packed_data(mapindex)%field_dst, & - routehandles, mapindex, rc=rc) + ! Mapping with no normalization that is not redistribution + call med_map_field_regrid (& + srcfield=packed_data(mapindex)%field_src, & + dstfield=packed_data(mapindex)%field_dst, & + routehandles=routehandles, & + mapindex=mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! obtain unity normalization factor and multiply + ! Obtain unity normalization factor and multiply ! interpolated field by reciprocal of normalization factor if (trim(packed_data(mapindex)%mapnorm) == 'one') then call ESMF_FieldBundleGet(FBNormOne(mapindex), fieldName='one', field=lfield, rc=rc) @@ -432,4 +389,79 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & end subroutine med_map_packed_field_map + !================================================================================ + subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, & + field_normsrc, field_normdst, rc) + + ! ----------------------------------------------- + ! Map a normalized field + ! ----------------------------------------------- + + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_RouteHandle + use ESMF , only : ESMF_SUCCESS + use med_map_mod , only : med_map_field_regrid + + ! input/output variables + type(ESMF_Field) , intent(in) :: field_src + type(ESMF_Field) , intent(inout) :: field_dst + type(ESMF_Field) , intent(in) :: field_normsrc + type(ESMF_Field) , intent(inout) :: field_normdst + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(in) :: maptype + integer , intent(out) :: rc + + ! local variables + integer :: n + real(r8), pointer :: data_src(:,:) => null() + real(r8), pointer :: data_dst(:,:) => null() + real(r8), pointer :: data_srctmp(:,:) => null() + real(r8), pointer :: data_normsrc(:) => null() + real(r8), pointer :: data_normdst(:) => null() + character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + !----------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! get a pointer (data_fracsrc) to the normalization array + ! get a pointer (data_src) to source field data in FBSrc + ! copy data_src to data_srctmp + + ! normalize data_src by data_fracsrc + call ESMF_FieldGet(field_normsrc, farrayPtr=data_normsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_src, farrayPtr=data_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) + data_srctmp(:,:) = data_src(:,:) + do n = 1,size(data_normsrc) + data_src(:,n) = data_src(:,n) * data_normsrc(n) + end do + + ! regrid normalized packed source field + call med_map_field_regrid (field_src, field_dst, routehandles, maptype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! restore original value to packed source field + data_src(:,:) = data_srctmp(:,:) + deallocate(data_srctmp) + + ! regrid normalization field from source to destination + call med_map_field_regrid(field_normsrc, field_normdst, routehandles, maptype, rc=rc) + + ! get pointer to mapped fraction and normalize + ! destination mapped values by the reciprocal of the mapped fraction + call ESMF_FieldGet(field_normdst, farrayPtr=data_normdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_dst, farrayPtr=data_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(data_dst,dim=2) + if (data_normdst(n) == 0.0_r8) then + data_dst(:,n) = 0.0_r8 + else + data_dst(:,n) = data_dst(:,n)/data_normdst(n) + end if + end do + + end subroutine med_map_normalized_field + end module med_map_packed_mod diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index 48fe8a116..e7559afc4 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -9,7 +9,7 @@ module med_phases_prep_wav_mod use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_merge_mod , only : med_merge_auto - use med_map_mod , only : med_map_FB_Regrid_Norm + use med_map_packed_mod , only : med_map_packed_field_map use med_internalstate_mod , only : InternalState, mastertask use esmFlds , only : compwav, ncomps, compname use esmFlds , only : fldListFr, fldListTo @@ -63,24 +63,21 @@ subroutine med_phases_prep_wav(gcomp, rc) ! fieldCount is 0 and not 1 here call ESMF_FieldBundleGet(is_local%wrap%FBExp(compwav), fieldCount=ncnt, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ncnt > 0) then ! map to create FBimp(:,compwav) do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compwav)) then - call med_map_FB_Regrid_Norm( & - fldsSrc=fldListFr(n1)%flds, & - srccomp=n1, destcomp=compwav, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compwav), & FBFracSrc=is_local%wrap%FBFrac(n1), & FBNormOne=is_local%wrap%FBNormOne(n1,compwav,:), & - RouteHandles=is_local%wrap%RH(n1,compwav,:), & - string=trim(compname(n1))//'2'//trim(compname(compwav)), rc=rc) + packed_data=is_local%wrap%packed_data(n1,compwav,:), & + routehandles=is_local%wrap%RH(n1,compwav,:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - enddo + end if + end do ! auto merges to create FBExp(compwav) call med_merge_auto(compwav, & From ed7a7216879251964fc74ed8263953519dd35571 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 21 Oct 2020 11:55:41 -0600 Subject: [PATCH 128/206] hard-wired max profile for now --- mediator/med.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index b3c02d36c..820049fc8 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -503,15 +503,15 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(cvalue), ESMF_LOGMSG_INFO) - call ESMF_AttributeSet(gcomp, name="Verbosity", value='65535', & - convention="NUOPC", purpose="Instance", rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator verbosity is set to "//trim(cvalue), ESMF_LOGMSG_INFO) + ! call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & + ! convention="NUOPC", purpose="Instance", 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) - call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & + call ESMF_AttributeSet(gcomp, name="Profiling", value='65535', & convention="NUOPC", purpose="Instance", 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) + call ESMF_LogWrite(trim(subname)//": Mediator profileing is set to "//trim(cvalue), ESMF_LOGMSG_INFO) ! 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) From f696f41069034ee7dbdd0b0c5e7721c43ad85a6b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 21 Oct 2020 12:27:50 -0600 Subject: [PATCH 129/206] updated mapping and med_phases_prep_rof_mod to using the new mapping functionality --- mediator/med_io_mod.F90 | 6 +- mediator/med_map_packed_mod.F90 | 85 ++++++-- mediator/med_phases_prep_rof_mod.F90 | 310 +++++++++++++++------------ 3 files changed, 243 insertions(+), 158 deletions(-) diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index 492a50849..9d12db4bf 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -1338,13 +1338,15 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) if (fldptr1tmp(l) == lfillvalue) fldptr1tmp(l) = 0.0_r8 enddo else - fldptr1tmp = 0.0_r8 + fldptr1tmp(:) = 0.0_r8 endif fldptr2(n,:) = fldptr1tmp(:) end do deallocate(fldptr1tmp) 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)) rcode = pio_inq_varid(pioid, trim(name1), varid) if (rcode == pio_noerr) then @@ -1360,7 +1362,7 @@ 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 diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index 832e08672..c65f60618 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -412,11 +412,17 @@ subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, ! local variables integer :: n - real(r8), pointer :: data_src(:,:) => null() - real(r8), pointer :: data_dst(:,:) => null() - real(r8), pointer :: data_srctmp(:,:) => null() - real(r8), pointer :: data_normsrc(:) => null() - real(r8), pointer :: data_normdst(:) => null() + real(r8), pointer :: data_src2d(:,:) => null() + real(r8), pointer :: data_dst2d(:,:) => null() + real(r8), pointer :: data_srctmp2d(:,:) => null() + real(r8), pointer :: data_src1d(:) => null() + real(r8), pointer :: data_dst1d(:) => null() + real(r8), pointer :: data_srctmp1d(:) => null() + real(r8), pointer :: data_normsrc(:) => null() + real(r8), pointer :: data_normdst(:) => null() + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + integer :: lsize_src + integer :: lsize_dst character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' !----------------------------------------------------------- @@ -427,23 +433,43 @@ subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, ! copy data_src to data_srctmp ! normalize data_src by data_fracsrc + call ESMF_FieldGet(field_normsrc, farrayPtr=data_normsrc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_src, farrayPtr=data_src, rc=rc) + lsize_src = size(data_normsrc) + + call ESMF_FieldGet(field_src, ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(data_srctmp(size(data_src,dim=1), size(data_src,dim=2))) - data_srctmp(:,:) = data_src(:,:) - do n = 1,size(data_normsrc) - data_src(:,n) = data_src(:,n) * data_normsrc(n) - end do + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(field_src, farrayPtr=data_src2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(data_srctmp2d(size(data_src2d,dim=1), lsize_src)) + data_srctmp2d(:,:) = data_src2d(:,:) + do n = 1,lsize_src + data_src2d(:,n) = data_src2d(:,n) * data_normsrc(n) + end do + else + call ESMF_FieldGet(field_src, farrayPtr=data_src1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(data_srctmp1d(lsize_src)) + data_srctmp1d(:) = data_src1d(:) + do n = 1,lsize_src + data_src1d(n) = data_src1d(n) * data_normsrc(n) + end do + end if ! regrid normalized packed source field call med_map_field_regrid (field_src, field_dst, routehandles, maptype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! restore original value to packed source field - data_src(:,:) = data_srctmp(:,:) - deallocate(data_srctmp) + if (ungriddedUbound(1) > 0) then + data_src2d(:,:) = data_srctmp2d(:,:) + deallocate(data_srctmp2d) + else + data_src1d(:) = data_srctmp1d(:) + deallocate(data_srctmp1d) + end if ! regrid normalization field from source to destination call med_map_field_regrid(field_normsrc, field_normdst, routehandles, maptype, rc=rc) @@ -452,16 +478,29 @@ subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, ! destination mapped values by the reciprocal of the mapped fraction call ESMF_FieldGet(field_normdst, farrayPtr=data_normdst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_dst, farrayPtr=data_dst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(data_dst,dim=2) - if (data_normdst(n) == 0.0_r8) then - data_dst(:,n) = 0.0_r8 - else - data_dst(:,n) = data_dst(:,n)/data_normdst(n) - end if - end do - + lsize_dst = size(data_normdst) + + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(field_dst, farrayPtr=data_dst2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,lsize_dst + if (data_normdst(n) == 0.0_r8) then + data_dst2d(:,n) = 0.0_r8 + else + data_dst2d(:,n) = data_dst2d(:,n)/data_normdst(n) + end if + end do + else + call ESMF_FieldGet(field_dst, farrayPtr=data_dst1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,lsize_dst + if (data_normdst(n) == 0.0_r8) then + data_dst1d(n) = 0.0_r8 + else + data_dst1d(n) = data_dst1d(n)/data_normdst(n) + end if + end do + end if end subroutine med_map_normalized_field end module med_map_packed_mod diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index a9e5b9521..0eb20ebd4 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -11,26 +11,15 @@ 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 - use esmFlds , only : ncomps, complnd, comprof, compname, mapconsf - use esmFlds , only : med_fldlist_type - use esmFlds , only : fldListTo, fldListFr - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_constants_mod , only : czero => med_constants_czero + 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_utils_mod , only : chkerr => med_utils_ChkErr - use med_methods_mod , only : FB_init => med_methods_FB_init - 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_getFldPtr => med_methods_FB_getFldPtr - use med_methods_mod , only : FB_average => med_methods_FB_average - use med_methods_mod , only : FB_reset => med_methods_FB_reset - use med_methods_mod , only : FB_clean => med_methods_FB_clean - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar - use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar - use med_merge_mod , only : med_merge_auto - use med_map_mod , only : med_map_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_FB_Field_Regrid + 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 perf_mod , only : t_startf, t_stopf implicit none @@ -41,23 +30,26 @@ module med_phases_prep_rof_mod private :: med_phases_prep_rof_irrig - type(ESMF_FieldBundle) :: FBlndVolr ! needed for lnd2rof irrigation - type(ESMF_FieldBundle) :: FBrofVolr ! needed for lnd2rof irrigation - type(ESMF_FieldBundle) :: FBlndIrrig ! needed for lnd2rof irrigation - type(ESMF_FieldBundle) :: FBrofIrrig ! needed for lnd2rof irrigation - type(med_fldlist_type) :: fldlist_lnd2rof ! needed for lnd2rof irrigation + ! the following are needed for lnd2rof irrigation + type(ESMF_Field) :: field_lndVolr + type(ESMF_Field) :: field_rofVolr + type(ESMF_Field) :: field_lndIrrig + type(ESMF_Field) :: field_rofIrrig + type(ESMF_Field) :: field_lndIrrig0 + type(ESMF_Field) :: field_rofIrrig0 + type(ESMF_Field) :: field_lfrac_rof character(len=*), parameter :: volr_field = 'Flrr_volrmch' character(len=*), parameter :: irrig_flux_field = 'Flrl_irrig' character(len=*), parameter :: irrig_normalized_field = 'Flrl_irrig_normalized' - character(len=*), parameter :: irrig_volr0_field = 'Flrl_irrig_volr0 ' + character(len=*), parameter :: irrig_volr0_field = 'Flrl_irrig_volr0 ' character(*) , parameter :: u_FILE_u = & __FILE__ -!----------------------------------------------------------------------------- +!=============================================================================== contains -!----------------------------------------------------------------------------- +!=============================================================================== subroutine med_phases_prep_rof_accum(gcomp, rc) @@ -145,28 +137,36 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end subroutine med_phases_prep_rof_accum - !----------------------------------------------------------------------------- - + !=============================================================================== subroutine med_phases_prep_rof_avg(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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet + 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_packed_mod , only : med_map_packed_field_map + use med_merge_mod , only : med_merge_auto ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - integer :: i,j,n,n1,ncnt - logical :: connected - real(r8), pointer :: dataptr(:) + type(InternalState) :: is_local + integer :: i,j,n,n1,ncnt + logical :: connected + real(r8), pointer :: dataptr(:) + real(r8), pointer :: dataptr1d(:) + real(r8), pointer :: dataptr2d(:,:) + type(ESMF_Field) :: field_irrig_flux + integer :: fieldcount + type(ESMF_Field), pointer :: fieldlist(:) => null() + integer :: ungriddedUBound(1) character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_avg)' !--------------------------------------- @@ -185,7 +185,7 @@ 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 + ! 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 @@ -200,7 +200,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) else !--------------------------------------- - !--- average import from land accumuled FB + ! average import from land accumuled FB !--------------------------------------- call FB_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) @@ -213,24 +213,21 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) end if !--------------------------------------- - !--- map to create FBImpAccum(complnd,comprof) + ! 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_FB_Regrid_Norm( & - fldsSrc=fldListFr(complnd)%flds, & - srccomp=complnd, destcomp=comprof, & + call med_map_packed_field_map( & FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & FBFracSrc=is_local%wrap%FBFrac(complnd), & FBNormOne=is_local%wrap%FBNormOne(complnd,comprof,:), & - RouteHandles=is_local%wrap%RH(complnd,comprof,:), & - string=trim(compname(complnd))//'2'//trim(compname(comprof)), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + 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), & @@ -244,15 +241,17 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else ! This will ensure that no irrig is sent from the land - call FB_getFldPtr(is_local%wrap%FBImpAccum(complnd,comprof), & - trim(irrig_flux_field), dataptr, rc=rc) + 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) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 0._r8 end if endif !--------------------------------------- - !--- auto merges to create FBExp(comprof) + ! auto merges to create FBExp(comprof) !--------------------------------------- if (dbug_flag > 1) then @@ -276,21 +275,30 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) end if !--------------------------------------- - !--- zero accumulator + ! zero accumulator and FBAccum !--------------------------------------- is_local%wrap%FBImpAccumCnt(complnd) = 0 - call FB_reset(is_local%wrap%FBImpAccum(complnd,complnd), value=czero, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - - !--------------------------------------- - !--- clean up - !--------------------------------------- + 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 (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + else + call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + end if + end do + deallocate(fieldlist) endif if (dbug_flag > 20) then @@ -300,8 +308,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) end subroutine med_phases_prep_rof_avg - !----------------------------------------------------------------------------- - + !=============================================================================== subroutine med_phases_prep_rof_irrig(gcomp, rc) !--------------------------------------------------------------- @@ -325,26 +332,39 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! (non-volr-normalized) flux on the rof grid. !--------------------------------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_Field - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleIsCreated - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR + 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 + use med_map_mod , only : med_map_field_regrid + use med_map_packed_mod , only : med_map_normalized_field ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables - integer :: r,l - type(InternalState) :: is_local - real(r8), pointer :: volr_l(:) - real(r8), pointer :: volr_r(:), volr_r_import(:) - real(r8), pointer :: irrig_normalized_l(:) - real(r8), pointer :: irrig_normalized_r(:) - real(r8), pointer :: irrig_volr0_l(:) - real(r8), pointer :: irrig_volr0_r(:) - real(r8), pointer :: irrig_flux_l(:) - real(r8), pointer :: irrig_flux_r(:) + integer :: r,l + type(InternalState) :: is_local + integer :: fieldcount + type(ESMF_Field) :: field_import_rof + type(ESMF_Field) :: field_import_lnd + type(ESMF_Field) :: field_irrig_flux + type(ESMF_Field) :: field_lfrac_lnd + type(ESMF_Field), pointer :: fieldlist_lnd(:) => null() + type(ESMF_Field), pointer :: fieldlist_rof(:) => null() + type(ESMF_Mesh) :: lmesh_lnd + type(ESMF_Mesh) :: lmesh_rof + real(r8), pointer :: volr_l(:) + real(r8), pointer :: volr_r(:), volr_r_import(:) + real(r8), pointer :: irrig_normalized_l(:) + real(r8), pointer :: irrig_normalized_r(:) + real(r8), pointer :: irrig_volr0_l(:) + real(r8), pointer :: irrig_volr0_r(:) + real(r8), pointer :: irrig_flux_l(:) + real(r8), pointer :: irrig_flux_r(:) character(len=*), parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_irrig)' !--------------------------------------------------------------- @@ -380,42 +400,51 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! Initialize module field bundles if not already initialized ! ------------------------------------------------------------------------ - if (.not. ESMF_FieldBundleIsCreated(FBlndVolr) .and. & - .not. ESMF_FieldBundleIsCreated(FBrofVolr) .and. & - .not. ESMF_FieldBundleIsCreated(FBlndIrrig) .and. & - .not. ESMF_FieldBundleIsCreated(FBrofIrrig)) then + if (.not. ESMF_FieldIsCreated(field_lndVolr) .and. & + .not. ESMF_FieldIsCreated(field_rofVolr) .and. & + .not. ESMF_FieldIsCreated(field_lndIrrig) .and. & + .not. ESMF_FieldIsCreated(field_rofIrrig) .and. & + .not. ESMF_FieldIsCreated(field_lndIrrig0) .and. & + .not. ESMF_FieldIsCreated(field_rofIrrig0) .and. & + .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) + 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) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist_rof) - call FB_init(FBout=FBlndVolr, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(complnd,complnd), & - fieldNameList=(/trim(volr_field)/), rc=rc) + field_lndVolr = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_rofVolr = ESMF_FieldCreate(lmesh_rof, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_init(FBout=FBrofVolr, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(comprof,comprof), & - fieldNameList=(/trim(volr_field)/), rc=rc) + field_lndIrrig = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_rofIrrig = ESMF_FieldCreate(lmesh_rof, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_init(FBout=FBlndIrrig, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(complnd,complnd), & - fieldNameList=(/irrig_normalized_field, irrig_volr0_field/), rc=rc) + field_lndIrrig0 = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_rofIrrig0 = ESMF_FieldCreate(lmesh_rof, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_init(FBout=FBrofIrrig, & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(comprof,comprof), & - fieldNameList=(/irrig_normalized_field, irrig_volr0_field/), rc=rc) + field_lfrac_rof = ESMF_FieldCreate(lmesh_rof, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldlist_lnd2rof%flds(2)) - fldlist_lnd2rof%flds(1)%shortname = irrig_normalized_field - fldlist_lnd2rof%flds(2)%shortname = irrig_volr0_field - fldlist_lnd2rof%flds(1)%mapindex(comprof) = mapconsf - fldlist_lnd2rof%flds(2)%mapindex(comprof) = mapconsf - fldlist_lnd2rof%flds(1)%mapnorm(comprof) = 'lfrac' - fldlist_lnd2rof%flds(2)%mapnorm(comprof) = 'lfrac' end if ! ------------------------------------------------------------------------ @@ -427,13 +456,14 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! cells: while conservative, this would be unphysical (it would mean that irrigation ! actually adds water to those cells). - call FB_getFldPtr(is_local%wrap%FBImp(comprof,comprof), & - trim(volr_field), volr_r_import, rc=rc) + ! 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 FB_getFldPtr(FBrofVolr, trim(volr_field), volr_r, rc=rc) + call ESMF_FieldGet(field_import_rof, farrayptr=volr_r_import, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_rofVolr, farrayptr=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 volr_r(r) = 0._r8 @@ -443,12 +473,15 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) end do ! Map volr_r to volr_l (rof->lnd) using conservative mapping without any fractional weighting - call med_map_FB_Field_Regrid(FBrofVolr, trim(volr_field), FBlndVolr, trim(volr_field), & - is_local%wrap%RH(comprof, complnd, :), mapconsf, rc=rc) + call med_map_field_regrid(& + srcfield=field_rofVolr, & + dstfield=field_lndVolr, & + routehandles=is_local%wrap%RH(comprof,complnd,:), & + mapindex=mapconsf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get volr_l - call FB_getFldPtr(FBlndVolr, trim(volr_field), volr_l, rc=rc) + call ESMF_FieldGet(field_lndVolr, farrayptr=volr_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! ------------------------------------------------------------------------ @@ -467,15 +500,16 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! flux on the rof grid. ! First extract accumulated irrigation flux from land - call FB_getFldPtr(is_local%wrap%FBImpAccum(complnd,complnd), & - trim(irrig_flux_field), irrig_flux_l, rc=rc) + 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 - - ! Fill in values for irrig_normalized_l and irrig_volr0_l in temporary FBlndIrrig field bundle - call FB_getFldPtr(FBlndIrrig, trim(irrig_normalized_field), irrig_normalized_l, rc=rc) + call ESMF_FieldGet(field_irrig_flux, farrayptr=irrig_flux_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(FBlndIrrig, trim(irrig_volr0_field), irrig_volr0_l, rc=rc) + ! Fill in values for irrig_normalized_l and irrig_volr0_l + call ESMF_FieldGet(field_lndIrrig, farrayptr=irrig_normalized_l, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_lndIrrig0, farrayptr=irrig_volr0_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do l = 1, size(volr_l) @@ -493,26 +527,36 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! convert to a total irrigation flux on the ROF grid ! ------------------------------------------------------------------------ - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList_lnd2rof%flds, & - srccomp=complnd, destcomp=comprof, & - FBSrc=FBlndIrrig, & - FBDst=FBrofIrrig, & - FBFracSrc=is_local%wrap%FBFrac(complnd), & - FBNormOne=is_local%wrap%FBNormOne(complnd,comprof,:), & - RouteHandles=is_local%wrap%RH(complnd,comprof,:), & - string=trim(compname(complnd))//'2'//trim(compname(comprof)), rc=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 FB_getFldPtr(FBrofIrrig, trim(irrig_normalized_field), irrig_normalized_r, rc=rc) + call med_map_normalized_field( & + field_src=field_lndIrrig, & + field_dst=field_rofIrrig, & + routehandles=is_local%wrap%RH(complnd,comprof,:), & + maptype=mapconsf, & + field_normsrc=field_lfrac_lnd, & + field_normdst=field_lfrac_rof, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call FB_getFldPtr(FBrofIrrig, trim(irrig_volr0_field), irrig_volr0_r, rc=rc) + call med_map_normalized_field( & + field_src=field_lndIrrig0, & + field_dst=field_rofIrrig0, & + routehandles=is_local%wrap%RH(complnd,comprof,:), & + maptype=mapconsf, & + 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 FB_getFldPtr(is_local%wrap%FBImpAccum(complnd,comprof), & - trim(irrig_flux_field), irrig_flux_r, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,comprof), fieldname=trim(irrig_flux_field), & + field=field_import_rof, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_import_rof, farrayptr=irrig_flux_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 do r = 1, size(irrig_flux_r) From a1b6b4ab70875ea0bc3bcb4948ad47208ea276fe Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 21 Oct 2020 20:52:06 -0600 Subject: [PATCH 130/206] updated med_map_prep_lnd_mod with new interface call for glc->lnd mapping --- mediator/med_map_packed_mod.F90 | 93 +++++++++++++++++++++++++--- mediator/med_phases_aofluxes_mod.F90 | 4 +- mediator/med_phases_prep_atm_mod.F90 | 8 +-- mediator/med_phases_prep_ice_mod.F90 | 4 +- mediator/med_phases_prep_ocn_mod.F90 | 21 +------ mediator/med_phases_prep_rof_mod.F90 | 10 +-- mediator/med_phases_prep_wav_mod.F90 | 4 +- 7 files changed, 103 insertions(+), 41 deletions(-) diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 index c65f60618..01ce3f7c4 100644 --- a/mediator/med_map_packed_mod.F90 +++ b/mediator/med_map_packed_mod.F90 @@ -17,8 +17,9 @@ module med_map_packed_mod private public :: med_map_packed_field_create - public :: med_map_packed_field_map - public :: med_map_normalized_field + public :: med_map_field_packed + public :: med_map_field_normalized + public :: med_map_field character(*),parameter :: u_FILE_u = & __FILE__ @@ -198,8 +199,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & end subroutine med_map_packed_field_create !================================================================================ - subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & - packed_data, routehandles, rc) + subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, routehandles, rc) ! ----------------------------------------------- ! Do the redistribution on the packed field bundles @@ -310,7 +310,7 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & ! Normalized mapping - assume that each packed field has only one normalization type call ESMF_FieldBundleGet(FBFracSrc, packed_data(mapindex)%mapnorm, field=field_fracsrc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_normalized_field(& + call med_map_field_normalized(& field_src=packed_data(mapindex)%field_src, & field_dst=packed_data(mapindex)%field_dst, & routehandles=routehandles, & @@ -387,10 +387,10 @@ subroutine med_map_packed_field_map(FBSrc, FBDst, FBFracSrc, FBNormOne, & deallocate(fieldlist_src) deallocate(fieldlist_dst) - end subroutine med_map_packed_field_map + end subroutine med_map_field_packed !================================================================================ - subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, & + subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, & field_normsrc, field_normdst, rc) ! ----------------------------------------------- @@ -501,6 +501,83 @@ subroutine med_map_normalized_field(field_src, field_dst, routehandles, maptype, end if end do end if - end subroutine med_map_normalized_field + end subroutine med_map_field_normalized + + !================================================================================ + subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, rc) + + !--------------------------------------------------- + ! map the source field to the destination field + !--------------------------------------------------- + + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR + use ESMF , only : ESMF_Field, ESMF_FieldRegrid + use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL + use ESMF , only : ESMF_REGION_SELECT + use ESMF , only : ESMF_RouteHandle + use esmFlds , only : mapnstod_consd, mapnstod_consf, mapnstod_consd, mapnstod + use esmFlds , only : mapconsd, mapconsf + use med_methods_mod , only : Field_diagnose => med_methods_Field_diagnose + + ! input/output variables + type(ESMF_Field) , intent(in) :: field_src + type(ESMF_Field) , intent(inout) :: field_dst + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(in) :: maptype + character(len=*) , intent(in), optional :: fldname + integer , intent(out) :: rc + + ! local variables + logical :: checkflag = .false. + character(len=CS) :: lfldname + character(len=*), parameter :: subname='(med_map_field) ' + !--------------------------------------------------- + + rc = ESMF_SUCCESS + +#ifdef DEBUG + checkflag = .true. +#endif + lfldname = 'unknown' + if (present(fldname)) lfldname = trim(fldname) + + if (maptype == mapnstod_consd) then + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsd), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + call Field_diagnose(field_dst, lfldname, " --> after consd: ", rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + else if (maptype == mapnstod_consf) then + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsf), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + call Field_diagnose(field_dst, lfldname, " --> after consf: ", rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + else + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(maptype), & + termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + end subroutine med_map_field end module med_map_packed_mod diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 8a91293d1..2600cca18 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -10,7 +10,7 @@ module med_phases_aofluxes_mod use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_init => med_methods_FB_init - use med_map_packed_mod , only : med_map_packed_field_map + use med_map_packed_mod , only : med_map_field_packed use perf_mod , only : t_startf, t_stopf implicit none @@ -155,7 +155,7 @@ subroutine med_phases_aofluxes_run(gcomp, rc) ! 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_packed_field_map( & + 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), & diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index 5774dd8af..d84da40ff 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -14,7 +14,7 @@ module med_phases_prep_atm_mod use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk use med_merge_mod , only : med_merge_auto - use med_map_packed_mod , only : med_map_packed_field_map + use med_map_packed_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, mastertask use esmFlds , only : compatm, compocn, compice, ncomps, compname use esmFlds , only : fldListFr, fldListTo, fldListMed_aoflux @@ -83,7 +83,7 @@ subroutine med_phases_prep_atm(gcomp, rc) !--------------------------------------- do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compatm)) then - call med_map_packed_field_map( & + 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), & @@ -98,7 +98,7 @@ subroutine med_phases_prep_atm(gcomp, rc) !--- map ocean albedos from ocn to atm grid if appropriate !--------------------------------------- if (trim(coupling_mode) == 'cesm') then - call med_map_packed_field_map( & + 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), & @@ -113,7 +113,7 @@ subroutine med_phases_prep_atm(gcomp, rc) !--------------------------------------- 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_packed_field_map( & + 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), & diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 8eee9f7dc..5ad02ccda 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -13,7 +13,7 @@ module med_phases_prep_ice_mod 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_packed_mod , only : med_map_packed_field_map + use med_map_packed_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 @@ -94,7 +94,7 @@ subroutine med_phases_prep_ice(gcomp, rc) ! 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_packed_field_map( & + 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), & diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index c72745dcb..70ad9000a 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -9,8 +9,7 @@ module med_phases_prep_ocn_mod 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_packed_mod , only : med_map_packed_field_create - use med_map_packed_mod , only : med_map_packed_field_map + use med_map_packed_mod , only : med_map_field_packed use med_utils_mod , only : memcheck => med_memcheck use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose @@ -20,7 +19,7 @@ module med_phases_prep_ocn_mod use med_methods_mod , only : FB_average => med_methods_FB_average 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 : fldListFr, fldListTo + use esmFlds , only : fldListTo use esmFlds , only : compocn, compatm, compice, ncomps, compname use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -82,23 +81,9 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) ! map all fields in FBImp that have active ocean coupling if (ncnt > 0) then - if (first_call) then - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,compocn)) then - call med_map_packed_field_create(compocn, & - is_local%wrap%flds_scalar_name, & - fldsSrc=fldListFr(n1)%flds, & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,compocn), & - packed_data=is_local%wrap%packed_data(n1,compocn,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do - first_call = .false. - end if do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compocn)) then - call med_map_packed_field_map( & + 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), & diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 0eb20ebd4..420ac7478 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -149,7 +149,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use esmFlds , only : fldListTo - use med_map_packed_mod , only : med_map_packed_field_map + use med_map_packed_mod , only : med_map_field_packed use med_merge_mod , only : med_merge_auto ! input/output variables @@ -220,7 +220,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) ! 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_packed_field_map( & + 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), & @@ -339,7 +339,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR use med_map_mod , only : med_map_rh_is_created use med_map_mod , only : med_map_field_regrid - use med_map_packed_mod , only : med_map_normalized_field + use med_map_packed_mod , only : med_map_field_normalized ! input/output variables type(ESMF_GridComp) :: gcomp @@ -529,7 +529,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_normalized_field( & + call med_map_field_normalized( & field_src=field_lndIrrig, & field_dst=field_rofIrrig, & routehandles=is_local%wrap%RH(complnd,comprof,:), & @@ -537,7 +537,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_normalized_field( & + call med_map_field_normalized( & field_src=field_lndIrrig0, & field_dst=field_rofIrrig0, & routehandles=is_local%wrap%RH(complnd,comprof,:), & diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index e7559afc4..bc8f362ff 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -9,7 +9,7 @@ module med_phases_prep_wav_mod use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_merge_mod , only : med_merge_auto - use med_map_packed_mod , only : med_map_packed_field_map + use med_map_packed_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, mastertask use esmFlds , only : compwav, ncomps, compname use esmFlds , only : fldListFr, fldListTo @@ -68,7 +68,7 @@ subroutine med_phases_prep_wav(gcomp, rc) ! map to create FBimp(:,compwav) do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compwav)) then - call med_map_packed_field_map( & + call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compwav), & FBFracSrc=is_local%wrap%FBFrac(n1), & From 38a9306a6c19961f1787c7d408b4a887761fdad8 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 22 Oct 2020 17:36:41 -0600 Subject: [PATCH 131/206] more updates to remove all references to old mapping --- mediator/med.F90 | 3 +- mediator/med_map_mod.F90 | 918 ++++++++++++++------------- mediator/med_map_packed_mod.F90 | 583 ----------------- mediator/med_phases_aofluxes_mod.F90 | 2 +- mediator/med_phases_prep_atm_mod.F90 | 5 +- mediator/med_phases_prep_glc_mod.F90 | 377 +++++------ mediator/med_phases_prep_ice_mod.F90 | 2 +- mediator/med_phases_prep_ocn_mod.F90 | 2 +- mediator/med_phases_prep_rof_mod.F90 | 14 +- mediator/med_phases_prep_wav_mod.F90 | 2 +- 10 files changed, 694 insertions(+), 1214 deletions(-) delete mode 100644 mediator/med_map_packed_mod.F90 diff --git a/mediator/med.F90 b/mediator/med.F90 index 820049fc8..185416c4f 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1577,8 +1577,7 @@ subroutine DataInitialize(gcomp, rc) use med_phases_aofluxes_mod , only : med_phases_aofluxes_run use med_phases_profile_mod , only : med_phases_profile use med_diag_mod , only : med_diag_zero, med_diag_init - use med_map_mod , only : med_map_MapNorm_init, med_map_RouteHandles_init - use med_map_packed_mod , only : med_map_packed_field_create + use med_map_mod , only : med_map_mapnorm_init, med_map_routehandles_init, med_map_packed_field_create use med_io_mod , only : med_io_init ! input/output variables diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 0743d3241..067fa3cd4 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -9,12 +9,8 @@ module med_map_mod use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd use esmFlds , only : ncomps, compatm, compice, compocn, compname use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod - use esmFlds , only : mapuv_with_cart3d - use esmFlds , only : med_fldList_entry_type - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : coupling_mode - use med_internalstate_mod , only : InternalState - use med_internalstate_mod , only : logunit, mastertask + use esmFlds , only : mapuv_with_cart3d, fldListFr, coupling_mode + use med_internalstate_mod , only : InternalState, logunit, mastertask use med_constants_mod , only : ispval_mask => med_constants_ispval_mask use med_constants_mod , only : czero => med_constants_czero use med_constants_mod , only : dbug_flag => med_constants_dbug_flag @@ -36,21 +32,19 @@ module med_map_mod ! public routines public :: med_map_routehandles_init - public :: med_map_RH_is_created - public :: med_map_MapNorm_init - public :: med_map_FB_Regrid_Norm - public :: med_map_FB_Field_Regrid - public :: med_map_Field_Regrid + public :: med_map_rh_is_created + public :: med_map_mapnorm_init + public :: med_map_packed_field_create + public :: med_map_field_packed + public :: med_map_field_normalized + public :: med_map_field + public :: med_map_fb_field_regrid ! TODO: do we still need this? interface med_map_routehandles_init module procedure med_map_routehandles_init_esmflds module procedure med_map_routehandles_init_field end interface - interface med_map_FB_Regrid_norm - module procedure med_map_FB_Regrid_Norm_All - end interface - interface med_map_RH_is_created module procedure med_map_RH_is_created_RH3d module procedure med_map_RH_is_created_RH1d @@ -355,7 +349,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) end subroutine med_map_RouteHandles_init_esmflds -!================================================================================ + !================================================================================ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) !--------------------------------------------- @@ -530,7 +524,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route end subroutine med_map_routehandles_init_field -!================================================================================ + !================================================================================ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) use ESMF , only : ESMF_RouteHandle @@ -594,9 +588,8 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) end function med_map_RH_is_created_RH1d -!================================================================================ - - subroutine med_map_MapNorm_init(gcomp, llogunit, rc) + !================================================================================ + subroutine med_map_mapnorm_init(gcomp, llogunit, rc) !--------------------------------------- ! Initialize unity normalization field bundle @@ -618,7 +611,7 @@ subroutine med_map_MapNorm_init(gcomp, llogunit, rc) character(len=CS) :: normname character(len=1) :: cn1,cn2,cm real(R8), pointer :: dataptr(:) - character(len=*),parameter :: subname='(module_MED_MAP:MapNorm_init)' + character(len=*),parameter :: subname='(med_map_mapnorm_init)' !----------------------------------------------------------- call t_startf('MED:'//subname) @@ -670,7 +663,7 @@ subroutine med_map_MapNorm_init(gcomp, llogunit, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr(:) = 1.0_R8 - call med_map_FB_Field_Regrid(FBTmp, trim(normname), is_local%wrap%FBNormOne(n1,n2,m), trim(normname), & + call med_map_fb_field_regrid(FBTmp, trim(normname), is_local%wrap%FBNormOne(n1,n2,m), trim(normname), & is_local%wrap%RH(n1,n2,:), m, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -688,446 +681,512 @@ subroutine med_map_MapNorm_init(gcomp, llogunit, rc) endif call t_stopf('MED:'//subname) - end subroutine med_map_MapNorm_init + end subroutine med_map_mapnorm_init !================================================================================ + subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & + fldsSrc, FBSrc, FBDst, packed_data, rc) - subroutine med_map_FB_Regrid_Norm_All(fldsSrc, srccomp, destcomp, & - FBSrc, FBDst, FBFracSrc, FBNormOne, RouteHandles, string, rc) - - ! ---------------------------------------------- - ! Map field bundles with appropriate fraction weighting - ! ---------------------------------------------- - - use NUOPC , only: NUOPC_IsConnected - use ESMF , only: ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only: ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR - use ESMF , only: ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use ESMF , only: ESMF_FieldBundle, ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet - use ESMF , only: ESMF_RouteHandle, ESMF_FieldRegrid - use ESMF , only: ESMF_REGION_SELECT, ESMF_REGION_TOTAL - use ESMF , only: ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated - use ESMF , only: ESMF_FieldDestroy, ESMF_FieldCreate - use ESMF , only: ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL - use ESMF , only: ESMF_REGION_SELECT + use ESMF + use esmFlds , only : med_fldList_entry_type, nmappers + use esmFlds , only : ncomps, compatm, compice, compocn, compname, mapnames + use med_internalstate_mod , only : packed_data_type ! input/output variables - type(med_fldList_entry_type) , pointer :: fldsSrc(:) - integer , intent(in) :: srccomp - integer , intent(in) :: destcomp - type(ESMF_FieldBundle) , intent(inout) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_FieldBundle) , intent(in) :: FBFracSrc - type(ESMF_FieldBundle) , intent(in) :: FBNormOne(:) - type(ESMF_RouteHandle) , intent(inout) :: RouteHandles(:) - character(len=*), optional , intent(in) :: string - integer , intent(out) :: rc + integer , intent(in) :: destcomp + character(len=*) , intent(in) :: flds_scalar_name + type(med_fldList_entry_type) , pointer :: fldsSrc(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(in) :: FBSrc + type(ESMF_FieldBundle) , intent(inout) :: FBDst + type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types + integer , intent(out) :: rc ! local variables - integer :: i, n, k - integer :: lrank - character(len=CS) :: lstring - integer :: mapindex - character(len=CS) :: mapnorm - character(len=CS) :: fldname - type(ESMF_Mesh) :: lmesh - type(ESMF_Field) :: srcField - type(ESMF_Field) :: dstField - type(ESMF_Field) :: lfield - type(ESMF_Field) :: frac_field_src - type(ESMF_Field) :: frac_field_dst - real(R8), allocatable :: data_srctmp(:) - real(R8), allocatable :: data_srctmp_1d(:) - real(R8), allocatable :: data_srctmp_2d(:,:) - real(R8), pointer :: data_src_1d(:) - real(R8), pointer :: data_src_2d(:,:) - real(R8), pointer :: data_frac(:) - real(R8), pointer :: data_norm(:) - logical :: used_cart3d_for_uvmapping - logical :: frac_field_created - type(ESMF_Field) :: usrc,vsrc - type(ESMF_Field) :: udst,vdst - 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 :: checkflag = .false. - character(len=*), parameter :: subname='(module_MED_Map:med_map_Regrid_Norm)' - !------------------------------------------------------------------------------- - - call t_startf('MED:'//subname) - call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) - call memcheck(subname, 1, mastertask) - -#ifdef DEBUG - checkflag = .true. -#endif - - !--------------------------------------- - - if (present(string)) then - lstring = trim(string) - else - lstring = " " - endif + integer :: nf, nu, ns + integer, allocatable :: npacked(:) + integer :: fieldcount + type(ESMF_Field) :: lfield + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + real(r8), pointer :: ptrsrc_packed(:,:) => null() + real(r8), pointer :: ptrdst_packed(:,:) => null() + integer :: lsize_src + integer :: lsize_dst + type(ESMF_Mesh) :: lmesh_src + type(ESMF_Mesh) :: lmesh_dst + integer :: mapindex + type(ESMF_Field), pointer :: fieldlist_src(:) => null() + type(ESMF_Field), pointer :: fieldlist_dst(:) => null() + character(CL), allocatable :: fieldNameList(:) + character(len=*), parameter :: subname=' (med_packed_fieldbundles_create) ' + !----------------------------------------------------------- rc = ESMF_SUCCESS - !--------------------------------------- - ! First - reset the field bundle on the destination grid to zero - !--------------------------------------- - - ! call FB_reset(FBDst, value=czero, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! Loop over all fields in the source field bundle and map them to - ! the destination field bundle accordingly - !--------------------------------------- - - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//" *** mapping from "//trim(compname(srccomp))//" to "//& - trim(compname(destcomp))//" ***", ESMF_LOGMSG_INFO) - end if + ! Get field count for both FBsrc and FBdst + call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! get fields in source and destination field bundles + allocate(fieldlist_src(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist_dst(fieldcount)) + call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! field names are the same for the source and destination field bundles + allocate(fieldnamelist(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldnamelist=fieldnamelist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine local size and mesh of source fields + ! Allocate a source fortran pointer for the new packed field bundle + ! Create the packed source field bundle + call ESMF_FieldGet(fieldlist_src(1), mesh=lmesh_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - used_cart3d_for_uvmapping = .false. - do n = 1,size(fldsSrc) + ! Determine local size of destination fields + ! Allocate a destination fortran pointer for the new packed field bundle + ! Create the packed source field bundle + call ESMF_FieldGet(fieldlist_dst(1), mesh=lmesh_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Determine if field is a scalar - and if so go to next iternation - fldname = fldsSrc(n)%shortname - if (fldname == flds_scalar_name) CYCLE + ! Gather all fields that will be mapped with a target map index into a packed field + ! Calculated size of packed field based on the fact that some fields have + ! ungridded dimensions and need to unwrap them into separate fields for the + ! purposes of packing - ! Determine if there is a map index and if its zero go to next iteration - mapindex = fldsSrc(n)%mapindex(destcomp) - if (mapindex == 0) CYCLE - mapnorm = fldsSrc(n)%mapnorm(destcomp) + ! Allocate memory to keep tracked of packing index for each mapping type + allocate(npacked(nmappers)) + npacked(:) = 0 - !Determine if field is FBSrc or FBDst or connected - and if not go to next iteration - if (.not. FB_FldChk(FBSrc, trim(fldname), rc=rc)) then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//" field not found in FBSrc: "//trim(fldname), ESMF_LOGMSG_INFO) - end if - CYCLE - else if (.not. FB_FldChk(FBDst, trim(fldname), rc=rc)) then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//" field not found in FBDst: "//trim(fldname), ESMF_LOGMSG_INFO) - end if - CYCLE - end if + if (mastertask) write(logunit,*) + ! Loop over mapping types + do mapindex = 1,nmappers - ! ------------------- - ! Error checks - ! ------------------- - - if (dbug_flag > 2) then - if (.not. FB_FldChk(FBSrc, fldname, rc=rc)) then - call ESMF_LogWrite(trim(subname)//" field not found in FBSrc: "//trim(fldname), ESMF_LOGMSG_INFO) - else if (.not. FB_FldChk(FBDst, fldname, rc=rc)) then - call ESMF_LogWrite(trim(subname)//" field not found in FBDst: "//trim(fldname), ESMF_LOGMSG_INFO) - else if (.not. med_map_RH_is_created(RouteHandles,mapindex,rc=rc)) then - call ESMF_LogWrite(trim(subname)//trim(lstring)//& - ": ERROR RH not available for "//mapnames(mapindex)//": fld="//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - end if + ! Allocate the fldindex attribute of packed_indices if needed + if (.not. allocated(packed_data(mapindex)%fldindex)) then + allocate(packed_data(mapindex)%fldindex(fieldcount)) + packed_data(mapindex)%fldindex(:) = -999 end if - ! ------------------- - ! Do cart3d mapping for u and v fields from atm if appropriate - ! ------------------- + ! Loop over the fields in FBSrc + do nf = 1, fieldCount + + ! Loop over the fldsSrc types + do ns = 1,size(fldsSrc) + + if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & + fldsSrc(ns)%shortname /= flds_scalar_name .and. & + trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then + + ! Determine mapnorm - the assumption is that there is only one + ! mapnorm type for a source packed field bundle + if (npacked(mapindex) == 0) then + packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) + else + if (fldsSrc(ns)%mapnorm(destcomp) /= packed_data(mapindex)%mapnorm) then + call ESMF_LogWrite(trim(subname)//& + ": ERROR mapnorm "//trim(fldsSrc(ns)%mapnorm(destcomp))//" is not equal to "// & + trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & + ESMF_LOGMSG_ERROR, rc=rc) + rc = ESMF_FAILURE + return + end if + end if - if (mapuv_with_cart3d) then - if ((trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v')) then - if (.not. used_cart3d_for_uvmapping) then - mapindex = fldsSrc(n)%mapindex(destcomp) - mapnorm = fldsSrc(n)%mapnorm(destcomp) - call ESMF_FieldBundleGet(FBSrc, fieldName='Sa_u', field=usrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBSrc, fieldName='Sa_v', field=vsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBDst, fieldName='Sa_u', field=udst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBDst, fieldName='Sa_v', field=vdst, rc=rc) + ! Determine mapping of indices into packed field bundle + ! Get source field + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + do nu = 1,ungriddedUBound(1) + npacked(mapindex) = npacked(mapindex) + 1 + if (nu == 1) then + packed_data(mapindex)%fldindex(nf) = npacked(mapindex) + end if + end do + else + npacked(mapindex) = npacked(mapindex) + 1 + packed_data(mapindex)%fldindex(nf) = npacked(mapindex) + end if - call ESMF_LogWrite(trim(subname)//" --> remapping "//trim(fldname)//" with "//trim(mapnames(mapindex)), & - ESMF_LOGMSG_INFO) + if (mastertask) then + write(logunit,'(5(a,2x),2x,i4)') trim(subname)//& + 'Packed field: destcomp,mapping,mapnorm,fldname,index: ', & + trim(compname(destcomp)), & + trim(mapnames(mapindex)), & + trim(fldsSrc(ns)%mapnorm(destcomp)), & + trim(fieldnamelist(nf)), & + packed_data(mapindex)%fldindex(nf) + end if - call med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + end if! end if source field is mapped to destination field with mapindex + end do ! end loop over FBSrc fields + end do ! end loop over fldSrc elements - used_cart3d_for_uvmapping = .true. - end if - CYCLE - end if - end if + ! Create the source and destination packed fields for mapindex + if (npacked(mapindex) > 0) then + allocate(ptrsrc_packed(npacked(mapindex), lsize_src)) + packed_data(mapindex)%field_src = ESMF_FieldCreate(lmesh_src, & + ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! ------------------- - ! Get the source and destination fields - ! ------------------- + allocate(ptrdst_packed(npacked(mapindex), lsize_dst)) + packed_data(mapindex)%field_dst = ESMF_FieldCreate(lmesh_dst, & + ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//" --> remapping "//trim(fldname)//" with "//trim(mapnames(mapindex)), & - ESMF_LOGMSG_INFO) + packed_data(mapindex)%field_fracsrc = ESMF_FieldCreate(lmesh_src, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + packed_data(mapindex)%field_fracdst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) end if + end do ! end loop over mapindex - ! ------------------- - ! Do the mapping - ! ------------------- + deallocate(npacked) + deallocate(fieldlist_src) + deallocate(fieldlist_dst) - call t_startf('MED:'//subname//'time1') - call ESMF_FieldBundleGet(FBSrc, fieldName=trim(fldname), field=srcfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBDst, fieldName=trim(fldname), field=dstfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//subname//'time1') + end subroutine med_map_packed_field_create - if (mapindex == mapfcopy) then + !================================================================================ + subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, routehandles, rc) - call t_startf('MED:'//subname//'time2') - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapfcopy), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//subname//'time2') + ! ----------------------------------------------- + ! Do the redistribution on the packed field bundles + ! ----------------------------------------------- - else + use ESMF + use esmFlds , only : nmappers, mapfcopy + use med_internalstate_mod , only : packed_data_type - ! Determine the normalization for the map - mapnorm = fldsSrc(n)%mapnorm(destcomp) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FBSrc + type(ESMF_FieldBundle) , intent(inout) :: FBDst + type(ESMF_FieldBundle) , intent(in) :: FBNormOne(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(in) :: FBFracSrc ! fraction field bundle for source + type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(out) :: rc - if ( trim(mapnorm) /= 'unset' .and. trim(mapnorm) /= 'one' .and. trim(mapnorm) /= 'none') then + ! local variables + integer :: nf, nu, np, n + integer :: fieldcount + integer :: mapindex + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: dataptr2d_packed(:,:) => null() + type(ESMF_Field) :: lfield + type(ESMF_Field) :: field_fracsrc + type(ESMF_Field), pointer :: fieldlist_src(:) => null() + type(ESMF_Field), pointer :: fieldlist_dst(:) => null() + character(CL), allocatable :: fieldNameList(:) + real(r8), pointer :: data_norm(:) => null() + real(r8), pointer :: data_dst(:,:) => null() + character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + !----------------------------------------------------------- - call ESMF_FieldGet(srcfield, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + rc = ESMF_SUCCESS - ! get a pointer to source field data in FBSrc - if (lrank == 1) then - call ESMF_FieldGet(srcfield, farrayPtr=data_src_1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (lrank == 2) then - call ESMF_FieldGet(srcfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (gridToFieldMap(1) /= 2) then - call ESMF_LogWrite(trim(subname)//" fldname= "//trim(fldname)//& - "has gridTofieldMap not equal to 2", ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - end if - call ESMF_FieldGet(srcfield, farrayPtr=data_src_2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + ! Get field count for both FBsrc and FBdst + call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! allocate memory for a save array if not already allocated - if (lrank == 1) then - if (.not. allocated(data_srctmp_1d) .or. size(data_srctmp_1d) /= size(data_src_1d)) then - if (allocated(data_srctmp_1d)) then - deallocate(data_srctmp_1d) - endif - allocate(data_srctmp_1d(size(data_src_1d))) - endif - elseif (lrank == 2) then - if (.not. allocated(data_srctmp_2d) .or. size(data_srctmp_2d) /= size(data_src_2d)) then - if (allocated(data_srctmp_2d)) then - deallocate(data_srctmp_2d) - endif - allocate(data_srctmp_2d(size(data_src_2d,dim=1), size(data_src_2d,dim=2))) - endif - end if + allocate(fieldlist_src(fieldcount)) + call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! get a pointer to the array of the normalization on the source grid - this must - ! be the same size is as fraction on the source grid - call FB_GetFldPtr(FBFracSrc, trim(mapnorm), data_frac, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist_dst(fieldcount)) + call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! copy data_src to data_srctmp then multiply data_src by fraction - if (lrank == 1) then - data_srctmp_1d(:) = data_src_1d(:) - data_src_1d(:) = data_src_1d(:) * data_frac(:) - elseif (lrank == 2) then - if (size(data_frac) /= size(data_src_2d,dim=2)) then - write(6,*)'ERROR: size(frac) = ',size(data_frac) - write(6,*)'ERROR: size(data_src_2d,dim=1),size(data_src_2d,dim=2) = ',& - size(data_src_2d,dim=1),size(data_src_2d,dim=2) - call ESMF_LogWrite(trim(subname)//" fldname= "//trim(fldname)//& - "size of frac not equal to size of distributed data", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - end if - data_srctmp_2d(:,:) = data_src_2d(:,:) - do i = 1,size(data_frac) - data_src_2d(:,i) = data_src_2d(:,i) * data_frac(i) - end do - end if + ! Loop over mapping types + do mapindex = 1,nmappers - ! regrid field with name fldname from FBsrc to FBDst - call med_map_Field_Regrid (srcfield, dstfield, RouteHandles, mapindex, subname//trim(fldname), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! restore original value - if (lrank == 1) then - data_src_1d(:) = data_srctmp_1d(:) - elseif (lrank == 2) then - data_src_2d(:,:) = data_srctmp_2d(:,:) - end if + ! If packed field is created + if (ESMF_FieldIsCreated(packed_data(mapindex)%field_src)) then - ! regrid fraction from source to dest - if (.not. ESMF_FieldIsCreated(frac_field_dst)) then - ! get fraction field on source mesh - call ESMF_FieldBundleGet(FBFracSrc, mapnorm, field=frac_field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! ----------------------------------- + ! Copy the src fields into the packed field bundle + ! ----------------------------------- - ! create fraction field on destination mesh - call ESMF_FieldGet(dstfield, mesh=lmesh, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_field_dst = ESMF_FieldCreate(lmesh, ESMF_TYPEKIND_R8, name=mapnorm, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call t_startf('MED:'//trim(subname)//' copy from src') - ! regrid fraction field from source to destination - call med_map_Field_Regrid(frac_field_src, frac_field_dst, RouteHandles, mapindex, subname//trim(fldname), rc=rc) + ! First get the pointer for the packed source data + call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayptr=dataptr2d_packed, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get pointer to mapped fraction - call ESMF_FieldGet(frac_field_dst, farrayPtr=data_norm, rc=rc) + ! Now do the copy + do nf = 1,fieldcount + ! Get the indices into the packed data structure + np = packed_data(mapindex)%fldindex(nf) + if (np > 0) then + call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + dataptr2d_packed(np+nu-1,:) = dataptr2d(nu,:) + end do + else + call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d_packed(np,:) = dataptr1d(:) + end if end if + end do + call t_stopf('MED:'//trim(subname)//' copy from src') - ! normalize destination mapped values by the reciprocal of the mapped fraction - call norm_field_dest(trim(fldname), dstfield, data_norm, rc) - - if (dbug_flag > 1) then - call FB_Field_diagnose(FBDst, fldname, " --> after frac: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + ! ----------------------------------- + ! Do the mapping + ! ----------------------------------- - else if (trim(mapnorm) == 'one' .or. trim(mapnorm) == 'none') then + call t_startf('MED:'//trim(subname)//' map') + if (mapindex == mapfcopy) then - !------------------------------------------------- - ! unity or no normalization - !------------------------------------------------- + ! Mapping is redistribution + call ESMF_FieldRedist(& + packed_data(mapindex)%field_src, & + packed_data(mapindex)%field_dst, & + routehandles(mapindex), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! map source field to destination grid - call med_map_Field_Regrid (srcfield, dstfield, RouteHandles, mapindex, subname//trim(fldname), rc=rc) + else if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & + trim(packed_data(mapindex)%mapnorm) /= 'none') then + + ! Normalized mapping - assume that each packed field has only one normalization type + call ESMF_FieldBundleGet(FBFracSrc, packed_data(mapindex)%mapnorm, field=field_fracsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field_normalized(& + field_src=packed_data(mapindex)%field_src, & + field_dst=packed_data(mapindex)%field_dst, & + routehandles=routehandles, & + maptype=mapindex, & + field_normsrc=field_fracsrc, & + field_normdst=packed_data(mapindex)%field_fracdst, rc=rc) + + else if ( trim(packed_data(mapindex)%mapnorm) == 'one' .or. trim(packed_data(mapindex)%mapnorm) == 'none') then + + ! Mapping with no normalization that is not redistribution + call med_map_field (& + field_src=packed_data(mapindex)%field_src, & + field_dst=packed_data(mapindex)%field_dst, & + routehandles=routehandles, & + maptype=mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! obtain unity normalization factor and multiply interpolated field by reciprocal of normalization factor - if (trim(mapnorm) == 'one') then + ! Obtain unity normalization factor and multiply + ! interpolated field by reciprocal of normalization factor + if (trim(packed_data(mapindex)%mapnorm) == 'one') then call ESMF_FieldBundleGet(FBNormOne(mapindex), fieldName='one', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayPtr=data_norm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(data_dst,dim=2) + if (data_norm(n) == 0.0_r8) then + data_dst(:,n) = 0.0_r8 + else + data_dst(:,n) = data_dst(:,n)/data_norm(n) + end if + end do + end if - call norm_field_dest(trim(fldname), dstfield, data_norm, rc) - end if ! mapnorm is 'one' + end if + call t_stopf('MED:'//trim(subname)//' map') - end if ! mapnorm is 'one' or 'nne' + ! ----------------------------------- + ! Copy the destination packed field bundle into the destination unpacked field bundle + ! ----------------------------------- - end if ! mapindex is not mapfcopy and field exists + call t_startf('MED:'//trim(subname)//' copy to dest') - if (dbug_flag > 1) then - call FB_Field_diagnose(FBDst, fldname, & - string=trim(subname) //' FBImp('//trim(compname(srccomp))//','//trim(compname(destcomp))//') ', rc=rc) + ! First get the pointer for the packed destination data + call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayptr=dataptr2d_packed, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - end do ! loop over fields + ! Now do the copy back to FBDst + do nf = 1,fieldcount + ! Get the indices into the packed data structure + np = packed_data(mapindex)%fldindex(nf) + if (np > 0) then + call ESMF_FieldGet(fieldlist_dst(nf), ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nu = 1,ungriddedUBound(1) + dataptr2d(nu,:) = dataptr2d_packed(np+nu-1,:) + end do + else + call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = dataptr2d_packed(np,:) + end if + end if + end do + call t_stopf('MED:'//trim(subname)//' copy to dest') - if (ESMF_FieldIsCreated(frac_field_dst)) then - call ESMF_FieldDestroy(frac_field_dst, noGarbage=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - if (allocated(data_srctmp)) deallocate(data_srctmp) + end if + end do ! end of loop over mapindex - call t_stopf('MED:'//subname) + deallocate(fieldlist_src) + deallocate(fieldlist_dst) - end subroutine med_map_FB_Regrid_Norm_All + end subroutine med_map_field_packed !================================================================================ + subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, & + field_normsrc, field_normdst, rc) - subroutine med_map_FB_Field_Regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex,rc) - - ! ---------------------------------------------- - ! Regrid a field in a field bundle to another field in a field bundle - ! ---------------------------------------------- - - use ESMF , only : ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field - use perf_mod , only : t_startf, t_stopf + ! ----------------------------------------------- + ! Map a normalized field + ! ----------------------------------------------- - type(ESMF_FieldBundle), intent(in) :: FBin - character(len=*) , intent(in) :: fldin - type(ESMF_FieldBundle), intent(inout) :: FBout - character(len=*) , intent(in) :: fldout - type(ESMF_RouteHandle), intent(inout) :: RouteHandles(:) - integer , intent(in) :: mapindex - integer , intent(out) :: rc - ! ---------------------------------------------- + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_RouteHandle + use ESMF , only : ESMF_SUCCESS - ! local - type(ESMF_Field) :: field1, field2 - character(CS) :: lfldname - character(len=*),parameter :: subname='(med_map_FB_Field_Regrid)' - ! ---------------------------------------------- + ! input/output variables + type(ESMF_Field) , intent(in) :: field_src + type(ESMF_Field) , intent(inout) :: field_dst + type(ESMF_Field) , intent(in) :: field_normsrc + type(ESMF_Field) , intent(inout) :: field_normdst + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(in) :: maptype + integer , intent(out) :: rc - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) - endif + ! local variables + integer :: n + real(r8), pointer :: data_src2d(:,:) => null() + real(r8), pointer :: data_dst2d(:,:) => null() + real(r8), pointer :: data_srctmp2d(:,:) => null() + real(r8), pointer :: data_src1d(:) => null() + real(r8), pointer :: data_dst1d(:) => null() + real(r8), pointer :: data_srctmp1d(:) => null() + real(r8), pointer :: data_normsrc(:) => null() + real(r8), pointer :: data_normdst(:) => null() + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + integer :: lsize_src + integer :: lsize_dst + character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + !----------------------------------------------------------- - call t_startf(subname) rc = ESMF_SUCCESS - lfldname=trim(fldin)//'->'//trim(fldout) + ! get a pointer (data_fracsrc) to the normalization array + ! get a pointer (data_src) to source field data in FBSrc + ! copy data_src to data_srctmp - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - end if - if (FB_FldChk(FBin , trim(fldin) , rc=rc) .and. & - FB_FldChk(FBout, trim(fldout), rc=rc)) then + ! normalize data_src by data_fracsrc - call FB_GetFieldByName(FBin, trim(fldin), field1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_normsrc, farrayPtr=data_normsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + lsize_src = size(data_normsrc) - call FB_GetFieldByName(FBout, trim(fldout), field2, rc=rc) + call ESMF_FieldGet(field_src, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(field_src, farrayPtr=data_src2d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_map_Field_Regrid(field1, field2, RouteHandles, mapindex, subname//trim(lfldname), rc=rc) + allocate(data_srctmp2d(size(data_src2d,dim=1), lsize_src)) + data_srctmp2d(:,:) = data_src2d(:,:) + do n = 1,lsize_src + data_src2d(:,n) = data_src2d(:,n) * data_normsrc(n) + end do + else + call ESMF_FieldGet(field_src, farrayPtr=data_src1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(data_srctmp1d(lsize_src)) + data_srctmp1d(:) = data_src1d(:) + do n = 1,lsize_src + data_src1d(n) = data_src1d(n) * data_normsrc(n) + end do + end if + + ! regrid normalized packed source field + call med_map_field (field_src=field_src, field_dst=field_dst, routehandles=routehandles, maptype=maptype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! restore original value to packed source field + if (ungriddedUbound(1) > 0) then + data_src2d(:,:) = data_srctmp2d(:,:) + deallocate(data_srctmp2d) else - call ESMF_LogWrite(trim(subname)//" field not found: "//& - trim(fldin)//","//trim(fldout), ESMF_LOGMSG_INFO) - endif + data_src1d(:) = data_srctmp1d(:) + deallocate(data_srctmp1d) + end if - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - call t_stopf(subname) + ! regrid normalization field from source to destination + call med_map_field(field_src=field_normsrc, field_dst=field_normdst, routehandles=routehandles, maptype=maptype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - end subroutine med_map_FB_Field_Regrid + ! get pointer to mapped fraction and normalize + ! destination mapped values by the reciprocal of the mapped fraction + call ESMF_FieldGet(field_normdst, farrayPtr=data_normdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + lsize_dst = size(data_normdst) - !================================================================================ + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(field_dst, farrayPtr=data_dst2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,lsize_dst + if (data_normdst(n) == 0.0_r8) then + data_dst2d(:,n) = 0.0_r8 + else + data_dst2d(:,n) = data_dst2d(:,n)/data_normdst(n) + end if + end do + else + call ESMF_FieldGet(field_dst, farrayPtr=data_dst1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,lsize_dst + if (data_normdst(n) == 0.0_r8) then + data_dst1d(n) = 0.0_r8 + else + data_dst1d(n) = data_dst1d(n)/data_normdst(n) + end if + end do + end if + end subroutine med_map_field_normalized - subroutine med_map_Field_Regrid (srcfield, dstfield, RouteHandles, mapindex, fldname, rc) + !================================================================================ + subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, rc) !--------------------------------------------------- ! map the source field to the destination field !--------------------------------------------------- - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR - use ESMF , only : ESMF_Field, ESMF_FieldRegrid - use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL - use ESMF , only : ESMF_REGION_SELECT - use ESMF , only : ESMF_RouteHandle + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR + use ESMF , only : ESMF_Field, ESMF_FieldRegrid + use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL + use ESMF , only : ESMF_REGION_SELECT + use ESMF , only : ESMF_RouteHandle + use esmFlds , only : mapnstod_consd, mapnstod_consf, mapnstod_consd, mapnstod + use esmFlds , only : mapconsd, mapconsf + use med_methods_mod , only : Field_diagnose => med_methods_Field_diagnose ! input/output variables - type(ESMF_Field) , intent(in) :: srcfield - type(ESMF_Field) , intent(inout) :: dstfield - type(ESMF_RouteHandle) , intent(inout) :: RouteHandles(:) - integer , intent(in) :: mapindex + type(ESMF_Field) , intent(in) :: field_src + type(ESMF_Field) , intent(inout) :: field_dst + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) + integer , intent(in) :: maptype character(len=*) , intent(in), optional :: fldname - integer , intent(out) :: rc + integer , intent(out) :: rc ! local variables logical :: checkflag = .false. character(len=CS) :: lfldname - character(len=*), parameter :: subname='(module_MED_Map:med_map_Field_Regrid)' + character(len=*), parameter :: subname='(med_map_field) ' !--------------------------------------------------- rc = ESMF_SUCCESS @@ -1136,108 +1195,107 @@ subroutine med_map_Field_Regrid (srcfield, dstfield, RouteHandles, mapindex, fld checkflag = .true. #endif lfldname = 'unknown' - if (present(fldname)) then - lfldname = trim(fldname) - endif + if (present(fldname)) lfldname = trim(fldname) - if (mapindex == mapnstod_consd) then - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapnstod), & + if (maptype == mapnstod_consd) then + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call Field_diagnose(dstfield, lfldname, " --> after nstod: ", rc=rc) + call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapconsd), & + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsd), & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call Field_diagnose(dstfield, lfldname, " --> after consd: ", rc=rc) + call Field_diagnose(field_dst, lfldname, " --> after consd: ", rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - else if (mapindex == mapnstod_consf) then - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapnstod), & + else if (maptype == mapnstod_consf) then + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call Field_diagnose(dstfield, lfldname, " --> after nstod: ", rc=rc) + call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapconsf), & + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsf), & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call Field_diagnose(dstfield, lfldname, " --> after consf: ", rc=rc) + call Field_diagnose(field_dst, lfldname, " --> after consf: ", rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if else - call ESMF_FieldRegrid(srcfield, dstfield, routehandle=RouteHandles(mapindex), & + call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(maptype), & termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - end subroutine med_map_Field_Regrid + end subroutine med_map_field !================================================================================ + subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex,rc) - subroutine norm_field_dest (fldname, dstfield, frac, rc) + ! ---------------------------------------------- + ! Regrid a field in a field bundle to another field in a field bundle + ! ---------------------------------------------- - use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field + use perf_mod , only : t_startf, t_stopf - !------------------------------------------------ - ! normalize destination mapped values by the reciprocal of the - ! mapped fraction or 'one' - ! ------------------------------------------------ + type(ESMF_FieldBundle), intent(in) :: FBin + character(len=*) , intent(in) :: fldin + type(ESMF_FieldBundle), intent(inout) :: FBout + character(len=*) , intent(in) :: fldout + type(ESMF_RouteHandle), intent(inout) :: RouteHandles(:) + integer , intent(in) :: mapindex + integer , intent(out) :: rc + ! ---------------------------------------------- - ! input/output variables - character(len=*) , intent(in) :: fldname - type(ESMF_Field) , intent(inout) :: dstfield - real(r8) , intent(in) :: frac(:) - integer , intent(out) :: rc + ! local + type(ESMF_Field) :: field1, field2 + character(CS) :: lfldname + character(len=*),parameter :: subname='(med_map_fb_field_regrid)' + ! ---------------------------------------------- - ! local variables - integer :: i,n - real(R8), pointer :: data1d(:) - real(R8), pointer :: data2d(:,:) - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - ! ------------------------------------------------ + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) + endif + call t_startf(subname) rc = ESMF_SUCCESS - call ESMF_FieldGet(dstfield, ungriddedUBound=ungriddedUbound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + lfldname=trim(fldin)//'->'//trim(fldout) + + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if + if (FB_FldChk(FBin , trim(fldin) , rc=rc) .and. FB_FldChk(FBout, trim(fldout), rc=rc)) then - if (ungriddedUBound(1) > 0) then - call ESMF_FieldGet(dstfield, farrayPtr=data2d, rc=rc) + call FB_GetFieldByName(FBin, trim(fldin), field1, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,ungriddedUbound(1) - do i = 1,size(data2d,dim=2) - if (frac(i) == 0.0_r8) then - data2d(n,i) = 0.0_r8 - else - data2d(n,i) = data2d(n,i)/frac(i) - end if - end do - end do - else - call ESMF_FieldGet(dstfield, farrayPtr=data1d, rc=rc) + + call FB_GetFieldByName(FBout, trim(fldout), field2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do i= 1,size(data1d) - if (frac(i) == 0.0_R8) then - data1d(i) = 0.0_R8 - else - data1d(i) = data1d(i)/frac(i) - endif - end do - end if - call Field_diagnose(dstfield, fldname, " --> after frac: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field(field_src=field1, field_dst=field2, routehandles=routehandles, maptype=mapindex, & + fldname=trim(lfldname), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//" field not found: "//& + trim(fldin)//","//trim(fldout), ESMF_LOGMSG_INFO) + endif - end subroutine norm_field_dest + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + call t_stopf(subname) - !================================================================================ + end subroutine med_map_fb_field_regrid + !================================================================================ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 @@ -1345,7 +1403,11 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) enddo ! Map all thee vector fields at once from source to destination grid - call med_map_Field_Regrid(field3d_src, field3d_dst, RouteHandles, mapindex, subname, rc=rc) + call med_map_field(& + field_src=field3d_src, & + field_dst=field3d_dst, & + routehandles=routehandles, & + maptype=mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Rotate destination data back from cart3d to original diff --git a/mediator/med_map_packed_mod.F90 b/mediator/med_map_packed_mod.F90 deleted file mode 100644 index 01ce3f7c4..000000000 --- a/mediator/med_map_packed_mod.F90 +++ /dev/null @@ -1,583 +0,0 @@ -module med_map_packed_mod - - !------------------------------------------ - ! Create packed field bundles needed for mapping - ! and map the packed field bundles - !------------------------------------------ - - use med_kind_mod , only : cx=>shr_kind_cx, cs=>shr_kind_cs, cl=>shr_kind_cl, i8=>shr_kind_i8, r8=>shr_kind_r8 - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_utils_mod , only : chkerr => med_utils_ChkErr - use perf_mod , only : t_startf, t_stopf - use med_internalstate_mod, only : mastertask, logunit - - use shr_sys_mod, only : shr_sys_flush - - implicit none - private - - public :: med_map_packed_field_create - public :: med_map_field_packed - public :: med_map_field_normalized - public :: med_map_field - - character(*),parameter :: u_FILE_u = & - __FILE__ - -!=============================================================================== -contains -!=============================================================================== - - subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & - fldsSrc, FBSrc, FBDst, packed_data, rc) - - use ESMF - use esmFlds , only : med_fldList_entry_type, nmappers - use esmFlds , only : ncomps, compatm, compice, compocn, compname, mapnames - use med_internalstate_mod , only : packed_data_type - - ! input/output variables - integer , intent(in) :: destcomp - character(len=*) , intent(in) :: flds_scalar_name - type(med_fldList_entry_type) , pointer :: fldsSrc(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types - integer , intent(out) :: rc - - ! local variables - integer :: nf, nu, ns - integer, allocatable :: npacked(:) - integer :: fieldcount - type(ESMF_Field) :: lfield - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: ptrsrc_packed(:,:) => null() - real(r8), pointer :: ptrdst_packed(:,:) => null() - integer :: lsize_src - integer :: lsize_dst - type(ESMF_Mesh) :: lmesh_src - type(ESMF_Mesh) :: lmesh_dst - integer :: mapindex - type(ESMF_Field), pointer :: fieldlist_src(:) => null() - type(ESMF_Field), pointer :: fieldlist_dst(:) => null() - character(CL), allocatable :: fieldNameList(:) - character(len=*), parameter :: subname=' (med_packed_fieldbundles_create) ' - !----------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! Get field count for both FBsrc and FBdst - call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! get fields in source and destination field bundles - allocate(fieldlist_src(fieldcount)) - call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist_dst(fieldcount)) - call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! field names are the same for the source and destination field bundles - allocate(fieldnamelist(fieldcount)) - call ESMF_FieldBundleGet(FBsrc, fieldnamelist=fieldnamelist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Determine local size and mesh of source fields - ! Allocate a source fortran pointer for the new packed field bundle - ! Create the packed source field bundle - call ESMF_FieldGet(fieldlist_src(1), mesh=lmesh_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Determine local size of destination fields - ! Allocate a destination fortran pointer for the new packed field bundle - ! Create the packed source field bundle - call ESMF_FieldGet(fieldlist_dst(1), mesh=lmesh_dst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Gather all fields that will be mapped with a target map index into a packed field - ! Calculated size of packed field based on the fact that some fields have - ! ungridded dimensions and need to unwrap them into separate fields for the - ! purposes of packing - - ! Allocate memory to keep tracked of packing index for each mapping type - allocate(npacked(nmappers)) - npacked(:) = 0 - - if (mastertask) write(logunit,*) - ! Loop over mapping types - do mapindex = 1,nmappers - - ! Allocate the fldindex attribute of packed_indices if needed - if (.not. allocated(packed_data(mapindex)%fldindex)) then - allocate(packed_data(mapindex)%fldindex(fieldcount)) - packed_data(mapindex)%fldindex(:) = -999 - end if - - ! Loop over the fields in FBSrc - do nf = 1, fieldCount - - ! Loop over the fldsSrc types - do ns = 1,size(fldsSrc) - - if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & - fldsSrc(ns)%shortname /= flds_scalar_name .and. & - trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then - - ! Determine mapnorm - the assumption is that there is only one - ! mapnorm type for a source packed field bundle - if (npacked(mapindex) == 0) then - packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) - else - if (fldsSrc(ns)%mapnorm(destcomp) /= packed_data(mapindex)%mapnorm) then - call ESMF_LogWrite(trim(subname)//& - ": ERROR mapnorm "//trim(fldsSrc(ns)%mapnorm(destcomp))//" is not equal to "// & - trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & - ESMF_LOGMSG_ERROR, rc=rc) - rc = ESMF_FAILURE - return - end if - end if - - ! Determine mapping of indices into packed field bundle - ! Get source field - call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - do nu = 1,ungriddedUBound(1) - npacked(mapindex) = npacked(mapindex) + 1 - if (nu == 1) then - packed_data(mapindex)%fldindex(nf) = npacked(mapindex) - end if - end do - else - npacked(mapindex) = npacked(mapindex) + 1 - packed_data(mapindex)%fldindex(nf) = npacked(mapindex) - end if - - if (mastertask) then - write(logunit,'(5(a,2x),2x,i4)') trim(subname)//& - 'Packed field: destcomp,mapping,mapnorm,fldname,index: ', & - trim(compname(destcomp)), & - trim(mapnames(mapindex)), & - trim(fldsSrc(ns)%mapnorm(destcomp)), & - trim(fieldnamelist(nf)), & - packed_data(mapindex)%fldindex(nf) - end if - - end if! end if source field is mapped to destination field with mapindex - end do ! end loop over FBSrc fields - end do ! end loop over fldSrc elements - - ! Create the source and destination packed fields for mapindex - if (npacked(mapindex) > 0) then - allocate(ptrsrc_packed(npacked(mapindex), lsize_src)) - packed_data(mapindex)%field_src = ESMF_FieldCreate(lmesh_src, & - ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - allocate(ptrdst_packed(npacked(mapindex), lsize_dst)) - packed_data(mapindex)%field_dst = ESMF_FieldCreate(lmesh_dst, & - ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - packed_data(mapindex)%field_fracsrc = ESMF_FieldCreate(lmesh_src, ESMF_TYPEKIND_R8, & - meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - packed_data(mapindex)%field_fracdst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, & - meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - end if - end do ! end loop over mapindex - - deallocate(npacked) - deallocate(fieldlist_src) - deallocate(fieldlist_dst) - - end subroutine med_map_packed_field_create - - !================================================================================ - subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, routehandles, rc) - - ! ----------------------------------------------- - ! Do the redistribution on the packed field bundles - ! ----------------------------------------------- - - use ESMF - use esmFlds , only : nmappers, mapfcopy - use med_map_mod , only : med_map_field_regrid - use med_internalstate_mod , only : packed_data_type - - ! input/output variables - type(ESMF_FieldBundle) , intent(in) :: FBSrc - type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_FieldBundle) , intent(in) :: FBNormOne(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(in) :: FBFracSrc ! fraction field bundle for source - type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types - type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) - integer , intent(out) :: rc - - ! local variables - integer :: nf, nu, np, n - integer :: fieldcount - integer :: mapindex - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - real(r8), pointer :: dataptr1d(:) => null() - real(r8), pointer :: dataptr2d(:,:) => null() - real(r8), pointer :: dataptr2d_packed(:,:) => null() - type(ESMF_Field) :: lfield - type(ESMF_Field) :: field_fracsrc - type(ESMF_Field), pointer :: fieldlist_src(:) => null() - type(ESMF_Field), pointer :: fieldlist_dst(:) => null() - character(CL), allocatable :: fieldNameList(:) - real(r8), pointer :: data_norm(:) => null() - real(r8), pointer :: data_dst(:,:) => null() - character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' - !----------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! Get field count for both FBsrc and FBdst - call ESMF_FieldBundleGet(FBsrc, fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - allocate(fieldlist_src(fieldcount)) - call ESMF_FieldBundleGet(FBsrc, fieldlist=fieldlist_src, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - allocate(fieldlist_dst(fieldcount)) - call ESMF_FieldBundleGet(FBdst, fieldlist=fieldlist_dst, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Loop over mapping types - do mapindex = 1,nmappers - - ! If packed field is created - if (ESMF_FieldIsCreated(packed_data(mapindex)%field_src)) then - - ! ----------------------------------- - ! Copy the src fields into the packed field bundle - ! ----------------------------------- - - call t_startf('MED:'//trim(subname)//' copy from src') - - ! First get the pointer for the packed source data - call ESMF_FieldGet(packed_data(mapindex)%field_src, farrayptr=dataptr2d_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Now do the copy - do nf = 1,fieldcount - ! Get the indices into the packed data structure - np = packed_data(mapindex)%fldindex(nf) - if (np > 0) then - call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do nu = 1,ungriddedUBound(1) - dataptr2d_packed(np+nu-1,:) = dataptr2d(nu,:) - end do - else - call ESMF_FieldGet(fieldlist_src(nf), farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d_packed(np,:) = dataptr1d(:) - end if - end if - end do - call t_stopf('MED:'//trim(subname)//' copy from src') - - ! ----------------------------------- - ! Do the mapping - ! ----------------------------------- - - call t_startf('MED:'//trim(subname)//' map') - if (mapindex == mapfcopy) then - - ! Mapping is redistribution - call ESMF_FieldRedist(& - packed_data(mapindex)%field_src, & - packed_data(mapindex)%field_dst, & - routehandles(mapindex), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - else if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & - trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & - trim(packed_data(mapindex)%mapnorm) /= 'none') then - - ! Normalized mapping - assume that each packed field has only one normalization type - call ESMF_FieldBundleGet(FBFracSrc, packed_data(mapindex)%mapnorm, field=field_fracsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field_normalized(& - field_src=packed_data(mapindex)%field_src, & - field_dst=packed_data(mapindex)%field_dst, & - routehandles=routehandles, & - maptype=mapindex, & - field_normsrc=field_fracsrc, & - field_normdst=packed_data(mapindex)%field_fracdst, rc=rc) - - else if ( trim(packed_data(mapindex)%mapnorm) == 'one' .or. trim(packed_data(mapindex)%mapnorm) == 'none') then - - ! Mapping with no normalization that is not redistribution - call med_map_field_regrid (& - srcfield=packed_data(mapindex)%field_src, & - dstfield=packed_data(mapindex)%field_dst, & - routehandles=routehandles, & - mapindex=mapindex, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Obtain unity normalization factor and multiply - ! interpolated field by reciprocal of normalization factor - if (trim(packed_data(mapindex)%mapnorm) == 'one') then - call ESMF_FieldBundleGet(FBNormOne(mapindex), fieldName='one', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=data_norm, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(data_dst,dim=2) - if (data_norm(n) == 0.0_r8) then - data_dst(:,n) = 0.0_r8 - else - data_dst(:,n) = data_dst(:,n)/data_norm(n) - end if - end do - end if - - end if - call t_stopf('MED:'//trim(subname)//' map') - - ! ----------------------------------- - ! Copy the destination packed field bundle into the destination unpacked field bundle - ! ----------------------------------- - - call t_startf('MED:'//trim(subname)//' copy to dest') - - ! First get the pointer for the packed destination data - call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayptr=dataptr2d_packed, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Now do the copy back to FBDst - do nf = 1,fieldcount - ! Get the indices into the packed data structure - np = packed_data(mapindex)%fldindex(nf) - if (np > 0) then - call ESMF_FieldGet(fieldlist_dst(nf), ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound(1) > 0) then - call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do nu = 1,ungriddedUBound(1) - dataptr2d(nu,:) = dataptr2d_packed(np+nu-1,:) - end do - else - call ESMF_FieldGet(fieldlist_dst(nf), farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = dataptr2d_packed(np,:) - end if - end if - end do - call t_stopf('MED:'//trim(subname)//' copy to dest') - - end if - end do ! end of loop over mapindex - - deallocate(fieldlist_src) - deallocate(fieldlist_dst) - - end subroutine med_map_field_packed - - !================================================================================ - subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, & - field_normsrc, field_normdst, rc) - - ! ----------------------------------------------- - ! Map a normalized field - ! ----------------------------------------------- - - use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_RouteHandle - use ESMF , only : ESMF_SUCCESS - use med_map_mod , only : med_map_field_regrid - - ! input/output variables - type(ESMF_Field) , intent(in) :: field_src - type(ESMF_Field) , intent(inout) :: field_dst - type(ESMF_Field) , intent(in) :: field_normsrc - type(ESMF_Field) , intent(inout) :: field_normdst - type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) - integer , intent(in) :: maptype - integer , intent(out) :: rc - - ! local variables - integer :: n - real(r8), pointer :: data_src2d(:,:) => null() - real(r8), pointer :: data_dst2d(:,:) => null() - real(r8), pointer :: data_srctmp2d(:,:) => null() - real(r8), pointer :: data_src1d(:) => null() - real(r8), pointer :: data_dst1d(:) => null() - real(r8), pointer :: data_srctmp1d(:) => null() - real(r8), pointer :: data_normsrc(:) => null() - real(r8), pointer :: data_normdst(:) => null() - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - integer :: lsize_src - integer :: lsize_dst - character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' - !----------------------------------------------------------- - - rc = ESMF_SUCCESS - - ! get a pointer (data_fracsrc) to the normalization array - ! get a pointer (data_src) to source field data in FBSrc - ! copy data_src to data_srctmp - - ! normalize data_src by data_fracsrc - - call ESMF_FieldGet(field_normsrc, farrayPtr=data_normsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize_src = size(data_normsrc) - - call ESMF_FieldGet(field_src, ungriddedUBound=ungriddedUBound, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUbound(1) > 0) then - call ESMF_FieldGet(field_src, farrayPtr=data_src2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(data_srctmp2d(size(data_src2d,dim=1), lsize_src)) - data_srctmp2d(:,:) = data_src2d(:,:) - do n = 1,lsize_src - data_src2d(:,n) = data_src2d(:,n) * data_normsrc(n) - end do - else - call ESMF_FieldGet(field_src, farrayPtr=data_src1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(data_srctmp1d(lsize_src)) - data_srctmp1d(:) = data_src1d(:) - do n = 1,lsize_src - data_src1d(n) = data_src1d(n) * data_normsrc(n) - end do - end if - - ! regrid normalized packed source field - call med_map_field_regrid (field_src, field_dst, routehandles, maptype, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! restore original value to packed source field - if (ungriddedUbound(1) > 0) then - data_src2d(:,:) = data_srctmp2d(:,:) - deallocate(data_srctmp2d) - else - data_src1d(:) = data_srctmp1d(:) - deallocate(data_srctmp1d) - end if - - ! regrid normalization field from source to destination - call med_map_field_regrid(field_normsrc, field_normdst, routehandles, maptype, rc=rc) - - ! get pointer to mapped fraction and normalize - ! destination mapped values by the reciprocal of the mapped fraction - call ESMF_FieldGet(field_normdst, farrayPtr=data_normdst, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize_dst = size(data_normdst) - - if (ungriddedUbound(1) > 0) then - call ESMF_FieldGet(field_dst, farrayPtr=data_dst2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,lsize_dst - if (data_normdst(n) == 0.0_r8) then - data_dst2d(:,n) = 0.0_r8 - else - data_dst2d(:,n) = data_dst2d(:,n)/data_normdst(n) - end if - end do - else - call ESMF_FieldGet(field_dst, farrayPtr=data_dst1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,lsize_dst - if (data_normdst(n) == 0.0_r8) then - data_dst1d(n) = 0.0_r8 - else - data_dst1d(n) = data_dst1d(n)/data_normdst(n) - end if - end do - end if - end subroutine med_map_field_normalized - - !================================================================================ - subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, rc) - - !--------------------------------------------------- - ! map the source field to the destination field - !--------------------------------------------------- - - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_MAXSTR - use ESMF , only : ESMF_Field, ESMF_FieldRegrid - use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_Region_Flag, ESMF_REGION_TOTAL - use ESMF , only : ESMF_REGION_SELECT - use ESMF , only : ESMF_RouteHandle - use esmFlds , only : mapnstod_consd, mapnstod_consf, mapnstod_consd, mapnstod - use esmFlds , only : mapconsd, mapconsf - use med_methods_mod , only : Field_diagnose => med_methods_Field_diagnose - - ! input/output variables - type(ESMF_Field) , intent(in) :: field_src - type(ESMF_Field) , intent(inout) :: field_dst - type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) - integer , intent(in) :: maptype - character(len=*) , intent(in), optional :: fldname - integer , intent(out) :: rc - - ! local variables - logical :: checkflag = .false. - character(len=CS) :: lfldname - character(len=*), parameter :: subname='(med_map_field) ' - !--------------------------------------------------- - - rc = ESMF_SUCCESS - -#ifdef DEBUG - checkflag = .true. -#endif - lfldname = 'unknown' - if (present(fldname)) lfldname = trim(fldname) - - if (maptype == mapnstod_consd) then - call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsd), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call Field_diagnose(field_dst, lfldname, " --> after consd: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - else if (maptype == mapnstod_consf) then - call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapnstod), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call Field_diagnose(field_dst, lfldname, " --> after nstod: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(mapconsf), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_SELECT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 1) then - call Field_diagnose(field_dst, lfldname, " --> after consf: ", rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - else - call ESMF_FieldRegrid(field_src, field_dst, routehandle=RouteHandles(maptype), & - termorderflag=ESMF_TERMORDER_SRCSEQ, checkflag=checkflag, zeroregion=ESMF_REGION_TOTAL, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - end subroutine med_map_field - -end module med_map_packed_mod diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 2600cca18..705ccd33d 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -10,7 +10,7 @@ module med_phases_aofluxes_mod use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_init => med_methods_FB_init - use med_map_packed_mod , only : med_map_field_packed + use med_map_mod , only : med_map_field_packed use perf_mod , only : t_startf, t_stopf implicit none diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index d84da40ff..6aec4d01b 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -14,11 +14,10 @@ module med_phases_prep_atm_mod use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk use med_merge_mod , only : med_merge_auto - use med_map_packed_mod , only : med_map_field_packed + use med_map_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, mastertask use esmFlds , only : compatm, compocn, compice, ncomps, compname - use esmFlds , only : fldListFr, fldListTo, fldListMed_aoflux - use esmFlds , only : coupling_mode + use esmFlds , only : fldListTo, fldListMed_aoflux, coupling_mode use perf_mod , only : t_startf, t_stopf implicit none diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 4ab32080d..7bfd9f87b 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -8,25 +8,20 @@ module med_phases_prep_glc_mod use NUOPC , only : NUOPC_CompAttributeGet 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_FieldBundle, ESMF_Clock - use ESMF , only : ESMF_Alarm, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging, ESMF_AlarmRingerOff + use ESMF , only : ESMF_Clock,ESMF_ClockGetAlarm + use ESMF , only : ESMF_Alarm, 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 - use ESMF , only : ESMF_TYPEKIND_R8 - use esmFlds , only : compglc, complnd, mapbilnr, mapconsf, mapconsd, compname - use esmFlds , only : med_fldlist_type + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 + use esmFlds , only : compglc, complnd, mapbilnr, mapconsd, mapconsf, compname use med_internalstate_mod , only : InternalState, mastertask, logunit 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_FB_Regrid_Norm, med_map_RH_is_created - use med_map_mod , only : med_map_routehandles_init - use med_methods_mod , only : FB_Init => med_methods_FB_init - use med_methods_mod , only : FB_getFldPtr => med_methods_FB_getFldPtr + 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 @@ -42,7 +37,7 @@ module med_phases_prep_glc_mod public :: med_phases_prep_glc_accum public :: med_phases_prep_glc_avg - private :: med_phases_prep_glc_map_lnd2glc + private :: map_lnd2glc private :: med_phases_prep_glc_renormalize_smb ! glc fields with multiple elevation classes: lnd->glc @@ -54,7 +49,6 @@ module med_phases_prep_glc_mod type(ESMF_FieldBundle) :: FBlndAccum_lnd type(ESMF_FieldBundle) :: FBlndAccum_glc integer :: FBlndAccumCnt - type(med_fldlist_type) :: fldlist_lnd2glc 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 '/) @@ -64,18 +58,21 @@ module med_phases_prep_glc_mod logical :: smb_renormalize ! Needed if renormalize SMB - type(ESMF_FieldBundle) :: FBglc_icemask - type(ESMF_FieldBundle) :: FBlnd_icemask - type(med_fldlist_type) :: fldlist_glc2lnd_icemask - type(ESMF_FieldBundle) :: FBglc_frac - type(ESMF_FieldBundle) :: FBlnd_frac - type(med_fldlist_type) :: fldlist_glc2lnd_frac + 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(:) ! cell areas on land grid, for mapping real(r8) , pointer :: aream_g(:) ! cell areas on glc grid, for mapping character(len=*), parameter :: qice_fieldname = 'Flgl_qice' ! Name of flux field giving surface mass balance - character(len=*), parameter :: Sg_frac_field = 'Sg_ice_covered' - character(len=*), parameter :: Sg_topo_field = 'Sg_topo' - character(len=*), parameter :: Sg_icemask_field = 'Sg_icemask' + 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) @@ -114,6 +111,8 @@ subroutine med_phases_prep_glc_init(gcomp, rc) 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)' !--------------------------------------- @@ -161,11 +160,14 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ungriddedCount = ungriddedUBound_output(1) ! TODO: check that ungriddedCount = glc_nec+1 - - call FB_GetFldPtr(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(1), fldptr2=data2d_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_lnd, rc=rc) + 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) if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist) FBlndAccum_lnd = ESMF_FieldBundleCreate(name='FBlndAccum_lnd', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -185,15 +187,17 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! Create accumulation field bundle from land on the glc grid ! 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), fldnames_to_glc(1), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh_glc, rc=rc) + 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) 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, & @@ -205,22 +209,13 @@ subroutine med_phases_prep_glc_init(gcomp, rc) call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - FBlndAccumCnt = 0 - - allocate(fldlist_lnd2glc%flds(3)) - fldlist_lnd2glc%flds(1)%shortname = trim(fldnames_fr_lnd(1)) - fldlist_lnd2glc%flds(2)%shortname = trim(fldnames_fr_lnd(2)) - fldlist_lnd2glc%flds(3)%shortname = trim(fldnames_fr_lnd(3)) - fldlist_lnd2glc%flds(1)%mapindex(compglc) = mapbilnr - fldlist_lnd2glc%flds(2)%mapindex(compglc) = mapbilnr - fldlist_lnd2glc%flds(3)%mapindex(compglc) = mapbilnr - fldlist_lnd2glc%flds(1)%mapnorm(compglc) = 'lfrac' - fldlist_lnd2glc%flds(2)%mapnorm(compglc) = 'lfrac' - fldlist_lnd2glc%flds(3)%mapnorm(compglc) = 'lfrac' + ! 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 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 ", & + 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 @@ -262,14 +257,6 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! ------------------------------- if (smb_renormalize) then - ! ------------------------------- - ! get land and glc meshes and determine areas on corresponding meshes - ! ------------------------------- - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), mesh=lmesh_lnd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), mesh=lmesh_glc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! determine areas on land mesh call ESMF_MeshGet(lmesh_lnd, numOwnedElements=lsize, elementDistGrid=ldistgrid, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return @@ -294,54 +281,36 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return deallocate(dataptr1d) - ! ------------------------------- ! ice mask without elevation classes on glc and lnd - ! ------------------------------- - call FB_init(FBglc_icemask, is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBExp(compglc), fieldnameList=(/Sg_icemask_field/), rc=rc) + 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 - - call FB_init(FBlnd_icemask, is_local%wrap%flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(complnd,complnd), fieldNameList=(/Sg_icemask_field/), rc=rc) + field_glc_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldlist_glc2lnd_icemask%flds(1)) - fldlist_glc2lnd_icemask%flds(1)%shortname = Sg_icemask_field - fldlist_glc2lnd_icemask%flds(1)%mapindex(complnd) = mapconsf - fldlist_glc2lnd_icemask%flds(1)%mapnorm(complnd) = 'none' - - ! ------------------------------- - ! ice fraction in multiple elevation classes on glc and lnd - NOTE that this includes bare land - ! ------------------------------- - FBglc_frac = ESMF_FieldBundleCreate(rc=rc) + ! 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) if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, name=trim(Sg_frac_field), meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBglc_frac, (/lfield/), rc=rc) + field_glc_frac_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - FBlnd_frac = ESMF_FieldBundleCreate(rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lfield = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, name=trim(Sg_frac_field), meshloc=ESMF_MESHLOC_ELEMENT, & + ! 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, & ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBlnd_frac, (/lfield/), rc=rc) + field_glc_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 - allocate(fldlist_glc2lnd_frac%flds(1)) - fldlist_glc2lnd_frac%flds(1)%shortname = Sg_frac_field - fldlist_glc2lnd_frac%flds(1)%mapindex(complnd) = mapconsf - fldlist_glc2lnd_frac%flds(1)%mapnorm(complnd) = trim(Sg_icemask_field) ! will use FBglc_icemask - - ! Create route handle if it has not been created - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsd,rc=rc)) then + ! 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=FBlndAccum_glc, & - FBDst=FBlndAccum_lnd, & - mapindex=mapconsd, RouteHandle=is_local%wrap%RH, rc=rc) + 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 end if + end if end if @@ -353,7 +322,6 @@ subroutine med_phases_prep_glc_init(gcomp, rc) end subroutine med_phases_prep_glc_init !================================================================================================ - subroutine med_phases_prep_glc_accum(gcomp, rc) !--------------------------------------- @@ -368,6 +336,7 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) ! local variables type(InternalState) :: is_local + type(ESMF_Field) :: lfield integer :: i,n,ncnt real(r8), pointer :: data2d_in(:,:) real(r8), pointer :: data2d_out(:,:) @@ -407,19 +376,21 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) !--------------------------------------- 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) + 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 FB_GetFldPtr(is_local%wrap%FBImp(complnd,complnd), & - fldnames_fr_lnd(n), fldptr2=data2d_in, rc=rc) + 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 FB_GetFldPtr(FBlndAccum_lnd, fldnames_fr_lnd(n), fldptr2=data2d_out, rc=rc) + 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) @@ -432,7 +403,6 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) call FB_diagnose(FBlndAccum_lnd, string=trim(subname)// ' FBlndAccum_lnd ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if - end if if (dbug_flag > 5) then @@ -443,7 +413,6 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) end subroutine med_phases_prep_glc_accum !================================================================================================ - subroutine med_phases_prep_glc_avg(gcomp, rc) !--------------------------------------- @@ -458,6 +427,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) 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(:,:) real(r8), pointer :: data2d_import(:,:) @@ -535,7 +505,9 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) 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 FB_GetFldPtr(FBlndAccum_lnd, fldnames_fr_lnd(n), fldptr2=data2d, rc=rc) + 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 @@ -543,15 +515,16 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) else ! If accumulation count is 0, then simply set the averaged field bundle values from the land ! to the import field bundle values - call FB_GetFldPtr(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(n), fldptr2=data2d_import, rc=rc) + 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) 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) + 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 @@ -563,7 +536,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_phases_prep_glc_map_lnd2glc(gcomp, rc) + call map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then @@ -598,7 +571,7 @@ end subroutine med_phases_prep_glc_avg !================================================================================================ - subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) + subroutine map_lnd2glc(gcomp, rc) !--------------------------------------- ! map accumulated land fields from the land to the glc mesh @@ -610,25 +583,31 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) ! local variables type(InternalState) :: is_local - real(r8), pointer :: topolnd_g_ec(:,:) ! topo in elevation classes - real(r8), pointer :: dataptr_g(:) ! temporary data pointer for one elevation class - real(r8), pointer :: topoglc_g(:) ! ice topographic height on the glc grid extracted from glc import - real(r8), pointer :: data_ice_covered_g(:) ! data for ice-covered regions on the GLC grid - real(r8), pointer :: glc_ice_covered(:) ! if points on the glc grid is ice-covered (1) or ice-free (0) - integer , pointer :: glc_elevclass(:) ! elevation classes glc grid - real(r8), pointer :: dataexp_g(:) ! pointer into - real(r8), pointer :: dataptr2d(:,:) - real(r8), pointer :: dataptr1d(:) - real(r8) :: elev_l, elev_u ! lower and upper elevations in interpolation range - real(r8) :: d_elev ! elev_u - elev_l + real(r8), pointer :: topolnd_g_ec(:,:) => null() ! topo in elevation classes + real(r8), pointer :: dataptr_g(:) => null() ! temporary data pointer for one elevation class + real(r8), pointer :: topoglc_g(:) => null() ! ice topographic height on the glc grid extracted from glc import + real(r8), pointer :: data_ice_covered_g(:) => null() ! data for ice-covered regions on the GLC grid + real(r8), pointer :: ice_covered_g(:) => null() ! if points on the glc grid is ice-covered (1) or ice-free (0) + integer , pointer :: elevclass_g(:) => null() ! elevation classes glc grid + real(r8), pointer :: dataexp_g(:) => null() ! pointer into + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: dataptr1d(:) => null() + 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 :: ungriddedUBound_output(1) + integer :: fieldCount + type(ESMF_Field) :: lfield + type(ESMF_Field) :: field_lfrac_l + 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)' !--------------------------------------- + !--------------------------------------- ! Get the internal state !--------------------------------------- - nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -644,20 +623,35 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) ! 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) + 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) + 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) + 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 - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList_lnd2glc%flds, & - srccomp=complnd, & - destcomp=compglc, & - FBSrc=FBlndAccum_lnd, & - FBDst=FBlndAccum_glc, & - FBFracSrc=is_local%wrap%FBFrac(complnd), & - FBNormOne=is_local%wrap%FBNormOne(complnd,compglc,:), & - RouteHandles=is_local%wrap%RH(complnd,compglc,:), & - string=trim(compname(complnd))//'2'//trim(compname(compglc)), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! 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 + end do if (dbug_flag > 1) then call FB_diagnose(FBlndAccum_lnd, string=trim(subname)//' FBlndAccum_lnd ', rc=rc) @@ -677,24 +671,28 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) string=trim(subname)//' FBImp(compglc,compglc) ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if - - call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), Sg_frac_field, fldptr1=glc_ice_covered, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), Sg_topo_field, fldptr1=topoglc_g, rc=rc) + 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(glc_ice_covered) - allocate(glc_elevclass(lsize_g)) - call glc_get_elevation_classes(glc_ice_covered, topoglc_g, glc_elevclass, logunit) + 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 ! ------------------------------------------------------------------------ - call FB_getFldPtr(FBlndAccum_glc, 'Sl_topo_elev', fldptr2=topolnd_g_ec, rc=rc) + 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 ! ------------------------------------------------------------------------ @@ -706,7 +704,7 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) ! 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. - allocate(data_ice_covered_g (lsize_g)) + allocate(data_ice_covered_g(lsize_g)) do nfld = 1, size(fldnames_to_glc) ! ------------------------------------------------------------------------ @@ -715,11 +713,15 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) ! ------------------------------------------------------------------------ ! Get a pointer to the land data in multiple elevation classes on the glc grid - call FB_getFldPtr(FBlndAccum_glc, fldnames_fr_lnd(nfld), fldptr2=dataptr2d, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBExp(compglc), fldnames_to_glc(nfld), fldptr1=dataexp_g, rc=rc) + 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 @@ -729,7 +731,6 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) 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 @@ -767,7 +768,7 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) end do end if ! topoglc_g(n) - if (glc_elevclass(n) /= 0) then + if (elevclass_g(n) /= 0) then ! ice-covered cells have interpolated values dataexp_g(n) = data_ice_covered_g(n) else @@ -794,10 +795,10 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) end do ! end of loop over fields ! clean up memory - deallocate(glc_elevclass) + deallocate(elevclass_g) deallocate(data_ice_covered_g) - end subroutine med_phases_prep_glc_map_lnd2glc + end subroutine map_lnd2glc !================================================================================================ @@ -846,10 +847,9 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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_Mesh) :: lmesh type(ESMF_Field) :: lfield - real(r8) , pointer :: qice_l(:,:) ! SMB (Flgl_qice) on land grid with elev classes real(r8) , pointer :: qice_g(:) ! SMB (Flgl_qice) on glc grid without elev classes + real(r8) , pointer :: qice_l_ec(:,:) ! SMB (Flgl_qice) on land grid with elev classes real(r8) , pointer :: glc_topo_g(:) ! ice topographic height on the glc grid cell real(r8) , pointer :: glc_frac_g(:) ! total ice fraction in each glc cell real(r8) , pointer :: glc_frac_g_ec(:,:) ! total ice fraction in each glc cell @@ -892,36 +892,26 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Get vm - !--------------------------------------- - - call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- ! Map Sg_icemask_g from the glc grid to the land grid. !--------------------------------------- ! determine Sg_icemask_g and set as contents of FBglc_icemask - call FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_icemask_field), fldptr1=dataptr1d, rc=rc) + 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 FB_getFldPtr(FBglc_icemask, trim(Sg_icemask_field), fldptr1=Sg_icemask_g, rc=rc) + 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(:) - ! BUG(wjs, 2017-05-11, #1516) I think we actually want norm = .false. here, but this - ! requires some more thought - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList_glc2lnd_icemask%flds, & - srccomp=compglc, & - destcomp=complnd, & - FBSrc=FBglc_icemask, & - FBDst=FBlnd_icemask, & - FBFracSrc=FBglc_icemask, & ! this will not be used since are asking for 'none' normalization - FBNormOne=is_local%wrap%FBNormOne(compglc,complnd,:), & - RouteHandles=is_local%wrap%RH(compglc,complnd,:), & - string='mapping Sg_imask_g to Sg_imask_l (from glc to land)', rc=rc) + ! 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 + 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 ! ------------------------------------------------------------------------ @@ -933,46 +923,55 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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 FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_topo_field), fldptr1=glc_topo_g, rc=rc) + 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 FB_getFldPtr(is_local%wrap%FBImp(compglc,compglc), trim(Sg_frac_field), fldptr1=glc_frac_g, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=glc_topo_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(FBglc_frac, Sg_frac_field, fldptr2=glc_frac_g_ec, rc=rc) + 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 - call med_map_FB_Regrid_Norm( & - fldsSrc=fldList_glc2lnd_frac%flds, & - srccomp=compglc, & - destcomp=complnd, & - FBSrc=FBglc_frac, & ! this has multiple elevation classes - FBDst=FBlnd_frac, & ! this has multiple elvation classes - FBFracSrc=FBglc_icemask, & ! this is used with a mapnorm of Sg_icemask_field - FBNormOne=is_local%wrap%FBNormOne(compglc,complnd,:), & ! this will not be used - RouteHandles=is_local%wrap%RH(compglc,complnd,:), & - string='mapping elevation class fractions from glc to land ', rc=rc) + ! 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 FB_getFldPtr(FBlnd_frac, trim(Sg_frac_field), fldptr2=glc_frac_l_ec, rc=rc) + call ESMF_FieldGet(field_glc_frac_l_ec, farrayptr=glc_frac_l_ec, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine fraction on land grid, lfrac(:) - call FB_getFldPtr(is_local%wrap%FBFrac(complnd), 'lfrac', fldptr1=lfrac, rc=rc) + 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 Sg_icemask_l(:) - call FB_getFldPtr(FBlnd_icemask, Sg_icemask_field, fldptr1=Sg_icemask_l, rc=rc) + call ESMF_FieldGet(field_glc_icemask_l, farrayptr=Sg_icemask_l, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - ! determine qice_l - call FB_getFldPtr(FBlndAccum_lnd, trim(qice_fieldname)//'_elev', fldptr2=qice_l, rc=rc) + ! 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 !--------------------------------------- - ! Sum qice_l over all elevation classes for each local land grid cell then do a global sum + ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum !--------------------------------------- local_accum_lnd(1) = 0.0_r8 @@ -982,15 +981,19 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) effective_area = min(lfrac(n), Sg_icemask_l(n)) * aream_l(n) do ec = 1, ungriddedCount - if (qice_l(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,n) + 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,n) + 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 !--------------------------------------- ! Sum qice_g over local glc grid cells. @@ -1005,8 +1008,10 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! then it would be appropriate to use the native CISM areas in this sum. ! determine qice_g - call FB_getFldPtr(is_local%wrap%FBExp(compglc), qice_fieldname, fldptr1=qice_g, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + 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 diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 5ad02ccda..b027a45fc 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -13,7 +13,7 @@ module med_phases_prep_ice_mod 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_packed_mod , only : med_map_field_packed + 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 diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 70ad9000a..e69935402 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -9,7 +9,7 @@ module med_phases_prep_ocn_mod 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_packed_mod , only : med_map_field_packed + use med_map_mod , only : med_map_field_packed use med_utils_mod , only : memcheck => med_memcheck use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 420ac7478..fadc3fb7c 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -149,7 +149,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use esmFlds , only : fldListTo - use med_map_packed_mod , only : med_map_field_packed + use med_map_mod , only : med_map_field_packed use med_merge_mod , only : med_merge_auto ! input/output variables @@ -337,9 +337,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) 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 - use med_map_mod , only : med_map_field_regrid - use med_map_packed_mod , only : med_map_field_normalized + use med_map_mod , only : med_map_rh_is_created, med_map_field, med_map_field_normalized ! input/output variables type(ESMF_GridComp) :: gcomp @@ -473,11 +471,11 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) end do ! Map volr_r to volr_l (rof->lnd) using conservative mapping without any fractional weighting - call med_map_field_regrid(& - srcfield=field_rofVolr, & - dstfield=field_lndVolr, & + call med_map_field( & + field_src=field_rofVolr, & + field_dst=field_lndVolr, & routehandles=is_local%wrap%RH(comprof,complnd,:), & - mapindex=mapconsf, rc=rc) + maptype=mapconsf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get volr_l diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index bc8f362ff..2bffaf252 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -9,7 +9,7 @@ module med_phases_prep_wav_mod use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_merge_mod , only : med_merge_auto - use med_map_packed_mod , only : med_map_field_packed + use med_map_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, mastertask use esmFlds , only : compwav, ncomps, compname use esmFlds , only : fldListFr, fldListTo From e59e71e989f4f4ac1a9976d06e5939894ff4204b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 23 Oct 2020 11:19:52 -0600 Subject: [PATCH 132/206] refactored now one normalization is handled --- mediator/med.F90 | 69 +++++----- mediator/med_internalstate_mod.F90 | 6 +- mediator/med_map_mod.F90 | 192 +++++++++++++++------------ mediator/med_phases_aofluxes_mod.F90 | 2 +- mediator/med_phases_history_mod.F90 | 1 - mediator/med_phases_ocnalb_mod.F90 | 130 ++++++++++-------- mediator/med_phases_prep_atm_mod.F90 | 6 +- mediator/med_phases_prep_glc_mod.F90 | 6 +- mediator/med_phases_prep_ice_mod.F90 | 11 +- mediator/med_phases_prep_ocn_mod.F90 | 2 +- mediator/med_phases_prep_rof_mod.F90 | 2 +- mediator/med_phases_prep_wav_mod.F90 | 2 +- 12 files changed, 236 insertions(+), 193 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 185416c4f..584765329 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -57,6 +57,8 @@ module MED private InitializeIPDv03p5 ! realize all Fields with transfer action "accept" private DataInitialize ! finish initialization and resolve data dependencies private SetRunClock + private med_meshinfo_create + private med_grid_write private med_finalize character(len=*), parameter :: grid_arbopt = "grid_reg" ! grid_reg or grid_arb @@ -108,9 +110,13 @@ subroutine SetServices(gcomp, rc) use med_fraction_mod , only: med_fraction_init, med_fraction_set use med_phases_profile_mod , only: med_phases_profile + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc - character(len=*),parameter :: subname='(module_MED:SetServices)' + + ! local variables + character(len=*),parameter :: subname='(module_med:SetServices)' + !----------------------------------------------------------- rc = ESMF_SUCCESS if (profile_memory) call ESMF_VMLogMemInfo("Entering "//trim(subname)) @@ -468,7 +474,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) character(len=CX) :: msgString character(len=CX) :: diro character(len=CX) :: logfile - character(len=*),parameter :: subname='(module_MED:InitializeP0)' + character(len=*),parameter :: subname=' (module_med:InitializeP0) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -571,7 +577,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) 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)' + character(len=*),parameter :: subname=' (module_med:InitializeIPDv03p1) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -837,7 +843,7 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc) type(InternalState) :: is_local type(ESMF_VM) :: vm integer :: n - character(len=*),parameter :: subname='(module_MED:InitializeIPDv03p3)' + character(len=*),parameter :: subname=' (module_med:InitializeIPDv03p3) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -902,7 +908,7 @@ subroutine InitializeIPDv03p4(gcomp, importState, exportState, clock, rc) ! local variables type(InternalState) :: is_local integer :: n1,n2 - character(len=*),parameter :: subname='(module_MED:realizeConnectedGrid)' + character(len=*),parameter :: subname=' (module_med:InitalizeIPDv03p4) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -972,7 +978,7 @@ subroutine realizeConnectedGrid(State,string,rc) character(ESMF_MAXSTR),allocatable :: fieldNameList(:) type(ESMF_FieldStatus_Flag) :: fieldStatus character(len=CX) :: msgString - character(len=*),parameter :: subname='(module_MEDIATOR:realizeConnectedGrid)' + character(len=*),parameter :: subname=' (module_med:realizeConnectedGrid) ' !----------------------------------------------------------- !NOTE: All of the Fields that set their TransferOfferGeomObject Attribute @@ -1350,7 +1356,7 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc) ! local variables type(InternalState) :: is_local integer :: n1,n2 - character(len=*),parameter :: subname='(module_MED:InitializeIPDv03p5)' + character(len=*),parameter :: subname=' (module_med:InitializeIPDv03p5) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -1430,7 +1436,7 @@ subroutine completeFieldInitialization(State,rc) integer, allocatable :: ungriddedLBound(:), ungriddedUBound(:) logical :: isPresent logical :: meshcreated - character(len=*),parameter :: subname='(module_MED:completeFieldInitialization)' + character(len=*),parameter :: subname=' (module_med:completeFieldInitialization) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -1608,7 +1614,7 @@ subroutine DataInitialize(gcomp, rc) logical,save :: first_call = .true. real(r8) :: real_nx, real_ny character(len=CX) :: msgString - character(len=*), parameter :: subname='(module_MED:DataInitialize)' + character(len=*), parameter :: subname=' (module_med:DataInitialize) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -1897,7 +1903,7 @@ subroutine DataInitialize(gcomp, rc) call med_map_RouteHandles_init(gcomp, logunit, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_map_mapnorm_init(gcomp, logunit, rc) + call med_map_mapnorm_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do ndst = 1,ncomps @@ -2216,7 +2222,7 @@ subroutine SetRunClock(gcomp, rc) character(len=CS) :: glc_avg_period integer :: glc_cpl_dt logical :: first_time = .true. - character(len=*),parameter :: subname='(module_MED:SetRunClock)' + character(len=*),parameter :: subname=' (module_med:SetRunClock) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -2306,7 +2312,6 @@ subroutine SetRunClock(gcomp, rc) end subroutine SetRunClock - !----------------------------------------------------------------------------- !----------------------------------------------------------------------------- subroutine med_meshinfo_create(FB, mesh_info, rc) @@ -2332,7 +2337,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) real(r8), allocatable :: ownedElemCoords(:) real(r8), pointer :: dataptr(:) integer :: n, dimcount, fieldcount - character(len=*),parameter :: subname='(module_MED:med_meshinfo_create)' + character(len=*),parameter :: subname=' (module_med:med_meshinfo_create) ' !------------------------------------------------------------------------------- rc= ESMF_SUCCESS @@ -2377,26 +2382,8 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) end subroutine med_meshinfo_create !----------------------------------------------------------------------------- - - subroutine med_finalize(gcomp, rc) - - use ESMF, only : ESMF_GridComp, ESMF_SUCCESS - - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - rc = ESMF_SUCCESS - call memcheck("med_finalize", 0, mastertask) - if (mastertask) then - write(logunit,*)' SUCCESSFUL TERMINATION OF CMEPS' - call med_phases_profile_finalize() - end if - - end subroutine med_finalize - - !----------------------------------------------------------------------------- - subroutine med_grid_write(grid, fileName, rc) + use ESMF, only : ESMF_Grid, ESMF_Array, ESMF_ArrayBundle use ESMF, only : ESMF_ArrayBundleCreate, ESMF_GridGet use ESMF, only : ESMF_GridGetCoord, ESMF_ArraySet, ESMF_ArrayBundleAdd @@ -2414,7 +2401,7 @@ subroutine med_grid_write(grid, fileName, rc) type(ESMF_ArrayBundle) :: arrayBundle integer :: tileCount logical :: isPresent - character(len=*), parameter :: subname='(module_MED_Map:med_grid_write)' + character(len=*), parameter :: subname=' (module_med_map:med_grid_write) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS @@ -2568,4 +2555,20 @@ end subroutine med_grid_write !----------------------------------------------------------------------------- + subroutine med_finalize(gcomp, rc) + + use ESMF, only : ESMF_GridComp, ESMF_SUCCESS + + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + call memcheck("med_finalize", 0, mastertask) + if (mastertask) then + write(logunit,*)' SUCCESSFUL TERMINATION OF CMEPS' + call med_phases_profile_finalize() + end if + + end subroutine med_finalize + end module MED diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 23c53ce03..c4972f619 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -100,9 +100,9 @@ module med_internalstate_mod type(packed_data_type) :: packed_data_aoflux_o2a(nmappers) ! packed data for mapping ocn->atm ! Mapping - type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers - type(ESMF_FieldBundle) :: FBNormOne(ncomps,ncomps,nmappers) ! Unity static normalization - type(packed_data_type) :: packed_data(ncomps,ncomps,nmappers) + type(ESMF_RouteHandle) :: RH(ncomps,ncomps,nmappers) ! Routehandles for pairs of components and different mappers + type(ESMF_Field) :: field_NormOne(ncomps,ncomps,nmappers) ! Unity static normalization + type(packed_data_type) :: packed_data(ncomps,ncomps,nmappers) ! Packed data structure needed to efficiently map field bundles ! Fractions type(ESMF_FieldBundle) :: FBfrac(ncomps) ! Fraction data for various components, on their grid diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 067fa3cd4..3ce5010d0 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -36,7 +36,7 @@ module med_map_mod public :: med_map_mapnorm_init public :: med_map_packed_field_create public :: med_map_field_packed - public :: med_map_field_normalized + public :: med_map_field_normalized public :: med_map_field public :: med_map_fb_field_regrid ! TODO: do we still need this? @@ -128,7 +128,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) !integer(ESMF_KIND_I4), pointer :: unmappedDstList(:) character(len=128) :: logMsg type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG - character(len=*), parameter :: subname=' (module_med_map: RouteHandles_init) ' + character(len=*), parameter :: subname=' (RouteHandles_init) ' !----------------------------------------------------------- call t_startf('MED:'//subname) @@ -384,7 +384,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route integer :: SrcMaskValue integer :: DstMaskValue type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG - character(len=*), parameter :: subname=' (module_med_map: med_map_routehandles_init) ' + character(len=*), parameter :: subname=' (med_map_routehandles_init) ' !--------------------------------------------- call t_startf('MED:'//subname) @@ -529,6 +529,7 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) use ESMF , only : ESMF_RouteHandle + ! input/output variables type(ESMF_RouteHandle) , intent(in) :: RHs(:,:,:) integer , intent(in) :: n1 integer , intent(in) :: n2 @@ -538,10 +539,10 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) ! local variables integer :: rc1, rc2 logical :: mapexists - character(len=*), parameter :: subname=' (med_map_RH_is_created: ) ' + character(len=*), parameter :: subname=' (med_map_RH_is_created) ' + !----------------------------------------------------------- rc = ESMF_SUCCESS - med_map_RH_is_created_RH3d = med_map_RH_is_created_RH1d(RHs(n1,n2,:),mapindex,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -553,6 +554,7 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated + ! input/output varaibes type(ESMF_RouteHandle) , intent(in) :: RHs(:) integer , intent(in) :: mapindex integer , intent(out) :: rc @@ -560,7 +562,8 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) ! local variables integer :: rc1, rc2 logical :: mapexists - character(len=*), parameter :: subname=' (med_map_RH_is_created_RH1d: ) ' + character(len=*), parameter :: subname=' (med_map_RH_is_created_RH1d) ' + !----------------------------------------------------------- rc = ESMF_SUCCESS rc1 = ESMF_SUCCESS @@ -589,92 +592,113 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) end function med_map_RH_is_created_RH1d !================================================================================ - subroutine med_map_mapnorm_init(gcomp, llogunit, rc) + subroutine med_map_mapnorm_init(gcomp, rc) !--------------------------------------- - ! Initialize unity normalization field bundle - ! and do the mapping for unity normalization up front + ! Initialize unity normalization fields and do the mapping for unity normalization up front !--------------------------------------- use ESMF , only: ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only: ESMF_GridComp, ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only: ESMF_GridComp + use ESMF , only: ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT + use ESMF , only: ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleCreate + use ESMF , only: ESMF_FieldBundleIsCreated + use ESMF , only: ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate, ESMF_FieldDestroy ! input/output variables type(ESMF_GridComp) :: gcomp - integer, intent(in) :: llogunit integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - type(ESMF_FieldBundle) :: FBTmp - integer :: n1, n2, m - character(len=CS) :: normname - character(len=1) :: cn1,cn2,cm - real(R8), pointer :: dataptr(:) - character(len=*),parameter :: subname='(med_map_mapnorm_init)' + type(InternalState) :: is_local + integer :: n1, n2, m + character(len=1) :: cn1,cn2,cm + real(R8), pointer :: dataptr(:) => null() + integer :: fieldCount + type(ESMF_Field), pointer :: fieldlist(:) => null() + type(ESMF_Field) :: field_src + type(ESMF_Mesh) :: mesh_src + type(ESMF_Mesh) :: mesh_dst + character(len=*),parameter :: subname=' (med_map_mapnorm_init) ' !----------------------------------------------------------- call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + if (dbug_flag > 1) then - call ESMF_LogWrite("Starting to initialize unity map normalizations", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() + call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) + endif + if (mastertask) then + write(logunit,*) + write(logunit,'(a)') trim(subname)//"Initializing unity map normalizations" endif - - rc = ESMF_SUCCESS ! Get the internal state from Component. nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Initialize module variables - flds_scalar_name = is_local%wrap%flds_scalar_name - - ! Create the normalization field bundles - normname = 'one' + ! Create the destination normalization field do n1 = 1,ncomps - do n2 = 1,ncomps - if (n1 /= n2) then - if (is_local%wrap%med_coupling_active(n1,n2)) then - do m = 1,nmappers - if (med_map_RH_is_created(is_local%wrap%RH,n1,n2,m,rc=rc)) then - if (dbug_flag > 1) then - write(cn1,'(i1)') n1; write(cn2,'(i1)') n2; write(cm ,'(i1)') m - call ESMF_LogWrite(trim(subname)//":"//'creating FBMapNormOne for '& - //compname(n1)//'->'//compname(n2)//' with mapping '//mapnames(m), & - ESMF_LOGMSG_INFO) - endif - call FB_init(FBout=is_local%wrap%FBNormOne(n1,n2,m), & - flds_scalar_name=flds_scalar_name, & - FBgeom=is_local%wrap%FBImp(n1,n2), & - fieldNameList=(/trim(normname)/), name='FBNormOne', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_reset(is_local%wrap%FBNormOne(n1,n2,m), value=czero, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(n1,n1))) then + ! Get source mesh + call ESMF_FieldBundleGet(is_local%wrap%FBImp(n1,n1), fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(n1,n1), fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=mesh_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + field_src = ESMF_FieldCreate(mesh_src, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(field_src, farrayptr=dataPtr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = 1.0_R8 - call FB_init(FBout=FBTmp, & - flds_scalar_name=flds_scalar_name, & - STgeom=is_local%wrap%NStateImp(n1), & - fieldNameList=(/trim(normname)/), name='FBTmp', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + do n2 = 1,ncomps + if ( n1 /= n2 .and. & + ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(n1,n2)) .and. & + is_local%wrap%med_coupling_active(n1,n2) ) then - call FB_GetFldPtr(FBTmp, trim(normname), fldptr1=dataPtr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 1.0_R8 + ! Get destination mesh + call ESMF_FieldBundleGet(is_local%wrap%FBImp(n1,n2), fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=mesh_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_fb_field_regrid(FBTmp, trim(normname), is_local%wrap%FBNormOne(n1,n2,m), trim(normname), & - is_local%wrap%RH(n1,n2,:), m, rc=rc) + ! Createis_local%wrap%field_NormOne(n1,n2,m) + do m = 1,nmappers + if (med_map_RH_is_created(is_local%wrap%RH,n1,n2,m,rc=rc)) then + is_local%wrap%field_NormOne(n1,n2,m) = ESMF_FieldCreate(mesh_dst, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call FB_clean(FBTmp, rc=rc) + call ESMF_FieldGet(is_local%wrap%field_NormOne(n1,n2,m), farrayptr=dataptr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr(:) = czero + call med_map_field( & + field_src=field_src, & + field_dst=is_local%wrap%field_NormOne(n1,n2,m), & + routehandles=is_local%wrap%RH(n1,n2,:), & + maptype=m, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(cn1,'(i1)') n1; write(cn2,'(i1)') n2; write(cm ,'(i1)') m + write(logunit,'(a)') trim(subname)//' created field_NormOne for '& + //compname(n1)//'->'//compname(n2)//' with mapping '//mapnames(m) + endif end if - end do - end if - end if - end do - end do + end do ! end of loop over m mappers + end if ! end of if block for creating destination field + end do ! end of loop over n2 + + ! Deallocate memory + deallocate(fieldlist) + call ESMF_FieldDestroy(field_src, rc=rc, noGarbage=.true.) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end if ! end of if-block for existence of field bundle + end do ! end of loop over n1 if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) @@ -694,8 +718,8 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & ! input/output variables integer , intent(in) :: destcomp - character(len=*) , intent(in) :: flds_scalar_name - type(med_fldList_entry_type) , pointer :: fldsSrc(:) ! array over mapping types + character(len=*) , intent(in) :: flds_scalar_name + type(med_fldList_entry_type) , pointer :: fldsSrc(:) ! array over mapping types type(ESMF_FieldBundle) , intent(in) :: FBSrc type(ESMF_FieldBundle) , intent(inout) :: FBDst type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types @@ -756,8 +780,8 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & if (chkerr(rc,__LINE__,u_FILE_u)) return ! Gather all fields that will be mapped with a target map index into a packed field - ! Calculated size of packed field based on the fact that some fields have - ! ungridded dimensions and need to unwrap them into separate fields for the + ! Calculated size of packed field based on the fact that some fields have + ! ungridded dimensions and need to unwrap them into separate fields for the ! purposes of packing ! Allocate memory to keep tracked of packing index for each mapping type @@ -792,7 +816,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & if (fldsSrc(ns)%mapnorm(destcomp) /= packed_data(mapindex)%mapnorm) then call ESMF_LogWrite(trim(subname)//& ": ERROR mapnorm "//trim(fldsSrc(ns)%mapnorm(destcomp))//" is not equal to "// & - trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & + trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & ESMF_LOGMSG_ERROR, rc=rc) rc = ESMF_FAILURE return @@ -848,29 +872,31 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & end if end do ! end loop over mapindex - deallocate(npacked) + deallocate(npacked) deallocate(fieldlist_src) deallocate(fieldlist_dst) end subroutine med_map_packed_field_create !================================================================================ - subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, routehandles, rc) + subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_data, routehandles, rc) ! ----------------------------------------------- - ! Do the redistribution on the packed field bundles + ! Do regridding via packed field bundles ! ----------------------------------------------- - use ESMF + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only : ESMF_FieldRedist, ESMF_RouteHandle use esmFlds , only : nmappers, mapfcopy use med_internalstate_mod , only : packed_data_type ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FBSrc type(ESMF_FieldBundle) , intent(inout) :: FBDst - type(ESMF_FieldBundle) , intent(in) :: FBNormOne(:) ! array over mapping types - type(ESMF_FieldBundle) , intent(in) :: FBFracSrc ! fraction field bundle for source - type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types + type(ESMF_Field) , intent(in) :: field_normOne(:) ! array over mapping types + type(ESMF_FieldBundle) , intent(in) :: FBFracSrc ! fraction field bundle for source + type(packed_data_type) , intent(inout) :: packed_data(:) ! array over mapping types type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) integer , intent(out) :: rc @@ -889,7 +915,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, character(CL), allocatable :: fieldNameList(:) real(r8), pointer :: data_norm(:) => null() real(r8), pointer :: data_dst(:,:) => null() - character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + character(len=*), parameter :: subname=' (med_map_field_packed) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -961,7 +987,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, else if ( trim(packed_data(mapindex)%mapnorm) /= 'unset' .and. & trim(packed_data(mapindex)%mapnorm) /= 'one' .and. & trim(packed_data(mapindex)%mapnorm) /= 'none') then - + ! Normalized mapping - assume that each packed field has only one normalization type call ESMF_FieldBundleGet(FBFracSrc, packed_data(mapindex)%mapnorm, field=field_fracsrc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -986,9 +1012,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, ! Obtain unity normalization factor and multiply ! interpolated field by reciprocal of normalization factor if (trim(packed_data(mapindex)%mapnorm) == 'one') then - call ESMF_FieldBundleGet(FBNormOne(mapindex), fieldName='one', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=data_norm, rc=rc) + call ESMF_FieldGet(field_normOne(mapindex), farrayPtr=data_norm, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(packed_data(mapindex)%field_dst, farrayPtr=data_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1001,7 +1025,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, FBNormOne, packed_data, end do end if - end if + end if call t_stopf('MED:'//trim(subname)//' map') ! ----------------------------------- @@ -1061,7 +1085,7 @@ subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, type(ESMF_Field) , intent(in) :: field_normsrc type(ESMF_Field) , intent(inout) :: field_normdst type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) - integer , intent(in) :: maptype + integer , intent(in) :: maptype integer , intent(out) :: rc ! local variables @@ -1075,9 +1099,9 @@ subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, real(r8), pointer :: data_normsrc(:) => null() real(r8), pointer :: data_normdst(:) => null() integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - integer :: lsize_src + integer :: lsize_src integer :: lsize_dst - character(len=*), parameter :: subname=' (med_map_packed_fieldbundles) ' + character(len=*), parameter :: subname=' (med_map_field_normalized) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -1334,7 +1358,7 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) integer :: spatialDim logical :: checkflag = .false. real(r8), parameter :: deg2rad = shr_const_pi/180.0_R8 ! deg to rads - character(len=*), parameter :: subname='(module_MED_Map:med_map_uv_cart3d)' + character(len=*), parameter :: subname=' med_map_uv_cart3d) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 705ccd33d..3320cef13 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -159,7 +159,7 @@ subroutine med_phases_aofluxes_run(gcomp, rc) FBSrc=is_local%wrap%FBImp(compatm,compatm), & FBDst=is_local%wrap%FBImp(compatm,compocn), & FBFracSrc=is_local%wrap%FBFrac(compatm), & - FBNormOne=is_local%wrap%FBNormOne(compatm,compocn,:), & + 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 diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index ec57c94dc..743ee75af 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -24,7 +24,6 @@ module med_phases_history_mod use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_reset => med_methods_FB_reset use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_accum => med_methods_FB_accum use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar use med_internalstate_mod , only : InternalState, mastertask, logunit diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 540caf8f4..386dca2c1 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -1,13 +1,10 @@ module med_phases_ocnalb_mod use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use shr_const_mod , only : shr_const_pi - 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 : InternalState, logunit - use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + 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_methods_mod , only : State_GetScalar => med_methods_State_GetScalar use esmFlds , only : mapconsf, mapnames, compatm, compocn use perf_mod , only : t_startf, t_stopf @@ -76,9 +73,9 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) !----------------------------------------------------------------------- use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Field, ESMF_Grid, ESMF_Mesh, ESMF_GeomType_Flag - use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_FieldGet, ESMF_GEOMTYPE_MESH - use ESMF , only : ESMF_MeshGet + use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_Mesh, ESMF_MeshGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet use ESMF , only : operator(==) ! Arguments @@ -91,7 +88,6 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) integer :: iam type(ESMF_Field) :: lfield type(ESMF_Mesh) :: lmesh - type(ESMF_GeomType_Flag) :: geomtype integer :: n integer :: lsize integer :: dimCount @@ -101,6 +97,8 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) real(R8), pointer :: ownedElemCoords(:) character(len=CL) :: tempc1,tempc2 logical :: mastertask + integer :: fieldCount + type(ESMF_Field), pointer :: fieldlist(:) => null() character(*), parameter :: subname = '(med_phases_ocnalb_init) ' !----------------------------------------------------------------------- @@ -129,13 +127,24 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) ! These must must be on the ocean grid since the ocean albedo computation is on the ocean grid ! The following sets pointers to the module arrays - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, fldname='So_avsdr', fldptr1=ocnalb%avsdr, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldname='So_avsdr', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, fldname='So_avsdf', fldptr1=ocnalb%avsdf, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ocnalb%avsdr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, fldname='So_anidr', fldptr1=ocnalb%anidr, rc=rc) + + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldname='So_avsdf', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=ocnalb%avsdf, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldname='So_anidr', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFldPtr(is_local%wrap%FBMed_ocnalb_o, fldname='So_anidf', fldptr1=ocnalb%anidf, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ocnalb%anidr, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldname='So_anidf', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=ocnalb%anidf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return !---------------------------------- @@ -144,42 +153,34 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) ! The following assumes that all fields in FBMed_ocnalb_o have the same grid - so ! only need to query field 1 - call FB_getFieldN(is_local%wrap%FBMed_ocnalb_o, fieldnum=1, field=lfield, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBMed_ocnalb_o, fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=lmesh, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Determine if first field is on a grid or a mesh - default will be mesh - call ESMF_FieldGet(lfield, geomtype=geomtype, rc=rc) + deallocate(fieldlist) + call ESMF_MeshGet(lmesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (geomtype == ESMF_GEOMTYPE_MESH) then - call ESMF_LogWrite(trim(subname)//" : FBAtm is on a mesh ", ESMF_LOGMSG_INFO) - call ESMF_FieldGet(lfield, mesh=lmesh, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(lmesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize = size(ocnalb%anidr) - if (numOwnedElements /= lsize) then - write(tempc1,'(i10)') numOwnedElements - write(tempc2,'(i10)') lsize - call ESMF_LogWrite(trim(subname)//": ERROR numOwnedElements "// trim(tempc1) // & - " not equal to local size "// trim(tempc2), ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return - end if - allocate(ownedElemCoords(spatialDim*numOwnedElements)) - allocate(ocnalb%lons(numOwnedElements)) - allocate(ocnalb%lats(numOwnedElements)) - call ESMF_MeshGet(lmesh, ownedElemCoords=ownedElemCoords) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,lsize - ocnalb%lons(n) = ownedElemCoords(2*n-1) - ocnalb%lats(n) = ownedElemCoords(2*n) - end do - else - call ESMF_LogWrite(trim(subname)//": ERROR field bundle must be either on mesh", ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return + lsize = size(ocnalb%anidr) + if (numOwnedElements /= lsize) then + write(tempc1,'(i10)') numOwnedElements + write(tempc2,'(i10)') lsize + call ESMF_LogWrite(trim(subname)//": ERROR numOwnedElements "// trim(tempc1) // & + " not equal to local size "// trim(tempc2), ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + return end if + allocate(ownedElemCoords(spatialDim*numOwnedElements)) + allocate(ocnalb%lons(numOwnedElements)) + allocate(ocnalb%lats(numOwnedElements)) + call ESMF_MeshGet(lmesh, ownedElemCoords=ownedElemCoords) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,lsize + ocnalb%lons(n) = ownedElemCoords(2*n-1) + ocnalb%lats(n) = ownedElemCoords(2*n) + end do ! Initialize orbital values call med_phases_ocnalb_orbital_init(gcomp, logunit, iam==0, rc) @@ -200,14 +201,16 @@ subroutine med_phases_ocnalb_run(gcomp, rc) ! Compute ocean albedos (on the ocean grid) !----------------------------------------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_TimeInterval - use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_Time, ESMF_TimeGet - use ESMF , only : ESMF_VM, ESMF_VMGet - use ESMF , only : ESMF_LogWrite, ESMF_LogFoundError - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO - use ESMF , only : ESMF_FieldBundleIsCreated - use ESMF , only : operator(+) - use NUOPC , only : NUOPC_CompAttributeGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_TimeInterval + use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_Time, ESMF_TimeGet + use ESMF , only : ESMF_VM, ESMF_VMGet + use ESMF , only : ESMF_LogWrite, ESMF_LogFoundError + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldBundleIsCreated + use ESMF , only : operator(+) + use NUOPC , only : NUOPC_CompAttributeGet + use shr_const_mod , only : shr_const_pi ! input/output variables type(ESMF_GridComp) :: gcomp @@ -216,6 +219,7 @@ subroutine med_phases_ocnalb_run(gcomp, rc) ! local variables type(ocnalb_type), save :: ocnalb type(ESMF_VM) :: vm + type(ESMF_Field) :: lfield integer :: iam logical :: update_alb type(InternalState) :: is_local @@ -407,13 +411,21 @@ subroutine med_phases_ocnalb_run(gcomp, rc) ! Update current ifrad/ofrad values if albedo was updated in field bundle if (update_alb) then - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), fldname='ifrac', fldptr1=ifrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), 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(compocn), fieldname='ifrad', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=ifrad, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldname='ofrac', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), fldname='ifrad', fldptr1=ifrad, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ofrac, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), fldname='ofrac', fldptr1=ofrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldname='ofrad', field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), fldname='ofrad', fldptr1=ofrad, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ofrad, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ifrad(:) = ifrac(:) ofrad(:) = ofrac(:) diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index 6aec4d01b..807f8959f 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -86,7 +86,7 @@ subroutine med_phases_prep_atm(gcomp, rc) FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compatm), & FBFracSrc=is_local%wrap%FBFrac(n1), & - FBNormOne=is_local%wrap%FBNormOne(n1,compatm,:), & + 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 @@ -101,7 +101,7 @@ subroutine med_phases_prep_atm(gcomp, rc) FBSrc=is_local%wrap%FBMed_ocnalb_o, & FBDst=is_local%wrap%FBMed_ocnalb_a, & FBFracSrc=is_local%wrap%FBFrac(compocn), & - FBNormOne=is_local%wrap%FBNormOne(compocn,compatm,:), & + 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 @@ -116,7 +116,7 @@ subroutine med_phases_prep_atm(gcomp, rc) FBSrc=is_local%wrap%FBMed_aoflux_o, & FBDst=is_local%wrap%FBMed_aoflux_a, & FBFracSrc=is_local%wrap%FBFrac(compocn), & - FBNormOne=is_local%wrap%FBNormOne(compocn,compatm,:), & + 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 diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 7bfd9f87b..053acd1ee 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -713,13 +713,15 @@ subroutine map_lnd2glc(gcomp, rc) ! ------------------------------------------------------------------------ ! 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) + 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) + 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 diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index b027a45fc..da8cc90a6 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -7,7 +7,6 @@ module med_phases_prep_ice_mod 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_GetFldPtr => med_methods_FB_GetFldPtr 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 @@ -39,7 +38,7 @@ 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 + 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 @@ -51,6 +50,7 @@ subroutine med_phases_prep_ice(gcomp, rc) ! local variables type(ESMF_StateItem_Flag) :: itemType type(InternalState) :: is_local + type(ESMF_Field) :: lfield integer :: i,n,n1,ncnt character(len=CS) :: fldname integer :: fldnum @@ -98,7 +98,7 @@ subroutine med_phases_prep_ice(gcomp, rc) FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compice), & FBFracSrc=is_local%wrap%FBFrac(n1), & - FBNormOne=is_local%wrap%FBNormOne(n1,compice,:), & + 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 @@ -139,7 +139,10 @@ subroutine med_phases_prep_ice(gcomp, rc) 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 FB_GetFldPtr(is_local%wrap%FBExp(compice), trim(fldnames(n)) , dataptr, rc=rc) + 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 diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index e69935402..f017c31a2 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -87,7 +87,7 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compocn), & FBFracSrc=is_local%wrap%FBFrac(n1), & - FBNormOne=is_local%wrap%FBNormOne(n1,compocn,:), & + 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 diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index fadc3fb7c..58b685842 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -224,7 +224,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & FBFracSrc=is_local%wrap%FBFrac(complnd), & - FBNormOne=is_local%wrap%FBNormOne(complnd,comprof,:), & + 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 diff --git a/mediator/med_phases_prep_wav_mod.F90 b/mediator/med_phases_prep_wav_mod.F90 index 2bffaf252..9d5e51f54 100644 --- a/mediator/med_phases_prep_wav_mod.F90 +++ b/mediator/med_phases_prep_wav_mod.F90 @@ -72,7 +72,7 @@ subroutine med_phases_prep_wav(gcomp, rc) FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,compwav), & FBFracSrc=is_local%wrap%FBFrac(n1), & - FBNormOne=is_local%wrap%FBNormOne(n1,compwav,:), & + field_normOne=is_local%wrap%field_normOne(n1,compwav,:), & packed_data=is_local%wrap%packed_data(n1,compwav,:), & routehandles=is_local%wrap%RH(n1,compwav,:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 72ef8151a8375d07ee1fcb003361eb85b3cc47ca Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 26 Oct 2020 10:13:06 -0600 Subject: [PATCH 133/206] updates to fix BMOM case --- mediator/esmFldsExchange_cesm_mod.F90 | 6 ++-- mediator/med_constants_mod.F90 | 2 +- mediator/med_map_mod.F90 | 52 ++++++++++++++------------- mediator/med_phases_prep_ocn_mod.F90 | 13 ++++++- mediator/med_phases_prep_rof_mod.F90 | 2 +- 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index e626d6833..43a06c286 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -398,8 +398,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') else if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsd, 'one' , atm2ice_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsd, 'one' , atm2ocn_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsf, 'one' , atm2ice_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one' , atm2ocn_fmap) end if if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', rc=rc)) then call addmap(fldListFr(compice)%flds, 'Faii_swnet', compocn, mapfcopy, 'unset', 'unset') @@ -480,7 +480,7 @@ 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, mapconsd, 'one', atm2lnd_fmap) + 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') end if diff --git a/mediator/med_constants_mod.F90 b/mediator/med_constants_mod.F90 index 015101575..e580a462c 100644 --- a/mediator/med_constants_mod.F90 +++ b/mediator/med_constants_mod.F90 @@ -11,6 +11,6 @@ module med_constants_mod real(R8), parameter :: med_constants_czero = 0.0_R8 ! spval integer, parameter :: med_constants_ispval_mask = -987987 ! spval for RH mask values integer, parameter :: med_constants_SecPerDay = 86400 ! Seconds per day - integer :: med_constants_dbug_flag = 2 + integer :: med_constants_dbug_flag = 10 end module med_constants_mod diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 3ce5010d0..eeb4d515a 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -20,7 +20,6 @@ module med_map_mod 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_Clean => med_methods_FB_Clean - use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_Field_diagnose => med_methods_FB_Field_diagnose use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName @@ -692,7 +691,7 @@ subroutine med_map_mapnorm_init(gcomp, rc) end if ! end of if block for creating destination field end do ! end of loop over n2 - ! Deallocate memory + ! Deallocate memory deallocate(fieldlist) call ESMF_FieldDestroy(field_src, rc=rc, noGarbage=.true.) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -765,7 +764,6 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & ! Determine local size and mesh of source fields ! Allocate a source fortran pointer for the new packed field bundle - ! Create the packed source field bundle call ESMF_FieldGet(fieldlist_src(1), mesh=lmesh_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_src, numOwnedElements=lsize_src, rc=rc) @@ -773,7 +771,6 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & ! Determine local size of destination fields ! Allocate a destination fortran pointer for the new packed field bundle - ! Create the packed source field bundle call ESMF_FieldGet(fieldlist_dst(1), mesh=lmesh_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_dst, numOwnedElements=lsize_dst, rc=rc) @@ -784,11 +781,31 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & ! ungridded dimensions and need to unwrap them into separate fields for the ! purposes of packing + if (mastertask) write(logunit,*) + + ! Determine the normalization type for each packed_data mapping element + ! Loop over mapping types + do mapindex = 1,nmappers + ! Loop over source field bundle + do nf = 1, fieldCount + ! Loop over the fldsSrc types + do ns = 1,size(fldsSrc) + ! Note that fieldnamelist is an array of names for the source fields + ! The assumption is that there is only one mapping normalization + ! for any given mapping type + if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & + trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then + ! Set the normalization to the input + packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) + end if + end do + end do + end do + ! Allocate memory to keep tracked of packing index for each mapping type allocate(npacked(nmappers)) npacked(:) = 0 - if (mastertask) write(logunit,*) ! Loop over mapping types do mapindex = 1,nmappers @@ -805,24 +822,8 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & do ns = 1,size(fldsSrc) if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & - fldsSrc(ns)%shortname /= flds_scalar_name .and. & trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then - ! Determine mapnorm - the assumption is that there is only one - ! mapnorm type for a source packed field bundle - if (npacked(mapindex) == 0) then - packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) - else - if (fldsSrc(ns)%mapnorm(destcomp) /= packed_data(mapindex)%mapnorm) then - call ESMF_LogWrite(trim(subname)//& - ": ERROR mapnorm "//trim(fldsSrc(ns)%mapnorm(destcomp))//" is not equal to "// & - trim(packed_data(mapindex)%mapnorm)//" for packed field bundle ", & - ESMF_LOGMSG_ERROR, rc=rc) - rc = ESMF_FAILURE - return - end if - end if - ! Determine mapping of indices into packed field bundle ! Get source field call ESMF_FieldGet(fieldlist_src(nf), ungriddedUBound=ungriddedUBound, rc=rc) @@ -844,22 +845,23 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & 'Packed field: destcomp,mapping,mapnorm,fldname,index: ', & trim(compname(destcomp)), & trim(mapnames(mapindex)), & - trim(fldsSrc(ns)%mapnorm(destcomp)), & + trim(packed_data(mapindex)%mapnorm), & trim(fieldnamelist(nf)), & packed_data(mapindex)%fldindex(nf) end if end if! end if source field is mapped to destination field with mapindex end do ! end loop over FBSrc fields - end do ! end loop over fldSrc elements + end do ! end loop over fldsSrc elements - ! Create the source and destination packed fields for mapindex if (npacked(mapindex) > 0) then + ! Create the packed source field bundle for mapindex allocate(ptrsrc_packed(npacked(mapindex), lsize_src)) packed_data(mapindex)%field_src = ESMF_FieldCreate(lmesh_src, & ptrsrc_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Create the packed destination field bundle for mapindex allocate(ptrdst_packed(npacked(mapindex), lsize_dst)) packed_data(mapindex)%field_dst = ESMF_FieldCreate(lmesh_dst, & ptrdst_packed, gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) @@ -886,7 +888,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d ! ----------------------------------------------- use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet use ESMF , only : ESMF_FieldRedist, ESMF_RouteHandle use esmFlds , only : nmappers, mapfcopy use med_internalstate_mod , only : packed_data_type diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index f017c31a2..bbb2d41b3 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -20,7 +20,7 @@ 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 + use esmFlds , only : compocn, compatm, compice, ncomps, compname, comprof use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -81,6 +81,11 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) ! map all fields in FBImp that have active ocean coupling if (ncnt > 0) then + !DEBUG + call FB_diagnose(is_local%wrap%FBImp(comprof,comprof), string=trim(subname)//' FBImp(comprof,comprof) ', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !DEBUG + do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compocn)) then call med_map_field_packed( & @@ -93,6 +98,12 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do + + !DEBUG + call FB_diagnose(is_local%wrap%FBImp(comprof,compocn), string=trim(subname)//' FBImp(comprof,compocn) ', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !DEBUG + endif call t_stopf('MED:'//subname) diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 58b685842..79cd35bc5 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -231,7 +231,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & - string=trim(subname)//' FBImpAccum(complnd,comprof) after avg ', rc=rc) + string=trim(subname)//' FBImpAccum(complnd,comprof) after map ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if From 377a4cde20cf42b3532507f755b432bdc8151c56 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 26 Oct 2020 14:50:53 -0600 Subject: [PATCH 134/206] fixed bugs in testing --- mediator/med_phases_prep_lnd_mod.F90 | 2314 +++++++++++++++++++++----- 1 file changed, 1911 insertions(+), 403 deletions(-) diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 90bbb61b4..43a06c286 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -1,490 +1,1998 @@ -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 - 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 - 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 +module esmFldsExchange_cesm_mod - implicit none - private - - public :: med_phases_prep_lnd - - private :: map_glc2lnd_init - private :: map_glc2lnd + !--------------------------------------------------------------------- + ! This is a mediator specific routine that determines ALL possible + ! fields exchanged between components and their associated routing, + ! mapping and merging + !--------------------------------------------------------------------- - ! 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 + implicit none + public - ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 - integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + public :: esmFldsExchange_cesm - character(*) , parameter :: u_FILE_u = & + character(*), parameter :: u_FILE_u = & __FILE__ -!================================================================================================ +!================================================================================ contains -!================================================================================================ +!================================================================================ + + subroutine esmFldsExchange_cesm(gcomp, phase, rc) + + use ESMF + use NUOPC + 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_internalstate_mod , only : InternalState + use esmFlds , only : med_fldList_type + use esmFlds , only : addfld => med_fldList_AddFld + 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 : mapbilnr, mapconsf, mapconsd, mappatch + use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf + use esmflds , only : map_glc2ocn_ice, map_glc2ocn_liq, map_rof2ocn_ice, map_rof2ocn_liq + use esmflds , only : mapuv_with_cart3d + use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb + use esmFlds , only : coupling_mode + + ! input/output parameters: + type(ESMF_GridComp) :: gcomp + character(len=*) , intent(in) :: phase + integer , intent(inout) :: rc + + ! local variables: + type(InternalState) :: is_local + logical :: flds_i2o_per_cat + integer :: dbrc + integer :: num, i, n + integer :: n1, n2, n3, n4 + logical :: isPresent + character(len=5) :: iso(2) + character(len=CL) :: cvalue + character(len=CS) :: name, fldname + character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' + character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' + character(len=CX) :: atm2lnd_fmap='unset', atm2lnd_smap='unset' + character(len=CX) :: glc2lnd_smap='unset', glc2lnd_fmap='unset' + character(len=CX) :: glc2ice_rmap='unset' + character(len=CX) :: glc2ocn_liq_rmap='unset', glc2ocn_ice_rmap='unset' + character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' + character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' + character(len=CX) :: lnd2atm_fmap='unset', lnd2atm_smap='unset' + character(len=CX) :: lnd2glc_fmap='unset', lnd2glc_smap='unset' + character(len=CX) :: lnd2rof_fmap='unset' + character(len=CX) :: rof2lnd_fmap='unset' + character(len=CX) :: rof2ocn_fmap='unset', rof2ocn_ice_rmap='unset', rof2ocn_liq_rmap='unset' + character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' + character(len=CX) :: wav2ocn_smap='unset' + logical :: flds_co2a ! use case + logical :: flds_co2b ! use case + logical :: flds_co2c ! use case + character(len=CS), allocatable :: flds(:) + character(len=CS), allocatable :: suffix(:) + character(len=*) , parameter :: subname='(esmFldsExchange_cesm)' + !-------------------------------------- - subroutine med_phases_prep_lnd(gcomp, rc) + rc = ESMF_SUCCESS - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc + iso(1) = '' + iso(2) = '_wiso' - ! local variables - type(ESMF_StateItem_Flag) :: itemType - type(InternalState) :: is_local - integer :: n1,ncnt - real(r8) :: nextsw_cday - logical :: first_call = .true. - character(len=*), parameter :: subname='(med_phases_prep_lnd)' - !--------------------------------------- - rc = ESMF_SUCCESS + !--------------------------------------- + ! Get the internal state + !--------------------------------------- - call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + if (phase /= 'advertise') then + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, 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) - 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(complnd), fieldCount=ncnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - 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 + !-------------------------------------- + ! Merging arguments: + ! mrg_fromN = source component index that for the field to be merged + ! mrg_fldN = souce field name to be merged + ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', 'sum_with_weights', 'merge') + ! NOTE: + ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn fluxes or for ocn albedos + ! + ! NOTE: + ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in the + ! atm/ocn flux calculations. Input fields required from either the atm or the ocn for + ! these computation will use the logical 'use_med_aoflux' below. This is used to determine + ! mappings between the atm and ocn needed for these computations. + !-------------------------------------- + + 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) - !--------------------------------------- - ! auto merges to create FBExp(complnd) - !--------------------------------------- - - ! The following will merge all fields in fldsSrc - ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) - call med_merge_auto(complnd, & - is_local%wrap%med_coupling_active(:,complnd), & - is_local%wrap%FBExp(complnd), & - is_local%wrap%FBFrac(complnd), & - is_local%wrap%FBImp(:,complnd), & - fldListTo(complnd), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + !---------------------------------------------------------- + ! Initialize mapping file names + !---------------------------------------------------------- - !--------------------------------------- - ! custom calculations - !--------------------------------------- + ! to atm - ! 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 + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', value=ice2atm_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ice2atm_fmapname = '// trim(ice2atm_fmap), ESMF_LOGMSG_INFO) + end if - !--------------------------------------- - ! update scalar data - !--------------------------------------- - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (itemType /= ESMF_STATEITEM_NOTFOUND) then - ! send nextsw_cday to land - first obtain it from atm import - call State_GetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateImp(compatm), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call State_SetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateExp(complnd), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - ! diagnose - if (dbug_flag > 1) then - call FB_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 - - first_call = .false. - - 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_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)' - !--------------------------------------- + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', value=ice2atm_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ice2atm_smapname = '// trim(ice2atm_smap), ESMF_LOGMSG_INFO) + end if - rc = ESMF_SUCCESS + call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_fmapname', value=lnd2atm_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('lnd2atm_fmapname = '// trim(lnd2atm_fmap), ESMF_LOGMSG_INFO) + end if - !--------------------------------------- - ! Get the internal state - !--------------------------------------- + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', value=ocn2atm_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ocn2atm_smapname = '// trim(ocn2atm_smap), ESMF_LOGMSG_INFO) + end if - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', value=ocn2atm_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('ocn2atm_fmapname = '// trim(ocn2atm_fmap), ESMF_LOGMSG_INFO) + end if - !--------------------------------------- - ! Set the module variable for the number of elevation classes - !--------------------------------------- + call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_smapname', value=lnd2atm_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('lnd2atm_smapname = '// trim(lnd2atm_smap), ESMF_LOGMSG_INFO) + end if + + ! to lnd - ! 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) + call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_fmapname', value=atm2lnd_fmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) + if (isPresent) then + call ESMF_LogWrite('atm2lnd_fmapname = '// trim(atm2lnd_fmap), ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_smapname', value=atm2lnd_smap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ungriddedCount = ungriddedUBound_output(1) - ! TODO: check that ungriddedCount = glc_nec+1 + if (isPresent) then + call ESMF_LogWrite('atm2lnd_smapname = '// trim(atm2lnd_smap), ESMF_LOGMSG_INFO) + end if - !--------------------------------------- - ! Get the glc and land meshes - !--------------------------------------- + call NUOPC_CompAttributeGet(gcomp, name='rof2lnd_fmapname', value=rof2lnd_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('rof2lnd_fmapname = '// trim(rof2lnd_fmap), ESMF_LOGMSG_INFO) + end if - 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) + call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_fmapname', value=glc2lnd_fmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) + if (isPresent) then + call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_fmap), ESMF_LOGMSG_INFO) + end if - 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) + call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_smapname', value=glc2lnd_smap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) + if (isPresent) then + call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_smap), ESMF_LOGMSG_INFO) + end if - ! ------------------------------- - ! Create module field bundles - ! ------------------------------- + ! to ice - 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) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ice_fmapname = '// trim(atm2ice_fmap), ESMF_LOGMSG_INFO) + end if - field_frac_g_ec = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, isPresent=isPresent, 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 (isPresent) then + call ESMF_LogWrite('atm2ice_smapname = '// trim(atm2ice_smap), ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ice_vmapname = '// trim(atm2ice_vmap), ESMF_LOGMSG_INFO) + end if - 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) + call NUOPC_CompAttributeGet(gcomp, name='glc2ice_rmapname', value=glc2ice_rmap, isPresent=isPresent, 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 (isPresent) then + call ESMF_LogWrite('glc2ice_rmapname = '// trim(glc2ice_rmap), ESMF_LOGMSG_INFO) + end if + + ! to ocn + + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ocn_fmapname = '// trim(atm2ocn_fmap), ESMF_LOGMSG_INFO) + end if - 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) + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, isPresent=isPresent, 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 (isPresent) then + call ESMF_LogWrite('atm2ocn_smapname = '// trim(atm2ocn_smap), ESMF_LOGMSG_INFO) + end if + + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2ocn_vmapname = '// trim(atm2ocn_vmap), ESMF_LOGMSG_INFO) + end if - ! Verify that route handle has been created - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:), mapconsd,rc=rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for glc->lnd mapping", & - ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_liq_rmapname', value=glc2ocn_liq_rmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('glc2ocn_liq_rmapname = '// trim(glc2ocn_liq_rmap), ESMF_LOGMSG_INFO) 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 + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_ice_rmapname', value=glc2ocn_ice_rmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('glc2ocn_ice_rmapname = '// trim(glc2ocn_ice_rmap), ESMF_LOGMSG_INFO) end if - end subroutine map_glc2lnd_init + call NUOPC_CompAttributeGet(gcomp, name='wav2ocn_smapname', value=wav2ocn_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('wav2ocn_smapname = '// trim(wav2ocn_smap), ESMF_LOGMSG_INFO) + end if - !================================================================================================ - subroutine map_glc2lnd( gcomp, rc) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_fmapname', value=rof2ocn_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('rof2ocn_fmapname = '// trim(rof2ocn_fmap), ESMF_LOGMSG_INFO) + end if - !------------------ - ! 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. - !------------------ + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_liq_rmapname', value=rof2ocn_liq_rmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('rof2ocn_liq_rmapname = '// trim(rof2ocn_liq_rmap), ESMF_LOGMSG_INFO) + end if - ! input/output variables - type(ESMF_GridComp) , intent(inout) :: gcomp - integer , intent(out) :: rc + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_ice_rmapname', value=rof2ocn_ice_rmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('rof2ocn_ice_rmapname = '// trim(rof2ocn_ice_rmap), ESMF_LOGMSG_INFO) + end if - ! 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' - !----------------------------------------------------------------------- + ! to rof - call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + call NUOPC_CompAttributeGet(gcomp, name='lnd2rof_fmapname', value=lnd2rof_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('lnd2rof_fmapname = '// trim(lnd2rof_fmap), ESMF_LOGMSG_INFO) end if - rc = ESMF_SUCCESS - !--------------------------------------- - ! Get the internal state - !--------------------------------------- + ! to glc - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_fmapname', value=lnd2glc_fmap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('lnd2glc_fmapname = '// trim(lnd2glc_fmap), ESMF_LOGMSG_INFO) + end if - !--------------------------------- - ! Map fractional ice coverage to the land grid (multiple elevation classes) - !--------------------------------- + call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_smapname', value=lnd2glc_smap, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('lnd2glc_smapname = '// trim(lnd2glc_smap), ESMF_LOGMSG_INFO) + end if - ! Set contents of FBglc_ec to contain frac_g_ec - ! (fractional ice coverage for each elevation class on the glc grid) + ! to wav - ! 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) + call NUOPC_CompAttributeGet(gcomp, name='atm2wav_smapname', value=atm2wav_smap, isPresent=isPresent, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_LogWrite('atm2wav_smapname = '// trim(atm2wav_smap), ESMF_LOGMSG_INFO) + end if - ! 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) + call NUOPC_CompAttributeGet(gcomp, name='ice2wav_smapname', value=ice2wav_smap, isPresent=isPresent, 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) + if (isPresent) then + call ESMF_LogWrite('ice2wav_smapname = '// trim(ice2wav_smap), ESMF_LOGMSG_INFO) + end if - ! 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) + call NUOPC_CompAttributeGet(gcomp, name='ocn2wav_smapname', value=ocn2wav_smap, isPresent=isPresent, 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(:) + if (isPresent) then + call ESMF_LogWrite('ocn2wav_smapname = '// trim(ocn2wav_smap), ESMF_LOGMSG_INFO) + end if + + !---------------------------------------------------------- + ! Initialize if use 3d cartesian mapping for u,v + !---------------------------------------------------------- - ! 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) + call NUOPC_CompAttributeGet(gcomp, name='mapuv_with_cart3d', value=cvalue, isPresent=isPresent, 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(:) + read(cvalue,*) mapuv_with_cart3d + if (isPresent) then + call ESMF_LogWrite('mapuv_with_cart3d = '// trim(cvalue), ESMF_LOGMSG_INFO) + end if + + !===================================================================== + ! scalar information + !===================================================================== + + if (phase == 'advertise') then + call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldName", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,ncomps + call addfld(fldListFr(n)%flds, trim(cvalue)) + call addfld(fldListTo(n)%flds, trim(cvalue)) + end do + end if + + !===================================================================== + ! FIELDS TO MEDIATOR component (for fractions and atm/ocn flux calculation) + !===================================================================== + + !---------------------------------------------------------- + ! to med: masks from components + !---------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Sl_lfrin') + call addfld(fldListFr(compocn)%flds, 'So_omask') + call addfld(fldListFr(compice)%flds, 'Si_imask') + else + call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') + end if + + ! --------------------------------------------------------------------- + ! to med: atm and ocn fields required for atm/ocn flux calculation' + ! --------------------------------------------------------------------- + if (phase /= 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_u') + call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch, 'one', atm2ocn_vmap) + + call addfld(fldListFr(compatm)%flds, 'Sa_v') + call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch, 'one', atm2ocn_vmap) + + call addfld(fldListFr(compatm)%flds, 'Sa_z') + call addmap(fldListFr(compatm)%flds, 'Sa_z' , compocn, mapbilnr, 'one', atm2ocn_smap) + + call addfld(fldListFr(compatm)%flds, 'Sa_tbot') + call addmap(fldListFr(compatm)%flds, 'Sa_tbot', compocn, mapbilnr, 'one', atm2ocn_smap) + + call addfld(fldListFr(compatm)%flds, 'Sa_pbot') + call addmap(fldListFr(compatm)%flds, 'Sa_pbot', compocn, mapbilnr, 'one', atm2ocn_smap) + + call addfld(fldListFr(compatm)%flds, 'Sa_shum') + call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, mapbilnr, 'one', atm2ocn_smap) + + if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_shum_wiso', rc=rc)) then + call addfld(fldListFr(compatm)%flds, 'Sa_shum_wiso') + call addmap(fldListFr(compatm)%flds, 'Sa_shum_wiso', compocn, mapbilnr, 'one', atm2ocn_smap) + end if + + if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_ptem', rc=rc)) then + call addfld(fldListFr(compatm)%flds, 'Sa_ptem') + call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) + end if + + if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_dens', rc=rc)) then + call addfld(fldListFr(compatm)%flds, 'Sa_dens') + call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, mapbilnr, 'one', atm2ocn_smap) + end if + end if + + ! --------------------------------------------------------------------- + ! to med: swnet fluxes used for budget calculation + ! --------------------------------------------------------------------- + ! TODO (mvertens, 2019-01-11): budget implemention needs to be done in CMEPS + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Fall_swnet') + call addfld(fldListFr(compice)%flds, 'Faii_swnet') + call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') + else + if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', rc=rc)) then + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsf, 'one' , atm2ice_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one' , atm2ocn_fmap) + end if + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', rc=rc)) then + call addmap(fldListFr(compice)%flds, 'Faii_swnet', compocn, mapfcopy, 'unset', 'unset') + end if + end if + + !===================================================================== + ! FIELDS TO LAND + !===================================================================== + + ! --------------------------------------------------------------------- + ! from atm: + ! to lnd: height at the lowest model level from atm + ! to lnd: surface height from atm + ! to lnd: zonal wind at the lowest model level from atm + ! to lnd: meridional wind at the lowest model level from atm + ! to lnd: Temperature at the lowest model level from atm + ! to lnd: potential temperature at the lowest model level from atm + ! to lnd: Pressure at the lowest model level from atm + ! to lnd: specific humidity at the lowest model level from atm + ! --------------------------------------------------------------------- + + allocate(flds(9)) + 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)) + if (phase == 'advertise') then + 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, mapbilnr, 'one', atm2lnd_smap) + call addmrg(fldListTo(complnd)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to lnd: convective and large scale precipitation rate water equivalent from atm + ! to lnd: convective and large-scale (stable) snow rate from atm + ! to lnd: downward longwave heat flux from atm + ! to lnd: downward direct near-infrared incident solar radiation from atm + ! to lnd: downward direct visible incident solar radiation from atm + ! to lnd: downward diffuse near-infrared incident solar radiation from atm + ! to lnd: downward Diffuse visible incident solar radiation from atm + ! to lnd: black carbon deposition fluxes from atm + ! - hydrophylic black carbon dry deposition flux + ! - hydrophobic black carbon dry deposition flux + ! - hydrophylic black carbon wet deposition flux + ! to lnd: organic carbon deposition fluxes from atm + ! - hydrophylic organic carbon dry deposition flux + ! - hydrophobic organic carbon dry deposition flux + ! - hydrophylic organic carbon wet deposition flux + ! to lnd: dust wet deposition flux (sizes 1-4) from atm + ! to lnd: dust dry deposition flux (sizes 1-4) from atm + ! to lnd: nitrogen deposition fields from atm + ! --------------------------------------------------------------------- + + ! TODO (mvertens, 2018-12-13): the nitrogen deposition fluxes here + ! are not treated the same was as in cesm2.0 release + ! 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 ' /) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + 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) + call addmrg(fldListTo(complnd)%flds, trim(fldname), & + mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to lnd: river channel total water volume from rof + ! to lnd: river channel main channel water volume from rof + ! 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 '/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(comprof)%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(comprof, comprof), trim(fldname), rc=rc)) then + 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') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to lnd: ice sheet grid coverage on global grid from glc + ! 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 + + 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 + + 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 + end if + end if - ! 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) + !===================================================================== + ! FIELDS TO ATMOSPHERE + !===================================================================== + + !---------------------------------------------------------- + ! to atm: Fractions + !---------------------------------------------------------- + if (phase == 'advertise') then + ! the following are computed in med_phases_prep_atm + call addfld(fldListTo(compatm)%flds, 'Sl_lfrac') + call addfld(fldListTo(compatm)%flds, 'Si_ifrac') + call addfld(fldListTo(compatm)%flds, 'So_ofrac') 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(:,:) + ! --------------------------------------------------------------------- + ! to atm: merged direct albedo (visible radiation) + ! to atm: merged diffuse albedo (visible radiation) + ! to atm: merged direct albedo (near-infrared radiation) + ! to atm: merged diffuse albedo (near-infrared radiation) + ! --------------------------------------------------------------------- + allocate(suffix(4)) + suffix = (/'avsdr', 'avsdf', 'anidr', 'anidf'/) + + do n = 1,size(suffix) + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds, 'Si_'//trim(suffix(n))) + 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') + end if + end if + end do + deallocate(suffix) + + ! --------------------------------------------------------------------- + ! to atm: merged reference temperature at 2 meters + ! to atm: merged 10m wind speed + ! to atm: merged reference specific humidity at 2 meters + ! to atm: merged reference specific water isoptope humidity at 2 meters + ! --------------------------------------------------------------------- + allocate(suffix(4)) + suffix = (/'tref ', 'u10 ', 'qref ', 'qref_wiso'/) + + do n = 1,size(suffix) + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds , 'Sl_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds , 'Si_'//trim(suffix(n))) + 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') + end if + end if + end do + deallocate(suffix) + + ! --------------------------------------------------------------------- + ! to atm: merged zonal surface stress + ! to atm: merged meridional surface stress + ! to atm: merged surface latent heat flux + ! to atm: merged surface sensible heat flux + ! to atm: merged surface upward longwave heat flux + ! to atm: evaporation water flux from water + ! to atm: evaporation water flux from water isotopes + ! --------------------------------------------------------------------- + allocate(suffix(7)) + 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(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))) + 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') + end if + end if + end do + deallocate(suffix) + + ! --------------------------------------------------------------------- + ! to atm: merged surface temperature and unmerged temperatures from ice and ocn + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Sl_t') + call addfld(fldListFr(compice)%flds, 'Si_t') + call addfld(fldListFr(compocn)%flds, 'So_t') + 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') + call addmrg(fldListTo(compatm)%flds, 'So_t', & + mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') + end if + end if - !--------------------------------- - ! Map topo to the land grid (multiple elevation classes) - !--------------------------------- + ! --------------------------------------------------------------------- + ! to atm: surface snow depth from ice (needed for cam) + ! to atm: mean ice volume per unit area from ice + ! to atm: mean snow volume per unit area from ice + ! --------------------------------------------------------------------- + allocate(flds(3)) + flds = (/'Si_snowh', 'Si_vice ', 'Si_vsno '/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compice)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + 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 addmrg(fldListTo(compatm)%flds, trim(fldname), & + mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to atm: surface saturation specific humidity in ocean from med aoflux + ! to atm: square of exch. coeff (tracers) from med aoflux + ! to atm: surface fraction velocity from med aoflux + ! --------------------------------------------------------------------- + allocate(flds(3)) + flds = (/'So_ssq ', 'So_re ', 'So_ustar'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListMed_aoflux%flds , trim(fldname)) + call addfld(fldListTo(compatm)%flds , trim(fldname)) + 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 addmrg(fldListTo(compatm)%flds , trim(fldname), & + mrg_from1=compmed, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to atm: surface fraction velocity from land + ! to atm: aerodynamic resistance from land + ! to atm: surface snow water equivalent from land + ! --------------------------------------------------------------------- + allocate(flds(3)) + flds = (/'Sl_fv ', 'Sl_ram1 ', 'Sl_snowh'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + 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 addmrg(fldListTo(compatm)%flds, trim(fldname), & + mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to atm: dust fluxes from land (4 sizes) + ! --------------------------------------------------------------------- + fldname = 'Fall_flxdst' + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if - ! 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 + !----------------------------------------------------------------------------- + ! to atm: MEGAN emissions fluxes from land + !----------------------------------------------------------------------------- + fldname = 'Fall_voc' + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if - 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 + !----------------------------------------------------------------------------- + ! to atm: fire emissions fluxes from land + !----------------------------------------------------------------------------- + ! 'wild fire emission fluxes' + fldname = 'Fall_fire' + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if + + ! 'wild fire plume height' + fldname = 'Sl_fztop' + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if + + !----------------------------------------------------------------------------- + ! to atm: dry deposition velocities from land + !----------------------------------------------------------------------------- + fldname = 'Sl_ddvel' + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if + + !===================================================================== + ! FIELDS TO OCEAN (compocn) + !===================================================================== + + !---------------------------------------------------------- + ! to ocn: fractional ice coverage wrt ocean from ice + !---------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compice)%flds, 'Si_ifrac') + 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') + end if + + ! --------------------------------------------------------------------- + ! to ocn: downward longwave heat flux from atm + ! to ocn: downward direct near-infrared incident solar radiation from atm + ! to ocn: downward diffuse near-infrared incident solar radiation from atm + ! to ocn: downward dirrect visible incident solar radiation from atm + ! to ocn: downward diffuse visible incident solar radiation from atm + ! --------------------------------------------------------------------- + allocate(flds(5)) + flds = (/'Faxa_lwdn ', 'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + else + 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') + end if + end if end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ocn: surface upward longwave heat flux from mediator + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListMed_aoflux%flds , 'Faox_lwup') + call addfld(fldListTo(compocn)%flds , 'Foxx_lwup') + else + 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') + end if + end if - ! 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) + ! --------------------------------------------------------------------- + ! to ocn: merged longwave net heat flux + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds , 'Faxa_lwdn') + call addfld(fldListMed_aoflux%flds , 'Faox_lwup' ) + call addfld(fldListTo(compocn)%flds , 'Foxx_lwnet') + else + ! (mom6) (send longwave net to ocn via auto merge) + if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_lwnet', rc=rc) .and. & + fldchk(is_local%wrap%FBMed_aoflux_o , 'Faox_lwup' , rc=rc) .and. & + 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') + end if 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) + ! --------------------------------------------------------------------- + ! to ocn: downward shortwave heat flux + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Faxa_swdn') + call addfld(fldListTo(compocn)%flds, 'Faxa_swdn') + else + if (fldchk(is_local%wrap%FBImp(compatm, compatm), 'Faxa_swdn', rc=rc) .and. & + 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') + end if 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 + ! --------------------------------------------------------------------- + ! to ocn: net shortwave radiation from med + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Faxa_swvdr') + call addfld(fldListFr(compatm)%flds, 'Faxa_swndr') + call addfld(fldListFr(compatm)%flds, 'Faxa_swvdf') + call addfld(fldListFr(compatm)%flds, 'Faxa_swndf') + + call addfld(fldListFr(compice)%flds, 'Fioi_swpen') + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdr') + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdf') + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idr') + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idf') + + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet') + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdr') + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdf') + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idr') + call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idf') + else + ! Net shortwave ocean (custom calculation in prep_phases_ocn_mod.F90) + + ! import swpen from ice without bands + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen', rc=rc)) then + call addmap(fldListFr(compice)%flds, 'Fioi_swpen', compocn, mapfcopy, 'unset', 'unset') + end if + + ! import swpen from ice by bands + if ( fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdr', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdf', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idr', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idf', rc=rc)) then + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdr', compocn, mapfcopy, 'unset', 'unset') + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdf', compocn, mapfcopy, 'unset', 'unset') + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idr', compocn, mapfcopy, 'unset', 'unset') + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idf', compocn, mapfcopy, 'unset', 'unset') + end if + + ! import sw from atm by bands + if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdr', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdf', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & + (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet' , rc=rc)) .or. & + (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', rc=rc))) then + call addmap(fldListFr(compatm)%flds, 'Faxa_swvdr', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swvdf', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swndr', compocn, mapconsf, 'one', atm2ocn_fmap) + call addmap(fldListFr(compatm)%flds, 'Faxa_swndf', compocn, mapconsf, 'one', atm2ocn_fmap) + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: per ice thickness fraction and sw penetrating into ocean from ice + ! --------------------------------------------------------------------- + if (flds_i2o_per_cat) then + if (phase == 'advertise') then + ! 'fractional ice coverage wrt ocean for each thickness category ' + call addfld(fldListFr(compice)%flds, 'Si_ifrac_n') + call addfld(fldListTo(compocn)%flds, 'Si_ifrac_n') + + ! net shortwave radiation penetrating into ocean for each thickness category + call addfld(fldListFr(compice)%flds, 'Fioi_swpen_ifrac_n') + call addfld(fldListTo(compocn)%flds, 'Fioi_swpen_ifrac_n') + + ! 'fractional atmosphere coverage wrt ocean' (computed in med_phases_prep_ocn) + call addfld(fldListTo(compocn)%flds, 'Sf_afrac') + ! 'fractional atmosphere coverage used in radiation computations wrt ocean' (computed in med_phases_prep_ocn) + call addfld(fldListTo(compocn)%flds, 'Sf_afracr') + ! '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') + ! Note that 'Sf_afrac, 'Sf_afracr' and 'Foxx_swnet_afracr' will have explicit merging in med_phases_prep_ocn + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: precipitation rate water equivalent from atm + ! to ocn: snow rate water equivalent from atm + ! --------------------------------------------------------------------- + + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') + call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') + call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) + call addfld(fldListTo(compocn)%flds, 'Faxa_rain' ) + + call addfld(fldListFr(compatm)%flds, 'Faxa_rainc_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_rainl_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_rain_wiso' ) + call addfld(fldListTo(compocn)%flds, 'Faxa_rain_wiso' ) + + call addfld(fldListFr(compatm)%flds, 'Faxa_snowc') + call addfld(fldListFr(compatm)%flds, 'Faxa_snowl') + call addfld(fldListFr(compatm)%flds, 'Faxa_snow' ) + call addfld(fldListTo(compocn)%flds, 'Faxa_snow' ) + + call addfld(fldListFr(compatm)%flds, 'Faxa_snowc_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_snowl_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_snow_wiso' ) + call addfld(fldListTo(compocn)%flds, 'Faxa_snow_wiso' ) + else + do n = 1,2 + ! Note that the mediator atm/ocn flux calculation needs Faxa_rainc for the gustiness parameterization + ! which by default is not actually used + if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl'//iso(n), rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc'//iso(n), rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_rain' //iso(n), rc=rc)) then + call addmap(fldListFr(compatm)%flds, 'Faxa_rainl'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) + 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') + 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') + 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') + 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. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc'//iso(n), rc=rc)) then + call addmap(fldListFr(compatm)%flds, 'Faxa_snowl'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) + 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') else - dataptr2d(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) + 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') 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') + end if + end do + end if + + ! --------------------------------------------------------------------- + ! to ocn: merged sensible heat flux + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds , 'Faxa_sen') + call addfld(fldListMed_aoflux%flds , 'Faox_sen') + call addfld(fldListFr(compice)%flds , 'Fioi_melth') + call addfld(fldListTo(compocn)%flds , 'Foxx_sen') + else + 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') + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: surface latent heat flux and evaporation water flux + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + + call addfld(fldListFr(compatm)%flds, 'Faxa_lat' ) + call addfld(fldListMed_aoflux%flds , 'Faox_lat' ) + call addfld(fldListMed_aoflux%flds , 'Faox_evap') + call addfld(fldListTo(compocn)%flds, 'Foxx_lat' ) + call addfld(fldListTo(compocn)%flds, 'Foxx_evap') + else + 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') + 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') + end if + end if + + if (phase == 'advertise') then + call addfld(fldListMed_aoflux%flds , 'Faox_lat_wiso' ) + call addfld(fldListTo(compocn)%flds, 'Foxx_lat_wiso' ) + else + 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') + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: wind speed squared at 10 meters from med + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListMed_aoflux%flds , 'So_duu10n') + call addfld(fldListTo(compocn)%flds, 'So_duu10n') + else + if ( fldchk(is_local%wrap%FBMed_aoflux_o, 'So_duu10n', rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn), 'So_duu10n', rc=rc)) then + + 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') + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: sea level pressure from atm + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_pslv') + call addfld(fldListTo(compocn)%flds, 'Sa_pslv') + else + if ( fldchk(is_local%wrap%FBImp(compatm, compatm), 'Sa_pslv', rc=rc) .and. & + fldchk(is_local%wrap%FBExp(compocn) , 'Sa_pslv', rc=rc)) then + + call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compocn, mapbilnr, 'one', atm2ocn_smap) + 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') + end if + end if + + ! --------------------------------------------------------------------- + ! to ocn: black carbon deposition fluxes from atm + ! - hydrophylic black carbon dry deposition flux + ! - hydrophobic black carbon dry deposition flux + ! - hydrophylic black carbon wet deposition flux + ! to ocn: organic carbon deposition fluxes from atm + ! - hydrophylic organic carbon dry deposition flux + ! - hydrophobic organic carbon dry deposition flux + ! - hydrophylic organic carbon wet deposition flux + ! to ocn: dust wet deposition flux (sizes 1-4) from atm + ! to ocn: dust dry deposition flux (sizes 1-4) from atm + ! to ocn: nitrogen deposition fields (2) from atm + ! --------------------------------------------------------------------- + allocate(flds(5)) + flds = (/'Faxa_bcph ', 'Faxa_ocph ', 'Faxa_dstwet' , 'Faxa_dstdry', 'Faxa_ndep ' /) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(compatm,compatm), trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ocn: merge zonal surface stress from ice and (atm or med) + ! --------------------------------------------------------------------- + allocate(suffix(2)) + suffix = (/'taux', 'tauy'/) + + do n = 1,size(suffix) + if (phase == 'advertise') then + call addfld(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n))) + call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(suffix(n))) + call addfld(fldListFr(compatm)%flds , 'Faxa_'//trim(suffix(n))) + call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) + else + if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_'//trim(suffix(n)), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(suffix) + + ! --------------------------------------------------------------------- + ! to ocn: water flux due to melting ice from ice + ! --------------------------------------------------------------------- + do n = 1,size(iso) + if (phase == 'advertise') then + call addfld(fldListFr(compice)%flds , 'Fioi_meltw'//iso(n)) + call addfld(fldListTo(compocn)%flds , 'Fioi_meltw'//iso(n)) + else + if ( fldchk(is_local%wrap%FBexp(compocn) , 'Fioi_meltw'//iso(n), rc=rc) .and. & + 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') + end if + end if + end do + + ! --------------------------------------------------------------------- + ! to ocn: heat flux from melting ice from ice + ! to ocn: salt flux from ice + ! to ocn: hydrophylic black carbon deposition flux from ice + ! to ocn: hydrophobic black carbon deposition flux from ice + ! to ocn: dust flux from ice + ! --------------------------------------------------------------------- + ! TODO (mvertens, 2019-01-07): is fioi_melth being handled here? + ! Is fd.yaml correctly aliasing Fioi_melth? + + allocate(flds(5)) + flds = (/'Fioi_melth ', 'Fioi_salt ', 'Fioi_bcphi ', 'Fioi_bcpho ', 'Fioi_flxdst'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compice)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + !----------------------------- + ! to ocn: liquid runoff from rof and glc components + ! to ocn: frozen runoff flux from rof and glc components + ! to ocn: waterflux back to ocn due to flooding from rof + !----------------------------- + + if (phase == 'advertise') then + do n = 1,size(iso) + ! 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)) + 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)) + 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') + 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') end if end do + end if + + !----------------------------- + ! to ocn: Langmuir multiplier from wave + ! to ocn: Stokes drift u component from wave + ! to ocn: Stokes drift v component from wave + ! to ocn: Stokes drift depth from wave + !----------------------------- + allocate(flds(4)) + flds = (/'Sw_lamult ', 'Sw_ustokes', 'Sw_vstokes', 'Sw_hstokes'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compwav)%flds, trim(fldname)) + call addfld(fldListTo(compocn)%flds, trim(fldname)) + 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 addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from1=compwav, mrg_fld1=trim(fldname), mrg_type1='copy') + end if + end if + end do + deallocate(flds) + + !===================================================================== + ! FIELDS TO ICE (compice) + !===================================================================== + + ! --------------------------------------------------------------------- + ! to ice: downward longwave heat flux from atm + ! to ice: downward direct near-infrared incident solar radiation from atm + ! to ice: downward direct visible incident solar radiation from atm + ! to ice: downward diffuse near-infrared incident solar radiation from atm + ! to ice: downward Diffuse visible incident solar radiation from atm + ! to ice: hydrophylic black carbon dry deposition flux from atm + ! to ice: hydrophobic black carbon dry deposition flux from atm + ! to ice: hydrophylic black carbon wet deposition flux from atm + ! to ice: hydrophylic organic carbon dry deposition flux from atm + ! to ice: hydrophobic organic carbon dry deposition flux from atm + ! to ice: hydrophylic organic carbon wet deposition flux from atm + ! to ice: dust wet deposition flux (size 1) from atm + ! to ice: dust wet deposition flux (size 2) from atm + ! to ice: dust wet deposition flux (size 3) from atm + ! to ice: dust wet deposition flux (size 4) from atm + ! to ice: dust dry deposition flux (size 1) from atm + ! to ice: dust dry deposition flux (size 2) from atm + ! to ice: dust dry deposition flux (size 3) from atm + ! to ice: dust dry deposition flux (size 4) from atm + ! --------------------------------------------------------------------- + allocate(flds(9)) + flds = (/'Faxa_lwdn ' , 'Faxa_swndr ' , 'Faxa_swvdr ' , 'Faxa_swndf ' , 'Faxa_swvdf ', & + 'Faxa_bcph ' , 'Faxa_ocph ' , 'Faxa_dstwet' , 'Faxa_dstdry' /) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compice)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBExp(compice) , trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ice: convective and large scale precipitation rate water equivalent from atm + ! to ice: rain and snow rate from atm + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') + call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') + call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) + call addfld(fldListTo(compice)%flds, 'Faxa_rain' ) + + call addfld(fldListFr(compatm)%flds, 'Faxa_rainc_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_rainl_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_rain_wiso' ) + call addfld(fldListTo(compice)%flds, 'Faxa_rain_wiso' ) + else + if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_rain' , rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc', rc=rc)) then + 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') + 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') + 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. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc_wiso', rc=rc)) then + 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') + 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') + end if + end if + + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Faxa_snowc') + call addfld(fldListFr(compatm)%flds, 'Faxa_snowl') + call addfld(fldListFr(compatm)%flds, 'Faxa_snow' ) + call addfld(fldListTo(compice)%flds, 'Faxa_snow' ) + + call addfld(fldListFr(compatm)%flds, 'Faxa_snowc_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_snowl_wiso') + call addfld(fldListFr(compatm)%flds, 'Faxa_snow_wiso' ) + call addfld(fldListTo(compice)%flds, 'Faxa_snow_wiso' ) + else + if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_snow' , rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc', rc=rc)) then + 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') + 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') + 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. & + fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc_wiso', rc=rc)) then + 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') + 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') + end if + end if + + ! --------------------------------------------------------------------- + ! to ice: height at the lowest model level from atm + ! to ice: pressure at the lowest model level fromatm + ! to ice: temperature at the lowest model level from atm + ! to ice: potential temperature at the lowest model level from atm + ! to ice: density at the lowest model level from atm + ! to ice: zonal wind at the lowest model level from atm + ! to ice: meridional wind at the lowest model level from atm + ! to ice: specific humidity at the lowest model level from atm + ! to ice: specific humidity for water isotopes at the lowest model level from atm + ! --------------------------------------------------------------------- + allocate(flds(9)) + flds = (/'Sa_z ', 'Sa_pbot ', 'Sa_tbot ', 'Sa_ptem ', & + 'Sa_dens ', 'Sa_u ', 'Sa_v ', 'Sa_shum ', 'Sa_shum_wiso'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compice)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then + if (trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v') then + call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mappatch, 'one', atm2ice_vmap) + else + 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') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ice: sea surface temperature from ocn + ! to ice: sea surface salinity from ocn + ! to ice: zonal sea water velocity from ocn + ! to ice: meridional sea water velocity from ocn + ! to ice: zonal sea surface slope from ocean + ! to ice: meridional sea surface slope from ocn + ! --------------------------------------------------------------------- + allocate(flds(6)) + flds = (/'So_t ', 'So_s ', 'So_u ', 'So_v ', 'So_dhdx', 'So_dhdy'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, trim(fldname)) + call addfld(fldListTo(compice)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & + 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') + end if + end if end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to ice: ocean melt and freeze potential from ocn + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, 'Fioo_q') + call addfld(fldListTo(compice)%flds, 'Fioo_q') + else + 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') + end if + end if - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + !----------------------------- + ! to ice: Ratio of ocean surface level abund. H2_16O/H2O/Rstd from ocean + !----------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, 'So_roce_wiso') + call addfld(fldListTo(compice)%flds, 'So_roce_wiso') + else + 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') + end if end if - call t_stopf('MED:'//subname) - end subroutine map_glc2lnd + ! --------------------------------------------------------------------- + ! to ice: frozen runoff from rof and glc + ! --------------------------------------------------------------------- + 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 + 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') + end if + end if + end do + + !===================================================================== + ! FIELDS TO WAVE (compwav) + !===================================================================== + + !---------------------------------------------------------- + ! to wav: fractional ice coverage wrt ocean from ice + !---------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compice)%flds, 'Si_ifrac') + call addfld(fldListTo(compwav)%flds, 'Si_ifrac') + else + if ( fldchk(is_local%wrap%FBexp(compwav) , 'Si_ifrac', rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compice,compice ), 'Si_ifrac', 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(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') + end if + end if -end module med_phases_prep_lnd_mod + ! --------------------------------------------------------------------- + ! to wav: ocean boundary layer depth from ocn + ! to wav: ocean currents from ocn + ! to wav: ocean surface temperature from ocn + ! --------------------------------------------------------------------- + allocate(flds(4)) + flds = (/'So_t ', 'So_u ', 'So_v ', 'So_bldepth'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, trim(fldname)) + call addfld(fldListTo(compwav)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(compocn, compocn), trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + ! --------------------------------------------------------------------- + ! to wav: zonal wind at the lowest model level from atm + ! to wav: meridional wind at the lowest model level from atm + ! --------------------------------------------------------------------- + allocate(flds(3)) + flds = (/'Sa_u ', 'Sa_v ', 'Sa_tbot'/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, trim(fldname)) + call addfld(fldListTo(compwav)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBexp(compwav) , trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + !===================================================================== + ! FIELDS TO RIVER (comprof) + !===================================================================== + + ! --------------------------------------------------------------------- + ! to rof: water flux from land (liquid surface) + ! to rof: water flux from land (liquid glacier, wetland, and lake) + ! to rof: water flux from land (liquid subsurface) + ! to rof: water flux from land direct to ocean + ! to rof: irrigation flux from land (withdrawal from rivers) + ! --------------------------------------------------------------------- + ! TODO (mvertens, 2019-01-13): the following isotopes have not yet been defined in the NUOPC field dict + ! allocate(flds(12)) + ! flds = (/'Flrl_rofsur', 'Flrl_rofsur_wiso', 'Flrl_rofgwl', 'Flrl_rofgwl_wiso', & + ! 'Flrl_rofsub', 'Flrl_rofsub_wiso', 'Flrl_rofdto', 'Flrl_rofdto_wiso', & + ! 'Flrl_rofi' , 'Flrl_rofi_wiso' , 'Flrl_irrig' , 'Flrl_irrig_wiso' /) + + allocate(flds(6)) + flds = (/'Flrl_rofsur', 'Flrl_rofgwl', 'Flrl_rofsub', 'Flrl_rofdto', 'Flrl_rofi ', 'Flrl_irrig '/) + + do n = 1,size(flds) + fldname = trim(flds(n)) + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, trim(fldname)) + call addfld(fldListTo(comprof)%flds, trim(fldname)) + else + if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & + 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') + end if + end if + end do + deallocate(flds) + + !===================================================================== + ! FIELDS TO LAND-ICE (compglc) + !===================================================================== + + !----------------------------- + ! to glc: from land + !----------------------------- + ! - fields sent from lnd->med ARE in multiple elevation classes + ! - fields sent from med->glc do NOT have elevation classes + + ! Sets a coupling field for all glc elevation classes (1:glc_nec) plus bare land (index 0). + ! Note that, if glc_nec = 0, then we don't create any coupling fields (not even the bare land (0) fldindex) + ! Note : Sl_topo is sent from lnd -> med, but is NOT sent to glc (only used for the remapping in the mediator) + + 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) + 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) + end if + end if + + !===================================================================== + ! CO2 EXCHANGE + !===================================================================== + + call NUOPC_CompAttributeGet(gcomp, name='flds_co2a', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) flds_co2a + call ESMF_LogWrite('flds_co2a = '// trim(cvalue), ESMF_LOGMSG_INFO) + + call NUOPC_CompAttributeGet(gcomp, name='flds_co2b', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) flds_co2b + call ESMF_LogWrite('flds_co2b = '// trim(cvalue), ESMF_LOGMSG_INFO) + + call NUOPC_CompAttributeGet(gcomp, name='flds_co2c', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) flds_co2c + call ESMF_LogWrite('flds_co2c = '// trim(cvalue), ESMF_LOGMSG_INFO) + + if (flds_co2a) then + ! --------------------------------------------------------------------- + ! to lnd and ocn: prognostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') + call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') + call addfld(fldListTo(compocn)%flds, 'Sa_co2prog') + else + call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', complnd, mapbilnr, 'one', atm2lnd_smap) + 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') + call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & + mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + end if + + ! --------------------------------------------------------------------- + ! to lnd and ocn: diagnostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') + call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') + call addfld(fldListTo(compocn)%flds, 'Sa_co2diag') + else + call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', complnd, mapbilnr, 'one', atm2lnd_smap) + 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') + call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & + mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + end if + + else if (flds_co2b) then + + ! --------------------------------------------------------------------- + ! to lnd: prognostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') + call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') + 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') + end if + + ! --------------------------------------------------------------------- + ! to lnd: diagnostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') + call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') + 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') + end if + + ! --------------------------------------------------------------------- + ! to atm: surface flux of CO2 from land + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') + call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') + 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') + end if + + else if (flds_co2c) then + + ! --------------------------------------------------------------------- + ! to lnd and ocn: prognostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') + call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') + call addfld(fldListTo(compocn)%flds, 'Sa_co2prog') + else + call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', complnd, mapbilnr, 'one', atm2lnd_smap) + 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') + call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & + mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + end if + + ! --------------------------------------------------------------------- + ! to lnd and ocn: diagnostic CO2 at the lowest atm model level + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') + call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') + call addfld(fldListTo(compocn)%flds, 'Sa_co2diag') + else + call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', complnd, mapbilnr, 'one', atm2lnd_smap) + 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') + call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & + mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + end if + + ! --------------------------------------------------------------------- + ! to atm: surface flux of CO2 from land + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') + call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') + 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') + end if + + ! --------------------------------------------------------------------- + ! to atm: surface flux of CO2 from ocn + ! --------------------------------------------------------------------- + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, 'Faoo_fco2_ocn') + call addfld(fldListTo(compatm)%flds, 'Faoo_fco2_ocn') + else + call addmap(fldListFr(compocn)%flds, 'Faoo_fco2_ocn', compatm, mapconsf, 'one', ocn2atm_fmap) + ! custom merge in med_phases_prep_atm + end if + endif + + !----------------------------------------------------------------------------- + ! CARMA fields (volumetric soil water) + !----------------------------------------------------------------------------- + ! TODO: add this + ! if (carma_flds /= ' ') then + ! 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') + ! enddo + ! endif + + end subroutine esmFldsExchange_cesm + +end module esmFldsExchange_cesm_mod From 3690cb6bf79eeffd6026a02804d09620d46883e0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 28 Oct 2020 09:52:07 -0600 Subject: [PATCH 135/206] merge updates and cleanup of med_methods_mod --- mediator/med.F90 | 5 - mediator/med_map_mod.F90 | 11 +- mediator/med_merge_mod.F90 | 193 +-- mediator/med_methods_mod.F90 | 1422 ++-------------- mediator/med_phases_aofluxes_mod.F90 | 1 - mediator/med_phases_prep_lnd_mod.F90 | 2314 +++++--------------------- 6 files changed, 582 insertions(+), 3364 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 584765329..d8e49f8c4 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -14,14 +14,12 @@ module MED 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_GeomWrite => med_methods_State_GeomWrite 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_Copy => med_methods_FB_Copy 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 @@ -1396,9 +1394,6 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc) if (dbug_flag > 1) then call State_GeomPrint(is_local%wrap%NStateExp(n1),'gridExp'//trim(compname(n1)),rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call State_GeomWrite(is_local%wrap%NStateExp(n1), 'grid_med_'//trim(compname(n1)), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return end if endif enddo diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index eeb4d515a..72e8131e0 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -17,12 +17,9 @@ module med_map_mod use med_utils_mod , only : chkerr => med_utils_ChkErr use med_utils_mod , only : memcheck => med_memcheck use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN - 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_Clean => med_methods_FB_Clean use med_methods_mod , only : FB_Field_diagnose => med_methods_FB_Field_diagnose use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk - use med_methods_mod , only : FB_GetFieldByName => med_methods_FB_GetFieldByName use med_methods_mod , only : Field_diagnose => med_methods_Field_diagnose use perf_mod , only : t_startf, t_stopf @@ -1268,7 +1265,7 @@ subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex ! Regrid a field in a field bundle to another field in a field bundle ! ---------------------------------------------- - use ESMF , only : ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field + use ESMF , only : ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field, ESMF_FieldBundleGet use perf_mod , only : t_startf, t_stopf type(ESMF_FieldBundle), intent(in) :: FBin @@ -1300,12 +1297,10 @@ subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex end if if (FB_FldChk(FBin , trim(fldin) , rc=rc) .and. FB_FldChk(FBout, trim(fldout), rc=rc)) then - call FB_GetFieldByName(FBin, trim(fldin), field1, rc=rc) + call ESMF_FieldBundleGet(FBin, fieldName=trim(fldin), field=field1, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call FB_GetFieldByName(FBout, trim(fldout), field2, rc=rc) + call ESMF_FieldBundleGet(FBout, fieldName=trim(fldout), field=field2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field(field_src=field1, field_dst=field2, routehandles=routehandles, maptype=mapindex, & fldname=trim(lfldname), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index e5868cb7e..b34c560ad 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -13,7 +13,6 @@ module med_merge_mod use med_utils_mod , only : ChkErr => med_utils_ChkErr use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr - use med_methods_mod , only : FieldPtr_Compare => med_methods_FieldPtr_Compare use esmFlds , only : compmed, compname use esmFlds , only : med_fldList_type use esmFlds , only : med_fldList_GetNumFlds @@ -27,8 +26,7 @@ module med_merge_mod public :: med_merge_field interface med_merge_field ; module procedure & - med_merge_field_1D, & - med_merge_field_2D + med_merge_field_1D end interface private :: med_merge_auto_field @@ -543,15 +541,14 @@ subroutine med_merge_field_1D(FBout, fnameout, & endif if (FBinfound) then - if (.not.FieldPtr_Compare(dataPtr, dataOut, subname, rc)) then + if (lbound(dataPtr,1) /= lbound(dataOut,1) .or. ubound(dataPtr,1) /= ubound(dataOut,1)) then call ESMF_LogWrite(trim(subname)//": ERROR FBin wrong size", & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) rc = ESMF_FAILURE return endif - if (wgtfound) then - if (.not.FieldPtr_Compare(dataPtr, wgt, subname, rc)) then + if (lbound(dataPtr,1) /= lbound(wgt,1) .or. ubound(dataPtr,1) /= ubound(wgt,1)) then call ESMF_LogWrite(trim(subname)//": ERROR wgt wrong size", & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) rc = ESMF_FAILURE @@ -575,190 +572,6 @@ subroutine med_merge_field_1D(FBout, fnameout, & end subroutine med_merge_field_1D - !=============================================================================== - subroutine med_merge_field_2D(FBout, fnameout, & - FBinA, fnameA, wgtA, & - FBinB, fnameB, wgtB, & - FBinC, fnameC, wgtC, & - FBinD, fnameD, wgtD, & - FBinE, fnameE, wgtE, rc) - - use ESMF , only : ESMF_FieldBundle, ESMF_LogWrite - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_LOGMSG_WARNING, ESMF_LOGMSG_INFO - - ! ---------------------------------------------- - ! Supports up to a five way merge - ! ---------------------------------------------- - - ! input/output arguments - type(ESMF_FieldBundle) , intent(inout) :: FBout - character(len=*) , intent(in) :: fnameout - type(ESMF_FieldBundle) , intent(in) :: FBinA - character(len=*) , intent(in) :: fnameA - real(R8) , intent(in), pointer :: wgtA(:,:) - type(ESMF_FieldBundle) , intent(in), optional :: FBinB - character(len=*) , intent(in), optional :: fnameB - real(R8) , intent(in), optional, pointer :: wgtB(:,:) - type(ESMF_FieldBundle) , intent(in), optional :: FBinC - character(len=*) , intent(in), optional :: fnameC - real(R8) , intent(in), optional, pointer :: wgtC(:,:) - type(ESMF_FieldBundle) , intent(in), optional :: FBinD - character(len=*) , intent(in), optional :: fnameD - real(R8) , intent(in), optional, pointer :: wgtD(:,:) - type(ESMF_FieldBundle) , intent(in), optional :: FBinE - character(len=*) , intent(in), optional :: fnameE - real(R8) , intent(in), optional, pointer :: wgtE(:,:) - integer , intent(out) :: rc - - ! local variables - real(R8), pointer :: dataOut(:,:) - real(R8), pointer :: dataPtr(:,:) - real(R8), pointer :: wgt(:,:) - integer :: lb1,ub1,lb2,ub2,i,j,n - logical :: wgtfound, FBinfound - integer :: dbrc - character(len=*),parameter :: subname='(med_merge_field_2d)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc=ESMF_SUCCESS - - if (.not. FB_FldChk(FBout, trim(fnameout), rc=rc)) then - call ESMF_LogWrite(trim(subname)//": WARNING field not in FBout, skipping merge "//& - trim(fnameout), ESMF_LOGMSG_WARNING, line=__LINE__, file=u_FILE_u, rc=dbrc) - return - endif - - call FB_GetFldPtr(FBout, trim(fnameout), fldptr2=dataOut, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - lb1 = lbound(dataOut,1) - ub1 = ubound(dataOut,1) - lb2 = lbound(dataOut,2) - ub2 = ubound(dataOut,2) - - dataOut = czero - - ! check each field has a fieldname passed in - if ((present(FBinB) .and. .not.present(fnameB)) .or. & - (present(FBinC) .and. .not.present(fnameC)) .or. & - (present(FBinD) .and. .not.present(fnameD)) .or. & - (present(FBinE) .and. .not.present(fnameE))) then - call ESMF_LogWrite(trim(subname)//": ERROR fname not present with FBin", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) - rc = ESMF_FAILURE - return - endif - - ! check that each field passed in actually exists, if not DO NOT do any merge - FBinfound = .true. - if (present(FBinB)) then - if (.not. FB_FldChk(FBinB, trim(fnameB), rc=rc)) FBinfound = .false. - endif - if (present(FBinC)) then - if (.not. FB_FldChk(FBinC, trim(fnameC), rc=rc)) FBinfound = .false. - endif - if (present(FBinD)) then - if (.not. FB_FldChk(FBinD, trim(fnameD), rc=rc)) FBinfound = .false. - endif - if (present(FBinE)) then - if (.not. FB_FldChk(FBinE, trim(fnameE), rc=rc)) FBinfound = .false. - endif - if (.not. FBinfound) then - call ESMF_LogWrite(trim(subname)//": WARNING field not found in FBin, skipping merge "//trim(fnameout), & - ESMF_LOGMSG_WARNING, line=__LINE__, file=u_FILE_u, rc=dbrc) - return - endif - - ! n=1,5 represents adding A to E inputs if they exist - do n = 1,5 - FBinfound = .false. - wgtfound = .false. - - if (n == 1) then - FBinfound = .true. - call FB_GetFldPtr(FBinA, trim(fnameA), fldptr2=dataPtr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - wgtfound = .true. - wgt => wgtA - - elseif (n == 2 .and. present(FBinB)) then - FBinfound = .true. - call FB_GetFldPtr(FBinB, trim(fnameB), fldptr2=dataPtr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (present(wgtB)) then - wgtfound = .true. - wgt => wgtB - endif - - elseif (n == 3 .and. present(FBinC)) then - FBinfound = .true. - call FB_GetFldPtr(FBinC, trim(fnameC), fldptr2=dataPtr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (present(wgtC)) then - wgtfound = .true. - wgt => wgtC - endif - - elseif (n == 4 .and. present(FBinD)) then - FBinfound = .true. - call FB_GetFldPtr(FBinD, trim(fnameD), fldptr2=dataPtr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (present(wgtD)) then - wgtfound = .true. - wgt => wgtD - endif - - elseif (n == 5 .and. present(FBinE)) then - FBinfound = .true. - call FB_GetFldPtr(FBinE, trim(fnameE), fldptr2=dataPtr, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (present(wgtE)) then - wgtfound = .true. - wgt => wgtE - endif - - endif - - if (FBinfound) then - if (.not.FieldPtr_Compare(dataPtr, dataOut, subname, rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR FBin wrong size", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) - rc = ESMF_FAILURE - return - endif - - if (wgtfound) then - if (.not. FieldPtr_Compare(dataPtr, wgt, subname, rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR wgt wrong size", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u, rc=dbrc) - rc = ESMF_FAILURE - return - endif - do j = lb2,ub2 - do i = lb1,ub1 - dataOut(i,j) = dataOut(i,j) + dataPtr(i,j) * wgt(i,j) - enddo - enddo - else - do j = lb2,ub2 - do i = lb1,ub1 - dataOut(i,j) = dataOut(i,j) + dataPtr(i,j) - enddo - enddo - endif ! wgtfound - - endif ! FBin found - enddo ! n - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_merge_field_2D - !=============================================================================== integer function merge_listGetNum(str) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index 9ec6500a7..c53fc1abf 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -7,10 +7,10 @@ module med_methods_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 : operator(<), operator(/=), operator(+), operator(-), operator(*) , operator(>=) use ESMF , only : operator(<=), operator(>), operator(==) - use ESMF , only : ESMF_GeomType_Flag, ESMF_FieldStatus_Flag, ESMF_PoleMethod_Flag + use ESMF , only : ESMF_FieldStatus_Flag use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING, ESMF_POLEMETHOD_ALLAVG + use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING 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 : spval_init => med_constants_spval_init @@ -32,18 +32,12 @@ module med_methods_mod med_methods_FieldPtr_compare2 end interface - interface med_methods_UpdateTimestamp; module procedure & - med_methods_State_UpdateTimestamp, & - med_methods_Field_UpdateTimestamp - end interface - ! used/reused in module - logical :: isPresent - character(len=1024) :: msgString - type(ESMF_GeomType_Flag) :: geomtype - type(ESMF_FieldStatus_Flag) :: status - character(*) , parameter :: u_FILE_u = & + logical :: isPresent + character(len=1024) :: msgString + type(ESMF_FieldStatus_Flag) :: status + character(*) , parameter :: u_FILE_u = & __FILE__ public med_methods_FB_copy @@ -52,132 +46,36 @@ module med_methods_mod public med_methods_FB_init public med_methods_FB_init_pointer public med_methods_FB_reset - public med_methods_FB_clean public med_methods_FB_diagnose public med_methods_FB_FldChk public med_methods_FB_GetFldPtr public med_methods_FB_getNameN public med_methods_FB_getFieldN - public med_methods_FB_getFieldByName public med_methods_FB_getNumflds public med_methods_FB_Field_diagnose - public med_methods_Field_diagnose + public med_methods_FB_GeomPrint public med_methods_State_reset public med_methods_State_diagnose public med_methods_State_GeomPrint - public med_methods_State_GeomWrite - public med_methods_State_GetFldPtr public med_methods_State_SetScalar public med_methods_State_GetScalar public med_methods_State_GetNumFields - public med_methods_State_getFieldN - public med_methods_State_FldDebug + public med_methods_Field_diagnose public med_methods_Field_GeomPrint - public med_methods_Clock_TimePrint - public med_methods_UpdateTimestamp - public med_methods_Distgrid_Match public med_methods_FieldPtr_compare - public med_methods_States_GetSharedFlds + public med_methods_Clock_TimePrint - private med_methods_Grid_Write - private med_methods_Grid_Print private med_methods_Mesh_Print - private med_methods_Mesh_Write + private med_methods_Grid_Print private med_methods_Field_GetFldPtr - private med_methods_Field_GeomWrite - private med_methods_Field_UpdateTimestamp - private med_methods_FB_GeomPrint - private med_methods_FB_GeomWrite - private med_methods_FB_RWFields - private med_methods_FB_SetFldPtr private med_methods_FB_copyFB2FB private med_methods_FB_accumFB2FB - private med_methods_State_UpdateTimestamp - private med_methods_State_getNameN - private med_methods_State_getFieldByName - private med_methods_State_SetFldPtr private med_methods_Array_diagnose !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- - subroutine med_methods_FB_RWFields(mode,fname,FB,flag,rc) - - ! ---------------------------------------------- - ! Read or Write Field Bundles - ! ---------------------------------------------- - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleWrite - use ESMF, only : ESMF_FieldRead, ESMF_IOFMT_NETCDF, ESMF_FILESTATUS_REPLACE - - character(len=*) :: mode - character(len=*) :: fname - type(ESMF_FieldBundle) :: FB - logical,optional :: flag - integer,optional :: rc - - ! local variables - type(ESMF_Field) :: field - character(len=ESMF_MAXSTR) :: name - integer :: fieldcount, n - logical :: fexists - character(len=*), parameter :: subname='(med_methods_FB_RWFields)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//trim(fname)//": called", ESMF_LOGMSG_INFO) - endif - - if (mode == 'write') then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": write "//trim(fname), ESMF_LOGMSG_INFO) - end if - call ESMF_FieldBundleWrite(FB, fname, & - singleFile=.true., status=ESMF_FILESTATUS_REPLACE, iofmt=ESMF_IOFMT_NETCDF, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_FB_diagnose(FB, 'write '//trim(fname), rc) - - elseif (mode == 'read') then - inquire(file=fname,exist=fexists) - if (fexists) then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": read "//trim(fname), ESMF_LOGMSG_INFO) - end if - !----------------------------------------------------------------------------------------------------- - ! tcraig, ESMF_FieldBundleRead fails if a field is not on the field bundle, but we really want to just - ! ignore that field and read the rest, so instead read each field one at a time through ESMF_FieldRead - ! call ESMF_FieldBundleRead (FB, fname, & - ! singleFile=.true., iofmt=ESMF_IOFMT_NETCDF, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - !----------------------------------------------------------------------------------------------------- - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,fieldCount - call med_methods_FB_getFieldByName(FB, name, field, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRead (field, fname, iofmt=ESMF_IOFMT_NETCDF, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=u_FILE_u)) call ESMF_LogWrite(trim(subname)//& - ' WARNING missing field '//trim(name)) - enddo - - call med_methods_FB_diagnose(FB, 'read '//trim(fname), rc) - if (present(flag)) flag = .true. - endif - - else - call ESMF_LogWrite(trim(subname)//": mode WARNING "//trim(fname)//" mode="//trim(mode), ESMF_LOGMSG_INFO) - endif - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//trim(fname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_RWFields - - !----------------------------------------------------------------------------- - subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, rc) ! ---------------------------------------------- @@ -498,7 +396,9 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from FBgeom", ESMF_LOGMSG_INFO) end if elseif (present(STgeom)) then - call med_methods_State_getFieldN(STgeom, 1, lfield, rc=rc) + call med_methods_State_getNameN(STgeom, 1, lname, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(STgeom, itemName=lname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from STgeom", ESMF_LOGMSG_INFO) @@ -548,7 +448,9 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call med_methods_FB_getFieldN(FBflds, n, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (present(STflds)) then - call med_methods_State_getFieldN(STflds, n, lfield, rc=rc) + call med_methods_State_getNameN(STflds, n, lname, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(STflds, itemName=lname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -645,22 +547,17 @@ subroutine med_methods_FB_getNameN(FB, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif - allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldname = lfieldnamelist(fieldnum) - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -709,40 +606,6 @@ end subroutine med_methods_FB_getFieldN !----------------------------------------------------------------------------- - subroutine med_methods_FB_getFieldByName(FB, fieldname, field, rc) - - ! ---------------------------------------------- - ! Get field associated with fieldname out of FB - ! ---------------------------------------------- - - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet - - ! input/output variables - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*) , intent(in) :: fieldname - type(ESMF_Field) , intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=*),parameter :: subname='(med_methods_FB_getFieldByName)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_getFieldByName - - !----------------------------------------------------------------------------- - subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) ! ---------------------------------------------- @@ -768,22 +631,17 @@ subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' - call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif - allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldname = lfieldnamelist(fieldnum) - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -812,7 +670,6 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) integer :: n,itemCount type(ESMF_Field), pointer :: fieldList(:) type(ESMF_StateItem_Flag), pointer :: itemTypeList(:) - logical, parameter :: use_NUOPC_method = .true. character(len=*),parameter :: subname='(med_methods_State_getNumFields)' ! ---------------------------------------------- @@ -821,152 +678,20 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) endif rc = ESMF_SUCCESS - if (use_NUOPC_method) then - - nullify(fieldList) - call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldnum = 0 - if (associated(fieldList)) then - fieldnum = size(fieldList) - deallocate(fieldList) - endif - - else - - fieldnum = 0 - call ESMF_StateGet(State, itemCount=itemCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (itemCount > 0) then - allocate(itemTypeList(itemCount)) - call ESMF_StateGet(State, itemTypeList=itemTypeList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,itemCount - if (itemTypeList(n) == ESMF_STATEITEM_FIELD) fieldnum=fieldnum+1 - enddo - deallocate(itemTypeList) - endif - - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_getNumFields - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_getFieldN(State, fieldnum, field, rc) - - ! ---------------------------------------------- - ! Get field number fieldnum in State - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State), intent(in) :: State - integer , intent(in) :: fieldnum - type(ESMF_Field), intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=ESMF_MAXSTR) :: name - character(len=*),parameter :: subname='(med_methods_State_getFieldN)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_State_getNameN(State, fieldnum, name, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_StateGet(State, itemName=name, field=field, rc=rc) + nullify(fieldList) + call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_getFieldN - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_getFieldByName(State, fieldname, field, rc) - ! ---------------------------------------------- - ! Get field associated with fieldname from State - ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State), intent(in) :: State - character(len=*), intent(in) :: fieldname - type(ESMF_Field), intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=*),parameter :: subname='(med_methods_State_getFieldByName)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + fieldnum = 0 + if (associated(fieldList)) then + fieldnum = size(fieldList) + deallocate(fieldList) endif - rc = ESMF_SUCCESS - - call ESMF_StateGet(State, itemName=fieldname, field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif - end subroutine med_methods_State_getFieldByName - - !----------------------------------------------------------------------------- - - subroutine med_methods_FB_clean(FB, rc) - ! ---------------------------------------------- - ! Destroy fields in FB and FB - ! ---------------------------------------------- - - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldDestroy - use ESMF, only : ESMF_FieldBundleDestroy, ESMF_Field - - type(ESMF_FieldBundle), intent(inout) :: FB - integer , intent(out) :: rc - - ! local variables - integer :: i,j,n - integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - type(ESMF_Field) :: field - character(len=*),parameter :: subname='(med_methods_FB_clean)' - ! ---------------------------------------------- - - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldCount)) - call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=lfieldnamelist(n), field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldDestroy(field, rc=rc, noGarbage=.true.) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - - call ESMF_FieldBundleDestroy(FB, rc=rc, noGarbage=.true.) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(lfieldnamelist) - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - - end subroutine med_methods_FB_clean + end subroutine med_methods_State_getNumFields !----------------------------------------------------------------------------- @@ -976,18 +701,22 @@ subroutine med_methods_FB_reset(FB, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field ! intput/output variables - type(ESMF_FieldBundle), intent(inout) :: FB - real(R8) , intent(in), optional :: value - integer , intent(out) :: rc + type(ESMF_FieldBundle) , intent(inout) :: FB + real(R8) , intent(in), optional :: value + integer , intent(out) :: rc ! local variables integer :: i,j,n integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue + real(R8) :: lvalue + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) character(len=*),parameter :: subname='(med_methods_FB_reset)' ! ---------------------------------------------- @@ -1006,12 +735,25 @@ subroutine med_methods_FB_reset(FB, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call med_methods_FB_SetFldPtr(FB, lfieldnamelist(n), lvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = lvalue + elseif (lrank == 2) then + fldptr2 = lvalue + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + enddo deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -1029,7 +771,7 @@ subroutine med_methods_State_reset(State, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field ! intput/output variables type(ESMF_State) , intent(inout) :: State @@ -1040,7 +782,11 @@ subroutine med_methods_State_reset(State, value, rc) integer :: i,j,n integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue + real(R8) :: lvalue + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) character(len=*),parameter :: subname='(med_methods_State_reset)' ! ---------------------------------------------- @@ -1059,12 +805,24 @@ subroutine med_methods_State_reset(State, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call med_methods_State_SetFldPtr(State, lfieldnamelist(n), lvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = lvalue + elseif (lrank == 2) then + fldptr2 = lvalue + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif enddo - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -1081,7 +839,7 @@ subroutine med_methods_FB_average(FB, count, rc) ! Set all fields to zero in FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -1094,6 +852,7 @@ subroutine med_methods_FB_average(FB, count, rc) character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) real(R8), pointer :: dataPtr1(:) real(R8), pointer :: dataPtr2(:,:) + type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_FB_average)' ! ---------------------------------------------- @@ -1119,8 +878,10 @@ subroutine med_methods_FB_average(FB, count, rc) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, fieldCount - call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), dataPtr1, dataPtr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1, fldptr2=dataptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data @@ -1157,7 +918,7 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! Diagnose status of FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field type(ESMF_FieldBundle) , intent(inout) :: FB character(len=*) , intent(in), optional :: string @@ -1170,6 +931,7 @@ subroutine med_methods_FB_diagnose(FB, string, rc) character(len=CL) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) + type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_diagnose)' ! ---------------------------------------------- @@ -1192,8 +954,9 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! For each field in the bundle, get its memory location and print out the field do n = 1, fieldCount - call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), & - fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then @@ -1288,8 +1051,9 @@ subroutine med_methods_State_diagnose(State, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field + ! input/output variables type(ESMF_State), intent(in) :: State character(len=*), intent(in), optional :: string integer , intent(out) :: rc @@ -1301,6 +1065,7 @@ subroutine med_methods_State_diagnose(State, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) + type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_State_diagnose)' ! ---------------------------------------------- @@ -1316,19 +1081,16 @@ subroutine med_methods_State_diagnose(State, string, rc) call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(lfieldnamelist(fieldCount)) - call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - - call med_methods_State_GetFldPtr(State, lfieldnamelist(n), & - fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) + call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data - elseif (lrank == 1) then if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1337,7 +1099,6 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif - elseif (lrank == 2) then if (size(dataPtr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1346,7 +1107,6 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif - else call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE @@ -1373,7 +1133,7 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -1386,7 +1146,9 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) - character(len=*),parameter :: subname='(med_methods_FB_FieldDiagnose)' + 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)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -1399,30 +1161,29 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) lstring = trim(string) endif - call med_methods_FB_GetFldPtr(FB, fieldname, dataPtr1d, dataPtr2d, lrank, rc=rc) + call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - if (size(dataPtr1d) > 0) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (size(dataptr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) + minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - elseif (lrank == 2) then - if (size(dataPtr2d) > 0) then + else + call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) + minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - else - call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif + end if call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) if (dbug_flag > 10) then @@ -1538,9 +1299,9 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) ! If copy is passed in and true, the this is a copy ! ---------------------------------------------- - use ESMF , only : ESMF_FieldBundle - use ESMF , only : ESMF_FieldBundleGet + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FBout type(ESMF_FieldBundle), intent(in) :: FBin logical, optional , intent(in) :: copy @@ -1554,6 +1315,7 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) logical :: lcopy real(R8), pointer :: dataPtri1(:) , dataPtro1(:) real(R8), pointer :: dataPtri2(:,:), dataPtro2(:,:) + type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_accumFB2FB)' ! ---------------------------------------------- @@ -1577,9 +1339,14 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) call ESMF_FieldBundleGet(FBin, fieldName=lfieldnamelist(n), isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (exists) then - call med_methods_FB_GetFldPtr(FBin, lfieldnamelist(n), dataPtri1, dataPtri2, lranki, rc=rc) + call ESMF_FieldBundleGet(FBin, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_FB_GetFldPtr(FBout, lfieldnamelist(n), dataPtro1, dataPtro2, lranko, rc=rc) + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptri1, fldptr2=dataptri2, rank=lranki, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldBundleGet(FBout, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptro1, fldptr2=dataptro2, rank=lranko, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lranki == 1 .and. lranko == 1) then @@ -1706,6 +1473,7 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) use ESMF , only : ESMF_Field,ESMF_Mesh, ESMF_FieldGet, ESMF_MeshGet use ESMF , only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_COMPLETE + use ESMF , only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field) , intent(in) :: field @@ -1716,9 +1484,10 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) integer , intent(out) , optional :: rc ! local variables - type(ESMF_Mesh) :: lmesh - integer :: lrank, nnodes, nelements - logical :: labort + type(ESMF_Mesh) :: lmesh + integer :: lrank, nnodes, nelements + logical :: labort + type(ESMF_GeomType_Flag) :: geomtype character(len=*), parameter :: subname='(med_methods_Field_GetFldPtr)' ! ---------------------------------------------- @@ -1761,7 +1530,6 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - elseif (geomtype == ESMF_GEOMTYPE_MESH) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1770,10 +1538,8 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) call ESMF_MeshGet(lmesh, numOwnedNodes=nnodes, numOwnedElements=nelements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (nnodes == 0 .and. nelements == 0) lrank = 0 - else - call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & - ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return endif ! geomtype @@ -1867,9 +1633,7 @@ subroutine med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, rank, field, call ESMF_FieldBundleGet(FB, fieldName=trim(fldname), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Field_GetFldPtr(lfield, & - fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (present(rank)) then @@ -1886,156 +1650,13 @@ end subroutine med_methods_FB_GetFldPtr !----------------------------------------------------------------------------- - subroutine med_methods_FB_SetFldPtr(FB, fldname, val, rc) - - use ESMF, only : ESMF_FieldBundle, ESMF_Field - - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*) , intent(in) :: fldname - real(R8) , intent(in) :: val - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) - character(len=*), parameter :: subname='(med_methods_FB_SetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = val - elseif (lrank == 2) then - fldptr2 = val - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_SetFldPtr - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, rank, rc) - ! ---------------------------------------------- - ! Get pointer to a state field - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State), intent(in) :: ST - character(len=*), intent(in) :: fldname - real(R8), pointer, intent(inout), optional :: fldptr1(:) - real(R8), pointer, intent(inout), optional :: fldptr2(:,:) - integer , intent(out), optional :: rank - integer , intent(out), optional :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - character(len=*), parameter :: subname='(med_methods_State_GetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - - if (.not.present(rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR rc not present "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - rc = ESMF_SUCCESS - - call ESMF_StateGet(ST, itemName=trim(fldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Field_GetFldPtr(lfield, & - fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (present(rank)) then - rank = lrank - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_GetFldPtr - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_SetFldPtr(ST, fldname, val, rc) - - use ESMF, only : ESMF_State, ESMF_Field - - type(ESMF_State) , intent(in) :: ST - character(len=*) , intent(in) :: fldname - real(R8), intent(in) :: val - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) - character(len=*), parameter :: subname='(med_methods_State_SetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = val - elseif (lrank == 2) then - fldptr2 = val - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_SetFldPtr - - !----------------------------------------------------------------------------- - logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) - real(R8), pointer, intent(in) :: fldptr1(:) - real(R8), pointer, intent(in) :: fldptr2(:) - character(len=*) , intent(in) :: cstring - integer , intent(out) :: rc + ! input/output variables + real(R8) , pointer, intent(in) :: fldptr1(:) + real(R8) , pointer, intent(in) :: fldptr2(:) + character(len=*) , intent(in) :: cstring + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(med_methods_FieldPtr_Compare1)' @@ -2047,8 +1668,7 @@ logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare1 = .false. - if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & - ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr1 ',lbound(fldptr1),ubound(fldptr1) @@ -2084,10 +1704,8 @@ logical function med_methods_FieldPtr_Compare2(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare2 = .false. - if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. & - lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & - ubound(fldptr2,2) /= ubound(fldptr1,2) .or. & - ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & + ubound(fldptr2,2) /= ubound(fldptr1,2) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr2 ',lbound(fldptr2),ubound(fldptr2) @@ -2110,12 +1728,16 @@ subroutine med_methods_State_GeomPrint(state, string, rc) use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + ! input/output variables type(ESMF_State), intent(in) :: state character(len=*), intent(in) :: string integer , intent(out) :: rc - type(ESMF_Field) :: lfield - integer :: fieldcount + ! local variables + type(ESMF_Field) :: lfield + integer :: fieldcount + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) :: name character(len=*),parameter :: subname='(med_methods_State_GeomPrint)' ! ---------------------------------------------- @@ -2126,12 +1748,17 @@ subroutine med_methods_State_GeomPrint(state, string, rc) call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldCount > 0) then - call med_methods_State_GetFieldN(state, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomPrint(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(State, itemName=lfieldnamelist(1), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(lfieldnamelist) + call med_methods_Field_GeomPrint(lfield, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) endif ! fieldCount > 0 @@ -2164,9 +1791,7 @@ subroutine med_methods_FB_GeomPrint(FB, string, rc) call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldCount > 0) then - call med_methods_Field_GeomPrint(lfield, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else @@ -2185,6 +1810,7 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh use ESMF, only : ESMF_FieldGet, ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_EMPTY + use ESMF, only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field), intent(in) :: field @@ -2192,11 +1818,12 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) integer , intent(out) :: rc ! local variables - type(ESMF_Grid) :: lgrid - type(ESMF_Mesh) :: lmesh - integer :: lrank - real(R8), pointer :: dataPtr1(:) - real(R8), pointer :: dataPtr2(:,:) + type(ESMF_Grid) :: lgrid + type(ESMF_Mesh) :: lmesh + integer :: lrank + real(R8), pointer :: dataPtr1(:) + real(R8), pointer :: dataPtr2(:,:) + type(ESMF_GeomType_Flag) :: geomtype character(len=*),parameter :: subname='(med_methods_Field_GeomPrint)' ! ---------------------------------------------- @@ -2216,7 +1843,6 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, grid=lgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2417,29 +2043,30 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) end subroutine med_methods_Mesh_Print !----------------------------------------------------------------------------- - subroutine med_methods_Grid_Print(grid, string, rc) use ESMF, only : ESMF_Grid, ESMF_DistGrid, ESMF_StaggerLoc use ESMF, only : ESMF_GridGet, ESMF_DistGridGet, ESMF_GridGetCoord use ESMF, only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER + ! input/output variabes type(ESMF_Grid) , intent(in) :: grid character(len=*), intent(in) :: string integer , intent(out) :: rc - type(ESMF_Distgrid) :: distgrid - integer :: localDeCount - integer :: DeCount - integer :: dimCount, tileCount - integer :: staggerlocCount, arbdimCount, rank - type(ESMF_StaggerLoc) :: staggerloc - character(len=32) :: staggerstr - integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) - integer :: n1,n2,n3 - character(len=*),parameter :: subname='(med_methods_Grid_Print)' + ! local variables + type(ESMF_Distgrid) :: distgrid + integer :: localDeCount + integer :: DeCount + integer :: dimCount, tileCount + integer :: staggerlocCount, arbdimCount, rank + type(ESMF_StaggerLoc) :: staggerloc + character(len=32) :: staggerstr + integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) + integer :: n1,n2,n3 + character(len=*),parameter :: subname='(med_methods_Grid_Print)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -2457,13 +2084,10 @@ subroutine med_methods_Grid_Print(grid, string, rc) ! get dimCount and tileCount call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, deCount=deCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) @@ -2475,30 +2099,12 @@ subroutine med_methods_Grid_Print(grid, string, rc) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, & maxIndexPTile=maxIndexPTile, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - deallocate(minIndexPTile, maxIndexPTile) - ! get staggerlocCount, arbDimCount -! call ESMF_GridGet(grid, staggerlocCount=staggerlocCount, rc=rc) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! write (msgString,*) trim(subname)//":"//trim(string)//": staggerlocCount=", staggerlocCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! call ESMF_GridGet(grid, arbDimCount=arbDimCount, rc=rc) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! write (msgString,*) trim(subname)//":"//trim(string)//": arbDimCount=", arbDimCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get rank call ESMF_GridGet(grid, rank=rank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2527,12 +2133,14 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (rank == 1) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr1,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr1),maxval(fldptr1) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& + n2,n3,minval(fldptr1),maxval(fldptr1) endif if (rank == 2) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr2,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr2),maxval(fldptr2) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& + n2,n3,minval(fldptr2),maxval(fldptr2) endif call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) enddo @@ -2546,7 +2154,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) end subroutine med_methods_Grid_Print -!----------------------------------------------------------------------------- + !----------------------------------------------------------------------------- subroutine med_methods_Clock_TimePrint(clock,string,rc) use ESMF , only : ESMF_Clock, ESMF_Time, ESMF_TimeInterval @@ -2607,466 +2215,6 @@ subroutine med_methods_Clock_TimePrint(clock,string,rc) end subroutine med_methods_Clock_TimePrint - !----------------------------------------------------------------------------- - - subroutine med_methods_Mesh_Write(mesh, string, rc) - - use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_Array, ESMF_ArrayWrite, ESMF_DistGrid - - type(ESMF_Mesh) ,intent(in) :: mesh - character(len=*),intent(in) :: string - integer ,intent(out) :: rc - - ! local - integer :: n,l,i,lsize,ndims - character(len=CS) :: name - type(ESMF_DISTGRID) :: distgrid - type(ESMF_Array) :: array - real(R8), pointer :: rawdata(:) - real(R8), pointer :: coord(:) - character(len=*),parameter :: subname='(med_methods_Mesh_Write)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - -#if (1 == 0) - !--- elements --- - - call ESMF_MeshGet(mesh, spatialDim=ndims, numownedElements=lsize, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(rawdata(ndims*lsize)) - allocate(coord(lsize)) - - call ESMF_MeshGet(mesh, elementDistgrid=distgrid, ownedElemCoords=rawdata, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,ndims - name = "unknown" - if (n == 1) name = "lon_element" - if (n == 2) name = "lat_element" - do l = 1,lsize - i = 2*(l-1) + n - coord(l) = rawdata(i) - array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - enddo - - deallocate(rawdata,coord) - - !--- nodes --- - - call ESMF_MeshGet(mesh, spatialDim=ndims, numownedNodes=lsize, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(rawdata(ndims*lsize)) - allocate(coord(lsize)) - - call ESMF_MeshGet(mesh, nodalDistgrid=distgrid, ownedNodeCoords=rawdata, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,ndims - name = "unknown" - if (n == 1) name = "lon_nodes" - if (n == 2) name = "lat_nodes" - do l = 1,lsize - i = 2*(l-1) + n - coord(l) = rawdata(i) - array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - enddo - - deallocate(rawdata,coord) -#else - call ESMF_LogWrite(trim(subname)//": turned off right now", ESMF_LOGMSG_INFO) -#endif - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Mesh_Write - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_GeomWrite(state, string, rc) - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - type(ESMF_State), intent(in) :: state - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - type(ESMF_Field) :: lfield - integer :: fieldcount - character(len=*),parameter :: subname='(med_methods_State_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (fieldCount > 0) then - call med_methods_State_getFieldN(state, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomWrite(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) - endif ! fieldCount > 0 - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_FB_GeomWrite(FB, string, rc) - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet - - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - type(ESMF_Field) :: lfield - integer :: fieldcount - character(len=*),parameter :: subname='(med_methods_FB_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (fieldCount > 0) then - call med_methods_FB_getFieldN(FB, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomWrite(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) - endif ! fieldCount > 0 - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_Field_GeomWrite(field, string, rc) - - use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh, ESMF_FIeldGet, ESMF_FIELDSTATUS_EMPTY - use ESMF, only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID - - ! input/output variables - type(ESMF_Field), intent(in) :: field - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - ! local variables - type(ESMF_Grid) :: lgrid - type(ESMF_Mesh) :: lmesh - character(len=*),parameter :: subname='(med_methods_Field_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldGet(field, status=status, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (status == ESMF_FIELDSTATUS_EMPTY) then - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": ERROR field does not have a geom yet ") - rc = ESMF_FAILURE - return - endif - - call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (geomtype == ESMF_GEOMTYPE_GRID) then - call ESMF_FieldGet(field, grid=lgrid, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Grid_Write(lgrid, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - elseif (geomtype == ESMF_GEOMTYPE_MESH) then - call ESMF_FieldGet(field, mesh=lmesh, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Mesh_Write(lmesh, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Field_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_Grid_Write(grid, string, rc) - - use ESMF , only : ESMF_Grid, ESMF_Array, ESMF_GridGetCoord, ESMF_ArraySet - use ESMF , only : ESMF_ArrayWrite, ESMF_GridGetItem, ESMF_GridGetCoord - use ESMF , only : ESMF_GRIDITEM_AREA, ESMF_GRIDITEM_MASK - use ESMF , only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER - - ! input/output variables - type(ESMF_Grid) ,intent(in) :: grid - character(len=*),intent(in) :: string - integer ,intent(out) :: rc - - ! local - type(ESMF_Array) :: array - character(len=CS) :: name - character(len=*),parameter :: subname='(med_methods_Grid_Write)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - - ! -- centers -- - - call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - name = "lon_center" - call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - name = "lat_center" - call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - ! -- corners -- - - call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CORNER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - name = "lon_corner" - call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) - if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - name = "lat_corner" - call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) - if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - endif - - ! -- mask -- - - name = "mask" - call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - ! -- area -- - - name = "area" - call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_AREA, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_AREA, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Grid_Write - - !----------------------------------------------------------------------------- - - logical function med_methods_Distgrid_Match(distGrid1, distGrid2, rc) - use ESMF, only : ESMF_DistGrid, ESMF_DistGridGet - ! Arguments - type(ESMF_DistGrid), intent(in) :: distGrid1 - type(ESMF_DistGrid), intent(in) :: distGrid2 - integer, intent(out), optional :: rc - - ! Local Variables - integer :: dimCount1, dimCount2 - integer :: tileCount1, tileCount2 - integer, allocatable :: minIndexPTile1(:,:), minIndexPTile2(:,:) - integer, allocatable :: maxIndexPTile1(:,:), maxIndexPTile2(:,:) - integer, allocatable :: elementCountPTile1(:), elementCountPTile2(:) - character(len=*), parameter :: subname='(med_methods_Distgrid_Match)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(subname//": called", ESMF_LOGMSG_INFO) - endif - - if(present(rc)) rc = ESMF_SUCCESS - med_methods_Distgrid_Match = .true. - - call ESMF_DistGridGet(distGrid1, & - dimCount=dimCount1, tileCount=tileCount1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_DistGridGet(distGrid2, & - dimCount=dimCount2, tileCount=tileCount2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if ( dimCount1 /= dimCount2) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid dimCount MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( tileCount1 /= tileCount2) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid tileCount MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - allocate(elementCountPTile1(tileCount1)) - allocate(elementCountPTile2(tileCount2)) - allocate(minIndexPTile1(dimCount1,tileCount1)) - allocate(minIndexPTile2(dimCount2,tileCount2)) - allocate(maxIndexPTile1(dimCount1,tileCount1)) - allocate(maxIndexPTile2(dimCount2,tileCount2)) - - call ESMF_DistGridGet(distGrid1, & - elementCountPTile=elementCountPTile1, & - minIndexPTile=minIndexPTile1, & - maxIndexPTile=maxIndexPTile1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_DistGridGet(distGrid2, & - elementCountPTile=elementCountPTile2, & - minIndexPTile=minIndexPTile2, & - maxIndexPTile=maxIndexPTile2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if ( ANY((elementCountPTile1 - elementCountPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid elementCountPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( ANY((minIndexPTile1 - minIndexPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid minIndexPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( ANY((maxIndexPTile1 - maxIndexPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid maxIndexPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - deallocate(elementCountPTile1) - deallocate(elementCountPTile2) - deallocate(minIndexPTile1) - deallocate(minIndexPTile2) - deallocate(maxIndexPTile1) - deallocate(maxIndexPTile2) - - ! TODO: Optionally Check Coordinates - - if (dbug_flag > 10) then - call ESMF_LogWrite(subname//": done", ESMF_LOGMSG_INFO) - endif - - end function med_methods_Distgrid_Match - !================================================================================ subroutine med_methods_State_GetScalar(state, scalar_id, scalar_value, flds_scalar_name, flds_scalar_num, rc) @@ -3186,163 +2334,6 @@ end subroutine med_methods_State_SetScalar !----------------------------------------------------------------------------- - subroutine med_methods_State_UpdateTimestamp(state, time, rc) - - use NUOPC , only : NUOPC_GetStateMemberLists - use ESMF , only : ESMF_State, ESMF_Time, ESMF_Field, ESMF_SUCCESS - - ! input/output variables - type(ESMF_State) , intent(inout) :: state - type(ESMF_Time) , intent(in) :: time - integer , intent(out) :: rc - - ! local variables - integer :: i - type(ESMF_Field),pointer :: fieldList(:) - character(len=*), parameter :: subname='(med_methods_State_UpdateTimestamp)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do i=1, size(fieldList) - call med_methods_Field_UpdateTimestamp(fieldList(i), time, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - - end subroutine med_methods_State_UpdateTimestamp - - !----------------------------------------------------------------------------- - - subroutine med_methods_Field_UpdateTimestamp(field, time, rc) - - use ESMF, only : ESMF_Field, ESMF_Time, ESMF_TimeGet, ESMF_AttributeSet, ESMF_ATTNEST_ON, ESMF_SUCCESS - - ! input/output variables - type(ESMF_Field) , intent(inout) :: field - type(ESMF_Time) , intent(in) :: time - integer , intent(out) :: rc - - ! local variables - integer :: yy, mm, dd, h, m, s, ms, us, ns - character(len=*), parameter :: subname='(med_methods_Field_UpdateTimestamp)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - call ESMF_TimeGet(time, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, ms=ms, us=us, & - ns=ns, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_AttributeSet(field, & - name="TimeStamp", valueList=(/yy,mm,dd,h,m,s,ms,us,ns/), & - convention="NUOPC", purpose="Instance", & - attnestflag=ESMF_ATTNEST_ON, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - end subroutine med_methods_Field_UpdateTimestamp - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_FldDebug(state, flds_scalar_name, prefix, ymd, tod, logunit, rc) - - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field, ESMF_FieldGet - - ! input/output variables - type(ESMF_State) :: state - character(len=*) , intent(in) :: flds_scalar_name - character(len=*) , intent(in) :: prefix - integer , intent(in) :: ymd - integer , intent(in) :: tod - integer , intent(in) :: logunit - integer , intent(out) :: rc - - ! local variables - integer :: n, nfld, ungridded_index - integer :: lsize - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) - integer :: fieldCount - integer :: ungriddedUBound(1) - integer :: gridToFieldMap(1) - character(len=ESMF_MAXSTR) :: string - type(ESMF_Field) , allocatable :: lfields(:) - integer , allocatable :: dimCounts(:) - character(len=ESMF_MAXSTR) , allocatable :: fieldNameList(:) - !----------------------------------------------------- - - ! Determine the list of fields and the dimension count for each field - call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - allocate(fieldNameList(fieldCount)) - allocate(lfields(fieldCount)) - allocate(dimCounts(fieldCount)) - - call ESMF_StateGet(state, itemNameList=fieldNameList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do nfld=1, fieldCount - call ESMF_StateGet(state, itemName=trim(fieldNameList(nfld)), field=lfields(nfld), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfields(nfld), dimCount=dimCounts(nfld), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - - ! Determine local size of field - do nfld=1, fieldCount - if (dimCounts(nfld) == 1) then - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize = size(dataPtr1d) - exit - end if - end do - - ! Write out debug output - do n = 1,lsize - do nfld=1, fieldCount - if (dimCounts(nfld) == 1) then - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (trim(fieldNameList(nfld)) /= flds_scalar_name .and. dataPtr1d(n) /= 0.) then - string = trim(prefix) // ' ymd, tod, index, '// trim(fieldNameList(nfld)) //' = ' - write(logunit,100) trim(string), ymd, tod, n, dataPtr1d(n) - end if - else if (dimCounts(nfld) == 2) then - call ESMF_FieldGet(lfields(nfld), ungriddedUBound=ungriddedUBound, gridtoFieldMap=gridToFieldMap, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ungridded_index = 1,ungriddedUBound(1) - if (trim(fieldNameList(nfld)) /= flds_scalar_name) then - string = trim(prefix) // ' ymd, tod, lev, index, '// trim(fieldNameList(nfld)) //' = ' - if (gridToFieldMap(1) == 1) then - if (dataPtr2d(n,ungridded_index) /= 0.) then - write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(n,ungridded_index) - end if - else if (gridToFieldMap(1) == 2) then - if (dataPtr2d(ungridded_index,n) /= 0.) then - write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(ungridded_index,n) - end if - end if - end if - end do - end if - end do - end do -100 format(a60,3(i8,2x),d21.14) -101 format(a60,4(i8,2x),d21.14) - - deallocate(fieldNameList) - deallocate(lfields) - deallocate(dimCounts) - - end subroutine med_methods_State_FldDebug - - !----------------------------------------------------------------------------- - subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) ! ---------------------------------------------- @@ -3379,71 +2370,4 @@ end subroutine med_methods_FB_getNumFlds !----------------------------------------------------------------------------- - subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fldnames_shared, rc) - - ! ---------------------------------------------- - ! Get shared Fld names between State1 and State2 and - ! allocate the return array fldnames_shared - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_MAXSTR - - ! input/output variables - type(ESMF_State) , intent(in) :: State1 - type(ESMF_State) , intent(in) :: State2 - character(len=*) , intent(in) :: flds_scalar_name - character(len=ESMF_MAXSTR) , pointer :: fldnames_shared(:) - integer , intent(inout) :: rc - - ! local variables - integer :: ncnt1, ncnt2 - integer :: n1, n2, nshr - character(len=ESMF_MAXSTR), allocatable :: fldnames1(:) - character(len=ESMF_MAXSTR), allocatable :: fldnames2(:) - character(len=*), parameter :: subname='(med_methods_States_GetSharedFlds)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - if (associated(fldnames_shared)) then - call ESMF_LogWrite(trim(subname)//": ERROR fldnames_shared must not be associated ", ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - RETURN - end if - - call ESMF_StateGet(State1, itemCount=ncnt1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldnames1(ncnt1)) - call ESMF_StateGet(State1, itemNameList=fldnames1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_StateGet(State2, itemCount=ncnt2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldnames2(ncnt2)) - call ESMF_StateGet(State2, itemNameList=fldnames2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - nshr = 0 - do n1 = 1,ncnt1 - do n2 = 1,ncnt2 - if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then - nshr = nshr + 1 - end if - end do - end do - allocate(fldnames_shared(nshr)) - - nshr = 0 - do n1 = 1,ncnt1 - do n2 = 1,ncnt2 - if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then - nshr = nshr + 1 - fldnames_shared(nshr) = trim(fldnames1(n1)) - exit - end if - end do - end do - - end subroutine med_methods_States_GetSharedFlds - end module med_methods_mod diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 3320cef13..2d90a8fce 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -9,7 +9,6 @@ module med_phases_aofluxes_mod use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_init => med_methods_FB_init use med_map_mod , only : med_map_field_packed use perf_mod , only : t_startf, t_stopf diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 43a06c286..90bbb61b4 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -1,1998 +1,490 @@ -module esmFldsExchange_cesm_mod - - !--------------------------------------------------------------------- - ! This is a mediator specific routine that determines ALL possible - ! fields exchanged between components and their associated routing, - ! mapping and merging - !--------------------------------------------------------------------- +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 + 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 + 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 - public + 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 - public :: esmFldsExchange_cesm + ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 + integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) - character(*), parameter :: u_FILE_u = & + character(*) , parameter :: u_FILE_u = & __FILE__ -!================================================================================ +!================================================================================================ contains -!================================================================================ - - subroutine esmFldsExchange_cesm(gcomp, phase, rc) - - use ESMF - use NUOPC - 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_internalstate_mod , only : InternalState - use esmFlds , only : med_fldList_type - use esmFlds , only : addfld => med_fldList_AddFld - 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 : mapbilnr, mapconsf, mapconsd, mappatch - use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf - use esmflds , only : map_glc2ocn_ice, map_glc2ocn_liq, map_rof2ocn_ice, map_rof2ocn_liq - use esmflds , only : mapuv_with_cart3d - use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb - use esmFlds , only : coupling_mode - - ! input/output parameters: - type(ESMF_GridComp) :: gcomp - character(len=*) , intent(in) :: phase - integer , intent(inout) :: rc - - ! local variables: - type(InternalState) :: is_local - logical :: flds_i2o_per_cat - integer :: dbrc - integer :: num, i, n - integer :: n1, n2, n3, n4 - logical :: isPresent - character(len=5) :: iso(2) - character(len=CL) :: cvalue - character(len=CS) :: name, fldname - character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' - character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' - character(len=CX) :: atm2lnd_fmap='unset', atm2lnd_smap='unset' - character(len=CX) :: glc2lnd_smap='unset', glc2lnd_fmap='unset' - character(len=CX) :: glc2ice_rmap='unset' - character(len=CX) :: glc2ocn_liq_rmap='unset', glc2ocn_ice_rmap='unset' - character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' - character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' - character(len=CX) :: lnd2atm_fmap='unset', lnd2atm_smap='unset' - character(len=CX) :: lnd2glc_fmap='unset', lnd2glc_smap='unset' - character(len=CX) :: lnd2rof_fmap='unset' - character(len=CX) :: rof2lnd_fmap='unset' - character(len=CX) :: rof2ocn_fmap='unset', rof2ocn_ice_rmap='unset', rof2ocn_liq_rmap='unset' - character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' - character(len=CX) :: wav2ocn_smap='unset' - logical :: flds_co2a ! use case - logical :: flds_co2b ! use case - logical :: flds_co2c ! use case - character(len=CS), allocatable :: flds(:) - character(len=CS), allocatable :: suffix(:) - character(len=*) , parameter :: subname='(esmFldsExchange_cesm)' - !-------------------------------------- +!================================================================================================ - rc = ESMF_SUCCESS - - iso(1) = '' - iso(2) = '_wiso' + subroutine med_phases_prep_lnd(gcomp, rc) + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc - !--------------------------------------- - ! Get the internal state + ! local variables + type(ESMF_StateItem_Flag) :: itemType + type(InternalState) :: is_local + integer :: n1,ncnt + real(r8) :: nextsw_cday + logical :: first_call = .true. + character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- - if (phase /= 'advertise') then - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + rc = ESMF_SUCCESS - !-------------------------------------- - ! Merging arguments: - ! mrg_fromN = source component index that for the field to be merged - ! mrg_fldN = souce field name to be merged - ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', 'sum_with_weights', 'merge') - ! NOTE: - ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn fluxes or for ocn albedos - ! - ! NOTE: - ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in the - ! atm/ocn flux calculations. Input fields required from either the atm or the ocn for - ! these computation will use the logical 'use_med_aoflux' below. This is used to determine - ! mappings between the atm and ocn needed for these computations. - !-------------------------------------- - - 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) + call t_startf('MED:'//subname) + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if - !---------------------------------------------------------- - ! Initialize mapping file names - !---------------------------------------------------------- + ! 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(complnd), fieldCount=ncnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + 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 - ! to atm + !--------------------------------------- + ! auto merges to create FBExp(complnd) + !--------------------------------------- + + ! The following will merge all fields in fldsSrc + ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) + call med_merge_auto(complnd, & + is_local%wrap%med_coupling_active(:,complnd), & + is_local%wrap%FBExp(complnd), & + is_local%wrap%FBFrac(complnd), & + is_local%wrap%FBImp(:,complnd), & + fldListTo(complnd), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', value=ice2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_fmapname = '// trim(ice2atm_fmap), ESMF_LOGMSG_INFO) - end if + !--------------------------------------- + ! custom calculations + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', value=ice2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_smapname = '// trim(ice2atm_smap), ESMF_LOGMSG_INFO) - end if + ! 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 - call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_fmapname', value=lnd2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2atm_fmapname = '// trim(lnd2atm_fmap), ESMF_LOGMSG_INFO) - end if + !--------------------------------------- + ! update scalar data + !--------------------------------------- + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (itemType /= ESMF_STATEITEM_NOTFOUND) then + ! send nextsw_cday to land - first obtain it from atm import + call State_GetScalar(& + scalar_value=nextsw_cday, & + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & + state=is_local%wrap%NstateImp(compatm), & + flds_scalar_name=is_local%wrap%flds_scalar_name, & + flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call State_SetScalar(& + scalar_value=nextsw_cday, & + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & + state=is_local%wrap%NstateExp(complnd), & + flds_scalar_name=is_local%wrap%flds_scalar_name, & + flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + ! diagnose + if (dbug_flag > 1) then + call FB_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 + + first_call = .false. + + 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_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)' + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', value=ocn2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_smapname = '// trim(ocn2atm_smap), ESMF_LOGMSG_INFO) - end if + rc = ESMF_SUCCESS - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', value=ocn2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_fmapname = '// trim(ocn2atm_fmap), ESMF_LOGMSG_INFO) - end if + !--------------------------------------- + ! Get the internal state + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_smapname', value=lnd2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2atm_smapname = '// trim(lnd2atm_smap), ESMF_LOGMSG_INFO) - end if + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! to lnd + !--------------------------------------- + ! Set the module variable for the number of elevation classes + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_fmapname', value=atm2lnd_fmap, isPresent=isPresent, rc=rc) + ! 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 - if (isPresent) then - call ESMF_LogWrite('atm2lnd_fmapname = '// trim(atm2lnd_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_smapname', value=atm2lnd_smap, isPresent=isPresent, rc=rc) + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2lnd_smapname = '// trim(atm2lnd_smap), ESMF_LOGMSG_INFO) - end if + ungriddedCount = ungriddedUBound_output(1) + ! TODO: check that ungriddedCount = glc_nec+1 - call NUOPC_CompAttributeGet(gcomp, name='rof2lnd_fmapname', value=rof2lnd_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2lnd_fmapname = '// trim(rof2lnd_fmap), ESMF_LOGMSG_INFO) - end if + !--------------------------------------- + ! Get the glc and land meshes + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_fmapname', value=glc2lnd_fmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_fmap), ESMF_LOGMSG_INFO) - end if + deallocate(fieldlist) - call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_smapname', value=glc2lnd_smap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_smap), ESMF_LOGMSG_INFO) - end if + deallocate(fieldlist) - ! to ice + ! ------------------------------- + ! Create module field bundles + ! ------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, isPresent=isPresent, rc=rc) + field_icemask_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_fmapname = '// trim(atm2ice_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, isPresent=isPresent, rc=rc) + field_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_smapname = '// trim(atm2ice_smap), ESMF_LOGMSG_INFO) - end if - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('atm2ice_vmapname = '// trim(atm2ice_vmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2ice_rmapname', value=glc2ice_rmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('glc2ice_rmapname = '// trim(glc2ice_rmap), ESMF_LOGMSG_INFO) - end if - ! to ocn - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('atm2ocn_fmapname = '// trim(atm2ocn_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('atm2ocn_smapname = '// trim(atm2ocn_smap), ESMF_LOGMSG_INFO) - end if - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('atm2ocn_vmapname = '// trim(atm2ocn_vmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_liq_rmapname', value=glc2ocn_liq_rmap, isPresent=isPresent, rc=rc) + 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 - if (isPresent) then - call ESMF_LogWrite('glc2ocn_liq_rmapname = '// trim(glc2ocn_liq_rmap), ESMF_LOGMSG_INFO) - end if - call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_ice_rmapname', value=glc2ocn_ice_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2ocn_ice_rmapname = '// trim(glc2ocn_ice_rmap), ESMF_LOGMSG_INFO) + ! Verify that route handle has been created + if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:), mapconsd,rc=rc)) then + call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for glc->lnd mapping", & + ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return end if - call NUOPC_CompAttributeGet(gcomp, name='wav2ocn_smapname', value=wav2ocn_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('wav2ocn_smapname = '// trim(wav2ocn_smap), ESMF_LOGMSG_INFO) + ! 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 - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_fmapname', value=rof2ocn_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_fmapname = '// trim(rof2ocn_fmap), ESMF_LOGMSG_INFO) - end if + end subroutine map_glc2lnd_init - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_liq_rmapname', value=rof2ocn_liq_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_liq_rmapname = '// trim(rof2ocn_liq_rmap), ESMF_LOGMSG_INFO) - end if + !================================================================================================ + subroutine map_glc2lnd( gcomp, rc) - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_ice_rmapname', value=rof2ocn_ice_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_ice_rmapname = '// trim(rof2ocn_ice_rmap), ESMF_LOGMSG_INFO) - end if + !------------------ + ! 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. + !------------------ - ! to rof + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(out) :: rc - call NUOPC_CompAttributeGet(gcomp, name='lnd2rof_fmapname', value=lnd2rof_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2rof_fmapname = '// trim(lnd2rof_fmap), ESMF_LOGMSG_INFO) + ! 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 - ! to glc + !--------------------------------------- + ! Get the internal state + !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_fmapname', value=lnd2glc_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2glc_fmapname = '// trim(lnd2glc_fmap), ESMF_LOGMSG_INFO) - end if + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_smapname', value=lnd2glc_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2glc_smapname = '// trim(lnd2glc_smap), ESMF_LOGMSG_INFO) - end if + !--------------------------------- + ! Map fractional ice coverage to the land grid (multiple elevation classes) + !--------------------------------- - ! to wav + ! Set contents of FBglc_ec to contain frac_g_ec + ! (fractional ice coverage for each elevation class on the glc grid) - call NUOPC_CompAttributeGet(gcomp, name='atm2wav_smapname', value=atm2wav_smap, isPresent=isPresent, rc=rc) + ! 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 - if (isPresent) then - call ESMF_LogWrite('atm2wav_smapname = '// trim(atm2wav_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ice2wav_smapname', value=ice2wav_smap, isPresent=isPresent, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=topo_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2wav_smapname = '// trim(ice2wav_smap), ESMF_LOGMSG_INFO) - end if - call NUOPC_CompAttributeGet(gcomp, name='ocn2wav_smapname', value=ocn2wav_smap, isPresent=isPresent, rc=rc) + ! 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 - if (isPresent) then - call ESMF_LogWrite('ocn2wav_smapname = '// trim(ocn2wav_smap), ESMF_LOGMSG_INFO) - end if - - !---------------------------------------------------------- - ! Initialize if use 3d cartesian mapping for u,v - !---------------------------------------------------------- - - call NUOPC_CompAttributeGet(gcomp, name='mapuv_with_cart3d', value=cvalue, isPresent=isPresent, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=frac_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) mapuv_with_cart3d - if (isPresent) then - call ESMF_LogWrite('mapuv_with_cart3d = '// trim(cvalue), ESMF_LOGMSG_INFO) - end if - - !===================================================================== - ! scalar information - !===================================================================== - - if (phase == 'advertise') then - call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldName", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1,ncomps - call addfld(fldListFr(n)%flds, trim(cvalue)) - call addfld(fldListTo(n)%flds, trim(cvalue)) - end do - end if - - !===================================================================== - ! FIELDS TO MEDIATOR component (for fractions and atm/ocn flux calculation) - !===================================================================== - - !---------------------------------------------------------- - ! to med: masks from components - !---------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Sl_lfrin') - call addfld(fldListFr(compocn)%flds, 'So_omask') - call addfld(fldListFr(compice)%flds, 'Si_imask') - else - call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') - end if - - ! --------------------------------------------------------------------- - ! to med: atm and ocn fields required for atm/ocn flux calculation' - ! --------------------------------------------------------------------- - if (phase /= 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_u') - call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch, 'one', atm2ocn_vmap) - - call addfld(fldListFr(compatm)%flds, 'Sa_v') - call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch, 'one', atm2ocn_vmap) - - call addfld(fldListFr(compatm)%flds, 'Sa_z') - call addmap(fldListFr(compatm)%flds, 'Sa_z' , compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_tbot') - call addmap(fldListFr(compatm)%flds, 'Sa_tbot', compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_pbot') - call addmap(fldListFr(compatm)%flds, 'Sa_pbot', compocn, mapbilnr, 'one', atm2ocn_smap) - - call addfld(fldListFr(compatm)%flds, 'Sa_shum') - call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, mapbilnr, 'one', atm2ocn_smap) - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_shum_wiso', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_shum_wiso') - call addmap(fldListFr(compatm)%flds, 'Sa_shum_wiso', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_ptem', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_ptem') - call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_dens', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_dens') - call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - end if - - ! --------------------------------------------------------------------- - ! to med: swnet fluxes used for budget calculation - ! --------------------------------------------------------------------- - ! TODO (mvertens, 2019-01-11): budget implemention needs to be done in CMEPS - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Fall_swnet') - call addfld(fldListFr(compice)%flds, 'Faii_swnet') - call addfld(fldListFr(compatm)%flds, 'Faxa_swnet') - else - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compice, mapconsf, 'one' , atm2ice_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, mapconsf, 'one' , atm2ocn_fmap) - end if - if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Faii_swnet', compocn, mapfcopy, 'unset', 'unset') - end if - end if - - !===================================================================== - ! FIELDS TO LAND - !===================================================================== - - ! --------------------------------------------------------------------- - ! from atm: - ! to lnd: height at the lowest model level from atm - ! to lnd: surface height from atm - ! to lnd: zonal wind at the lowest model level from atm - ! to lnd: meridional wind at the lowest model level from atm - ! to lnd: Temperature at the lowest model level from atm - ! to lnd: potential temperature at the lowest model level from atm - ! to lnd: Pressure at the lowest model level from atm - ! to lnd: specific humidity at the lowest model level from atm - ! --------------------------------------------------------------------- - - allocate(flds(9)) - 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)) - if (phase == 'advertise') then - 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, mapbilnr, 'one', atm2lnd_smap) - call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to lnd: convective and large scale precipitation rate water equivalent from atm - ! to lnd: convective and large-scale (stable) snow rate from atm - ! to lnd: downward longwave heat flux from atm - ! to lnd: downward direct near-infrared incident solar radiation from atm - ! to lnd: downward direct visible incident solar radiation from atm - ! to lnd: downward diffuse near-infrared incident solar radiation from atm - ! to lnd: downward Diffuse visible incident solar radiation from atm - ! to lnd: black carbon deposition fluxes from atm - ! - hydrophylic black carbon dry deposition flux - ! - hydrophobic black carbon dry deposition flux - ! - hydrophylic black carbon wet deposition flux - ! to lnd: organic carbon deposition fluxes from atm - ! - hydrophylic organic carbon dry deposition flux - ! - hydrophobic organic carbon dry deposition flux - ! - hydrophylic organic carbon wet deposition flux - ! to lnd: dust wet deposition flux (sizes 1-4) from atm - ! to lnd: dust dry deposition flux (sizes 1-4) from atm - ! to lnd: nitrogen deposition fields from atm - ! --------------------------------------------------------------------- - - ! TODO (mvertens, 2018-12-13): the nitrogen deposition fluxes here - ! are not treated the same was as in cesm2.0 release - ! 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 ' /) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - 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) - call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to lnd: river channel total water volume from rof - ! to lnd: river channel main channel water volume from rof - ! 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 '/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(comprof)%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(comprof, comprof), trim(fldname), rc=rc)) then - 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') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to lnd: ice sheet grid coverage on global grid from glc - ! 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 - - 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 - - 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 - end if - end if - - !===================================================================== - ! FIELDS TO ATMOSPHERE - !===================================================================== - - !---------------------------------------------------------- - ! to atm: Fractions - !---------------------------------------------------------- - if (phase == 'advertise') then - ! the following are computed in med_phases_prep_atm - call addfld(fldListTo(compatm)%flds, 'Sl_lfrac') - call addfld(fldListTo(compatm)%flds, 'Si_ifrac') - call addfld(fldListTo(compatm)%flds, 'So_ofrac') - end if - - ! --------------------------------------------------------------------- - ! to atm: merged direct albedo (visible radiation) - ! to atm: merged diffuse albedo (visible radiation) - ! to atm: merged direct albedo (near-infrared radiation) - ! to atm: merged diffuse albedo (near-infrared radiation) - ! --------------------------------------------------------------------- - allocate(suffix(4)) - suffix = (/'avsdr', 'avsdf', 'anidr', 'anidf'/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds, 'Si_'//trim(suffix(n))) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged reference temperature at 2 meters - ! to atm: merged 10m wind speed - ! to atm: merged reference specific humidity at 2 meters - ! to atm: merged reference specific water isoptope humidity at 2 meters - ! --------------------------------------------------------------------- - allocate(suffix(4)) - suffix = (/'tref ', 'u10 ', 'qref ', 'qref_wiso'/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds , 'Sl_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds , 'Si_'//trim(suffix(n))) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged zonal surface stress - ! to atm: merged meridional surface stress - ! to atm: merged surface latent heat flux - ! to atm: merged surface sensible heat flux - ! to atm: merged surface upward longwave heat flux - ! to atm: evaporation water flux from water - ! to atm: evaporation water flux from water isotopes - ! --------------------------------------------------------------------- - allocate(suffix(7)) - 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(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))) - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to atm: merged surface temperature and unmerged temperatures from ice and ocn - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Sl_t') - call addfld(fldListFr(compice)%flds, 'Si_t') - call addfld(fldListFr(compocn)%flds, 'So_t') - 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') - call addmrg(fldListTo(compatm)%flds, 'So_t', & - mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') - end if - end if - - ! --------------------------------------------------------------------- - ! to atm: surface snow depth from ice (needed for cam) - ! to atm: mean ice volume per unit area from ice - ! to atm: mean snow volume per unit area from ice - ! --------------------------------------------------------------------- - allocate(flds(3)) - flds = (/'Si_snowh', 'Si_vice ', 'Si_vsno '/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - 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 addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to atm: surface saturation specific humidity in ocean from med aoflux - ! to atm: square of exch. coeff (tracers) from med aoflux - ! to atm: surface fraction velocity from med aoflux - ! --------------------------------------------------------------------- - allocate(flds(3)) - flds = (/'So_ssq ', 'So_re ', 'So_ustar'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , trim(fldname)) - call addfld(fldListTo(compatm)%flds , trim(fldname)) - 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 addmrg(fldListTo(compatm)%flds , trim(fldname), & - mrg_from1=compmed, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to atm: surface fraction velocity from land - ! to atm: aerodynamic resistance from land - ! to atm: surface snow water equivalent from land - ! --------------------------------------------------------------------- - allocate(flds(3)) - flds = (/'Sl_fv ', 'Sl_ram1 ', 'Sl_snowh'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - 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 addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to atm: dust fluxes from land (4 sizes) - ! --------------------------------------------------------------------- - fldname = 'Fall_flxdst' - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if - - !----------------------------------------------------------------------------- - ! to atm: MEGAN emissions fluxes from land - !----------------------------------------------------------------------------- - fldname = 'Fall_voc' - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if - - !----------------------------------------------------------------------------- - ! to atm: fire emissions fluxes from land - !----------------------------------------------------------------------------- - ! 'wild fire emission fluxes' - fldname = 'Fall_fire' - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if - - ! 'wild fire plume height' - fldname = 'Sl_fztop' - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if - - !----------------------------------------------------------------------------- - ! to atm: dry deposition velocities from land - !----------------------------------------------------------------------------- - fldname = 'Sl_ddvel' - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(compatm)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if + 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) - !===================================================================== - ! FIELDS TO OCEAN (compocn) - !===================================================================== - - !---------------------------------------------------------- - ! to ocn: fractional ice coverage wrt ocean from ice - !---------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds, 'Si_ifrac') - 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') - end if + ! 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(:) - ! --------------------------------------------------------------------- - ! to ocn: downward longwave heat flux from atm - ! to ocn: downward direct near-infrared incident solar radiation from atm - ! to ocn: downward diffuse near-infrared incident solar radiation from atm - ! to ocn: downward dirrect visible incident solar radiation from atm - ! to ocn: downward diffuse visible incident solar radiation from atm - ! --------------------------------------------------------------------- - allocate(flds(5)) - flds = (/'Faxa_lwdn ', 'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - 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') - end if - end if + ! 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 - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to ocn: surface upward longwave heat flux from mediator - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_lwup') - call addfld(fldListTo(compocn)%flds , 'Foxx_lwup') - else - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: merged longwave net heat flux - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_lwdn') - call addfld(fldListMed_aoflux%flds , 'Faox_lwup' ) - call addfld(fldListTo(compocn)%flds , 'Foxx_lwnet') - else - ! (mom6) (send longwave net to ocn via auto merge) - if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_lwnet', rc=rc) .and. & - fldchk(is_local%wrap%FBMed_aoflux_o , 'Faox_lwup' , rc=rc) .and. & - 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') - end if - end if - ! --------------------------------------------------------------------- - ! to ocn: downward shortwave heat flux - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swdn') - call addfld(fldListTo(compocn)%flds, 'Faxa_swdn') - else - if (fldchk(is_local%wrap%FBImp(compatm, compatm), 'Faxa_swdn', rc=rc) .and. & - 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') - end if + ! 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 - ! --------------------------------------------------------------------- - ! to ocn: net shortwave radiation from med - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_swvdr') - call addfld(fldListFr(compatm)%flds, 'Faxa_swndr') - call addfld(fldListFr(compatm)%flds, 'Faxa_swvdf') - call addfld(fldListFr(compatm)%flds, 'Faxa_swndf') - - call addfld(fldListFr(compice)%flds, 'Fioi_swpen') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_vdf') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idr') - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_idf') - - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_vdf') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idr') - call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_idf') - else - ! Net shortwave ocean (custom calculation in prep_phases_ocn_mod.F90) - - ! import swpen from ice without bands - if (fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Fioi_swpen', compocn, mapfcopy, 'unset', 'unset') - end if - - ! import swpen from ice by bands - if ( fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_vdf', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen_idf', rc=rc)) then - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdr', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_vdf', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idr', compocn, mapfcopy, 'unset', 'unset') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_idf', compocn, mapfcopy, 'unset', 'unset') - end if + ! 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(:,:) - ! import sw from atm by bands - if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swvdf', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swndr', rc=rc) .and. & - (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet' , rc=rc)) .or. & - (fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdr', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_vdf', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idr', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'Foxx_swnet_idf', rc=rc))) then - call addmap(fldListFr(compatm)%flds, 'Faxa_swvdr', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swvdf', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swndr', compocn, mapconsf, 'one', atm2ocn_fmap) - call addmap(fldListFr(compatm)%flds, 'Faxa_swndf', compocn, mapconsf, 'one', atm2ocn_fmap) - end if - end if + !--------------------------------- + ! Map topo to the land grid (multiple elevation classes) + !--------------------------------- - ! --------------------------------------------------------------------- - ! to ocn: per ice thickness fraction and sw penetrating into ocean from ice - ! --------------------------------------------------------------------- - if (flds_i2o_per_cat) then - if (phase == 'advertise') then - ! 'fractional ice coverage wrt ocean for each thickness category ' - call addfld(fldListFr(compice)%flds, 'Si_ifrac_n') - call addfld(fldListTo(compocn)%flds, 'Si_ifrac_n') - - ! net shortwave radiation penetrating into ocean for each thickness category - call addfld(fldListFr(compice)%flds, 'Fioi_swpen_ifrac_n') - call addfld(fldListTo(compocn)%flds, 'Fioi_swpen_ifrac_n') - - ! 'fractional atmosphere coverage wrt ocean' (computed in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Sf_afrac') - ! 'fractional atmosphere coverage used in radiation computations wrt ocean' (computed in med_phases_prep_ocn) - call addfld(fldListTo(compocn)%flds, 'Sf_afracr') - ! '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') - ! Note that 'Sf_afrac, 'Sf_afracr' and 'Foxx_swnet_afracr' will have explicit merging in med_phases_prep_ocn - end if - end if + ! 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 - ! --------------------------------------------------------------------- - ! to ocn: precipitation rate water equivalent from atm - ! to ocn: snow rate water equivalent from atm - ! --------------------------------------------------------------------- - - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') - call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') - call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) - call addfld(fldListTo(compocn)%flds, 'Faxa_rain' ) - - call addfld(fldListFr(compatm)%flds, 'Faxa_rainc_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_rainl_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_rain_wiso' ) - call addfld(fldListTo(compocn)%flds, 'Faxa_rain_wiso' ) - - call addfld(fldListFr(compatm)%flds, 'Faxa_snowc') - call addfld(fldListFr(compatm)%flds, 'Faxa_snowl') - call addfld(fldListFr(compatm)%flds, 'Faxa_snow' ) - call addfld(fldListTo(compocn)%flds, 'Faxa_snow' ) - - call addfld(fldListFr(compatm)%flds, 'Faxa_snowc_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_snowl_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_snow_wiso' ) - call addfld(fldListTo(compocn)%flds, 'Faxa_snow_wiso' ) - else - do n = 1,2 - ! Note that the mediator atm/ocn flux calculation needs Faxa_rainc for the gustiness parameterization - ! which by default is not actually used - if ( fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_rain' //iso(n), rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_rainl'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) - 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') - 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') - 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') - 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. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc'//iso(n), rc=rc)) then - call addmap(fldListFr(compatm)%flds, 'Faxa_snowl'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) - 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') - 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') - 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') - end if + 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 if - - ! --------------------------------------------------------------------- - ! to ocn: merged sensible heat flux - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds , 'Faxa_sen') - call addfld(fldListMed_aoflux%flds , 'Faox_sen') - call addfld(fldListFr(compice)%flds , 'Fioi_melth') - call addfld(fldListTo(compocn)%flds , 'Foxx_sen') - else - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: surface latent heat flux and evaporation water flux - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - - call addfld(fldListFr(compatm)%flds, 'Faxa_lat' ) - call addfld(fldListMed_aoflux%flds , 'Faox_lat' ) - call addfld(fldListMed_aoflux%flds , 'Faox_evap') - call addfld(fldListTo(compocn)%flds, 'Foxx_lat' ) - call addfld(fldListTo(compocn)%flds, 'Foxx_evap') - else - 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') - 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') - end if - end if - - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_lat_wiso' ) - call addfld(fldListTo(compocn)%flds, 'Foxx_lat_wiso' ) - else - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: wind speed squared at 10 meters from med - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'So_duu10n') - call addfld(fldListTo(compocn)%flds, 'So_duu10n') - else - if ( fldchk(is_local%wrap%FBMed_aoflux_o, 'So_duu10n', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn), 'So_duu10n', rc=rc)) then - - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: sea level pressure from atm - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_pslv') - call addfld(fldListTo(compocn)%flds, 'Sa_pslv') - else - if ( fldchk(is_local%wrap%FBImp(compatm, compatm), 'Sa_pslv', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(compocn) , 'Sa_pslv', rc=rc)) then - - call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compocn, mapbilnr, 'one', atm2ocn_smap) - 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') - end if - end if - - ! --------------------------------------------------------------------- - ! to ocn: black carbon deposition fluxes from atm - ! - hydrophylic black carbon dry deposition flux - ! - hydrophobic black carbon dry deposition flux - ! - hydrophylic black carbon wet deposition flux - ! to ocn: organic carbon deposition fluxes from atm - ! - hydrophylic organic carbon dry deposition flux - ! - hydrophobic organic carbon dry deposition flux - ! - hydrophylic organic carbon wet deposition flux - ! to ocn: dust wet deposition flux (sizes 1-4) from atm - ! to ocn: dust dry deposition flux (sizes 1-4) from atm - ! to ocn: nitrogen deposition fields (2) from atm - ! --------------------------------------------------------------------- - allocate(flds(5)) - flds = (/'Faxa_bcph ', 'Faxa_ocph ', 'Faxa_dstwet' , 'Faxa_dstdry', 'Faxa_ndep ' /) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(compatm,compatm), trim(fldname), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to ocn: merge zonal surface stress from ice and (atm or med) - ! --------------------------------------------------------------------- - allocate(suffix(2)) - suffix = (/'taux', 'tauy'/) - - do n = 1,size(suffix) - if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n))) - call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(suffix(n))) - call addfld(fldListFr(compatm)%flds , 'Faxa_'//trim(suffix(n))) - call addfld(fldListTo(compocn)%flds , 'Foxx_'//trim(suffix(n))) - else - if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_'//trim(suffix(n)), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(suffix) - - ! --------------------------------------------------------------------- - ! to ocn: water flux due to melting ice from ice - ! --------------------------------------------------------------------- - do n = 1,size(iso) - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds , 'Fioi_meltw'//iso(n)) - call addfld(fldListTo(compocn)%flds , 'Fioi_meltw'//iso(n)) - else - if ( fldchk(is_local%wrap%FBexp(compocn) , 'Fioi_meltw'//iso(n), rc=rc) .and. & - 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') - end if - end if - end do - - ! --------------------------------------------------------------------- - ! to ocn: heat flux from melting ice from ice - ! to ocn: salt flux from ice - ! to ocn: hydrophylic black carbon deposition flux from ice - ! to ocn: hydrophobic black carbon deposition flux from ice - ! to ocn: dust flux from ice - ! --------------------------------------------------------------------- - ! TODO (mvertens, 2019-01-07): is fioi_melth being handled here? - ! Is fd.yaml correctly aliasing Fioi_melth? - - allocate(flds(5)) - flds = (/'Fioi_melth ', 'Fioi_salt ', 'Fioi_bcphi ', 'Fioi_bcpho ', 'Fioi_flxdst'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc) .and. & - 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') - end if - end if end do - deallocate(flds) - - !----------------------------- - ! to ocn: liquid runoff from rof and glc components - ! to ocn: frozen runoff flux from rof and glc components - ! to ocn: waterflux back to ocn due to flooding from rof - !----------------------------- - - if (phase == 'advertise') then - do n = 1,size(iso) - ! 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)) - 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)) - 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') - 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') - end if - end do - end if - - !----------------------------- - ! to ocn: Langmuir multiplier from wave - ! to ocn: Stokes drift u component from wave - ! to ocn: Stokes drift v component from wave - ! to ocn: Stokes drift depth from wave - !----------------------------- - allocate(flds(4)) - flds = (/'Sw_lamult ', 'Sw_ustokes', 'Sw_vstokes', 'Sw_hstokes'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compwav)%flds, trim(fldname)) - call addfld(fldListTo(compocn)%flds, trim(fldname)) - 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 addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compwav, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - - !===================================================================== - ! FIELDS TO ICE (compice) - !===================================================================== - - ! --------------------------------------------------------------------- - ! to ice: downward longwave heat flux from atm - ! to ice: downward direct near-infrared incident solar radiation from atm - ! to ice: downward direct visible incident solar radiation from atm - ! to ice: downward diffuse near-infrared incident solar radiation from atm - ! to ice: downward Diffuse visible incident solar radiation from atm - ! to ice: hydrophylic black carbon dry deposition flux from atm - ! to ice: hydrophobic black carbon dry deposition flux from atm - ! to ice: hydrophylic black carbon wet deposition flux from atm - ! to ice: hydrophylic organic carbon dry deposition flux from atm - ! to ice: hydrophobic organic carbon dry deposition flux from atm - ! to ice: hydrophylic organic carbon wet deposition flux from atm - ! to ice: dust wet deposition flux (size 1) from atm - ! to ice: dust wet deposition flux (size 2) from atm - ! to ice: dust wet deposition flux (size 3) from atm - ! to ice: dust wet deposition flux (size 4) from atm - ! to ice: dust dry deposition flux (size 1) from atm - ! to ice: dust dry deposition flux (size 2) from atm - ! to ice: dust dry deposition flux (size 3) from atm - ! to ice: dust dry deposition flux (size 4) from atm - ! --------------------------------------------------------------------- - allocate(flds(9)) - flds = (/'Faxa_lwdn ' , 'Faxa_swndr ' , 'Faxa_swvdr ' , 'Faxa_swndf ' , 'Faxa_swvdf ', & - 'Faxa_bcph ' , 'Faxa_ocph ' , 'Faxa_dstwet' , 'Faxa_dstdry' /) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compice)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBExp(compice) , trim(fldname), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to ice: convective and large scale precipitation rate water equivalent from atm - ! to ice: rain and snow rate from atm - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_rainc') - call addfld(fldListFr(compatm)%flds, 'Faxa_rainl') - call addfld(fldListFr(compatm)%flds, 'Faxa_rain' ) - call addfld(fldListTo(compice)%flds, 'Faxa_rain' ) - - call addfld(fldListFr(compatm)%flds, 'Faxa_rainc_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_rainl_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_rain_wiso' ) - call addfld(fldListTo(compice)%flds, 'Faxa_rain_wiso' ) - else - if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_rain' , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc', rc=rc)) then - 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') - 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') - 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. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc_wiso', rc=rc)) then - 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') - 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') - end if + ! 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 - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Faxa_snowc') - call addfld(fldListFr(compatm)%flds, 'Faxa_snowl') - call addfld(fldListFr(compatm)%flds, 'Faxa_snow' ) - call addfld(fldListTo(compice)%flds, 'Faxa_snow' ) - - call addfld(fldListFr(compatm)%flds, 'Faxa_snowc_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_snowl_wiso') - call addfld(fldListFr(compatm)%flds, 'Faxa_snow_wiso' ) - call addfld(fldListTo(compice)%flds, 'Faxa_snow_wiso' ) - else - if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_snow' , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc', rc=rc)) then - 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') - 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') - 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. & - fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc_wiso', rc=rc)) then - 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') - 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') - end if + ! 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 - ! --------------------------------------------------------------------- - ! to ice: height at the lowest model level from atm - ! to ice: pressure at the lowest model level fromatm - ! to ice: temperature at the lowest model level from atm - ! to ice: potential temperature at the lowest model level from atm - ! to ice: density at the lowest model level from atm - ! to ice: zonal wind at the lowest model level from atm - ! to ice: meridional wind at the lowest model level from atm - ! to ice: specific humidity at the lowest model level from atm - ! to ice: specific humidity for water isotopes at the lowest model level from atm - ! --------------------------------------------------------------------- - allocate(flds(9)) - flds = (/'Sa_z ', 'Sa_pbot ', 'Sa_tbot ', 'Sa_ptem ', & - 'Sa_dens ', 'Sa_u ', 'Sa_v ', 'Sa_shum ', 'Sa_shum_wiso'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compice)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then - if (trim(fldname) == 'Sa_u' .or. trim(fldname) == 'Sa_v') then - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mappatch, 'one', atm2ice_vmap) + ! 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 - call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapbilnr, 'one', atm2ice_smap) + dataptr2d(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) end if - call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to ice: sea surface temperature from ocn - ! to ice: sea surface salinity from ocn - ! to ice: zonal sea water velocity from ocn - ! to ice: meridional sea water velocity from ocn - ! to ice: zonal sea surface slope from ocean - ! to ice: meridional sea surface slope from ocn - ! --------------------------------------------------------------------- - allocate(flds(6)) - flds = (/'So_t ', 'So_s ', 'So_u ', 'So_v ', 'So_dhdx', 'So_dhdy'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, trim(fldname)) - call addfld(fldListTo(compice)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBexp(compice) , trim(fldname), rc=rc) .and. & - 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') - end if - end if + end do end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to ice: ocean melt and freeze potential from ocn - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, 'Fioo_q') - call addfld(fldListTo(compice)%flds, 'Fioo_q') - else - 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') - end if - end if - !----------------------------- - ! to ice: Ratio of ocean surface level abund. H2_16O/H2O/Rstd from ocean - !----------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, 'So_roce_wiso') - call addfld(fldListTo(compice)%flds, 'So_roce_wiso') - else - 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') - end if + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if + call t_stopf('MED:'//subname) - ! --------------------------------------------------------------------- - ! to ice: frozen runoff from rof and glc - ! --------------------------------------------------------------------- - 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 - 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') - end if - end if - end do - - !===================================================================== - ! FIELDS TO WAVE (compwav) - !===================================================================== - - !---------------------------------------------------------- - ! to wav: fractional ice coverage wrt ocean from ice - !---------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compice)%flds, 'Si_ifrac') - call addfld(fldListTo(compwav)%flds, 'Si_ifrac') - else - if ( fldchk(is_local%wrap%FBexp(compwav) , 'Si_ifrac', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice ), 'Si_ifrac', 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(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') - end if - end if + end subroutine map_glc2lnd - ! --------------------------------------------------------------------- - ! to wav: ocean boundary layer depth from ocn - ! to wav: ocean currents from ocn - ! to wav: ocean surface temperature from ocn - ! --------------------------------------------------------------------- - allocate(flds(4)) - flds = (/'So_t ', 'So_u ', 'So_v ', 'So_bldepth'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, trim(fldname)) - call addfld(fldListTo(compwav)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(compocn, compocn), trim(fldname), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(flds) - - ! --------------------------------------------------------------------- - ! to wav: zonal wind at the lowest model level from atm - ! to wav: meridional wind at the lowest model level from atm - ! --------------------------------------------------------------------- - allocate(flds(3)) - flds = (/'Sa_u ', 'Sa_v ', 'Sa_tbot'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, trim(fldname)) - call addfld(fldListTo(compwav)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBexp(compwav) , trim(fldname), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(flds) - - !===================================================================== - ! FIELDS TO RIVER (comprof) - !===================================================================== - - ! --------------------------------------------------------------------- - ! to rof: water flux from land (liquid surface) - ! to rof: water flux from land (liquid glacier, wetland, and lake) - ! to rof: water flux from land (liquid subsurface) - ! to rof: water flux from land direct to ocean - ! to rof: irrigation flux from land (withdrawal from rivers) - ! --------------------------------------------------------------------- - ! TODO (mvertens, 2019-01-13): the following isotopes have not yet been defined in the NUOPC field dict - ! allocate(flds(12)) - ! flds = (/'Flrl_rofsur', 'Flrl_rofsur_wiso', 'Flrl_rofgwl', 'Flrl_rofgwl_wiso', & - ! 'Flrl_rofsub', 'Flrl_rofsub_wiso', 'Flrl_rofdto', 'Flrl_rofdto_wiso', & - ! 'Flrl_rofi' , 'Flrl_rofi_wiso' , 'Flrl_irrig' , 'Flrl_irrig_wiso' /) - - allocate(flds(6)) - flds = (/'Flrl_rofsur', 'Flrl_rofgwl', 'Flrl_rofsub', 'Flrl_rofdto', 'Flrl_rofi ', 'Flrl_irrig '/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, trim(fldname)) - call addfld(fldListTo(comprof)%flds, trim(fldname)) - else - if ( fldchk(is_local%wrap%FBImp(complnd, complnd), trim(fldname), rc=rc) .and. & - 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') - end if - end if - end do - deallocate(flds) - - !===================================================================== - ! FIELDS TO LAND-ICE (compglc) - !===================================================================== - - !----------------------------- - ! to glc: from land - !----------------------------- - ! - fields sent from lnd->med ARE in multiple elevation classes - ! - fields sent from med->glc do NOT have elevation classes - - ! Sets a coupling field for all glc elevation classes (1:glc_nec) plus bare land (index 0). - ! Note that, if glc_nec = 0, then we don't create any coupling fields (not even the bare land (0) fldindex) - ! Note : Sl_topo is sent from lnd -> med, but is NOT sent to glc (only used for the remapping in the mediator) - - 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) - 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) - end if - end if - - !===================================================================== - ! CO2 EXCHANGE - !===================================================================== - - call NUOPC_CompAttributeGet(gcomp, name='flds_co2a', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) flds_co2a - call ESMF_LogWrite('flds_co2a = '// trim(cvalue), ESMF_LOGMSG_INFO) - - call NUOPC_CompAttributeGet(gcomp, name='flds_co2b', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) flds_co2b - call ESMF_LogWrite('flds_co2b = '// trim(cvalue), ESMF_LOGMSG_INFO) - - call NUOPC_CompAttributeGet(gcomp, name='flds_co2c', value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) flds_co2c - call ESMF_LogWrite('flds_co2c = '// trim(cvalue), ESMF_LOGMSG_INFO) - - if (flds_co2a) then - ! --------------------------------------------------------------------- - ! to lnd and ocn: prognostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') - call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') - call addfld(fldListTo(compocn)%flds, 'Sa_co2prog') - else - call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', complnd, mapbilnr, 'one', atm2lnd_smap) - 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') - call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') - end if - - ! --------------------------------------------------------------------- - ! to lnd and ocn: diagnostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') - call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') - call addfld(fldListTo(compocn)%flds, 'Sa_co2diag') - else - call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', complnd, mapbilnr, 'one', atm2lnd_smap) - 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') - call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') - end if - - else if (flds_co2b) then - - ! --------------------------------------------------------------------- - ! to lnd: prognostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') - call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') - 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') - end if - - ! --------------------------------------------------------------------- - ! to lnd: diagnostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') - call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') - 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') - end if - - ! --------------------------------------------------------------------- - ! to atm: surface flux of CO2 from land - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') - call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') - 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') - end if - - else if (flds_co2c) then - - ! --------------------------------------------------------------------- - ! to lnd and ocn: prognostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2prog') - call addfld(fldListTo(complnd)%flds, 'Sa_co2prog') - call addfld(fldListTo(compocn)%flds, 'Sa_co2prog') - else - call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', complnd, mapbilnr, 'one', atm2lnd_smap) - 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') - call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') - end if - - ! --------------------------------------------------------------------- - ! to lnd and ocn: diagnostic CO2 at the lowest atm model level - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compatm)%flds, 'Sa_co2diag') - call addfld(fldListTo(complnd)%flds, 'Sa_co2diag') - call addfld(fldListTo(compocn)%flds, 'Sa_co2diag') - else - call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', complnd, mapbilnr, 'one', atm2lnd_smap) - 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') - call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') - end if - - ! --------------------------------------------------------------------- - ! to atm: surface flux of CO2 from land - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(complnd)%flds, 'Fall_fco2_lnd') - call addfld(fldListTo(compatm)%flds, 'Fall_fco2_lnd') - 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') - end if - - ! --------------------------------------------------------------------- - ! to atm: surface flux of CO2 from ocn - ! --------------------------------------------------------------------- - if (phase == 'advertise') then - call addfld(fldListFr(compocn)%flds, 'Faoo_fco2_ocn') - call addfld(fldListTo(compatm)%flds, 'Faoo_fco2_ocn') - else - call addmap(fldListFr(compocn)%flds, 'Faoo_fco2_ocn', compatm, mapconsf, 'one', ocn2atm_fmap) - ! custom merge in med_phases_prep_atm - end if - endif - - !----------------------------------------------------------------------------- - ! CARMA fields (volumetric soil water) - !----------------------------------------------------------------------------- - ! TODO: add this - ! if (carma_flds /= ' ') then - ! 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') - ! enddo - ! endif - - end subroutine esmFldsExchange_cesm - -end module esmFldsExchange_cesm_mod +end module med_phases_prep_lnd_mod From 25a31da2827081dadb24c030a17bef65db025b7b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 29 Oct 2020 09:31:12 -0600 Subject: [PATCH 136/206] undid debug settings that impacted performance --- mediator/med.F90 | 33 ++++++++++++++------------------- mediator/med_constants_mod.F90 | 2 +- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index d8e49f8c4..20d2d43c5 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -113,7 +113,7 @@ subroutine SetServices(gcomp, rc) integer, intent(out) :: rc ! local variables - character(len=*),parameter :: subname='(module_med:SetServices)' + character(len=*),parameter :: subname='(module_MED:SetServices)' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -472,7 +472,7 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) character(len=CX) :: msgString character(len=CX) :: diro character(len=CX) :: logfile - character(len=*),parameter :: subname=' (module_med:InitializeP0) ' + character(len=*),parameter :: subname=' (module_MED:InitializeP0) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -507,15 +507,10 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(cvalue), ESMF_LOGMSG_INFO) - ! call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & - ! convention="NUOPC", purpose="Instance", 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) - - call ESMF_AttributeSet(gcomp, name="Profiling", value='65535', & + call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator profileing is set to "//trim(cvalue), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(cvalue), ESMF_LOGMSG_INFO) ! 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) @@ -575,7 +570,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) 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) ' + character(len=*),parameter :: subname=' (module_MED:InitializeIPDv03p1) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -841,7 +836,7 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc) type(InternalState) :: is_local type(ESMF_VM) :: vm integer :: n - character(len=*),parameter :: subname=' (module_med:InitializeIPDv03p3) ' + character(len=*),parameter :: subname=' (module_MED:InitializeIPDv03p3) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -906,7 +901,7 @@ subroutine InitializeIPDv03p4(gcomp, importState, exportState, clock, rc) ! local variables type(InternalState) :: is_local integer :: n1,n2 - character(len=*),parameter :: subname=' (module_med:InitalizeIPDv03p4) ' + character(len=*),parameter :: subname=' (module_MED:InitalizeIPDv03p4) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -976,7 +971,7 @@ subroutine realizeConnectedGrid(State,string,rc) character(ESMF_MAXSTR),allocatable :: fieldNameList(:) type(ESMF_FieldStatus_Flag) :: fieldStatus character(len=CX) :: msgString - character(len=*),parameter :: subname=' (module_med:realizeConnectedGrid) ' + character(len=*),parameter :: subname=' (module_MED:realizeConnectedGrid) ' !----------------------------------------------------------- !NOTE: All of the Fields that set their TransferOfferGeomObject Attribute @@ -1354,7 +1349,7 @@ subroutine InitializeIPDv03p5(gcomp, importState, exportState, clock, rc) ! local variables type(InternalState) :: is_local integer :: n1,n2 - character(len=*),parameter :: subname=' (module_med:InitializeIPDv03p5) ' + character(len=*),parameter :: subname=' (module_MED:InitializeIPDv03p5) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -1431,7 +1426,7 @@ subroutine completeFieldInitialization(State,rc) integer, allocatable :: ungriddedLBound(:), ungriddedUBound(:) logical :: isPresent logical :: meshcreated - character(len=*),parameter :: subname=' (module_med:completeFieldInitialization) ' + character(len=*),parameter :: subname=' (module_MED:completeFieldInitialization) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -1609,7 +1604,7 @@ subroutine DataInitialize(gcomp, rc) logical,save :: first_call = .true. real(r8) :: real_nx, real_ny character(len=CX) :: msgString - character(len=*), parameter :: subname=' (module_med:DataInitialize) ' + character(len=*), parameter :: subname=' (module_MED:DataInitialize) ' !----------------------------------------------------------- call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) @@ -2217,7 +2212,7 @@ subroutine SetRunClock(gcomp, rc) character(len=CS) :: glc_avg_period integer :: glc_cpl_dt logical :: first_time = .true. - character(len=*),parameter :: subname=' (module_med:SetRunClock) ' + character(len=*),parameter :: subname=' (module_MED:SetRunClock) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -2332,7 +2327,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) real(r8), allocatable :: ownedElemCoords(:) real(r8), pointer :: dataptr(:) integer :: n, dimcount, fieldcount - character(len=*),parameter :: subname=' (module_med:med_meshinfo_create) ' + character(len=*),parameter :: subname=' (module_MED:med_meshinfo_create) ' !------------------------------------------------------------------------------- rc= ESMF_SUCCESS @@ -2396,7 +2391,7 @@ subroutine med_grid_write(grid, fileName, rc) type(ESMF_ArrayBundle) :: arrayBundle integer :: tileCount logical :: isPresent - character(len=*), parameter :: subname=' (module_med_map:med_grid_write) ' + character(len=*), parameter :: subname=' (module_MED_map:med_grid_write) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/mediator/med_constants_mod.F90 b/mediator/med_constants_mod.F90 index e580a462c..4cc96f4f7 100644 --- a/mediator/med_constants_mod.F90 +++ b/mediator/med_constants_mod.F90 @@ -11,6 +11,6 @@ module med_constants_mod real(R8), parameter :: med_constants_czero = 0.0_R8 ! spval integer, parameter :: med_constants_ispval_mask = -987987 ! spval for RH mask values integer, parameter :: med_constants_SecPerDay = 86400 ! Seconds per day - integer :: med_constants_dbug_flag = 10 + integer :: med_constants_dbug_flag = 0 end module med_constants_mod From 7540b4a760495d6cd4a42c114a482cb2bc473bfd Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 29 Oct 2020 10:02:20 -0600 Subject: [PATCH 137/206] backed out some subname changes --- mediator/med.F90 | 2 +- mediator/med_map_mod.F90 | 26 +- mediator/med_methods_mod.F90 | 1422 +++++++++++++++++++++++++++++----- 3 files changed, 1263 insertions(+), 187 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 20d2d43c5..6a134ee48 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -113,7 +113,7 @@ subroutine SetServices(gcomp, rc) integer, intent(out) :: rc ! local variables - character(len=*),parameter :: subname='(module_MED:SetServices)' + character(len=*),parameter :: subname=' (module_MED:SetServices) ' !----------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 72e8131e0..05880aefd 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -124,7 +124,7 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) !integer(ESMF_KIND_I4), pointer :: unmappedDstList(:) character(len=128) :: logMsg type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG - character(len=*), parameter :: subname=' (RouteHandles_init) ' + character(len=*), parameter :: subname=' (module_med_map: RouteHandles_init) ' !----------------------------------------------------------- call t_startf('MED:'//subname) @@ -380,7 +380,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route integer :: SrcMaskValue integer :: DstMaskValue type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG - character(len=*), parameter :: subname=' (med_map_routehandles_init) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_routehandles_init_fields) ' !--------------------------------------------- call t_startf('MED:'//subname) @@ -535,7 +535,7 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) ! local variables integer :: rc1, rc2 logical :: mapexists - character(len=*), parameter :: subname=' (med_map_RH_is_created) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_RH_is_created) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -558,7 +558,7 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) ! local variables integer :: rc1, rc2 logical :: mapexists - character(len=*), parameter :: subname=' (med_map_RH_is_created_RH1d) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_RH_is_created_RH1d) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -615,7 +615,7 @@ subroutine med_map_mapnorm_init(gcomp, rc) type(ESMF_Field) :: field_src type(ESMF_Mesh) :: mesh_src type(ESMF_Mesh) :: mesh_dst - character(len=*),parameter :: subname=' (med_map_mapnorm_init) ' + character(len=*),parameter :: subname=' (module_MED_MAP:MapNorm_init)' !----------------------------------------------------------- call t_startf('MED:'//subname) @@ -737,7 +737,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=' (med_packed_fieldbundles_create) ' + character(len=*), parameter :: subname=' (module_MED_map:med_packed_fieldbundles_create) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -914,7 +914,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d character(CL), allocatable :: fieldNameList(:) real(r8), pointer :: data_norm(:) => null() real(r8), pointer :: data_dst(:,:) => null() - character(len=*), parameter :: subname=' (med_map_field_packed) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_field_packed) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -1100,7 +1100,7 @@ subroutine med_map_field_normalized(field_src, field_dst, routehandles, maptype, integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields integer :: lsize_src integer :: lsize_dst - character(len=*), parameter :: subname=' (med_map_field_normalized) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_field_normalized) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -1209,7 +1209,7 @@ subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, r ! local variables logical :: checkflag = .false. character(len=CS) :: lfldname - character(len=*), parameter :: subname='(med_map_field) ' + character(len=*), parameter :: subname='(module_MED_map:med_map_field) ' !--------------------------------------------------- rc = ESMF_SUCCESS @@ -1280,14 +1280,14 @@ subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex ! local type(ESMF_Field) :: field1, field2 character(CS) :: lfldname - character(len=*),parameter :: subname='(med_map_fb_field_regrid)' + character(len=*),parameter :: subname='(module_MED_map:med_map_fb_field_regrid)' ! ---------------------------------------------- if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) endif - call t_startf(subname) + call t_startf('MED:'//trim(subname)) rc = ESMF_SUCCESS lfldname=trim(fldin)//'->'//trim(fldout) @@ -1312,7 +1312,7 @@ subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif - call t_stopf(subname) + call t_stopf('MED:'//trim(subname)) end subroutine med_map_fb_field_regrid @@ -1355,7 +1355,7 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) integer :: spatialDim logical :: checkflag = .false. real(r8), parameter :: deg2rad = shr_const_pi/180.0_R8 ! deg to rads - character(len=*), parameter :: subname=' med_map_uv_cart3d) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_uv_cart3d) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index c53fc1abf..9ec6500a7 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -7,10 +7,10 @@ module med_methods_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 : operator(<), operator(/=), operator(+), operator(-), operator(*) , operator(>=) use ESMF , only : operator(<=), operator(>), operator(==) - use ESMF , only : ESMF_FieldStatus_Flag + use ESMF , only : ESMF_GeomType_Flag, ESMF_FieldStatus_Flag, ESMF_PoleMethod_Flag use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING + use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING, ESMF_POLEMETHOD_ALLAVG 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 : spval_init => med_constants_spval_init @@ -32,12 +32,18 @@ module med_methods_mod med_methods_FieldPtr_compare2 end interface + interface med_methods_UpdateTimestamp; module procedure & + med_methods_State_UpdateTimestamp, & + med_methods_Field_UpdateTimestamp + end interface + ! used/reused in module - logical :: isPresent - character(len=1024) :: msgString - type(ESMF_FieldStatus_Flag) :: status - character(*) , parameter :: u_FILE_u = & + logical :: isPresent + character(len=1024) :: msgString + type(ESMF_GeomType_Flag) :: geomtype + type(ESMF_FieldStatus_Flag) :: status + character(*) , parameter :: u_FILE_u = & __FILE__ public med_methods_FB_copy @@ -46,36 +52,132 @@ module med_methods_mod public med_methods_FB_init public med_methods_FB_init_pointer public med_methods_FB_reset + public med_methods_FB_clean public med_methods_FB_diagnose public med_methods_FB_FldChk public med_methods_FB_GetFldPtr public med_methods_FB_getNameN public med_methods_FB_getFieldN + public med_methods_FB_getFieldByName public med_methods_FB_getNumflds public med_methods_FB_Field_diagnose - public med_methods_FB_GeomPrint + public med_methods_Field_diagnose public med_methods_State_reset public med_methods_State_diagnose public med_methods_State_GeomPrint + public med_methods_State_GeomWrite + public med_methods_State_GetFldPtr public med_methods_State_SetScalar public med_methods_State_GetScalar public med_methods_State_GetNumFields - public med_methods_Field_diagnose + public med_methods_State_getFieldN + public med_methods_State_FldDebug public med_methods_Field_GeomPrint - public med_methods_FieldPtr_compare public med_methods_Clock_TimePrint + public med_methods_UpdateTimestamp + public med_methods_Distgrid_Match + public med_methods_FieldPtr_compare + public med_methods_States_GetSharedFlds - private med_methods_Mesh_Print + private med_methods_Grid_Write private med_methods_Grid_Print + private med_methods_Mesh_Print + private med_methods_Mesh_Write private med_methods_Field_GetFldPtr + private med_methods_Field_GeomWrite + private med_methods_Field_UpdateTimestamp + private med_methods_FB_GeomPrint + private med_methods_FB_GeomWrite + private med_methods_FB_RWFields + private med_methods_FB_SetFldPtr private med_methods_FB_copyFB2FB private med_methods_FB_accumFB2FB + private med_methods_State_UpdateTimestamp + private med_methods_State_getNameN + private med_methods_State_getFieldByName + private med_methods_State_SetFldPtr private med_methods_Array_diagnose !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- + subroutine med_methods_FB_RWFields(mode,fname,FB,flag,rc) + + ! ---------------------------------------------- + ! Read or Write Field Bundles + ! ---------------------------------------------- + use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleWrite + use ESMF, only : ESMF_FieldRead, ESMF_IOFMT_NETCDF, ESMF_FILESTATUS_REPLACE + + character(len=*) :: mode + character(len=*) :: fname + type(ESMF_FieldBundle) :: FB + logical,optional :: flag + integer,optional :: rc + + ! local variables + type(ESMF_Field) :: field + character(len=ESMF_MAXSTR) :: name + integer :: fieldcount, n + logical :: fexists + character(len=*), parameter :: subname='(med_methods_FB_RWFields)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//trim(fname)//": called", ESMF_LOGMSG_INFO) + endif + + if (mode == 'write') then + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": write "//trim(fname), ESMF_LOGMSG_INFO) + end if + call ESMF_FieldBundleWrite(FB, fname, & + singleFile=.true., status=ESMF_FILESTATUS_REPLACE, iofmt=ESMF_IOFMT_NETCDF, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_diagnose(FB, 'write '//trim(fname), rc) + + elseif (mode == 'read') then + inquire(file=fname,exist=fexists) + if (fexists) then + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": read "//trim(fname), ESMF_LOGMSG_INFO) + end if + !----------------------------------------------------------------------------------------------------- + ! tcraig, ESMF_FieldBundleRead fails if a field is not on the field bundle, but we really want to just + ! ignore that field and read the rest, so instead read each field one at a time through ESMF_FieldRead + ! call ESMF_FieldBundleRead (FB, fname, & + ! singleFile=.true., iofmt=ESMF_IOFMT_NETCDF, rc=rc) + ! if (chkerr(rc,__LINE__,u_FILE_u)) return + !----------------------------------------------------------------------------------------------------- + call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,fieldCount + call med_methods_FB_getFieldByName(FB, name, field, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldRead (field, fname, iofmt=ESMF_IOFMT_NETCDF, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, file=u_FILE_u)) call ESMF_LogWrite(trim(subname)//& + ' WARNING missing field '//trim(name)) + enddo + + call med_methods_FB_diagnose(FB, 'read '//trim(fname), rc) + if (present(flag)) flag = .true. + endif + + else + call ESMF_LogWrite(trim(subname)//": mode WARNING "//trim(fname)//" mode="//trim(mode), ESMF_LOGMSG_INFO) + endif + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//trim(fname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_FB_RWFields + + !----------------------------------------------------------------------------- + subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, rc) ! ---------------------------------------------- @@ -396,9 +498,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from FBgeom", ESMF_LOGMSG_INFO) end if elseif (present(STgeom)) then - call med_methods_State_getNameN(STgeom, 1, lname, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_StateGet(STgeom, itemName=lname, field=lfield, rc=rc) + call med_methods_State_getFieldN(STgeom, 1, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from STgeom", ESMF_LOGMSG_INFO) @@ -448,9 +548,7 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call med_methods_FB_getFieldN(FBflds, n, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (present(STflds)) then - call med_methods_State_getNameN(STflds, n, lname, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_StateGet(STflds, itemName=lname, field=lfield, rc=rc) + call med_methods_State_getFieldN(STflds, n, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -547,17 +645,22 @@ subroutine med_methods_FB_getNameN(FB, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' + call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif + allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + fieldname = lfieldnamelist(fieldnum) + deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -606,6 +709,40 @@ end subroutine med_methods_FB_getFieldN !----------------------------------------------------------------------------- + subroutine med_methods_FB_getFieldByName(FB, fieldname, field, rc) + + ! ---------------------------------------------- + ! Get field associated with fieldname out of FB + ! ---------------------------------------------- + + use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet + + ! input/output variables + type(ESMF_FieldBundle), intent(in) :: FB + character(len=*) , intent(in) :: fieldname + type(ESMF_Field) , intent(inout) :: field + integer , intent(out) :: rc + + ! local variables + character(len=*),parameter :: subname='(med_methods_FB_getFieldByName)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=field, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_FB_getFieldByName + + !----------------------------------------------------------------------------- + subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) ! ---------------------------------------------- @@ -631,17 +768,22 @@ subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' + call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif + allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + fieldname = lfieldnamelist(fieldnum) + deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -670,6 +812,7 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) integer :: n,itemCount type(ESMF_Field), pointer :: fieldList(:) type(ESMF_StateItem_Flag), pointer :: itemTypeList(:) + logical, parameter :: use_NUOPC_method = .true. character(len=*),parameter :: subname='(med_methods_State_getNumFields)' ! ---------------------------------------------- @@ -678,13 +821,34 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) endif rc = ESMF_SUCCESS - nullify(fieldList) - call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldnum = 0 - if (associated(fieldList)) then - fieldnum = size(fieldList) - deallocate(fieldList) + if (use_NUOPC_method) then + + nullify(fieldList) + call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + fieldnum = 0 + if (associated(fieldList)) then + fieldnum = size(fieldList) + deallocate(fieldList) + endif + + else + + fieldnum = 0 + call ESMF_StateGet(State, itemCount=itemCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (itemCount > 0) then + allocate(itemTypeList(itemCount)) + call ESMF_StateGet(State, itemTypeList=itemTypeList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1,itemCount + if (itemTypeList(n) == ESMF_STATEITEM_FIELD) fieldnum=fieldnum+1 + enddo + deallocate(itemTypeList) + endif + endif if (dbug_flag > 10) then @@ -695,28 +859,135 @@ end subroutine med_methods_State_getNumFields !----------------------------------------------------------------------------- + subroutine med_methods_State_getFieldN(State, fieldnum, field, rc) + + ! ---------------------------------------------- + ! Get field number fieldnum in State + ! ---------------------------------------------- + + use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + + type(ESMF_State), intent(in) :: State + integer , intent(in) :: fieldnum + type(ESMF_Field), intent(inout) :: field + integer , intent(out) :: rc + + ! local variables + character(len=ESMF_MAXSTR) :: name + character(len=*),parameter :: subname='(med_methods_State_getFieldN)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call med_methods_State_getNameN(State, fieldnum, name, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_StateGet(State, itemName=name, field=field, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_State_getFieldN + + !----------------------------------------------------------------------------- + + subroutine med_methods_State_getFieldByName(State, fieldname, field, rc) + ! ---------------------------------------------- + ! Get field associated with fieldname from State + ! ---------------------------------------------- + use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + + type(ESMF_State), intent(in) :: State + character(len=*), intent(in) :: fieldname + type(ESMF_Field), intent(inout) :: field + integer , intent(out) :: rc + + ! local variables + character(len=*),parameter :: subname='(med_methods_State_getFieldByName)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call ESMF_StateGet(State, itemName=fieldname, field=field, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_State_getFieldByName + + !----------------------------------------------------------------------------- + + subroutine med_methods_FB_clean(FB, rc) + ! ---------------------------------------------- + ! Destroy fields in FB and FB + ! ---------------------------------------------- + + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldDestroy + use ESMF, only : ESMF_FieldBundleDestroy, ESMF_Field + + type(ESMF_FieldBundle), intent(inout) :: FB + integer , intent(out) :: rc + + ! local variables + integer :: i,j,n + integer :: fieldCount + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + type(ESMF_Field) :: field + character(len=*),parameter :: subname='(med_methods_FB_clean)' + ! ---------------------------------------------- + + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1, fieldCount + call ESMF_FieldBundleGet(FB, fieldName=lfieldnamelist(n), field=field, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldDestroy(field, rc=rc, noGarbage=.true.) + if (chkerr(rc,__LINE__,u_FILE_u)) return + enddo + + call ESMF_FieldBundleDestroy(FB, rc=rc, noGarbage=.true.) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(lfieldnamelist) + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + + end subroutine med_methods_FB_clean + + !----------------------------------------------------------------------------- + subroutine med_methods_FB_reset(FB, value, rc) ! ---------------------------------------------- ! Set all fields to value in FB ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet ! intput/output variables - type(ESMF_FieldBundle) , intent(inout) :: FB - real(R8) , intent(in), optional :: value - integer , intent(out) :: rc + type(ESMF_FieldBundle), intent(inout) :: FB + real(R8) , intent(in), optional :: value + integer , intent(out) :: rc ! local variables integer :: i,j,n integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) + real(R8) :: lvalue character(len=*),parameter :: subname='(med_methods_FB_reset)' ! ---------------------------------------------- @@ -735,25 +1006,12 @@ subroutine med_methods_FB_reset(FB, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = lvalue - elseif (lrank == 2) then - fldptr2 = lvalue - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif + do n = 1, fieldCount + call med_methods_FB_SetFldPtr(FB, lfieldnamelist(n), lvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return enddo + deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -771,7 +1029,7 @@ subroutine med_methods_State_reset(State, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field + use ESMF, only : ESMF_State, ESMF_StateGet ! intput/output variables type(ESMF_State) , intent(inout) :: State @@ -782,11 +1040,7 @@ subroutine med_methods_State_reset(State, value, rc) integer :: i,j,n integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) + real(R8) :: lvalue character(len=*),parameter :: subname='(med_methods_State_reset)' ! ---------------------------------------------- @@ -805,24 +1059,12 @@ subroutine med_methods_State_reset(State, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, fieldCount - call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = lvalue - elseif (lrank == 2) then - fldptr2 = lvalue - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif + call med_methods_State_SetFldPtr(State, lfieldnamelist(n), lvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return enddo + deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -839,7 +1081,7 @@ subroutine med_methods_FB_average(FB, count, rc) ! Set all fields to zero in FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -852,7 +1094,6 @@ subroutine med_methods_FB_average(FB, count, rc) character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) real(R8), pointer :: dataPtr1(:) real(R8), pointer :: dataPtr2(:,:) - type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_FB_average)' ! ---------------------------------------------- @@ -878,10 +1119,8 @@ subroutine med_methods_FB_average(FB, count, rc) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1, fldptr2=dataptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), dataPtr1, dataPtr2, lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data @@ -918,7 +1157,7 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! Diagnose status of FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet type(ESMF_FieldBundle) , intent(inout) :: FB character(len=*) , intent(in), optional :: string @@ -931,7 +1170,6 @@ subroutine med_methods_FB_diagnose(FB, string, rc) character(len=CL) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) - type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_diagnose)' ! ---------------------------------------------- @@ -954,9 +1192,8 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! For each field in the bundle, get its memory location and print out the field do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) + call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), & + fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then @@ -1051,9 +1288,8 @@ subroutine med_methods_State_diagnose(State, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field + use ESMF, only : ESMF_State, ESMF_StateGet - ! input/output variables type(ESMF_State), intent(in) :: State character(len=*), intent(in), optional :: string integer , intent(out) :: rc @@ -1065,7 +1301,6 @@ subroutine med_methods_State_diagnose(State, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) - type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_State_diagnose)' ! ---------------------------------------------- @@ -1081,16 +1316,19 @@ subroutine med_methods_State_diagnose(State, string, rc) call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(lfieldnamelist(fieldCount)) + call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1, fieldCount - call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) + + call med_methods_State_GetFldPtr(State, lfieldnamelist(n), & + fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data + elseif (lrank == 1) then if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1099,6 +1337,7 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif + elseif (lrank == 2) then if (size(dataPtr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1107,6 +1346,7 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif + else call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE @@ -1133,7 +1373,7 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + use ESMF, only : ESMF_FieldBundle ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -1146,9 +1386,7 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) real(R8), pointer :: dataPtr2d(:,:) - 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_FieldDiagnose)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -1161,29 +1399,30 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) lstring = trim(string) endif - call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=lfield, rc=rc) + call med_methods_FB_GetFldPtr(FB, fieldname, dataPtr1d, dataPtr2d, lrank, 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 ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (size(dataptr2d) > 0) then + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) + minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - else - call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (size(dataPtr1d) > 0) then + elseif (lrank == 2) then + if (size(dataPtr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) + minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - end if + else + call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) if (dbug_flag > 10) then @@ -1299,9 +1538,9 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) ! If copy is passed in and true, the this is a copy ! ---------------------------------------------- - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + use ESMF , only : ESMF_FieldBundle + use ESMF , only : ESMF_FieldBundleGet - ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FBout type(ESMF_FieldBundle), intent(in) :: FBin logical, optional , intent(in) :: copy @@ -1315,7 +1554,6 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) logical :: lcopy real(R8), pointer :: dataPtri1(:) , dataPtro1(:) real(R8), pointer :: dataPtri2(:,:), dataPtro2(:,:) - type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_accumFB2FB)' ! ---------------------------------------------- @@ -1339,14 +1577,9 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) call ESMF_FieldBundleGet(FBin, fieldName=lfieldnamelist(n), isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (exists) then - call ESMF_FieldBundleGet(FBin, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + call med_methods_FB_GetFldPtr(FBin, lfieldnamelist(n), dataPtri1, dataPtri2, lranki, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptri1, fldptr2=dataptri2, rank=lranki, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_FieldBundleGet(FBout, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptro1, fldptr2=dataptro2, rank=lranko, rc=rc) + call med_methods_FB_GetFldPtr(FBout, lfieldnamelist(n), dataPtro1, dataPtro2, lranko, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lranki == 1 .and. lranko == 1) then @@ -1473,7 +1706,6 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) use ESMF , only : ESMF_Field,ESMF_Mesh, ESMF_FieldGet, ESMF_MeshGet use ESMF , only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_COMPLETE - use ESMF , only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field) , intent(in) :: field @@ -1484,10 +1716,9 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) integer , intent(out) , optional :: rc ! local variables - type(ESMF_Mesh) :: lmesh - integer :: lrank, nnodes, nelements - logical :: labort - type(ESMF_GeomType_Flag) :: geomtype + type(ESMF_Mesh) :: lmesh + integer :: lrank, nnodes, nelements + logical :: labort character(len=*), parameter :: subname='(med_methods_Field_GetFldPtr)' ! ---------------------------------------------- @@ -1530,6 +1761,7 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + elseif (geomtype == ESMF_GEOMTYPE_MESH) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1538,8 +1770,10 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) call ESMF_MeshGet(lmesh, numOwnedNodes=nnodes, numOwnedElements=nelements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (nnodes == 0 .and. nelements == 0) lrank = 0 + else - call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & + ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return endif ! geomtype @@ -1633,7 +1867,9 @@ subroutine med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, rank, field, call ESMF_FieldBundleGet(FB, fieldName=trim(fldname), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + + call med_methods_Field_GetFldPtr(lfield, & + fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (present(rank)) then @@ -1650,13 +1886,156 @@ end subroutine med_methods_FB_GetFldPtr !----------------------------------------------------------------------------- + subroutine med_methods_FB_SetFldPtr(FB, fldname, val, rc) + + use ESMF, only : ESMF_FieldBundle, ESMF_Field + + type(ESMF_FieldBundle), intent(in) :: FB + character(len=*) , intent(in) :: fldname + real(R8) , intent(in) :: val + integer , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) + character(len=*), parameter :: subname='(med_methods_FB_SetFldPtr)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = val + elseif (lrank == 2) then + fldptr2 = val + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_FB_SetFldPtr + + !----------------------------------------------------------------------------- + + subroutine med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, rank, rc) + ! ---------------------------------------------- + ! Get pointer to a state field + ! ---------------------------------------------- + + use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + + type(ESMF_State), intent(in) :: ST + character(len=*), intent(in) :: fldname + real(R8), pointer, intent(inout), optional :: fldptr1(:) + real(R8), pointer, intent(inout), optional :: fldptr2(:,:) + integer , intent(out), optional :: rank + integer , intent(out), optional :: rc + + ! local variables + type(ESMF_Field) :: lfield + integer :: lrank + character(len=*), parameter :: subname='(med_methods_State_GetFldPtr)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + + if (.not.present(rc)) then + call ESMF_LogWrite(trim(subname)//": ERROR rc not present "//trim(fldname), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + + rc = ESMF_SUCCESS + + call ESMF_StateGet(ST, itemName=trim(fldname), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Field_GetFldPtr(lfield, & + fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (present(rank)) then + rank = lrank + endif + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_State_GetFldPtr + + !----------------------------------------------------------------------------- + + subroutine med_methods_State_SetFldPtr(ST, fldname, val, rc) + + use ESMF, only : ESMF_State, ESMF_Field + + type(ESMF_State) , intent(in) :: ST + character(len=*) , intent(in) :: fldname + real(R8), intent(in) :: val + integer , intent(out) :: rc + + ! local variables + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) + character(len=*), parameter :: subname='(med_methods_State_SetFldPtr)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = val + elseif (lrank == 2) then + fldptr2 = val + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_State_SetFldPtr + + !----------------------------------------------------------------------------- + logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) - ! input/output variables - real(R8) , pointer, intent(in) :: fldptr1(:) - real(R8) , pointer, intent(in) :: fldptr2(:) - character(len=*) , intent(in) :: cstring - integer , intent(out) :: rc + real(R8), pointer, intent(in) :: fldptr1(:) + real(R8), pointer, intent(in) :: fldptr2(:) + character(len=*) , intent(in) :: cstring + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(med_methods_FieldPtr_Compare1)' @@ -1668,7 +2047,8 @@ logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare1 = .false. - if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & + ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr1 ',lbound(fldptr1),ubound(fldptr1) @@ -1704,8 +2084,10 @@ logical function med_methods_FieldPtr_Compare2(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare2 = .false. - if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & - ubound(fldptr2,2) /= ubound(fldptr1,2) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. & + lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & + ubound(fldptr2,2) /= ubound(fldptr1,2) .or. & + ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr2 ',lbound(fldptr2),ubound(fldptr2) @@ -1728,16 +2110,12 @@ subroutine med_methods_State_GeomPrint(state, string, rc) use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - ! input/output variables type(ESMF_State), intent(in) :: state character(len=*), intent(in) :: string integer , intent(out) :: rc - ! local variables - type(ESMF_Field) :: lfield - integer :: fieldcount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - character(ESMF_MAXSTR) :: name + type(ESMF_Field) :: lfield + integer :: fieldcount character(len=*),parameter :: subname='(med_methods_State_GeomPrint)' ! ---------------------------------------------- @@ -1748,17 +2126,12 @@ subroutine med_methods_State_GeomPrint(state, string, rc) call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (fieldCount > 0) then - call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldCount)) - call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_StateGet(State, itemName=lfieldnamelist(1), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(lfieldnamelist) - call med_methods_Field_GeomPrint(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_State_GetFieldN(state, 1, lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GeomPrint(lfield, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) endif ! fieldCount > 0 @@ -1791,7 +2164,9 @@ subroutine med_methods_FB_GeomPrint(FB, string, rc) call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (fieldCount > 0) then + call med_methods_Field_GeomPrint(lfield, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else @@ -1810,7 +2185,6 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh use ESMF, only : ESMF_FieldGet, ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_EMPTY - use ESMF, only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field), intent(in) :: field @@ -1818,12 +2192,11 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) integer , intent(out) :: rc ! local variables - type(ESMF_Grid) :: lgrid - type(ESMF_Mesh) :: lmesh - integer :: lrank - real(R8), pointer :: dataPtr1(:) - real(R8), pointer :: dataPtr2(:,:) - type(ESMF_GeomType_Flag) :: geomtype + type(ESMF_Grid) :: lgrid + type(ESMF_Mesh) :: lmesh + integer :: lrank + real(R8), pointer :: dataPtr1(:) + real(R8), pointer :: dataPtr2(:,:) character(len=*),parameter :: subname='(med_methods_Field_GeomPrint)' ! ---------------------------------------------- @@ -1843,6 +2216,7 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, grid=lgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2043,30 +2417,29 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) end subroutine med_methods_Mesh_Print !----------------------------------------------------------------------------- + subroutine med_methods_Grid_Print(grid, string, rc) use ESMF, only : ESMF_Grid, ESMF_DistGrid, ESMF_StaggerLoc use ESMF, only : ESMF_GridGet, ESMF_DistGridGet, ESMF_GridGetCoord use ESMF, only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER - ! input/output variabes type(ESMF_Grid) , intent(in) :: grid character(len=*), intent(in) :: string integer , intent(out) :: rc - ! local variables - type(ESMF_Distgrid) :: distgrid - integer :: localDeCount - integer :: DeCount - integer :: dimCount, tileCount - integer :: staggerlocCount, arbdimCount, rank - type(ESMF_StaggerLoc) :: staggerloc - character(len=32) :: staggerstr - integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) - integer :: n1,n2,n3 - character(len=*),parameter :: subname='(med_methods_Grid_Print)' + type(ESMF_Distgrid) :: distgrid + integer :: localDeCount + integer :: DeCount + integer :: dimCount, tileCount + integer :: staggerlocCount, arbdimCount, rank + type(ESMF_StaggerLoc) :: staggerloc + character(len=32) :: staggerstr + integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) + real(R8), pointer :: fldptr1(:) + real(R8), pointer :: fldptr2(:,:) + integer :: n1,n2,n3 + character(len=*),parameter :: subname='(med_methods_Grid_Print)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -2084,10 +2457,13 @@ subroutine med_methods_Grid_Print(grid, string, rc) ! get dimCount and tileCount call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, deCount=deCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) + write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) + write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) @@ -2099,12 +2475,30 @@ subroutine med_methods_Grid_Print(grid, string, rc) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, & maxIndexPTile=maxIndexPTile, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) + write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) + deallocate(minIndexPTile, maxIndexPTile) + ! get staggerlocCount, arbDimCount +! call ESMF_GridGet(grid, staggerlocCount=staggerlocCount, rc=rc) +! if (chkerr(rc,__LINE__,u_FILE_u)) return + +! write (msgString,*) trim(subname)//":"//trim(string)//": staggerlocCount=", staggerlocCount +! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) +! if (chkerr(rc,__LINE__,u_FILE_u)) return + +! call ESMF_GridGet(grid, arbDimCount=arbDimCount, rc=rc) +! if (chkerr(rc,__LINE__,u_FILE_u)) return + +! write (msgString,*) trim(subname)//":"//trim(string)//": arbDimCount=", arbDimCount +! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) +! if (chkerr(rc,__LINE__,u_FILE_u)) return + ! get rank call ESMF_GridGet(grid, rank=rank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2133,14 +2527,12 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (rank == 1) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr1,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& - n2,n3,minval(fldptr1),maxval(fldptr1) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr1),maxval(fldptr1) endif if (rank == 2) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr2,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& - n2,n3,minval(fldptr2),maxval(fldptr2) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr2),maxval(fldptr2) endif call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) enddo @@ -2154,7 +2546,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) end subroutine med_methods_Grid_Print - !----------------------------------------------------------------------------- +!----------------------------------------------------------------------------- subroutine med_methods_Clock_TimePrint(clock,string,rc) use ESMF , only : ESMF_Clock, ESMF_Time, ESMF_TimeInterval @@ -2215,6 +2607,466 @@ subroutine med_methods_Clock_TimePrint(clock,string,rc) end subroutine med_methods_Clock_TimePrint + !----------------------------------------------------------------------------- + + subroutine med_methods_Mesh_Write(mesh, string, rc) + + use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_Array, ESMF_ArrayWrite, ESMF_DistGrid + + type(ESMF_Mesh) ,intent(in) :: mesh + character(len=*),intent(in) :: string + integer ,intent(out) :: rc + + ! local + integer :: n,l,i,lsize,ndims + character(len=CS) :: name + type(ESMF_DISTGRID) :: distgrid + type(ESMF_Array) :: array + real(R8), pointer :: rawdata(:) + real(R8), pointer :: coord(:) + character(len=*),parameter :: subname='(med_methods_Mesh_Write)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + +#if (1 == 0) + !--- elements --- + + call ESMF_MeshGet(mesh, spatialDim=ndims, numownedElements=lsize, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(rawdata(ndims*lsize)) + allocate(coord(lsize)) + + call ESMF_MeshGet(mesh, elementDistgrid=distgrid, ownedElemCoords=rawdata, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1,ndims + name = "unknown" + if (n == 1) name = "lon_element" + if (n == 2) name = "lat_element" + do l = 1,lsize + i = 2*(l-1) + n + coord(l) = rawdata(i) + array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + enddo + enddo + + deallocate(rawdata,coord) + + !--- nodes --- + + call ESMF_MeshGet(mesh, spatialDim=ndims, numownedNodes=lsize, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(rawdata(ndims*lsize)) + allocate(coord(lsize)) + + call ESMF_MeshGet(mesh, nodalDistgrid=distgrid, ownedNodeCoords=rawdata, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do n = 1,ndims + name = "unknown" + if (n == 1) name = "lon_nodes" + if (n == 2) name = "lat_nodes" + do l = 1,lsize + i = 2*(l-1) + n + coord(l) = rawdata(i) + array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + enddo + enddo + + deallocate(rawdata,coord) +#else + call ESMF_LogWrite(trim(subname)//": turned off right now", ESMF_LOGMSG_INFO) +#endif + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_Mesh_Write + + !----------------------------------------------------------------------------- + + subroutine med_methods_State_GeomWrite(state, string, rc) + use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + type(ESMF_State), intent(in) :: state + character(len=*), intent(in) :: string + integer , intent(out) :: rc + + type(ESMF_Field) :: lfield + integer :: fieldcount + character(len=*),parameter :: subname='(med_methods_State_GeomWrite)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (fieldCount > 0) then + call med_methods_State_getFieldN(state, 1, lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GeomWrite(lfield, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) + endif ! fieldCount > 0 + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_State_GeomWrite + + !----------------------------------------------------------------------------- + + subroutine med_methods_FB_GeomWrite(FB, string, rc) + use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet + + type(ESMF_FieldBundle), intent(in) :: FB + character(len=*), intent(in) :: string + integer , intent(out) :: rc + + type(ESMF_Field) :: lfield + integer :: fieldcount + character(len=*),parameter :: subname='(med_methods_FB_GeomWrite)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (fieldCount > 0) then + call med_methods_FB_getFieldN(FB, 1, lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GeomWrite(lfield, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) + endif ! fieldCount > 0 + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_FB_GeomWrite + + !----------------------------------------------------------------------------- + + subroutine med_methods_Field_GeomWrite(field, string, rc) + + use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh, ESMF_FIeldGet, ESMF_FIELDSTATUS_EMPTY + use ESMF, only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID + + ! input/output variables + type(ESMF_Field), intent(in) :: field + character(len=*), intent(in) :: string + integer , intent(out) :: rc + + ! local variables + type(ESMF_Grid) :: lgrid + type(ESMF_Mesh) :: lmesh + character(len=*),parameter :: subname='(med_methods_Field_GeomWrite)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + rc = ESMF_SUCCESS + + call ESMF_FieldGet(field, status=status, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (status == ESMF_FIELDSTATUS_EMPTY) then + call ESMF_LogWrite(trim(subname)//":"//trim(string)//": ERROR field does not have a geom yet ") + rc = ESMF_FAILURE + return + endif + + call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (geomtype == ESMF_GEOMTYPE_GRID) then + call ESMF_FieldGet(field, grid=lgrid, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Grid_Write(lgrid, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + elseif (geomtype == ESMF_GEOMTYPE_MESH) then + call ESMF_FieldGet(field, mesh=lmesh, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Mesh_Write(lmesh, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_Field_GeomWrite + + !----------------------------------------------------------------------------- + + subroutine med_methods_Grid_Write(grid, string, rc) + + use ESMF , only : ESMF_Grid, ESMF_Array, ESMF_GridGetCoord, ESMF_ArraySet + use ESMF , only : ESMF_ArrayWrite, ESMF_GridGetItem, ESMF_GridGetCoord + use ESMF , only : ESMF_GRIDITEM_AREA, ESMF_GRIDITEM_MASK + use ESMF , only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER + + ! input/output variables + type(ESMF_Grid) ,intent(in) :: grid + character(len=*),intent(in) :: string + integer ,intent(out) :: rc + + ! local + type(ESMF_Array) :: array + character(len=CS) :: name + character(len=*),parameter :: subname='(med_methods_Grid_Write)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + endif + + ! -- centers -- + + call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + name = "lon_center" + call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + name = "lat_center" + call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + ! -- corners -- + + call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CORNER, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + name = "lon_corner" + call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) + if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + name = "lat_corner" + call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) + if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + endif + + ! -- mask -- + + name = "mask" + call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=array, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + ! -- area -- + + name = "area" + call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_AREA, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_AREA, array=array, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArraySet(array, name=name, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_methods_Array_diagnose(array, string=trim(string)//trim(name), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif + + if (dbug_flag > 10) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + + end subroutine med_methods_Grid_Write + + !----------------------------------------------------------------------------- + + logical function med_methods_Distgrid_Match(distGrid1, distGrid2, rc) + use ESMF, only : ESMF_DistGrid, ESMF_DistGridGet + ! Arguments + type(ESMF_DistGrid), intent(in) :: distGrid1 + type(ESMF_DistGrid), intent(in) :: distGrid2 + integer, intent(out), optional :: rc + + ! Local Variables + integer :: dimCount1, dimCount2 + integer :: tileCount1, tileCount2 + integer, allocatable :: minIndexPTile1(:,:), minIndexPTile2(:,:) + integer, allocatable :: maxIndexPTile1(:,:), maxIndexPTile2(:,:) + integer, allocatable :: elementCountPTile1(:), elementCountPTile2(:) + character(len=*), parameter :: subname='(med_methods_Distgrid_Match)' + ! ---------------------------------------------- + + if (dbug_flag > 10) then + call ESMF_LogWrite(subname//": called", ESMF_LOGMSG_INFO) + endif + + if(present(rc)) rc = ESMF_SUCCESS + med_methods_Distgrid_Match = .true. + + call ESMF_DistGridGet(distGrid1, & + dimCount=dimCount1, tileCount=tileCount1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_DistGridGet(distGrid2, & + dimCount=dimCount2, tileCount=tileCount2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if ( dimCount1 /= dimCount2) then + med_methods_Distgrid_Match = .false. + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": Grid dimCount MISMATCH ", & + ESMF_LOGMSG_INFO) + endif + endif + + if ( tileCount1 /= tileCount2) then + med_methods_Distgrid_Match = .false. + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": Grid tileCount MISMATCH ", & + ESMF_LOGMSG_INFO) + endif + endif + + allocate(elementCountPTile1(tileCount1)) + allocate(elementCountPTile2(tileCount2)) + allocate(minIndexPTile1(dimCount1,tileCount1)) + allocate(minIndexPTile2(dimCount2,tileCount2)) + allocate(maxIndexPTile1(dimCount1,tileCount1)) + allocate(maxIndexPTile2(dimCount2,tileCount2)) + + call ESMF_DistGridGet(distGrid1, & + elementCountPTile=elementCountPTile1, & + minIndexPTile=minIndexPTile1, & + maxIndexPTile=maxIndexPTile1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_DistGridGet(distGrid2, & + elementCountPTile=elementCountPTile2, & + minIndexPTile=minIndexPTile2, & + maxIndexPTile=maxIndexPTile2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if ( ANY((elementCountPTile1 - elementCountPTile2) .NE. 0) ) then + med_methods_Distgrid_Match = .false. + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": Grid elementCountPTile MISMATCH ", & + ESMF_LOGMSG_INFO) + endif + endif + + if ( ANY((minIndexPTile1 - minIndexPTile2) .NE. 0) ) then + med_methods_Distgrid_Match = .false. + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": Grid minIndexPTile MISMATCH ", & + ESMF_LOGMSG_INFO) + endif + endif + + if ( ANY((maxIndexPTile1 - maxIndexPTile2) .NE. 0) ) then + med_methods_Distgrid_Match = .false. + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": Grid maxIndexPTile MISMATCH ", & + ESMF_LOGMSG_INFO) + endif + endif + + deallocate(elementCountPTile1) + deallocate(elementCountPTile2) + deallocate(minIndexPTile1) + deallocate(minIndexPTile2) + deallocate(maxIndexPTile1) + deallocate(maxIndexPTile2) + + ! TODO: Optionally Check Coordinates + + if (dbug_flag > 10) then + call ESMF_LogWrite(subname//": done", ESMF_LOGMSG_INFO) + endif + + end function med_methods_Distgrid_Match + !================================================================================ subroutine med_methods_State_GetScalar(state, scalar_id, scalar_value, flds_scalar_name, flds_scalar_num, rc) @@ -2334,6 +3186,163 @@ end subroutine med_methods_State_SetScalar !----------------------------------------------------------------------------- + subroutine med_methods_State_UpdateTimestamp(state, time, rc) + + use NUOPC , only : NUOPC_GetStateMemberLists + use ESMF , only : ESMF_State, ESMF_Time, ESMF_Field, ESMF_SUCCESS + + ! input/output variables + type(ESMF_State) , intent(inout) :: state + type(ESMF_Time) , intent(in) :: time + integer , intent(out) :: rc + + ! local variables + integer :: i + type(ESMF_Field),pointer :: fieldList(:) + character(len=*), parameter :: subname='(med_methods_State_UpdateTimestamp)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do i=1, size(fieldList) + call med_methods_Field_UpdateTimestamp(fieldList(i), time, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + enddo + + end subroutine med_methods_State_UpdateTimestamp + + !----------------------------------------------------------------------------- + + subroutine med_methods_Field_UpdateTimestamp(field, time, rc) + + use ESMF, only : ESMF_Field, ESMF_Time, ESMF_TimeGet, ESMF_AttributeSet, ESMF_ATTNEST_ON, ESMF_SUCCESS + + ! input/output variables + type(ESMF_Field) , intent(inout) :: field + type(ESMF_Time) , intent(in) :: time + integer , intent(out) :: rc + + ! local variables + integer :: yy, mm, dd, h, m, s, ms, us, ns + character(len=*), parameter :: subname='(med_methods_Field_UpdateTimestamp)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_TimeGet(time, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, ms=ms, us=us, & + ns=ns, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_AttributeSet(field, & + name="TimeStamp", valueList=(/yy,mm,dd,h,m,s,ms,us,ns/), & + convention="NUOPC", purpose="Instance", & + attnestflag=ESMF_ATTNEST_ON, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_methods_Field_UpdateTimestamp + + !----------------------------------------------------------------------------- + + subroutine med_methods_State_FldDebug(state, flds_scalar_name, prefix, ymd, tod, logunit, rc) + + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field, ESMF_FieldGet + + ! input/output variables + type(ESMF_State) :: state + character(len=*) , intent(in) :: flds_scalar_name + character(len=*) , intent(in) :: prefix + integer , intent(in) :: ymd + integer , intent(in) :: tod + integer , intent(in) :: logunit + integer , intent(out) :: rc + + ! local variables + integer :: n, nfld, ungridded_index + integer :: lsize + real(R8), pointer :: dataPtr1d(:) + real(R8), pointer :: dataPtr2d(:,:) + integer :: fieldCount + integer :: ungriddedUBound(1) + integer :: gridToFieldMap(1) + character(len=ESMF_MAXSTR) :: string + type(ESMF_Field) , allocatable :: lfields(:) + integer , allocatable :: dimCounts(:) + character(len=ESMF_MAXSTR) , allocatable :: fieldNameList(:) + !----------------------------------------------------- + + ! Determine the list of fields and the dimension count for each field + call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + allocate(fieldNameList(fieldCount)) + allocate(lfields(fieldCount)) + allocate(dimCounts(fieldCount)) + + call ESMF_StateGet(state, itemNameList=fieldNameList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + do nfld=1, fieldCount + call ESMF_StateGet(state, itemName=trim(fieldNameList(nfld)), field=lfields(nfld), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfields(nfld), dimCount=dimCounts(nfld), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + + ! Determine local size of field + do nfld=1, fieldCount + if (dimCounts(nfld) == 1) then + call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + lsize = size(dataPtr1d) + exit + end if + end do + + ! Write out debug output + do n = 1,lsize + do nfld=1, fieldCount + if (dimCounts(nfld) == 1) then + call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (trim(fieldNameList(nfld)) /= flds_scalar_name .and. dataPtr1d(n) /= 0.) then + string = trim(prefix) // ' ymd, tod, index, '// trim(fieldNameList(nfld)) //' = ' + write(logunit,100) trim(string), ymd, tod, n, dataPtr1d(n) + end if + else if (dimCounts(nfld) == 2) then + call ESMF_FieldGet(lfields(nfld), ungriddedUBound=ungriddedUBound, gridtoFieldMap=gridToFieldMap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ungridded_index = 1,ungriddedUBound(1) + if (trim(fieldNameList(nfld)) /= flds_scalar_name) then + string = trim(prefix) // ' ymd, tod, lev, index, '// trim(fieldNameList(nfld)) //' = ' + if (gridToFieldMap(1) == 1) then + if (dataPtr2d(n,ungridded_index) /= 0.) then + write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(n,ungridded_index) + end if + else if (gridToFieldMap(1) == 2) then + if (dataPtr2d(ungridded_index,n) /= 0.) then + write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(ungridded_index,n) + end if + end if + end if + end do + end if + end do + end do +100 format(a60,3(i8,2x),d21.14) +101 format(a60,4(i8,2x),d21.14) + + deallocate(fieldNameList) + deallocate(lfields) + deallocate(dimCounts) + + end subroutine med_methods_State_FldDebug + + !----------------------------------------------------------------------------- + subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) ! ---------------------------------------------- @@ -2370,4 +3379,71 @@ end subroutine med_methods_FB_getNumFlds !----------------------------------------------------------------------------- + subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fldnames_shared, rc) + + ! ---------------------------------------------- + ! Get shared Fld names between State1 and State2 and + ! allocate the return array fldnames_shared + ! ---------------------------------------------- + + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_MAXSTR + + ! input/output variables + type(ESMF_State) , intent(in) :: State1 + type(ESMF_State) , intent(in) :: State2 + character(len=*) , intent(in) :: flds_scalar_name + character(len=ESMF_MAXSTR) , pointer :: fldnames_shared(:) + integer , intent(inout) :: rc + + ! local variables + integer :: ncnt1, ncnt2 + integer :: n1, n2, nshr + character(len=ESMF_MAXSTR), allocatable :: fldnames1(:) + character(len=ESMF_MAXSTR), allocatable :: fldnames2(:) + character(len=*), parameter :: subname='(med_methods_States_GetSharedFlds)' + ! ---------------------------------------------- + + rc = ESMF_SUCCESS + + if (associated(fldnames_shared)) then + call ESMF_LogWrite(trim(subname)//": ERROR fldnames_shared must not be associated ", ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + RETURN + end if + + call ESMF_StateGet(State1, itemCount=ncnt1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fldnames1(ncnt1)) + call ESMF_StateGet(State1, itemNameList=fldnames1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_StateGet(State2, itemCount=ncnt2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fldnames2(ncnt2)) + call ESMF_StateGet(State2, itemNameList=fldnames2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + nshr = 0 + do n1 = 1,ncnt1 + do n2 = 1,ncnt2 + if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then + nshr = nshr + 1 + end if + end do + end do + allocate(fldnames_shared(nshr)) + + nshr = 0 + do n1 = 1,ncnt1 + do n2 = 1,ncnt2 + if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then + nshr = nshr + 1 + fldnames_shared(nshr) = trim(fldnames1(n1)) + exit + end if + end do + end do + + end subroutine med_methods_States_GetSharedFlds + end module med_methods_mod From c339bdcb339297455cd1aed1c9cdb68a7351585e Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 29 Oct 2020 16:41:38 -0600 Subject: [PATCH 138/206] made all local arrays initialized to null() --- mediator/esmFlds.F90 | 54 +++++----- mediator/med.F90 | 6 +- mediator/med_diag_mod.F90 | 82 +++++++-------- mediator/med_internalstate_mod.F90 | 6 +- mediator/med_io_mod.F90 | 22 ++-- mediator/med_map_mod.F90 | 20 ++-- mediator/med_merge_mod.F90 | 12 +-- mediator/med_methods_mod.F90 | 152 ++++++++++++++------------- mediator/med_phases_aofluxes_mod.F90 | 80 +++++++------- mediator/med_phases_ocnalb_mod.F90 | 48 ++++----- mediator/med_phases_prep_atm_mod.F90 | 2 +- mediator/med_phases_prep_glc_mod.F90 | 80 +++++++------- mediator/med_phases_prep_ice_mod.F90 | 2 +- mediator/med_phases_prep_ocn_mod.F90 | 55 ++++------ mediator/med_phases_prep_rof_mod.F90 | 22 ++-- 15 files changed, 321 insertions(+), 322 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 9234db892..f0681f52c 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -93,7 +93,7 @@ module esmflds ! merge_type(comptm) = 'copy' (could also have 'copy_with_weighting') type, public :: med_fldList_type - type (med_fldList_entry_type), pointer :: flds(:) + type (med_fldList_entry_type), pointer :: flds(:) => null() end type med_fldList_type interface med_fldList_GetFldInfo ; module procedure & @@ -136,13 +136,13 @@ subroutine med_fldList_AddFld(flds, stdname, shortname) ! ---------------------------------------------- type(med_fldList_entry_type) , pointer :: flds(:) - character(len=*) , intent(in) :: stdname - character(len=*) , intent(in) , optional :: shortname + character(len=*) , intent(in) :: stdname + character(len=*) , intent(in) , optional :: shortname ! local variables integer :: n,oldsize,id logical :: found - type(med_fldList_entry_type), pointer :: newflds(:) + type(med_fldList_entry_type), pointer :: newflds(:) => null() character(len=*), parameter :: subname='(med_fldList_AddFld)' ! ---------------------------------------------- @@ -217,23 +217,23 @@ subroutine med_fldList_AddMrg(flds, fldname, & ! 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 + 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 ! local variables integer :: n, id @@ -389,10 +389,10 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num character(ESMF_MAXSTR) :: transferActionAttr #endif character(ESMF_MAXSTR) :: transferAction - character(ESMF_MAXSTR), pointer :: StandardNameList(:) - character(ESMF_MAXSTR), pointer :: ConnectedList(:) - character(ESMF_MAXSTR), pointer :: NameSpaceList(:) - character(ESMF_MAXSTR), pointer :: itemNameList(:) + character(ESMF_MAXSTR), pointer :: StandardNameList(:) => null() + character(ESMF_MAXSTR), pointer :: ConnectedList(:) => null() + character(ESMF_MAXSTR), pointer :: NameSpaceList(:) => null() + character(ESMF_MAXSTR), pointer :: itemNameList(:) => null() character(len=*),parameter :: subname='(med_fldList_Realize)' ! ---------------------------------------------- @@ -685,8 +685,8 @@ subroutine med_fldList_GetFldNames(flds, fldnames, rc) ! input/output variables type(med_fldList_entry_type) , pointer :: flds(:) - character(len=*) , pointer :: fldnames(:) - integer, optional , intent(out) :: rc + character(len=*) , pointer :: fldnames(:) + integer, optional , intent(out) :: rc !local variables integer :: n diff --git a/mediator/med.F90 b/mediator/med.F90 index 6a134ee48..d65d935f1 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1418,7 +1418,7 @@ subroutine completeFieldInitialization(State,rc) type(ESMF_Grid) :: grid type(ESMF_Mesh) :: mesh type(ESMF_Field) :: meshField - type(ESMF_Field),pointer :: fieldList(:) + type(ESMF_Field),pointer :: fieldList(:) => null() type(ESMF_FieldStatus_Flag) :: fieldStatus type(ESMF_GeomType_Flag) :: geomtype integer :: gridToFieldMapCount, ungriddedCount @@ -1595,7 +1595,7 @@ subroutine DataInitialize(gcomp, rc) integer :: fieldCount character(ESMF_MAXSTR),allocatable :: fieldNameList(:) character(CL) :: value - character(CL), pointer :: fldnames(:) + character(CL), pointer :: fldnames(:) => null() character(CL) :: cvalue character(CL) :: start_type logical :: read_restart @@ -2325,7 +2325,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) integer :: numOwnedElements integer :: spatialDim real(r8), allocatable :: ownedElemCoords(:) - real(r8), pointer :: dataptr(:) + real(r8), pointer :: dataptr(:) => null() integer :: n, dimcount, fieldcount character(len=*),parameter :: subname=' (module_MED:med_meshinfo_create) ' !------------------------------------------------------------------------------- diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 90c931dc5..cae818903 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -57,9 +57,9 @@ module med_diag_mod character(CS) :: name end type budget_diag_type type, public :: budget_diag_indices - type(budget_diag_type), pointer :: comps(:) - type(budget_diag_type), pointer :: fields(:) - type(budget_diag_type), pointer :: periods(:) + type(budget_diag_type), pointer :: comps(:) => null() + type(budget_diag_type), pointer :: fields(:) => null() + type(budget_diag_type), pointer :: periods(:) => null() end type budget_diag_indices type(budget_diag_indices) :: budget_diags @@ -579,12 +579,12 @@ subroutine med_phases_diag_atm(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: n,nf,ic,ip - real(r8), pointer :: afrac(:) - real(r8), pointer :: lfrac(:) - real(r8), pointer :: ifrac(:) - real(r8), pointer :: ofrac(:) - real(r8), pointer :: areas(:) - real(r8), pointer :: lats(:) + real(r8), pointer :: afrac(:) => null() + real(r8), pointer :: lfrac(:) => null() + real(r8), pointer :: ifrac(:) => null() + real(r8), pointer :: ofrac(:) => null() + real(r8), pointer :: areas(:) => null() + real(r8), pointer :: lats(:) => null() character(*), parameter :: subName = '(med_phases_diag_atm) ' !------------------------------------------------------------------------------- @@ -709,7 +709,7 @@ subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, bu integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -747,7 +747,7 @@ subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -803,9 +803,9 @@ subroutine med_phases_diag_lnd( gcomp, rc) ! local variables type(InternalState) :: is_local - real(r8), pointer :: lfrac(:) + real(r8), pointer :: lfrac(:) => null() integer :: n,ip, ic - real(r8), pointer :: areas(:) + real(r8), pointer :: areas(:) => null() character(*), parameter :: subName = '(med_phases_diag_lnd) ' ! ------------------------------------------------------------------ @@ -904,7 +904,7 @@ subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -937,7 +937,7 @@ subroutine diag_lnd_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, lfrac, integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -978,7 +978,7 @@ subroutine med_phases_diag_rof( gcomp, rc) ! local variables type(InternalState) :: is_local integer :: ic, ip, n - real(r8), pointer :: areas(:) + real(r8), pointer :: areas(:) => null() character(*), parameter :: subName = '(med_phases_diag_rof) ' ! ------------------------------------------------------------------ @@ -1048,7 +1048,7 @@ subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -1081,7 +1081,7 @@ subroutine diag_rof_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, budget, ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -1122,7 +1122,7 @@ subroutine med_phases_diag_glc( gcomp, rc) ! local variables type(InternalState) :: is_local integer :: ic, ip - real(r8), pointer :: areas(:) + real(r8), pointer :: areas(:) => null() character(*), parameter :: subName = '(med_phases_diag_glc) ' ! ------------------------------------------------------------------ @@ -1163,7 +1163,7 @@ subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -1200,11 +1200,11 @@ subroutine med_phases_diag_ocn( gcomp, rc) type(InternalState) :: is_local integer :: n,ic,ip real(r8) :: wgt_i,wgt_o - real(r8), pointer :: ifrac(:) ! ice fraction in ocean grid cell - real(r8), pointer :: ofrac(:) ! non-ice fraction nin ocean grid cell - real(r8), pointer :: sfrac(:) ! sum of ifrac and ofrac - real(r8), pointer :: areas(:) - real(r8), pointer :: data(:) + real(r8), pointer :: ifrac(:) => null() ! ice fraction in ocean grid cell + real(r8), pointer :: ofrac(:) => null() ! non-ice fraction nin ocean grid cell + real(r8), pointer :: sfrac(:) => null() ! sum of ifrac and ofrac + real(r8), pointer :: areas(:) => null() + real(r8), pointer :: data(:) => null() character(*), parameter :: subName = '(med_phases_diag_ocn) ' ! ------------------------------------------------------------------ @@ -1309,7 +1309,7 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -1337,7 +1337,7 @@ subroutine diag_ocn_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, frac, b ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -1372,10 +1372,10 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) ! local variables type(InternalState) :: is_local integer :: n,ic,ip - real(r8), pointer :: ofrac(:) - real(r8), pointer :: ifrac(:) - real(r8), pointer :: areas(:) - real(r8), pointer :: lats(:) + real(r8), pointer :: ofrac(:) => null() + real(r8), pointer :: ifrac(:) => null() + real(r8), pointer :: areas(:) => null() + real(r8), pointer :: lats(:) => null() character(*), parameter :: subName = '(med_phases_diag_ice_ice2med) ' ! ------------------------------------------------------------------ @@ -1445,7 +1445,7 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -1491,7 +1491,7 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -1539,11 +1539,11 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) type(InternalState) :: is_local integer :: n,ic,ip real(r8) :: wgt_i, wgt_o - real(r8), pointer :: ofrac(:) - real(r8), pointer :: ifrac(:) - real(r8), pointer :: data(:) - real(r8), pointer :: areas(:) - real(r8), pointer :: lats(:) + real(r8), pointer :: ofrac(:) => null() + real(r8), pointer :: ifrac(:) => null() + real(r8), pointer :: data(:) => null() + real(r8), pointer :: areas(:) => null() + real(r8), pointer :: lats(:) => null() character(*), parameter :: subName = '(med_phases_diag_ice_med2ice) ' ! ------------------------------------------------------------------ @@ -1625,7 +1625,7 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r integer , intent(out) :: rc ! local variables integer :: n, ip - real(r8), pointer :: data(:) + real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then @@ -1671,7 +1671,7 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! local variables integer :: n, ip - real(r8), pointer :: data(:,:) + real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -2367,7 +2367,7 @@ subroutine add_to_budget_diag(entries, index, name) integer :: n integer :: oldsize logical :: found - type(budget_diag_type), pointer :: new_entries(:) + type(budget_diag_type), pointer :: new_entries(:) => null() character(len=*), parameter :: subname='(add_to_budget_diag)' !---------------------------------------------------------------------- diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index c4972f619..149d10374 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -43,9 +43,9 @@ module med_internalstate_mod ! med atm lnd ocn ice rof wav glc type, public :: mesh_info_type - real(r8), pointer :: areas(:) - real(r8), pointer :: lats(:) - real(r8), pointer :: lons(:) + real(r8), pointer :: areas(:) => null() + real(r8), pointer :: lats(:) => null() + real(r8), pointer :: lons(:) => null() end type mesh_info_type type, public :: packed_data_type diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index 9d12db4bf..1295eec53 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -81,7 +81,7 @@ module med_io_mod type(file_desc_t) :: io_file(0:file_desc_t_cnt) integer :: pio_iotype integer :: pio_ioformat - type(iosystem_desc_t), pointer :: io_subsystem + type(iosystem_desc_t), pointer :: io_subsystem => null() character(*),parameter :: u_FILE_u = & __FILE__ @@ -433,7 +433,7 @@ 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(:) + integer ,pointer :: dimid(:) => null() type(var_desc_t) :: varid type(io_desc_t) :: iodesc integer(kind=Pio_Offset_Kind) :: frame @@ -446,13 +446,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(:,:) - integer, pointer :: maxIndexPTile(:,:) + integer, pointer :: minIndexPTile(:,:) => null() + integer, pointer :: maxIndexPTile(:,:) => null() integer :: dimCount, tileCount - integer, pointer :: Dof(:) + integer, pointer :: Dof(:) => null() integer :: lfile_ind - real(r8), pointer :: fldptr1(:) - real(r8), pointer :: fldptr2(:,:) + real(r8), pointer :: fldptr1(:) => null() + real(r8), pointer :: fldptr2(:,:) => null() real(r8), allocatable :: ownedElemCoords(:), ownedElemCoords_x(:), ownedElemCoords_y(:) character(len=number_strlen) :: cnumber character(CL) :: tmpstr @@ -1407,14 +1407,14 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) integer :: rcode integer :: ns,ng integer :: n,ndims - integer, pointer :: dimid(:) + integer, pointer :: dimid(:) => null() type(var_desc_t) :: varid integer :: lnx,lny integer :: tmp(1) - integer, pointer :: minIndexPTile(:,:) - integer, pointer :: maxIndexPTile(:,:) + integer, pointer :: minIndexPTile(:,:) => null() + integer, pointer :: maxIndexPTile(:,:) => null() integer :: dimCount, tileCount - integer, pointer :: Dof(:) + integer, pointer :: Dof(:) => null() character(CL) :: tmpstr integer :: fieldcount type(ESMF_Field), pointer :: fieldlist(:) => null() diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 05880aefd..c8a90f7b2 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -119,8 +119,8 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) integer :: mapindex logical :: rhprint_flag = .false. logical :: mapexists = .false. - real(R8) , pointer :: factorList(:) - character(CL) , pointer :: fldnames(:) + real(R8) , pointer :: factorList(:) => null() + character(CL) , pointer :: fldnames(:) => null() !integer(ESMF_KIND_I4), pointer :: unmappedDstList(:) character(len=128) :: logMsg type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG @@ -1343,14 +1343,14 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) type(ESMF_Mesh) :: lmesh_dst type(ESMF_Field) :: field3d_src type(ESMF_Field) :: field3d_dst - real(r8), pointer :: data_u_src(:) - real(r8), pointer :: data_u_dst(:) - real(r8), pointer :: data_v_src(:) - real(r8), pointer :: data_v_dst(:) - real(r8), pointer :: data2d_src(:,:) - real(r8), pointer :: data2d_dst(:,:) - real(r8), pointer :: ownedElemCoords_src(:) - real(r8), pointer :: ownedElemCoords_dst(:) + real(r8), pointer :: data_u_src(:) => null() + real(r8), pointer :: data_u_dst(:) => null() + real(r8), pointer :: data_v_src(:) => null() + real(r8), pointer :: data_v_dst(:) => null() + real(r8), pointer :: data2d_src(:,:) => null() + real(r8), pointer :: data2d_dst(:,:) => null() + real(r8), pointer :: ownedElemCoords_src(:) => null() + real(r8), pointer :: ownedElemCoords_dst(:) => null() integer :: numOwnedElements integer :: spatialDim logical :: checkflag = .false. diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index b34c560ad..8b85a4a86 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -226,9 +226,9 @@ subroutine med_merge_auto_field(merge_type, field_out, ungriddedUBound_out, & integer :: n type(ESMF_Field) :: field_wgt type(ESMF_Field) :: field_in - real(R8), pointer :: dp1 (:), dp2(:,:) ! output pointers to 1d and 2d fields - real(R8), pointer :: dpf1(:), dpf2(:,:) ! intput pointers to 1d and 2d fields - real(R8), pointer :: dpw1(:) ! weight pointer + real(R8), pointer :: dp1 (:), dp2(:,:) => null() ! output pointers to 1d and 2d fields + real(R8), pointer :: dpf1(:), 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)' !--------------------------------------- @@ -431,9 +431,9 @@ subroutine med_merge_field_1D(FBout, fnameout, & integer , intent(out) :: rc ! local variables - real(R8), pointer :: dataOut(:) - real(R8), pointer :: dataPtr(:) - real(R8), pointer :: wgt(:) + real(R8), pointer :: dataOut(:) => null() + real(R8), pointer :: dataPtr(:) => null() + real(R8), pointer :: wgt(:) => null() integer :: lb1,ub1,i,j,n logical :: wgtfound, FBinfound integer :: dbrc diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index 9ec6500a7..c30a9b9e2 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -210,8 +210,8 @@ subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, r integer :: ungriddedLBound(1) integer :: ungriddedUBound(1) integer :: gridToFieldMap(1) - real(R8), pointer :: dataptr1d(:) - real(R8), pointer :: dataptr2d(:,:) + real(R8), pointer :: dataptr1d(:) => null() + real(R8), pointer :: dataptr2d(:,:) => null() character(ESMF_MAXSTR), allocatable :: lfieldNameList(:) character(len=*), parameter :: subname='(med_methods_FB_init_pointer)' ! ---------------------------------------------- @@ -635,7 +635,7 @@ subroutine med_methods_FB_getNameN(FB, fieldnum, fieldname, rc) ! local variables integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() character(len=*),parameter :: subname='(med_methods_FB_getNameN)' ! ---------------------------------------------- @@ -758,7 +758,7 @@ subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) ! local variables integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() character(len=*),parameter :: subname='(med_methods_State_getNameN)' ! ---------------------------------------------- @@ -810,8 +810,8 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) ! local variables integer :: n,itemCount - type(ESMF_Field), pointer :: fieldList(:) - type(ESMF_StateItem_Flag), pointer :: itemTypeList(:) + type(ESMF_Field), pointer :: fieldList(:) => null() + type(ESMF_StateItem_Flag), pointer :: itemTypeList(:) => null() logical, parameter :: use_NUOPC_method = .true. character(len=*),parameter :: subname='(med_methods_State_getNumFields)' ! ---------------------------------------------- @@ -940,7 +940,7 @@ subroutine med_methods_FB_clean(FB, rc) ! local variables integer :: i,j,n integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() type(ESMF_Field) :: field character(len=*),parameter :: subname='(med_methods_FB_clean)' ! ---------------------------------------------- @@ -979,15 +979,15 @@ subroutine med_methods_FB_reset(FB, value, rc) use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet ! intput/output variables - type(ESMF_FieldBundle), intent(inout) :: FB - real(R8) , intent(in), optional :: value - integer , intent(out) :: rc + type(ESMF_FieldBundle) , intent(inout) :: FB + real(R8) , intent(in), optional :: value + integer , intent(out) :: rc ! local variables integer :: i,j,n integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() + real(R8) :: lvalue character(len=*),parameter :: subname='(med_methods_FB_reset)' ! ---------------------------------------------- @@ -1040,7 +1040,7 @@ subroutine med_methods_State_reset(State, value, rc) integer :: i,j,n integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8) :: lvalue + real(R8) :: lvalue character(len=*),parameter :: subname='(med_methods_State_reset)' ! ---------------------------------------------- @@ -1091,9 +1091,9 @@ subroutine med_methods_FB_average(FB, count, rc) ! local variables integer :: i,j,n integer :: fieldCount, lrank - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) - real(R8), pointer :: dataPtr1(:) - real(R8), pointer :: dataPtr2(:,:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() + real(R8), pointer :: dataPtr1(:) => null() + real(R8), pointer :: dataPtr2(:,:) => null() character(len=*),parameter :: subname='(med_methods_FB_average)' ! ---------------------------------------------- @@ -1166,10 +1166,10 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! local variables integer :: i,j,n integer :: fieldCount, lrank - character(ESMF_MAXSTR), pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR), pointer :: lfieldnamelist(:) => null() character(len=CL) :: lstring - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) + real(R8), pointer :: dataPtr1d(:) => null() + real(R8), pointer :: dataPtr2d(:,:) => null() character(len=*), parameter :: subname='(med_methods_FB_diagnose)' ! ---------------------------------------------- @@ -1248,7 +1248,7 @@ subroutine med_methods_Array_diagnose(array, string, rc) ! local variables character(len=CS) :: lstring - real(R8), pointer :: dataPtr3d(:,:,:) + real(R8), pointer :: dataPtr3d(:,:,:) => null() character(len=*),parameter :: subname='(med_methods_Array_diagnose)' ! ---------------------------------------------- @@ -1297,10 +1297,10 @@ subroutine med_methods_State_diagnose(State, string, rc) ! local variables integer :: i,j,n integer :: fieldCount, lrank - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() character(len=CS) :: lstring - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) + real(R8), pointer :: dataPtr1d(:) => null() + real(R8), pointer :: dataPtr2d(:,:) => null() character(len=*),parameter :: subname='(med_methods_State_diagnose)' ! ---------------------------------------------- @@ -1384,8 +1384,8 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) ! local variables integer :: lrank character(len=CS) :: lstring - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) + real(R8), pointer :: dataPtr1d(:) => null() + real(R8), pointer :: dataPtr2d(:,:) => null() character(len=*),parameter :: subname='(med_methods_FB_FieldDiagnose)' ! ---------------------------------------------- @@ -1450,8 +1450,8 @@ subroutine med_methods_Field_diagnose(field, fieldname, string, rc) ! local variables integer :: lrank character(len=CS) :: lstring - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) + real(R8), pointer :: dataPtr1d(:) => null() + real(R8), pointer :: dataPtr2d(:,:) => null() character(len=*),parameter :: subname='(med_methods_FB_FieldDiagnose)' ! ---------------------------------------------- @@ -1552,8 +1552,10 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) logical :: exists logical :: lcopy - real(R8), pointer :: dataPtri1(:) , dataPtro1(:) - real(R8), pointer :: dataPtri2(:,:), dataPtro2(:,:) + real(R8), pointer :: dataPtri1(:) => null() + real(R8), pointer :: dataPtro1(:) => null() + real(R8), pointer :: dataPtri2(:,:) => null() + real(R8), pointer :: dataPtro2(:,:) => null() character(len=*), parameter :: subname='(med_methods_FB_accumFB2FB)' ! ---------------------------------------------- @@ -1890,16 +1892,17 @@ subroutine med_methods_FB_SetFldPtr(FB, fldname, val, rc) use ESMF, only : ESMF_FieldBundle, ESMF_Field - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*) , intent(in) :: fldname - real(R8) , intent(in) :: val - integer , intent(out) :: rc + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + real(R8) , intent(in) :: val + integer , intent(out) :: rc ! local variables type(ESMF_Field) :: lfield integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() character(len=*), parameter :: subname='(med_methods_FB_SetFldPtr)' ! ---------------------------------------------- @@ -1939,12 +1942,12 @@ subroutine med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, rank, rc) use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - type(ESMF_State), intent(in) :: ST - character(len=*), intent(in) :: fldname - real(R8), pointer, intent(inout), optional :: fldptr1(:) - real(R8), pointer, intent(inout), optional :: fldptr2(:,:) - integer , intent(out), optional :: rank - integer , intent(out), optional :: rc + type(ESMF_State) , intent(in) :: ST + character(len=*) , intent(in) :: fldname + real(R8) , pointer, intent(inout), optional :: fldptr1(:) + real(R8) , pointer, intent(inout), optional :: fldptr2(:,:) + integer , intent(out), optional :: rank + integer , intent(out), optional :: rc ! local variables type(ESMF_Field) :: lfield @@ -1996,8 +1999,8 @@ subroutine med_methods_State_SetFldPtr(ST, fldname, val, rc) ! local variables type(ESMF_Field) :: lfield integer :: lrank - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() character(len=*), parameter :: subname='(med_methods_State_SetFldPtr)' ! ---------------------------------------------- @@ -2032,10 +2035,11 @@ end subroutine med_methods_State_SetFldPtr logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) - real(R8), pointer, intent(in) :: fldptr1(:) - real(R8), pointer, intent(in) :: fldptr2(:) - character(len=*) , intent(in) :: cstring - integer , intent(out) :: rc + ! input/output variables + real(R8) , pointer, intent(in) :: fldptr1(:) + real(R8) , pointer, intent(in) :: fldptr2(:) + character(len=*) , intent(in) :: cstring + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(med_methods_FieldPtr_Compare1)' @@ -2069,10 +2073,11 @@ end function med_methods_FieldPtr_Compare1 logical function med_methods_FieldPtr_Compare2(fldptr1, fldptr2, cstring, rc) - real(R8), pointer, intent(in) :: fldptr1(:,:) - real(R8), pointer, intent(in) :: fldptr2(:,:) - character(len=*) , intent(in) :: cstring - integer , intent(out) :: rc + ! input/output variables + real(R8) , pointer, intent(in) :: fldptr1(:,:) + real(R8) , pointer, intent(in) :: fldptr2(:,:) + character(len=*) , intent(in) :: cstring + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(med_methods_FieldPtr_Compare2)' @@ -2195,8 +2200,8 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) type(ESMF_Grid) :: lgrid type(ESMF_Mesh) :: lmesh integer :: lrank - real(R8), pointer :: dataPtr1(:) - real(R8), pointer :: dataPtr2(:,:) + real(R8), pointer :: dataPtr1(:) => null() + real(R8), pointer :: dataPtr2(:,:) => null() character(len=*),parameter :: subname='(med_methods_Field_GeomPrint)' ! ---------------------------------------------- @@ -2424,22 +2429,24 @@ subroutine med_methods_Grid_Print(grid, string, rc) use ESMF, only : ESMF_GridGet, ESMF_DistGridGet, ESMF_GridGetCoord use ESMF, only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER + ! input/output variables type(ESMF_Grid) , intent(in) :: grid character(len=*), intent(in) :: string integer , intent(out) :: rc - type(ESMF_Distgrid) :: distgrid - integer :: localDeCount - integer :: DeCount - integer :: dimCount, tileCount - integer :: staggerlocCount, arbdimCount, rank - type(ESMF_StaggerLoc) :: staggerloc - character(len=32) :: staggerstr - integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) - real(R8), pointer :: fldptr1(:) - real(R8), pointer :: fldptr2(:,:) - integer :: n1,n2,n3 - character(len=*),parameter :: subname='(med_methods_Grid_Print)' + ! local variables + type(ESMF_Distgrid) :: distgrid + integer :: localDeCount + integer :: DeCount + integer :: dimCount, tileCount + integer :: staggerlocCount, arbdimCount, rank + type(ESMF_StaggerLoc) :: staggerloc + character(len=32) :: staggerstr + integer, allocatable :: minIndexPTile(:,:), maxIndexPTile(:,:) + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() + integer :: n1,n2,n3 + character(len=*),parameter :: subname='(med_methods_Grid_Print)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -2613,6 +2620,7 @@ subroutine med_methods_Mesh_Write(mesh, string, rc) use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_Array, ESMF_ArrayWrite, ESMF_DistGrid + ! input/output variables type(ESMF_Mesh) ,intent(in) :: mesh character(len=*),intent(in) :: string integer ,intent(out) :: rc @@ -2622,8 +2630,8 @@ subroutine med_methods_Mesh_Write(mesh, string, rc) character(len=CS) :: name type(ESMF_DISTGRID) :: distgrid type(ESMF_Array) :: array - real(R8), pointer :: rawdata(:) - real(R8), pointer :: coord(:) + real(R8), pointer :: rawdata(:) => null() + real(R8), pointer :: coord(:) => null() character(len=*),parameter :: subname='(med_methods_Mesh_Write)' ! ---------------------------------------------- @@ -3092,7 +3100,7 @@ subroutine med_methods_State_GetScalar(state, scalar_id, scalar_value, flds_scal integer :: mytask, ierr, len, icount type(ESMF_VM) :: vm type(ESMF_Field) :: field - real(R8), pointer :: farrayptr(:,:) + real(R8), pointer :: farrayptr(:,:) => null() real(r8) :: tmp(1) character(len=*), parameter :: subname='(med_methods_State_GetScalar)' ! ---------------------------------------------- @@ -3156,7 +3164,7 @@ subroutine med_methods_State_SetScalar(scalar_value, scalar_id, State, flds_scal integer :: mytask type(ESMF_Field) :: field type(ESMF_VM) :: vm - real(R8), pointer :: farrayptr(:,:) + real(R8), pointer :: farrayptr(:,:) => null() character(len=*), parameter :: subname='(med_methods_State_SetScalar)' ! ---------------------------------------------- @@ -3198,7 +3206,7 @@ subroutine med_methods_State_UpdateTimestamp(state, time, rc) ! local variables integer :: i - type(ESMF_Field),pointer :: fieldList(:) + type(ESMF_Field),pointer :: fieldList(:) => null() character(len=*), parameter :: subname='(med_methods_State_UpdateTimestamp)' ! ---------------------------------------------- @@ -3261,8 +3269,8 @@ subroutine med_methods_State_FldDebug(state, flds_scalar_name, prefix, ymd, tod, ! local variables integer :: n, nfld, ungridded_index integer :: lsize - real(R8), pointer :: dataPtr1d(:) - real(R8), pointer :: dataPtr2d(:,:) + real(R8), pointer :: dataPtr1d(:) => null() + real(R8), pointer :: dataPtr2d(:,:) => null() integer :: fieldCount integer :: ungriddedUBound(1) integer :: gridToFieldMap(1) diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 2d90a8fce..8ab54e4fd 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -33,44 +33,44 @@ module med_phases_aofluxes_mod !-------------------------------------------------------------------------- type aoflux_type - integer , pointer :: mask (:) ! ocn domain mask: 0 <=> inactive cell - real(R8) , pointer :: rmask (:) ! ocn domain mask: 0 <=> inactive cell - real(R8) , pointer :: lats (:) ! latitudes (degrees) - real(R8) , pointer :: lons (:) ! longitudes (degrees) - real(R8) , pointer :: uocn (:) ! ocn velocity, zonal - real(R8) , pointer :: vocn (:) ! ocn velocity, meridional - real(R8) , pointer :: tocn (:) ! ocean temperature - real(R8) , pointer :: zbot (:) ! atm level height - real(R8) , pointer :: ubot (:) ! atm velocity, zonal - real(R8) , pointer :: vbot (:) ! atm velocity, meridional - real(R8) , pointer :: thbot (:) ! atm potential T - real(R8) , pointer :: shum (:) ! atm specific humidity - real(R8) , pointer :: shum_16O (:) ! atm H2O tracer - real(R8) , pointer :: shum_HDO (:) ! atm HDO tracer - real(R8) , pointer :: shum_18O (:) ! atm H218O tracer - real(R8) , pointer :: roce_16O (:) ! ocn H2O ratio - real(R8) , pointer :: roce_HDO (:) ! ocn HDO ratio - real(R8) , pointer :: roce_18O (:) ! ocn H218O ratio - real(R8) , pointer :: pbot (:) ! atm bottom pressure - real(R8) , pointer :: dens (:) ! atm bottom density - real(R8) , pointer :: tbot (:) ! atm bottom surface T - real(R8) , pointer :: sen (:) ! heat flux: sensible - real(R8) , pointer :: lat (:) ! heat flux: latent - real(R8) , pointer :: lwup (:) ! lwup over ocean - real(R8) , pointer :: evap (:) ! water flux: evaporation - real(R8) , pointer :: evap_16O (:) ! H2O flux: evaporation - real(R8) , pointer :: evap_HDO (:) ! HDO flux: evaporation - real(R8) , pointer :: evap_18O (:) ! H218O flux: evaporation - real(R8) , pointer :: taux (:) ! wind stress, zonal - real(R8) , pointer :: tauy (:) ! wind stress, meridional - real(R8) , pointer :: tref (:) ! diagnostic: 2m ref T - real(R8) , pointer :: qref (:) ! diagnostic: 2m ref Q - real(R8) , pointer :: u10 (:) ! diagnostic: 10m wind speed - real(R8) , pointer :: duu10n (:) ! diagnostic: 10m wind speed squared - real(R8) , pointer :: lwdn (:) ! long wave, downward - real(R8) , pointer :: ustar (:) ! saved ustar - real(R8) , pointer :: re (:) ! saved re - real(R8) , pointer :: ssq (:) ! saved sq + integer , pointer :: mask (:) => null() ! ocn domain mask: 0 <=> inactive cell + real(R8) , pointer :: rmask (:) => null() ! ocn domain mask: 0 <=> inactive cell + real(R8) , pointer :: lats (:) => null() ! latitudes (degrees) + real(R8) , pointer :: lons (:) => null() ! longitudes (degrees) + real(R8) , pointer :: uocn (:) => null() ! ocn velocity, zonal + real(R8) , pointer :: vocn (:) => null() ! ocn velocity, meridional + real(R8) , pointer :: tocn (:) => null() ! ocean temperature + real(R8) , pointer :: zbot (:) => null() ! atm level height + real(R8) , pointer :: ubot (:) => null() ! atm velocity, zonal + real(R8) , pointer :: vbot (:) => null() ! atm velocity, meridional + real(R8) , pointer :: thbot (:) => null() ! atm potential T + real(R8) , pointer :: shum (:) => null() ! atm specific humidity + real(R8) , pointer :: shum_16O (:) => null() ! atm H2O tracer + real(R8) , pointer :: shum_HDO (:) => null() ! atm HDO tracer + real(R8) , pointer :: shum_18O (:) => null() ! atm H218O tracer + real(R8) , pointer :: roce_16O (:) => null() ! ocn H2O ratio + real(R8) , pointer :: roce_HDO (:) => null() ! ocn HDO ratio + real(R8) , pointer :: roce_18O (:) => null() ! ocn H218O ratio + real(R8) , pointer :: pbot (:) => null() ! atm bottom pressure + real(R8) , pointer :: dens (:) => null() ! atm bottom density + real(R8) , pointer :: tbot (:) => null() ! atm bottom surface T + real(R8) , pointer :: sen (:) => null() ! heat flux: sensible + real(R8) , pointer :: lat (:) => null() ! heat flux: latent + real(R8) , pointer :: lwup (:) => null() ! lwup over ocean + real(R8) , pointer :: evap (:) => null() ! water flux: evaporation + real(R8) , pointer :: evap_16O (:) => null() ! H2O flux: evaporation + real(R8) , pointer :: evap_HDO (:) => null() ! HDO flux: evaporation + real(R8) , pointer :: evap_18O (:) => null() ! H218O flux: evaporation + real(R8) , pointer :: taux (:) => null() ! wind stress, zonal + real(R8) , pointer :: tauy (:) => null() ! wind stress, meridional + real(R8) , pointer :: tref (:) => null() ! diagnostic: 2m ref T + real(R8) , pointer :: qref (:) => null() ! diagnostic: 2m ref Q + real(R8) , pointer :: u10 (:) => null() ! diagnostic: 10m wind speed + real(R8) , pointer :: duu10n (:) => null() ! diagnostic: 10m wind speed squared + real(R8) , pointer :: lwdn (:) => null() ! long wave, downward + real(R8) , pointer :: ustar (:) => null() ! saved ustar + real(R8) , pointer :: re (:) => null() ! saved re + real(R8) , pointer :: ssq (:) => null() ! saved sq logical :: created ! has this data type been created end type aoflux_type @@ -204,8 +204,8 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, integer :: iam integer :: n integer :: lsize - real(R8), pointer :: ofrac(:) - real(R8), pointer :: ifrac(:) + real(R8), pointer :: ofrac(:) => null() + real(R8), pointer :: ifrac(:) => null() character(CL) :: cvalue logical :: flds_wiso ! use case character(len=CX) :: tmpstr diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 386dca2c1..11822da64 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -8,7 +8,7 @@ module med_phases_ocnalb_mod use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar use esmFlds , only : mapconsf, mapnames, compatm, compocn use perf_mod , only : t_startf, t_stopf -#ifdef CESMCOUPLED +#ifdef CESMCOUPLED use shr_orb_mod , only : shr_orb_cosz, shr_orb_decl use shr_orb_mod , only : shr_orb_params, SHR_ORB_UNDEF_INT, SHR_ORB_UNDEF_REAL #endif @@ -35,13 +35,13 @@ module med_phases_ocnalb_mod !-------------------------------------------------------------------------- type ocnalb_type - real(r8) , pointer :: lats (:) ! latitudes (degrees) - real(r8) , pointer :: lons (:) ! longitudes (degrees) - integer , pointer :: mask (:) ! ocn domain mask: 0 <=> inactive cell - real(r8) , pointer :: anidr (:) ! albedo: near infrared, direct - real(r8) , pointer :: avsdr (:) ! albedo: visible , direct - real(r8) , pointer :: anidf (:) ! albedo: near infrared, diffuse - real(r8) , pointer :: avsdf (:) ! albedo: visible , diffuse + real(r8) , pointer :: lats (:) => null() ! latitudes (degrees) + real(r8) , pointer :: lons (:) => null() ! longitudes (degrees) + integer , pointer :: mask (:) => null() ! ocn domain mask: 0 <=> inactive cell + real(r8) , pointer :: anidr (:) => null() ! albedo: near infrared, direct + real(r8) , pointer :: avsdr (:) => null() ! albedo: visible , direct + real(r8) , pointer :: anidf (:) => null() ! albedo: near infrared, diffuse + real(r8) , pointer :: avsdf (:) => null() ! albedo: visible , diffuse logical :: created ! has memory been allocated here end type ocnalb_type @@ -94,7 +94,7 @@ subroutine med_phases_ocnalb_init(gcomp, ocnalb, rc) integer :: spatialDim integer :: numOwnedElements type(InternalState) :: is_local - real(R8), pointer :: ownedElemCoords(:) + real(R8), pointer :: ownedElemCoords(:) => null() character(len=CL) :: tempc1,tempc2 logical :: mastertask integer :: fieldCount @@ -205,7 +205,7 @@ subroutine med_phases_ocnalb_run(gcomp, rc) use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_Time, ESMF_TimeGet use ESMF , only : ESMF_VM, ESMF_VMGet use ESMF , only : ESMF_LogWrite, ESMF_LogFoundError - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO use ESMF , only : ESMF_Field, ESMF_FieldGet use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldBundleIsCreated use ESMF , only : operator(+) @@ -232,10 +232,10 @@ subroutine med_phases_ocnalb_run(gcomp, rc) character(CL) :: runtype ! initial, continue, hybrid, branch logical :: flux_albav ! flux avg option real(R8) :: nextsw_cday ! calendar day of next atm shortwave - real(R8), pointer :: ofrac(:) - real(R8), pointer :: ofrad(:) - real(R8), pointer :: ifrac(:) - real(R8), pointer :: ifrad(:) + real(R8), pointer :: ofrac(:) => null() + real(R8), pointer :: ofrad(:) => null() + real(R8), pointer :: ifrac(:) => null() + real(R8), pointer :: ifrad(:) => null() integer :: lsize ! local size integer :: n,i ! indices real(R8) :: rlat ! gridcell latitude in radians @@ -380,7 +380,7 @@ subroutine med_phases_ocnalb_run(gcomp, rc) ! Solar declination ! Will only do albedo calculation if nextsw_cday is not -1. write(msg,*)trim(subname)//' nextsw_cday = ',nextsw_cday - call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO) if (nextsw_cday >= -0.5_r8) then call shr_orb_decl(nextsw_cday, eccen, mvelpp,lambm0, obliqr, delta, eccf) @@ -449,15 +449,15 @@ subroutine med_phases_ocnalb_orbital_init(gcomp, logunit, mastertask, rc) ! Obtain orbital related values !---------------------------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet use ESMF , only : ESMF_LogWrite, ESMF_LogFoundError, ESMF_LogSetError - use ESMF , only : ESMf_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO, ESMF_RC_NOT_VALID + use ESMF , only : ESMf_SUCCESS, ESMF_FAILURE, ESMF_LOGMSG_INFO, ESMF_RC_NOT_VALID use NUOPC , only : NUOPC_CompAttributeGet ! input/output variables type(ESMF_GridComp) :: gcomp integer , intent(in) :: logunit ! output logunit - logical , intent(in) :: mastertask + logical , intent(in) :: mastertask integer , intent(out) :: rc ! output error ! local variables @@ -468,7 +468,7 @@ subroutine med_phases_ocnalb_orbital_init(gcomp, logunit, mastertask, rc) rc = ESMF_SUCCESS -#ifdef CESMCOUPLED +#ifdef CESMCOUPLED ! Determine orbital attributes from input call NUOPC_CompAttributeGet(gcomp, name="orb_mode", value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -547,7 +547,7 @@ end subroutine med_phases_ocnalb_orbital_init subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, obliqr, lambm0, mvelpp, rc) !---------------------------------------------------------- - ! Update orbital settings + ! Update orbital settings !---------------------------------------------------------- use ESMF, only : ESMF_Clock, ESMF_ClockGet, ESMF_Time, ESMF_TimeGet @@ -555,7 +555,7 @@ subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, ! input/output variables type(ESMF_Clock) , intent(in) :: clock - integer , intent(in) :: logunit + integer , intent(in) :: logunit logical , intent(in) :: mastertask real(R8) , intent(inout) :: eccen ! orbital eccentricity real(R8) , intent(inout) :: obliqr ! Earths obliquity in rad @@ -565,7 +565,7 @@ subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, ! local variables type(ESMF_Time) :: CurrTime ! current time - integer :: year ! model year at current time + integer :: year ! model year at current time integer :: orb_year ! orbital year for current orbital computation character(len=CL) :: msgstr ! temporary logical :: lprint @@ -573,7 +573,7 @@ subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, character(len=*) , parameter :: subname = "(lnd_orbital_update)" !------------------------------------------- -#ifdef CESMCOUPLED +#ifdef CESMCOUPLED rc = ESMF_SUCCESS if (trim(orb_mode) == trim(orb_variable_year)) then @@ -584,7 +584,7 @@ subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, orb_year = orb_iyear + (year - orb_iyear_align) lprint = mastertask else - orb_year = orb_iyear + orb_year = orb_iyear if (first_time) then lprint = mastertask first_time = .false. diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index 807f8959f..bacb7af31 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -42,7 +42,7 @@ subroutine med_phases_prep_atm(gcomp, rc) type(ESMF_Field) :: lfield character(len=64) :: timestr type(InternalState) :: is_local - real(R8), pointer :: dataPtr1(:),dataPtr2(:) + real(R8), pointer :: dataPtr1(:),dataPtr2(:) => null() integer :: i, j, n, n1, ncnt character(len=*),parameter :: subname='(med_phases_prep_atm)' !------------------------------------------------------------------------------- diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 053acd1ee..24dc79e2b 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -20,7 +20,7 @@ module med_phases_prep_glc_mod use esmFlds , only : compglc, complnd, mapbilnr, mapconsd, mapconsf, compname 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_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 @@ -67,8 +67,9 @@ module med_phases_prep_glc_mod type(ESMF_Field) :: field_lnd_icemask_l type(ESMF_Field) :: field_lfrac_g - real(r8) , pointer :: aream_l(:) ! cell areas on land grid, for mapping - real(r8) , pointer :: aream_g(:) ! cell areas on glc grid, for mapping + 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 character(len=*), parameter :: Sg_frac_fieldname = 'Sg_ice_covered' character(len=*), parameter :: Sg_topo_fieldname = 'Sg_topo' @@ -97,23 +98,23 @@ subroutine med_phases_prep_glc_init(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - integer :: i,n,ncnt - type(ESMF_Mesh) :: lmesh_glc - type(ESMF_Mesh) :: lmesh_lnd - type(ESMF_Field) :: lfield - real(r8), pointer :: data2d_in(:,:) - real(r8), pointer :: data2d_out(:,:) - real(r8), pointer :: dataptr1d(:) - character(len=CS) :: glc_renormalize_smb - logical :: glc_coupled_fluxes - type(ESMF_Array) :: larray - type(ESMF_DistGrid) :: ldistgrid - integer :: lsize - logical :: isPresent + type(InternalState) :: is_local + integer :: i,n,ncnt + type(ESMF_Mesh) :: lmesh_glc + type(ESMF_Mesh) :: lmesh_lnd + 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 + integer :: ungriddedUBound_output(1) ! currently the size must equal 1 for rank 2 fieldds character(len=*),parameter :: subname='(med_phases_prep_glc_init)' !--------------------------------------- @@ -209,7 +210,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) 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) + ! 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 @@ -304,7 +305,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! 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), & + FBSrc=is_local%wrap%FBImp(compglc,compglc), & FBDst=is_local%wrap%FBImp(compglc,complnd), & mapindex=mapconsf, & RouteHandle=is_local%wrap%RH, rc=rc) @@ -338,8 +339,8 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) type(InternalState) :: is_local type(ESMF_Field) :: lfield integer :: i,n,ncnt - real(r8), pointer :: data2d_in(:,:) - real(r8), pointer :: data2d_out(:,:) + real(r8), pointer :: data2d_in(:,:) => null() + real(r8), pointer :: data2d_out(:,:) => null() character(len=*),parameter :: subname='(med_phases_prep_glc_accum)' !--------------------------------------- @@ -429,8 +430,8 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) type(ESMF_Alarm) :: alarm type(ESMF_Field) :: lfield integer :: i, n, ncnt ! counters - real(r8), pointer :: data2d(:,:) - real(r8), pointer :: data2d_import(:,:) + real(r8), pointer :: data2d(:,:) => null() + real(r8), pointer :: data2d_import(:,:) => null() character(len=*) , parameter :: subname='(med_phases_prep_glc_avg)' !--------------------------------------- @@ -587,8 +588,8 @@ subroutine map_lnd2glc(gcomp, rc) real(r8), pointer :: dataptr_g(:) => null() ! temporary data pointer for one elevation class real(r8), pointer :: topoglc_g(:) => null() ! ice topographic height on the glc grid extracted from glc import real(r8), pointer :: data_ice_covered_g(:) => null() ! data for ice-covered regions on the GLC grid - real(r8), pointer :: ice_covered_g(:) => null() ! if points on the glc grid is ice-covered (1) or ice-free (0) - integer , pointer :: elevclass_g(:) => null() ! elevation classes glc grid + real(r8), pointer :: ice_covered_g(:) => null() ! if points on the glc grid is ice-covered (1) or ice-free (0) + integer , pointer :: elevclass_g(:) => null() ! elevation classes glc grid real(r8), pointer :: dataexp_g(:) => null() ! pointer into real(r8), pointer :: dataptr2d(:,:) => null() real(r8), pointer :: dataptr1d(:) => null() @@ -850,18 +851,18 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) type(InternalState) :: is_local type(ESMF_VM) :: vm type(ESMF_Field) :: lfield - real(r8) , pointer :: qice_g(:) ! SMB (Flgl_qice) on glc grid without elev classes - real(r8) , pointer :: qice_l_ec(:,:) ! SMB (Flgl_qice) on land grid with elev classes - real(r8) , pointer :: glc_topo_g(:) ! ice topographic height on the glc grid cell - real(r8) , pointer :: glc_frac_g(:) ! total ice fraction in each glc cell - real(r8) , pointer :: glc_frac_g_ec(:,:) ! total ice fraction in each glc cell - real(r8) , pointer :: glc_frac_l_ec(:,:) ! EC fractions (Sg_ice_covered) on land grid - real(r8) , pointer :: Sg_icemask_g(:) ! icemask on glc grid - real(r8) , pointer :: Sg_icemask_l(:) ! icemask on land grid - real(r8) , pointer :: lfrac(:) ! land fraction on land grid - real(r8) , pointer :: dataptr1d(:) ! temporary 1d pointer - real(r8) , pointer :: dataptr2d(:,:) ! temporary 2d pointer - integer :: ec ! loop index over elevation classes + 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 ! local and global sums of accumulation and ablation; used to compute renormalization factors @@ -909,6 +910,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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, & @@ -941,7 +943,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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 + ! 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, & diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index da8cc90a6..a65680681 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -55,7 +55,7 @@ subroutine med_phases_prep_ice(gcomp, rc) character(len=CS) :: fldname integer :: fldnum integer :: mapindex - real(R8), pointer :: dataptr(:) + real(R8), pointer :: dataptr(:) => null() real(R8) :: precip_fact character(len=CS) :: cvalue character(len=64), allocatable :: fldnames(:) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index bbb2d41b3..4352239b9 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -81,11 +81,6 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) ! map all fields in FBImp that have active ocean coupling if (ncnt > 0) then - !DEBUG - call FB_diagnose(is_local%wrap%FBImp(comprof,comprof), string=trim(subname)//' FBImp(comprof,comprof) ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - !DEBUG - do n1 = 1,ncomps if (is_local%wrap%med_coupling_active(n1,compocn)) then call med_map_field_packed( & @@ -98,12 +93,6 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do - - !DEBUG - call FB_diagnose(is_local%wrap%FBImp(comprof,compocn), string=trim(subname)//' FBImp(comprof,compocn) ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - !DEBUG - endif call t_stopf('MED:'//subname) @@ -343,21 +332,21 @@ subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) ! local variables type(InternalState) :: is_local - real(R8), pointer :: ifrac(:), ofrac(:) - real(R8), pointer :: ifracr(:), ofracr(:) - real(R8), pointer :: avsdr(:), avsdf(:) - real(R8), pointer :: anidr(:), anidf(:) - real(R8), pointer :: Faxa_swvdf(:), Faxa_swndf(:) - real(R8), pointer :: Faxa_swvdr(:), Faxa_swndr(:) - real(R8), pointer :: Foxx_swnet(:) - real(R8), pointer :: Foxx_swnet_afracr(:) - real(R8), pointer :: Foxx_swnet_vdr(:), Foxx_swnet_vdf(:) - real(R8), pointer :: Foxx_swnet_idr(:), Foxx_swnet_idf(:) - real(R8), pointer :: Fioi_swpen_vdr(:), Fioi_swpen_vdf(:) - real(R8), pointer :: Fioi_swpen_idr(:), Fioi_swpen_idf(:) - real(R8), pointer :: Fioi_swpen(:) - real(R8), pointer :: dataptr(:) - real(R8), pointer :: dataptr_o(:) + real(R8), pointer :: ifrac(:), ofrac(:) => null() + real(R8), pointer :: ifracr(:), ofracr(:) => null() + real(R8), pointer :: avsdr(:), avsdf(:) => null() + real(R8), pointer :: anidr(:), anidf(:) => null() + real(R8), pointer :: Faxa_swvdf(:), Faxa_swndf(:) => null() + real(R8), pointer :: Faxa_swvdr(:), Faxa_swndr(:) => null() + real(R8), pointer :: Foxx_swnet(:) => null() + real(R8), pointer :: Foxx_swnet_afracr(:) => null() + real(R8), pointer :: Foxx_swnet_vdr(:), Foxx_swnet_vdf(:) => null() + real(R8), pointer :: Foxx_swnet_idr(:), Foxx_swnet_idf(:) => null() + real(R8), pointer :: Fioi_swpen_vdr(:), Fioi_swpen_vdf(:) => null() + real(R8), pointer :: Fioi_swpen_idr(:), Fioi_swpen_idf(:) => null() + real(R8), pointer :: Fioi_swpen(:) => null() + real(R8), pointer :: dataptr(:) => null() + real(R8), pointer :: dataptr_o(:) => null() real(R8) :: frac_sum real(R8) :: ifrac_scaled, ofrac_scaled real(R8) :: ifracr_scaled, ofracr_scaled @@ -611,13 +600,13 @@ subroutine med_phases_prep_ocn_custom_nems(gcomp, rc) ! local variables type(InternalState) :: is_local - real(R8), pointer :: ocnwgt1(:) - real(R8), pointer :: icewgt1(:) - real(R8), pointer :: wgtp01(:) - real(R8), pointer :: wgtm01(:) - real(R8), pointer :: customwgt(:) - real(R8), pointer :: ifrac(:) - real(R8), pointer :: ofrac(:) + real(R8), pointer :: ocnwgt1(:) => null() + real(R8), pointer :: icewgt1(:) => null() + real(R8), pointer :: wgtp01(:) => null() + real(R8), pointer :: wgtm01(:) => null() + real(R8), pointer :: customwgt(:) => null() + real(R8), pointer :: ifrac(:) => null() + real(R8), pointer :: ofrac(:) => null() integer :: lsize real(R8) , parameter :: const_lhvap = 2.501e6_R8 ! latent heat of evaporation ~ J/kg character(len=*), parameter :: subname='(med_phases_prep_ocn_custom_nems)' diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 79cd35bc5..483be2693 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -160,9 +160,9 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) type(InternalState) :: is_local integer :: i,j,n,n1,ncnt logical :: connected - real(r8), pointer :: dataptr(:) - real(r8), pointer :: dataptr1d(:) - real(r8), pointer :: dataptr2d(:,:) + 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), pointer :: fieldlist(:) => null() @@ -355,14 +355,14 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) type(ESMF_Field), pointer :: fieldlist_rof(:) => null() type(ESMF_Mesh) :: lmesh_lnd type(ESMF_Mesh) :: lmesh_rof - real(r8), pointer :: volr_l(:) - real(r8), pointer :: volr_r(:), volr_r_import(:) - real(r8), pointer :: irrig_normalized_l(:) - real(r8), pointer :: irrig_normalized_r(:) - real(r8), pointer :: irrig_volr0_l(:) - real(r8), pointer :: irrig_volr0_r(:) - real(r8), pointer :: irrig_flux_l(:) - real(r8), pointer :: irrig_flux_r(:) + real(r8), pointer :: volr_l(:) => null() + real(r8), pointer :: volr_r(:), volr_r_import(:) => null() + real(r8), pointer :: irrig_normalized_l(:) => null() + real(r8), pointer :: irrig_normalized_r(:) => null() + real(r8), pointer :: irrig_volr0_l(:) => null() + real(r8), pointer :: irrig_volr0_r(:) => null() + real(r8), pointer :: irrig_flux_l(:) => null() + real(r8), pointer :: irrig_flux_r(:) => null() character(len=*), parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_irrig)' !--------------------------------------------------------------- From 3d1e7df9dcd18e2c5b1488ac615ebb8048257d86 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 29 Oct 2020 19:06:31 -0600 Subject: [PATCH 139/206] removed DEBUG statements --- drivers/cime/esm_time_mod.F90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/cime/esm_time_mod.F90 b/drivers/cime/esm_time_mod.F90 index 8990632d5..72b246ccd 100644 --- a/drivers/cime/esm_time_mod.F90 +++ b/drivers/cime/esm_time_mod.F90 @@ -130,8 +130,6 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, mastert call NUOPC_CompAttributeGet(instance_driver, name='drv_restart_pointer', value=restart_file, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(6,*)'DEBUG: restart_file = ',trim(restart_file) - if (trim(restart_file) /= 'none') then call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", isPresent=isPresent, rc=rc) @@ -144,7 +142,6 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, mastert endif restart_pfile = trim(restart_file)//inst_suffix - write(6,*)'DEBUG: restart_pfile = ',restart_pfile if (mastertask) then call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), & @@ -170,8 +167,6 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, mastert call esm_time_read_restart(restart_file, start_ymd, start_tod, curr_ymd, curr_tod, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(6,*)'DEBUG: curr_ymd = ',curr_ymd - write(6,*)'DEBUG: curr_tod = ',curr_tod tmp(1) = start_ymd ; tmp(2) = start_tod tmp(3) = curr_ymd ; tmp(4) = curr_tod endif From f53d4bba39021d3db75810b168464d93753377ad Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 30 Oct 2020 10:49:04 -0600 Subject: [PATCH 140/206] original code failed with rc2 error using gnu compiler --- mediator/med_map_mod.F90 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 91b5fdb9e..1f7dabfc5 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -576,21 +576,27 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) if (mapindex == mapnstod_consd .and. & ESMF_RouteHandleIsCreated(RHs(mapnstod), rc=rc1) .and. & ESMF_RouteHandleIsCreated(RHs(mapconsd), rc=rc2)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return + rc = rc2 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. else if (mapindex == mapnstod_consf .and. & ESMF_RouteHandleIsCreated(RHs(mapnstod), rc=rc1) .and. & ESMF_RouteHandleIsCreated(RHs(mapconsf), rc=rc2)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return + rc = rc2 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. else if (ESMF_RouteHandleIsCreated(RHs(mapindex), rc=rc1)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. end if med_map_RH_is_created_RH1d = mapexists - rc = rc1 - if (chkerr(rc,__LINE__,u_FILE_u)) return - rc = rc2 - if (chkerr(rc,__LINE__,u_FILE_u)) return end function med_map_RH_is_created_RH1d From 3d30938dc9cdaee3d8e098ee075278053192fc7d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 30 Oct 2020 20:32:25 -0600 Subject: [PATCH 141/206] updates for refactor of med_map_mod --- mediator/med_io_mod.F90 | 91 +++-- mediator/med_map_mod.F90 | 526 +++++++++------------------ mediator/med_phases_prep_lnd_mod.F90 | 15 +- nems/lib/ParallelIO | 2 +- nems/lib/genf90 | 2 +- 5 files changed, 221 insertions(+), 415 deletions(-) diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index 1295eec53..770229263 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -1,5 +1,4 @@ module med_io_mod - !------------------------------------------ ! Create mediator history files !------------------------------------------ @@ -13,10 +12,9 @@ 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, med_id + 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 perf_mod , only : t_startf, t_stopf implicit none private @@ -81,7 +79,7 @@ module med_io_mod type(file_desc_t) :: io_file(0:file_desc_t_cnt) integer :: pio_iotype integer :: pio_ioformat - type(iosystem_desc_t), pointer :: io_subsystem => null() + type(iosystem_desc_t), pointer :: io_subsystem character(*),parameter :: u_FILE_u = & __FILE__ @@ -123,7 +121,9 @@ subroutine med_io_init() ! initialize pio !--------------- - use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat + use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat + use med_internalstate_mod , only : med_id + #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 @@ -1201,7 +1201,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 @@ -1217,8 +1217,9 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) integer ,intent(out) :: rc ! local variables + type(ESMF_Field) :: lfield integer :: rcode - integer :: nf + integer :: nf,ns,ng integer :: k,n,l type(file_desc_t) :: pioid type(var_desc_t) :: varid @@ -1226,9 +1227,10 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) character(CL) :: name1 ! var name character(CL) :: lpre ! local prefix real(r8) :: lfillvalue - integer :: lsize + integer :: tmp(1) + integer :: rank, lsize real(r8), pointer :: fldptr1(:) => null() - real(r8), pointer :: fldptr1tmp(:) => null() + real(r8), pointer :: fldptr1_tmp(:) => null() real(r8), pointer :: fldptr2(:,:) => null() character(CL) :: tmpstr character(len=16) :: cnumber @@ -1236,7 +1238,7 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) integer :: ungriddedUBound(1) character(CL) , pointer :: fieldnamelist(:) => null() type(ESMF_Field), pointer :: fieldlist(:) => null() - character(*), parameter :: subName = '(med_io_read_FB) ' + character(*),parameter :: subName = '(med_io_read_FB) ' !------------------------------------------------------------------------------- rc = ESMF_Success @@ -1245,43 +1247,43 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if + lpre = ' ' + if (present(pre)) then + lpre = trim(pre) + endif + if (present(frame)) then + lframe = frame + 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 - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return return endif - lpre = ' ' - if (present(pre)) lpre = trim(pre) - lframe = 1 - if (present(frame)) lframe = frame - call ESMF_FieldBundleGet(FB, fieldCount=nf, rc=rc) 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 + 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 - if (dbug_flag > 1) then - 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 - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - return - end if - endif - + ! 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) @@ -1294,6 +1296,7 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) endif call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) + do k = 1,nf call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1318,7 +1321,7 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr2, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return lsize = size(fldptr2, dim=2) - allocate(fldptr1tmp(lsize)) + 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 @@ -1329,20 +1332,20 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) call ESMF_LogWrite(trim(subname)//' read field '//trim(name1), ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return call pio_setframe(pioid, varid, lframe) - call pio_read_darray(pioid, varid, iodesc, fldptr1tmp, rcode) + call pio_read_darray(pioid, varid, iodesc, fldptr1_tmp, rcode) rcode = pio_get_att(pioid, varid, "_FillValue", lfillvalue) if (rcode /= pio_noerr) then lfillvalue = fillvalue endif - do l = 1,size(fldptr1tmp) - if (fldptr1tmp(l) == lfillvalue) fldptr1tmp(l) = 0.0_r8 + do l = 1,size(fldptr1_tmp) + if (fldptr1_tmp(l) == lfillvalue) fldptr1_tmp(l) = 0.0_r8 enddo else - fldptr1tmp(:) = 0.0_r8 + fldptr1_tmp = 0.0_r8 endif - fldptr2(n,:) = fldptr1tmp(:) + fldptr2(n,:) = fldptr1_tmp(:) end do - deallocate(fldptr1tmp) + deallocate(fldptr1_tmp) else ! No ungridded dimensions call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr1, rc=rc) @@ -1368,13 +1371,9 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) enddo ! end of loop over fields call pio_seterrorhandling(pioid,PIO_INTERNAL_ERROR) - call pio_freedecomp(pioid, iodesc) call pio_closefile(pioid) - deallocate(fieldlist) - deallocate(fieldnamelist) - if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif @@ -1451,7 +1450,6 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) 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 call ESMF_MeshGet(mesh, elementDistgrid=distgrid, rc=rc) @@ -1475,6 +1473,7 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) call ESMF_DistGridGet(distgrid, localDE=0, elementCount=ns, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(dof(ns)) 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) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index c8a90f7b2..929e95028 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -1,26 +1,12 @@ module med_map_mod use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use shr_const_mod , only : shr_const_pi use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_LOGMSG_INFO, ESMF_LogWrite - use esmFlds , only : mapbilnr, mapconsf, mapconsd, mappatch, mapfcopy - use esmFlds , only : mapunset, mapnames, nmappers - use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd - use esmFlds , only : ncomps, compatm, compice, compocn, compname - use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod - use esmFlds , only : mapuv_with_cart3d, fldListFr, coupling_mode + use esmFlds , only : mapuv_with_cart3d use med_internalstate_mod , only : InternalState, logunit, mastertask - use med_constants_mod , only : ispval_mask => med_constants_ispval_mask - use med_constants_mod , only : czero => med_constants_czero - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_utils_mod , only : memcheck => med_memcheck - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN - use med_methods_mod , only : FB_reset => med_methods_FB_Reset - use med_methods_mod , only : FB_Field_diagnose => med_methods_FB_Field_diagnose - use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk - use med_methods_mod , only : Field_diagnose => med_methods_Field_diagnose + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr use perf_mod , only : t_startf, t_stopf implicit none @@ -34,11 +20,11 @@ module med_map_mod public :: med_map_field_packed public :: med_map_field_normalized public :: med_map_field - public :: med_map_fb_field_regrid ! TODO: do we still need this? interface med_map_routehandles_init - module procedure med_map_routehandles_init_esmflds - module procedure med_map_routehandles_init_field + module procedure med_map_routehandles_initfrom_esmflds + module procedure med_map_routehandles_initfrom_fieldbundle + module procedure med_map_routehandles_initfrom_field end interface interface med_map_RH_is_created @@ -48,8 +34,6 @@ module med_map_mod ! private module variables - character(len=CL) :: flds_scalar_name - integer :: srcTermProcessing_Value = 0 ! should this be a module variable? character(*), parameter :: u_FILE_u = & __FILE__ @@ -57,7 +41,7 @@ module med_map_mod contains !================================================================================ - subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) + subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) !--------------------------------------------- ! Initialize route handles in the mediator @@ -87,14 +71,10 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) ! for the field !--------------------------------------------- - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush, ESMF_KIND_I4 - use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Field, ESMF_PoleMethod_Flag, ESMF_POLEMETHOD_ALLAVG - use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_FieldSMMStore - use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRegridStore, ESMF_REGRIDMETHOD_BILINEAR - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_FRACAREA - use ESMF , only : ESMF_REGRIDMETHOD_NEAREST_STOD - use ESMF , only : ESMF_NORMTYPE_DSTAREA, ESMF_REGRIDMETHOD_PATCH, ESMF_RouteHandlePrint - use NUOPC , only : NUOPC_Write + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_Field + use esmFlds , only : fldListFr, ncomps, mapunset, compname + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN ! input/output variables type(ESMF_GridComp) :: gcomp @@ -102,95 +82,39 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - type(ESMF_VM) :: vm - type(ESMF_Field) :: fldsrc - type(ESMF_Field) :: flddst - integer :: localPet - integer :: n,n1,n2,m,nf,nflds,ncomp - integer :: SrcMaskValue - integer :: DstMaskValue - character(len=128) :: value - character(len=128) :: rhname - character(len=128) :: rhname_file - character(len=CS) :: mapname - character(len=CX) :: mapfile - character(len=CS) :: string - integer :: mapindex - logical :: rhprint_flag = .false. - logical :: mapexists = .false. - real(R8) , pointer :: factorList(:) => null() - character(CL) , pointer :: fldnames(:) => null() - !integer(ESMF_KIND_I4), pointer :: unmappedDstList(:) - character(len=128) :: logMsg - type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG + type(InternalState) :: is_local + type(ESMF_Field) :: fldsrc + type(ESMF_Field) :: flddst + integer :: n,n1,n2,m,nf + character(len=CX) :: mapfile + character(len=CS) :: string + integer :: mapindex + logical :: mapexists = .false. character(len=*), parameter :: subname=' (module_med_map: RouteHandles_init) ' !----------------------------------------------------------- + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS if (dbug_flag > 1) then call ESMF_LogWrite("Starting to initialize RHs", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() endif - rc = ESMF_SUCCESS - - ! Determine mastertask - call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) - call ESMF_VMGet(vm, localPet=localPet, rc=rc) - mastertask = .false. - if (localPet == 0) mastertask=.true. ! Get the internal state from Component. nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Create the necessary route handles - if (mastertask) write(llogunit,*) ' ' + ! First loop over source and destination components components + if (mastertask) write(logunit,*) ' ' do n1 = 1, ncomps do n2 = 1, ncomps - - if (trim(coupling_mode) == 'cesm') then - dstMaskValue = ispval_mask - srcMaskValue = ispval_mask - if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 - if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 - else if (coupling_mode(1:4) == 'nems') then - if (n1 == compatm .and. (n2 == compocn .or. n2 == compice)) then - srcMaskValue = 1 - dstMaskValue = 0 - else if (n2 == compatm .and. (n1 == compocn .or. n1 == compice)) then - srcMaskValue = 0 - dstMaskValue = 1 - else if ((n1 == compocn .and. n2 == compice) .or. (n1 == compice .and. n2 == compocn)) then - srcMaskValue = 0 - dstMaskValue = 0 - else - ! TODO: what should the condition be here? - dstMaskValue = ispval_mask - srcMaskValue = ispval_mask - end if - else if (trim(coupling_mode) == 'hafs') then - dstMaskValue = ispval_mask - srcMaskValue = ispval_mask - if (n1 == compocn .or. n1 == compice) srcMaskValue = 0 - if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 - end if - - !--- get single fields from bundles - !--- 1) ASSUMES all fields in the bundle are on identical grids - !--- 2) MULTIPLE route handles are going to be generated for - !--- given field bundle source and destination grids - if (n1 /= n2) then - ! Determine route handle names - rhname = trim(compname(n1))//"2"//trim(compname(n2)) - if (is_local%wrap%med_coupling_active(n1,n2)) then ! If coupling is active between n1 and n2 - + ! Get source and destination fields call FB_GetFieldN(is_local%wrap%FBImp(n1,n1), 1, fldsrc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldN(is_local%wrap%FBImp(n1,n2), 1, flddst, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -199,139 +123,22 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) ! Determine the mapping type for mapping field nf from n1 to n2 mapindex = fldListFr(n1)%flds(nf)%mapindex(n2) + if (mapindex /= mapunset) then - ! separate check first since Fortran does not have short-circuit evaluation - if (mapindex == mapunset) cycle - - ! Create route handle for target mapindex if route handle is required - ! (i.e. mapindex /= mapunset) and route handle has not already been created - mapexists = med_map_RH_is_created(is_local%wrap%RH,n1,n2,mapindex,rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! determine if route handle has already been created + mapexists = med_map_RH_is_created(is_local%wrap%RH,n1,n2,mapindex,rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - if (.not. mapexists) then - mapname = trim(mapnames(mapindex)) - mapfile = trim(fldListFr(n1)%flds(nf)%mapfile(n2)) - string = trim(rhname)//'_weights' - - if (mapindex == mapfcopy) then - if (mastertask) then - write(llogunit,'(3A)') subname,trim(string),' RH redist ' - end if - call ESMF_LogWrite(subname // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) - call ESMF_FieldRedistStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapindex), & - ignoreUnmatchedIndices = .true., rc=rc) + ! Create route handle for target mapindex if route handle is required + ! (i.e. mapindex /= mapunset) and route handle has not already been created + if (.not. mapexists) then + mapfile = trim(fldListFr(n1)%flds(nf)%mapfile(n2)) + call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, & + mapindex, is_local%wrap%rh(n1,n2,mapindex), mapfile=trim(mapfile), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (mapfile /= 'unset') then - if (mastertask) then - write(llogunit,'(4A)') subname,trim(string),' RH '//trim(mapname)//' via input file ',& - trim(mapfile) - end if - call ESMF_LogWrite(subname // trim(string) //& - ' RH '//trim(mapname)//' via input file '//trim(mapfile), ESMF_LOGMSG_INFO) - call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, & - routehandle=is_local%wrap%RH(n1,n2,mapindex), & - ignoreUnmatchedIndices=.true., & - srcTermProcessing=srcTermProcessing_Value, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - ! Create route handle on the fly - if (mastertask) write(llogunit,'(3A)') subname,trim(string),& - ' RH regrid for '//trim(mapname)//' computed on the fly' - call ESMF_LogWrite(subname // trim(string) //& - ' RH regrid for '//trim(mapname)//' computed on the fly', ESMF_LOGMSG_INFO) - if (mapindex == mapbilnr) then - srcTermProcessing_Value = 0 - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapindex), & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & - polemethod=polemethod, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if ((mapindex == mapconsf .or. mapindex == mapnstod_consf) .and. & - .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapconsf,rc)) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapconsf), & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - normType=ESMF_NORMTYPE_FRACAREA, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if ((mapindex == mapconsd .or. mapindex == mapnstod_consd) .and. & - .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapconsd,rc)) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapconsd), & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & - normType=ESMF_NORMTYPE_DSTAREA, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (mapindex == mappatch) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapindex), & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_PATCH, & - polemethod=polemethod, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - ! consd_nstod method requires a second routehandle - if ((mapindex == mapnstod .or. mapindex == mapnstod_consd .or. mapindex == mapnstod_consf) .and. & - .not. med_map_RH_is_created(is_local%wrap%RH(n1,n2,:),mapnstod,rc)) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=is_local%wrap%RH(n1,n2,mapnstod), & - srcMaskValues=(/srcMaskValue/), & - dstMaskValues=(/dstMaskValue/), & - regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, & - srcTermProcessing=srcTermProcessing_Value, & - factorList=factorList, & - ignoreDegenerate=.true., & - unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & - rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - if (rhprint_flag .and. mapindex /= mapnstod_consd .and. mapindex /= mapnstod_consf) then - call NUOPC_Write(factorList, "array_med_"//trim(string)//"_consf.nc", rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - !if (associated(unmappedDstList)) then - ! write(logMsg,*) trim(subname),trim(string),& - ! number of unmapped dest points = ', size(unmappedDstList) - ! call ESMF_LogWrite(trim(logMsg), ESMF_LOGMSG_INFO) - !end if end if - if (rhprint_flag .and. mapindex /= mapnstod_consd .and. mapindex /= mapnstod_consf) then - call ESMF_LogWrite(trim(subname)//trim(string)//": printing RH for "//trim(mapname), & - ESMF_LOGMSG_INFO) - call ESMF_RouteHandlePrint(is_local%wrap%RH(n1,n2,mapindex), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Check that a valid route handle has been created - if (.not.med_map_RH_is_created(is_local%wrap%RH,n1,n2,mapindex,rc=rc)) then - call ESMF_LogWrite(trim(subname)//trim(string)//": failed RH "//trim(mapname), & - ESMF_LOGMSG_INFO) - endif - end if + + end if ! end if mapindex is mapunset end do ! loop over fields end if ! if coupling is active between n1 and n2 end if ! if n1 not equal to n2 @@ -343,26 +150,19 @@ subroutine med_map_RouteHandles_init_esmflds(gcomp, llogunit, rc) endif call t_stopf('MED:'//subname) - end subroutine med_map_RouteHandles_init_esmflds + end subroutine med_map_RouteHandles_initfrom_esmflds !================================================================================ - subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) + subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) + + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush + use ESMF , only : ESMf_Field, ESMF_FieldBundle, ESMF_RouteHandle + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN !--------------------------------------------- - ! Initialize initialize additional route handles - ! for mapping fractions - ! + ! Initialize initialize additional route handles for mapping fractions !--------------------------------------------- - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only : ESMF_GridComp, ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field - use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Field, ESMF_PoleMethod_Flag, ESMF_POLEMETHOD_ALLAVG - use ESMF , only : ESMF_GridCompGet, ESMF_VMGet, ESMF_FieldSMMStore - use ESMF , only : ESMF_FieldRedistStore, ESMF_FieldRegridStore, ESMF_REGRIDMETHOD_BILINEAR - use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA, ESMF_NORMTYPE_FRACAREA - use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_NEAREST_STOD - use ESMF , only : ESMF_REGRIDMETHOD_PATCH - ! input/output variables integer , intent(in) :: n1 integer , intent(in) :: n2 @@ -375,27 +175,79 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route ! local variables type(ESMF_Field) :: fldsrc type(ESMF_Field) :: flddst - character(len=CS) :: string - character(len=CS) :: mapname - integer :: SrcMaskValue - integer :: DstMaskValue - type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG character(len=*), parameter :: subname=' (module_MED_map:med_map_routehandles_init_fields) ' !--------------------------------------------- call t_startf('MED:'//subname) rc = ESMF_SUCCESS + if (dbug_flag > 1) then - call ESMF_LogWrite("Initializing RHs not yet created and needed", & - ESMF_LOGMSG_INFO) + call ESMF_LogWrite("Initializing RHs not yet created and needed", ESMF_LOGMSG_INFO) call ESMF_LogFlush() endif + call FB_getFieldN(FBsrc, 1, fldsrc, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call FB_getFieldN(FBDst, 1, flddst, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle(n1,n2,mapindex), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + call t_stopf('MED:'//subname) + + end subroutine med_map_routehandles_initfrom_fieldbundle + + !================================================================================ + subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle, mapfile, rc) + + use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandlePrint, ESMF_Field, ESMF_MAXSTR + use ESMF , only : ESMF_PoleMethod_Flag, ESMF_POLEMETHOD_ALLAVG + use ESMF , only : ESMF_FieldSMMStore, ESMF_FieldRedistStore, ESMF_FieldRegridStore + use ESMF , only : ESMF_REGRIDMETHOD_BILINEAR, ESMF_REGRIDMETHOD_PATCH + use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA, ESMF_NORMTYPE_FRACAREA + use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_NEAREST_STOD + use esmFlds , only : mapbilnr, mapconsf, mapconsd, mappatch, mapfcopy + use esmFlds , only : mapunset, mapnames, nmappers + use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd + use esmFlds , only : ncomps, compatm, compice, compocn, compname + use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod + use esmFlds , only : coupling_mode + use med_constants_mod , only : ispval_mask => med_constants_ispval_mask + + ! input/output variables + integer , intent(in) :: n1 + integer , intent(in) :: n2 + type(ESMF_Field) , intent(inout) :: fldsrc + type(ESMF_Field) , intent(inout) :: flddst + integer , intent(in) :: mapindex + type(ESMF_RouteHandle) , intent(inout) :: RouteHandle + character(len=*), optional , intent(in) :: mapfile + integer , intent(out) :: rc + + ! local variables + character(len=CS) :: string + character(len=CS) :: mapname + integer :: srcMaskValue + integer :: dstMaskValue + character(len=ESMF_MAXSTR) :: lmapfile + logical :: rhprint = .false. + integer :: srcTermProcessing_Value = 0 + type(ESMF_PoleMethod_Flag), parameter :: polemethod=ESMF_POLEMETHOD_ALLAVG + character(len=*), parameter :: subname=' (module_med_map: med_map_routehandles_initfrom_field) ' + !--------------------------------------------- + + lmapfile = 'unset' + if (present(mapfile)) then + lmapfile = trim(mapfile) + end if + mapname = trim(mapnames(mapindex)) if (mastertask) then - string = trim(compname(n1))//"2"//trim(compname(n2))//'_weights' - write(logunit,'(3A)') subname, trim(string),& - ' RH regrid for '//trim(mapname)//' computed on the fly' + write(6,*)'DEBUG: mapindex, mapname= ',mapindex,trim(mapname) end if if (trim(coupling_mode) == 'cesm') then @@ -425,29 +277,27 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 end if - call FB_getFieldN(FBsrc, 1, fldsrc, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFieldN(FBDst, 1, flddst, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create route handle on the fly - if (mastertask) write(logunit,'(3A)') subname,trim(string),& - ' RH regrid for '//trim(mapname)//' computed on the fly' - call ESMF_LogWrite(subname // trim(string) //& - ' RH regrid for '//trim(mapname)//' computed on the fly', ESMF_LOGMSG_INFO) - + ! Create route handle if (mapindex == mapfcopy) then if (mastertask) then write(logunit,'(3A)') subname,trim(string),' RH redist ' end if call ESMF_LogWrite(subname // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) - call ESMF_FieldRedistStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapindex), & + call ESMF_FieldRedistStore(fldsrc, flddst, routehandle=routehandle, & ignoreUnmatchedIndices = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + else if (lmapfile /= 'unset') then + if (mastertask) then + write(logunit,'(4A)') subname,trim(string),' RH '//trim(mapname)//' via input file ',trim(mapfile) + end if + call ESMF_LogWrite(subname // trim(string) //& + ' RH '//trim(mapname)//' via input file '//trim(mapfile), ESMF_LOGMSG_INFO) + call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, routehandle=routehandle, & + ignoreUnmatchedIndices=.true., & + srcTermProcessing=srcTermProcessing_Value, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapbilnr) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapindex), & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & @@ -457,8 +307,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapconsf .or. mapindex == mapnstod_consf) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapconsf), & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & @@ -469,8 +318,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapconsd .or. mapindex == mapnstod_consd) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapconsd), & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & @@ -481,8 +329,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mappatch) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapindex), & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_PATCH, & @@ -492,8 +339,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else - call ESMF_LogWrite(trim(subname)//' mapindex '//trim(mapnames(mapindex))//& - ' not supported for fraction mapping', & + call ESMF_LogWrite(trim(subname)//' mapindex '//trim(mapname)//' not supported ', & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) rc = ESMF_FAILURE return @@ -502,7 +348,7 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route ! consd_nstod method requires a second routehandle if (mapindex == mapnstod .or. mapindex == mapnstod_consd .or. mapindex == mapnstod_consf) then call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle(n1,n2,mapnstod), & + routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, & @@ -513,17 +359,29 @@ subroutine med_map_routehandles_init_field(n1, n2, FBsrc, FBdst, mapindex, Route if (chkerr(rc,__LINE__,u_FILE_u)) return end if - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + ! Check that a valid route handle has been created + ! TODO: should this be implemented as an error check or ignored? + ! if (.not. med_map_RH_is_created(routehandle ,rc=rc)) then + ! string = trim(compname(n1))//"2"//trim(compname(n2))//'_weights' + ! call ESMF_LogWrite(trim(subname)//trim(string)//": failed RH "//trim(mapnames(mapindex)), & + ! ESMF_LOGMSG_INFO) + ! endif + + ! Output route handle to file if requested + if (rhprint) then + if (mastertask) then + write(logunit,'(a)') trim(subname)//trim(string)//": printing RH for "//trim(mapname) + end if + call ESMF_RouteHandlePrint(routehandle, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return endif - call t_stopf('MED:'//subname) - end subroutine med_map_routehandles_init_field + end subroutine med_map_routehandles_initfrom_field !================================================================================ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) - use ESMF , only : ESMF_RouteHandle + use ESMF, only : ESMF_RouteHandle ! input/output variables type(ESMF_RouteHandle) , intent(in) :: RHs(:,:,:) @@ -534,7 +392,6 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) ! local variables integer :: rc1, rc2 - logical :: mapexists character(len=*), parameter :: subname=' (module_MED_map:med_map_RH_is_created) ' !----------------------------------------------------------- @@ -548,7 +405,9 @@ end function med_map_RH_is_created_RH3d logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) - use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated + use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated + use esmFlds , only : mapconsd, mapconsf, mapnstod + use esmFlds , only : mapnstod_consd, mapnstod_consf ! input/output varaibes type(ESMF_RouteHandle) , intent(in) :: RHs(:) @@ -569,22 +428,26 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) if (mapindex == mapnstod_consd .and. & ESMF_RouteHandleIsCreated(RHs(mapnstod), rc=rc1) .and. & ESMF_RouteHandleIsCreated(RHs(mapconsd), rc=rc2)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return + rc = rc2 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. else if (mapindex == mapnstod_consf .and. & ESMF_RouteHandleIsCreated(RHs(mapnstod), rc=rc1) .and. & ESMF_RouteHandleIsCreated(RHs(mapconsf), rc=rc2)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return + rc = rc2 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. else if (ESMF_RouteHandleIsCreated(RHs(mapindex), rc=rc1)) then + rc = rc1 + if (chkerr(rc,__LINE__,u_FILE_u)) return mapexists = .true. end if - med_map_RH_is_created_RH1d = mapexists - rc = rc1 - if (chkerr(rc,__LINE__,u_FILE_u)) return - rc = rc2 - if (chkerr(rc,__LINE__,u_FILE_u)) return - end function med_map_RH_is_created_RH1d !================================================================================ @@ -594,12 +457,14 @@ subroutine med_map_mapnorm_init(gcomp, rc) ! Initialize unity normalization fields and do the mapping for unity normalization up front !--------------------------------------- - use ESMF , only: ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only: ESMF_GridComp - use ESMF , only: ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT - use ESMF , only: ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleCreate - use ESMF , only: ESMF_FieldBundleIsCreated - use ESMF , only: ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate, ESMF_FieldDestroy + use ESMF , only: ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush + use ESMF , only: ESMF_GridComp + use ESMF , only: ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT + use ESMF , only: ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleCreate + use ESMF , only: ESMF_FieldBundleIsCreated + use ESMF , only: ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate, ESMF_FieldDestroy + use esmFlds , only: ncomps, nmappers, compname, mapnames + use med_constants_mod , only: czero => med_constants_czero ! input/output variables type(ESMF_GridComp) :: gcomp @@ -617,8 +482,8 @@ subroutine med_map_mapnorm_init(gcomp, rc) type(ESMF_Mesh) :: mesh_dst character(len=*),parameter :: subname=' (module_MED_MAP:MapNorm_init)' !----------------------------------------------------------- - call t_startf('MED:'//subname) + call t_startf('MED:'//subname) rc = ESMF_SUCCESS if (dbug_flag > 1) then @@ -1258,71 +1123,14 @@ subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, r end subroutine med_map_field - !================================================================================ - subroutine med_map_fb_field_regrid(FBin,fldin,FBout,fldout,RouteHandles,mapindex,rc) - - ! ---------------------------------------------- - ! Regrid a field in a field bundle to another field in a field bundle - ! ---------------------------------------------- - - use ESMF , only : ESMF_FieldBundle, ESMF_RouteHandle, ESMF_Field, ESMF_FieldBundleGet - use perf_mod , only : t_startf, t_stopf - - type(ESMF_FieldBundle), intent(in) :: FBin - character(len=*) , intent(in) :: fldin - type(ESMF_FieldBundle), intent(inout) :: FBout - character(len=*) , intent(in) :: fldout - type(ESMF_RouteHandle), intent(inout) :: RouteHandles(:) - integer , intent(in) :: mapindex - integer , intent(out) :: rc - ! ---------------------------------------------- - - ! local - type(ESMF_Field) :: field1, field2 - character(CS) :: lfldname - character(len=*),parameter :: subname='(module_MED_map:med_map_fb_field_regrid)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) - endif - - call t_startf('MED:'//trim(subname)) - rc = ESMF_SUCCESS - - lfldname=trim(fldin)//'->'//trim(fldout) - - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - end if - if (FB_FldChk(FBin , trim(fldin) , rc=rc) .and. FB_FldChk(FBout, trim(fldout), rc=rc)) then - - call ESMF_FieldBundleGet(FBin, fieldName=trim(fldin), field=field1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBout, fieldName=trim(fldout), field=field2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field(field_src=field1, field_dst=field2, routehandles=routehandles, maptype=mapindex, & - fldname=trim(lfldname), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//" field not found: "//& - trim(fldin)//","//trim(fldout), ESMF_LOGMSG_INFO) - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - call t_stopf('MED:'//trim(subname)) - - end subroutine med_map_fb_field_regrid - !================================================================================ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) - use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use ESMF, only : ESMF_Field, ESMF_FieldGet - use ESMF, only : ESMF_FieldCreate, ESMF_FieldDestroy, ESMF_FieldRegrid - use ESMF, only : ESMF_RouteHandle, ESMF_TERMORDER_SRCSEQ, ESMF_REGION_TOTAL + use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 + use ESMF , only : ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_FieldCreate, ESMF_FieldDestroy, ESMF_FieldRegrid + use ESMF , only : ESMF_RouteHandle, ESMF_TERMORDER_SRCSEQ, ESMF_REGION_TOTAL + use shr_const_mod , only : shr_const_pi ! input/output variables type(ESMF_Field) , intent(in) :: usrc diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 90bbb61b4..7508431dc 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -12,7 +12,7 @@ module med_phases_prep_lnd_mod 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 + 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 @@ -22,7 +22,7 @@ module med_phases_prep_lnd_mod 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 + 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 @@ -279,12 +279,11 @@ subroutine map_glc2lnd_init(gcomp, rc) ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Verify that route handle has been created - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:), mapconsd,rc=rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR conservative route handle not created for glc->lnd mapping", & - ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - 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, routehandle=is_local%wrap%rh(compglc,complnd,mapconsd), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! Currently cannot map hflx in multiple elevation classes from glc to land diff --git a/nems/lib/ParallelIO b/nems/lib/ParallelIO index 6f9fb5e1b..86ad4463a 160000 --- a/nems/lib/ParallelIO +++ b/nems/lib/ParallelIO @@ -1 +1 @@ -Subproject commit 6f9fb5e1b9b8adb3fb6e531f6296b2abf9d58a7f +Subproject commit 86ad4463ab46e706aca632c2c4c2ffd48854113b diff --git a/nems/lib/genf90 b/nems/lib/genf90 index 4816965ba..acb24bb13 160000 --- a/nems/lib/genf90 +++ b/nems/lib/genf90 @@ -1 +1 @@ -Subproject commit 4816965ba946731352bad195b7d946a5fe682ff5 +Subproject commit acb24bb13b54db505163f683ed5a0e6271bf5e79 From e8b42146fb1e3a9873532d59e5acdd100fa9d006 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 1 Nov 2020 09:12:13 -0700 Subject: [PATCH 142/206] added option for uv mapping with cart3d --- mediator/esmFlds.F90 | 47 +-- mediator/esmFldsExchange_cesm_mod.F90 | 436 +++++++++++--------------- mediator/esmFldsExchange_hafs_mod.F90 | 6 - mediator/esmFldsExchange_nems_mod.F90 | 5 +- mediator/med_map_mod.F90 | 134 ++++---- 5 files changed, 285 insertions(+), 343 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index f0681f52c..6f2396923 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -26,27 +26,36 @@ module esmflds ! Set mappers !----------------------------------------------- - integer , public, parameter :: mapunset = 0 - integer , public, parameter :: mapbilnr = 1 - integer , public, parameter :: mapconsf = 2 - integer , public, parameter :: mapconsd = 3 - integer , public, parameter :: mappatch = 4 - integer , public, parameter :: mapfcopy = 5 - integer , public, parameter :: mapnstod = 6 ! nearest source to destination - 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 :: map_glc2ocn_ice = 9 ! custom smoothing map to map ice from glc->ocn (cesm only) - integer , public, parameter :: map_glc2ocn_liq = 10 ! custom smoothing map to map liq from glc->ocn (cesm only) - integer , public, parameter :: map_rof2ocn_ice = 11 ! custom smoothing map to map ice from rof->ocn (cesm only) - integer , public, parameter :: map_rof2ocn_liq = 12 ! custom smoothing map to map liq from rof->ocn (cesm only) - integer , public, parameter :: nmappers = 12 + integer , public, parameter :: mapunset = 0 + integer , public, parameter :: mapbilnr = 1 + integer , public, parameter :: mapconsf = 2 + integer , public, parameter :: mapconsd = 3 + integer , public, parameter :: mappatch = 4 + integer , public, parameter :: mapfcopy = 5 + integer , public, parameter :: mapnstod = 6 ! nearest source to destination + 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 :: nmappers = 13 character(len=*) , public, parameter :: mapnames(nmappers) = & - (/'bilnr ','consf ','consd ','patch ','fcopy ',& - 'nstod ','nstod_consd','nstod_consf', & - 'glc2ocn_ice','glc2ocn_liq','rof2ocn_ice','rof2ocn_liq'/) - - logical, public :: mapuv_with_cart3d ! rotate u,v to 3d cartesian space, map from src->dest, then rotate back + (/'bilnr ',& + 'consf ',& + 'consd ',& + 'patch ',& + 'fcopy ',& + 'nstod ',& + 'nstod_consd',& + 'nstod_consf',& + 'patch_uv3d ',& + 'glc2ocn_ice',& + 'glc2ocn_liq',& + 'rof2ocn_ice',& + 'rof2ocn_liq'/) !----------------------------------------------- ! Set coupling mode diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 43a06c286..1040f6c46 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -4,13 +4,50 @@ module esmFldsExchange_cesm_mod ! This is a mediator specific routine that determines ALL possible ! fields exchanged between components and their associated routing, ! mapping and merging - !--------------------------------------------------------------------- + ! + ! Merging arguments: + ! mrg_fromN = source component index that for the field to be merged + ! mrg_fldN = souce field name to be merged + ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', 'sum_with_weights', 'merge') + ! NOTE: + ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn fluxes or for ocn albedos + ! + ! NOTE: + ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in the + ! atm/ocn flux calculations. Input fields required from either the atm or the ocn for + ! these computation will use the logical 'use_med_aoflux' below. This is used to determine + ! 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 implicit none public public :: esmFldsExchange_cesm + character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' + character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' + character(len=CX) :: atm2lnd_fmap='unset', atm2lnd_smap='unset' + character(len=CX) :: glc2lnd_smap='unset', glc2lnd_fmap='unset' + character(len=CX) :: glc2ice_rmap='unset' + character(len=CX) :: glc2ocn_liq_rmap='unset' + character(len=CX) :: glc2ocn_ice_rmap='unset' + character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' + character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' + character(len=CX) :: lnd2atm_fmap='unset', lnd2atm_smap='unset' + character(len=CX) :: lnd2glc_fmap='unset', lnd2glc_smap='unset' + character(len=CX) :: lnd2rof_fmap='unset' + character(len=CX) :: rof2lnd_fmap='unset' + character(len=CX) :: rof2ocn_fmap='unset', rof2ocn_ice_rmap='unset', rof2ocn_liq_rmap='unset' + character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' + character(len=CX) :: wav2ocn_smap='unset' + logical :: mapuv_with_cart3d + logical :: flds_i2o_per_cat + logical :: flds_co2a + logical :: flds_co2b + logical :: flds_co2c + character(*), parameter :: u_FILE_u = & __FILE__ @@ -25,17 +62,15 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_internalstate_mod , only : InternalState - use esmFlds , only : med_fldList_type + use med_internalstate_mod , only : InternalState, logunit, mastertask use esmFlds , only : addfld => med_fldList_AddFld 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 : mapbilnr, mapconsf, mapconsd, mappatch + 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 - use esmflds , only : mapuv_with_cart3d use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb use esmFlds , only : coupling_mode @@ -46,43 +81,20 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! local variables: type(InternalState) :: is_local - logical :: flds_i2o_per_cat - integer :: dbrc - integer :: num, i, n - integer :: n1, n2, n3, n4 - logical :: isPresent + integer :: n character(len=5) :: iso(2) character(len=CL) :: cvalue character(len=CS) :: name, fldname - character(len=CX) :: atm2ice_fmap='unset', atm2ice_smap='unset', atm2ice_vmap='unset' - character(len=CX) :: atm2ocn_fmap='unset', atm2ocn_smap='unset', atm2ocn_vmap='unset' - character(len=CX) :: atm2lnd_fmap='unset', atm2lnd_smap='unset' - character(len=CX) :: glc2lnd_smap='unset', glc2lnd_fmap='unset' - character(len=CX) :: glc2ice_rmap='unset' - character(len=CX) :: glc2ocn_liq_rmap='unset', glc2ocn_ice_rmap='unset' - character(len=CX) :: ice2atm_fmap='unset', ice2atm_smap='unset' - character(len=CX) :: ocn2atm_fmap='unset', ocn2atm_smap='unset' - character(len=CX) :: lnd2atm_fmap='unset', lnd2atm_smap='unset' - character(len=CX) :: lnd2glc_fmap='unset', lnd2glc_smap='unset' - character(len=CX) :: lnd2rof_fmap='unset' - character(len=CX) :: rof2lnd_fmap='unset' - character(len=CX) :: rof2ocn_fmap='unset', rof2ocn_ice_rmap='unset', rof2ocn_liq_rmap='unset' - character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' - character(len=CX) :: wav2ocn_smap='unset' - logical :: flds_co2a ! use case - logical :: flds_co2b ! use case - logical :: flds_co2c ! use case character(len=CS), allocatable :: flds(:) character(len=CS), allocatable :: suffix(:) - character(len=*) , parameter :: subname='(esmFldsExchange_cesm)' + character(len=*) , parameter :: subname=' (esmFldsExchange_cesm) ' !-------------------------------------- rc = ESMF_SUCCESS - iso(1) = '' + iso(1) = ' ' iso(2) = '_wiso' - !--------------------------------------- ! Get the internal state !--------------------------------------- @@ -93,233 +105,137 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - !-------------------------------------- - ! Merging arguments: - ! mrg_fromN = source component index that for the field to be merged - ! mrg_fldN = souce field name to be merged - ! mrg_typeN = merge type ('copy', 'copy_with_weights', 'sum', 'sum_with_weights', 'merge') - ! NOTE: - ! mrg_from(compmed) can either be for mediator computed fields for atm/ocn fluxes or for ocn albedos - ! - ! NOTE: - ! FBMed_aoflux_o only refer to output fields to the atm/ocn that computed in the - ! atm/ocn flux calculations. Input fields required from either the atm or the ocn for - ! these computation will use the logical 'use_med_aoflux' below. This is used to determine - ! mappings between the atm and ocn needed for these computations. - !-------------------------------------- - - 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) - - !---------------------------------------------------------- - ! Initialize mapping file names - !---------------------------------------------------------- - - ! to atm - - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', value=ice2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_fmapname = '// trim(ice2atm_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', value=ice2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2atm_smapname = '// trim(ice2atm_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_fmapname', value=lnd2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2atm_fmapname = '// trim(lnd2atm_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', value=ocn2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_smapname = '// trim(ocn2atm_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', value=ocn2atm_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2atm_fmapname = '// trim(ocn2atm_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_smapname', value=lnd2atm_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2atm_smapname = '// trim(lnd2atm_smap), ESMF_LOGMSG_INFO) - end if - - ! to lnd - - call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_fmapname', value=atm2lnd_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2lnd_fmapname = '// trim(atm2lnd_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_smapname', value=atm2lnd_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2lnd_smapname = '// trim(atm2lnd_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='rof2lnd_fmapname', value=rof2lnd_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2lnd_fmapname = '// trim(rof2lnd_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_fmapname', value=glc2lnd_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_smapname', value=glc2lnd_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2lnd_smapname = '// trim(glc2lnd_smap), ESMF_LOGMSG_INFO) - end if - - ! to ice - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_fmapname = '// trim(atm2ice_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_smapname = '// trim(atm2ice_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ice_vmapname = '// trim(atm2ice_vmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2ice_rmapname', value=glc2ice_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2ice_rmapname = '// trim(glc2ice_rmap), ESMF_LOGMSG_INFO) - end if - - ! to ocn - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_fmapname = '// trim(atm2ocn_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_smapname = '// trim(atm2ocn_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2ocn_vmapname = '// trim(atm2ocn_vmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_liq_rmapname', value=glc2ocn_liq_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2ocn_liq_rmapname = '// trim(glc2ocn_liq_rmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_ice_rmapname', value=glc2ocn_ice_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('glc2ocn_ice_rmapname = '// trim(glc2ocn_ice_rmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='wav2ocn_smapname', value=wav2ocn_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('wav2ocn_smapname = '// trim(wav2ocn_smap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_fmapname', value=rof2ocn_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_fmapname = '// trim(rof2ocn_fmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_liq_rmapname', value=rof2ocn_liq_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_liq_rmapname = '// trim(rof2ocn_liq_rmap), ESMF_LOGMSG_INFO) - end if - - call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_ice_rmapname', value=rof2ocn_ice_rmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('rof2ocn_ice_rmapname = '// trim(rof2ocn_ice_rmap), ESMF_LOGMSG_INFO) - end if + if (phase == 'advertise') then - ! to rof + ! mapping to atm + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_fmapname', value=ice2atm_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'ice2atm_fmapname = '// trim(ice2atm_fmap) + call NUOPC_CompAttributeGet(gcomp, name='ice2atm_smapname', value=ice2atm_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'ice2atm_smapname = '// trim(ice2atm_smap) + call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_fmapname', value=lnd2atm_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'lnd2atm_fmapname = '// trim(lnd2atm_fmap) + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_smapname', value=ocn2atm_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'ocn2atm_smapname = '// trim(ocn2atm_smap) + call NUOPC_CompAttributeGet(gcomp, name='ocn2atm_fmapname', value=ocn2atm_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'ocn2atm_fmapname = '// trim(ocn2atm_fmap) + call NUOPC_CompAttributeGet(gcomp, name='lnd2atm_smapname', value=lnd2atm_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'lnd2atm_smapname = '// trim(lnd2atm_smap) - call NUOPC_CompAttributeGet(gcomp, name='lnd2rof_fmapname', value=lnd2rof_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2rof_fmapname = '// trim(lnd2rof_fmap), ESMF_LOGMSG_INFO) - end if + ! mapping to lnd + call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_fmapname', value=atm2lnd_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'atm2lnd_fmapname = '// trim(atm2lnd_fmap) + call NUOPC_CompAttributeGet(gcomp, name='atm2lnd_smapname', value=atm2lnd_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'atm2lnd_smapname = '// trim(atm2lnd_smap) + call NUOPC_CompAttributeGet(gcomp, name='rof2lnd_fmapname', value=rof2lnd_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'rof2lnd_fmapname = '// trim(rof2lnd_fmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_fmapname', value=glc2lnd_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'glc2lnd_smapname = '// trim(glc2lnd_fmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2lnd_smapname', value=glc2lnd_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'glc2lnd_smapname = '// trim(glc2lnd_smap) - ! to glc + ! mapping to ice + 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) - call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_fmapname', value=lnd2glc_fmap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2glc_fmapname = '// trim(lnd2glc_fmap), ESMF_LOGMSG_INFO) - end if + ! mapping to ocn + 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) - call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_smapname', value=lnd2glc_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('lnd2glc_smapname = '// trim(lnd2glc_smap), ESMF_LOGMSG_INFO) - end if + ! mapping to rof + call NUOPC_CompAttributeGet(gcomp, name='lnd2rof_fmapname', value=lnd2rof_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'lnd2rof_fmapname = '// trim(lnd2rof_fmap) - ! to wav + ! mapping to glc + call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_fmapname', value=lnd2glc_fmap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'lnd2glc_fmapname = '// trim(lnd2glc_fmap) + call NUOPC_CompAttributeGet(gcomp, name='lnd2glc_smapname', value=lnd2glc_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit, '(a)') trim(subname)//'lnd2glc_smapname = '// trim(lnd2glc_smap) - call NUOPC_CompAttributeGet(gcomp, name='atm2wav_smapname', value=atm2wav_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('atm2wav_smapname = '// trim(atm2wav_smap), ESMF_LOGMSG_INFO) - end if + ! mapping to wav + call NUOPC_CompAttributeGet(gcomp, name='atm2wav_smapname', value=atm2wav_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit,'(a)') trim(subname)//'atm2wav_smapname = '// trim(atm2wav_smap) + call NUOPC_CompAttributeGet(gcomp, name='ice2wav_smapname', value=ice2wav_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit,'(a)') trim(subname)//'ice2wav_smapname = '// trim(ice2wav_smap) + call NUOPC_CompAttributeGet(gcomp, name='ocn2wav_smapname', value=ocn2wav_smap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit,'(a)') trim(subname)//'ocn2wav_smapname = '// trim(ocn2wav_smap) - call NUOPC_CompAttributeGet(gcomp, name='ice2wav_smapname', value=ice2wav_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ice2wav_smapname = '// trim(ice2wav_smap), ESMF_LOGMSG_INFO) - end if + ! uv cart3d mapping + call NUOPC_CompAttributeGet(gcomp, name='mapuv_with_cart3d', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (mastertask) write(logunit,'(a)') trim(subname)//'mapuv_with_cart3d = '// trim(cvalue) + read(cvalue,*) mapuv_with_cart3d - call NUOPC_CompAttributeGet(gcomp, name='ocn2wav_smapname', value=ocn2wav_smap, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_LogWrite('ocn2wav_smapname = '// trim(ocn2wav_smap), ESMF_LOGMSG_INFO) - end if + ! co2 transfer between componetns + call NUOPC_CompAttributeGet(gcomp, name='flds_co2a', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) flds_co2a + call NUOPC_CompAttributeGet(gcomp, name='flds_co2b', value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) flds_co2b + 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) - !---------------------------------------------------------- - ! Initialize if use 3d cartesian mapping for u,v - !---------------------------------------------------------- + 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) - call NUOPC_CompAttributeGet(gcomp, name='mapuv_with_cart3d', value=cvalue, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) mapuv_with_cart3d - if (isPresent) then - call ESMF_LogWrite('mapuv_with_cart3d = '// trim(cvalue), ESMF_LOGMSG_INFO) end if !===================================================================== @@ -355,10 +271,14 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! --------------------------------------------------------------------- if (phase /= 'advertise') then call addfld(fldListFr(compatm)%flds, 'Sa_u') - call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch, 'one', atm2ocn_vmap) - call addfld(fldListFr(compatm)%flds, 'Sa_v') - call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch, 'one', atm2ocn_vmap) + if (mapuv_with_cart3d) then + call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch_uv3d, 'one', atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch_uv3d, 'one', atm2ocn_vmap) + else + call addmap(fldListFr(compatm)%flds, 'Sa_u' , compocn, mappatch, 'one', atm2ocn_vmap) + call addmap(fldListFr(compatm)%flds, 'Sa_v' , compocn, mappatch, 'one', atm2ocn_vmap) + end if call addfld(fldListFr(compatm)%flds, 'Sa_z') call addmap(fldListFr(compatm)%flds, 'Sa_z' , compocn, mapbilnr, 'one', atm2ocn_smap) @@ -372,20 +292,16 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Sa_shum') call addmap(fldListFr(compatm)%flds, 'Sa_shum', compocn, mapbilnr, 'one', atm2ocn_smap) + call addfld(fldListFr(compatm)%flds, 'Sa_ptem') + call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) + + call addfld(fldListFr(compatm)%flds, 'Sa_dens') + call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, mapbilnr, 'one', atm2ocn_smap) + if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_shum_wiso', rc=rc)) then call addfld(fldListFr(compatm)%flds, 'Sa_shum_wiso') call addmap(fldListFr(compatm)%flds, 'Sa_shum_wiso', compocn, mapbilnr, 'one', atm2ocn_smap) end if - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_ptem', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_ptem') - call addmap(fldListFr(compatm)%flds, 'Sa_ptem', compocn, mapbilnr, 'one', atm2ocn_smap) - end if - - if (fldchk(is_local%wrap%FBImp(compatm,compatm), 'Sa_dens', rc=rc)) then - call addfld(fldListFr(compatm)%flds, 'Sa_dens') - call addmap(fldListFr(compatm)%flds, 'Sa_dens', compocn, mapbilnr, 'one', atm2ocn_smap) - end if end if ! --------------------------------------------------------------------- diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index eb8181635..29fd506ed 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -295,7 +295,6 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch use esmflds , only : mapfcopy, mapnstod, mapnstod_consd use esmflds , only : mapnstod_consf - use esmflds , only : mapuv_with_cart3d ! input/output parameters: type(ESMF_GridComp) :: gcomp @@ -346,11 +345,6 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call esmFldsExchange_hafs_attr(gcomp, hafs_attr, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - !---------------------------------------------------------- - ! Initialize if use 3d cartesian mapping for u,v - !---------------------------------------------------------- - mapuv_with_cart3d = .false. - !===================================================================== ! FIELDS TO MEDIATOR component (for fractions and atm/ocn flux calculation) !===================================================================== diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index 7d5e7eabe..cc61512b8 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -31,7 +31,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) use esmflds , only : compmed, compatm, compocn, compice, comprof, ncomps use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf - use esmflds , only : coupling_mode, mapuv_with_cart3d, mapnames + use esmflds , only : coupling_mode, mapnames use esmflds , only : fldListTo, fldListFr, fldListMed_aoflux, fldListMed_ocnalb use med_internalstate_mod , only : mastertask, logunit @@ -51,9 +51,6 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) rc = ESMF_SUCCESS - ! Initialize if use 3d cartesian mapping for u,v - mapuv_with_cart3d = .false. - ! Set maptype according to coupling_mode if (trim(coupling_mode) == 'nems_orig' .or. trim(coupling_mode) == 'nems_orig_data') then maptype = mapnstod_consf diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 929e95028..627c3f91b 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -3,7 +3,7 @@ module med_map_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_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_LOGMSG_INFO, ESMF_LogWrite - use esmFlds , only : mapuv_with_cart3d + use ESMF , only : ESMF_Field use med_internalstate_mod , only : InternalState, logunit, mastertask use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_utils_mod , only : chkerr => med_utils_ChkErr @@ -32,6 +32,8 @@ module med_map_mod module procedure med_map_RH_is_created_RH1d end interface + type(ESMF_Field) :: uv3d_src, uv3d_dst ! needed for 3d mapping of u,v vector pairs + ! private module variables character(*), parameter :: u_FILE_u = & @@ -74,7 +76,7 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_Field use esmFlds , only : fldListFr, ncomps, mapunset, compname - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use med_methods_mod , only : med_methods_FB_getFieldN ! input/output variables type(ESMF_GridComp) :: gcomp @@ -87,7 +89,6 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) type(ESMF_Field) :: flddst integer :: n,n1,n2,m,nf character(len=CX) :: mapfile - character(len=CS) :: string integer :: mapindex logical :: mapexists = .false. character(len=*), parameter :: subname=' (module_med_map: RouteHandles_init) ' @@ -97,7 +98,7 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) rc = ESMF_SUCCESS if (dbug_flag > 1) then - call ESMF_LogWrite("Starting to initialize RHs", ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) endif ! Get the internal state from Component. @@ -113,9 +114,9 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) if (n1 /= n2) then if (is_local%wrap%med_coupling_active(n1,n2)) then ! If coupling is active between n1 and n2 ! Get source and destination fields - call FB_GetFieldN(is_local%wrap%FBImp(n1,n1), 1, fldsrc, rc) + call med_methods_FB_getFieldN(is_local%wrap%FBImp(n1,n1), 1, fldsrc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_GetFieldN(is_local%wrap%FBImp(n1,n2), 1, flddst, rc) + call med_methods_FB_getFieldN(is_local%wrap%FBImp(n1,n2), 1, flddst, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Loop over fields @@ -156,8 +157,8 @@ end subroutine med_map_RouteHandles_initfrom_esmflds subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapindex, RouteHandle, rc) use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_LogFlush - use ESMF , only : ESMf_Field, ESMF_FieldBundle, ESMF_RouteHandle - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use ESMF , only : ESMf_Field, ESMF_FieldBundle, ESMF_RouteHandle + use med_methods_mod , only : med_methods_FB_getFieldN !--------------------------------------------- ! Initialize initialize additional route handles for mapping fractions @@ -182,13 +183,12 @@ subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapin rc = ESMF_SUCCESS if (dbug_flag > 1) then - call ESMF_LogWrite("Initializing RHs not yet created and needed", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() + call ESMF_LogWrite(trim(subname)//": start", ESMF_LOGMSG_INFO) endif - call FB_getFieldN(FBsrc, 1, fldsrc, rc) + call med_methods_FB_getFieldN(FBsrc, 1, fldsrc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call FB_getFieldN(FBDst, 1, flddst, rc) + call med_methods_FB_getFieldN(FBDst, 1, flddst, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle(n1,n2,mapindex), rc=rc) @@ -215,7 +215,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd use esmFlds , only : ncomps, compatm, compice, compocn, compname use esmFlds , only : mapfcopy, mapconsd, mapconsf, mapnstod - use esmFlds , only : coupling_mode + use esmFlds , only : coupling_mode, compname use med_constants_mod , only : ispval_mask => med_constants_ispval_mask ! input/output variables @@ -277,26 +277,29 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (n2 == compocn .or. n2 == compice) dstMaskValue = 0 end if + write(string,'(a)') trim(compname(n1))//' to '//trim(compname(n2)) + ! Create route handle if (mapindex == mapfcopy) then if (mastertask) then - write(logunit,'(3A)') subname,trim(string),' RH redist ' + write(logunit,'(A)') trim(subname)//' creating RH redist for '//trim(string) end if - call ESMF_LogWrite(subname // trim(string) // ' RH redist ', ESMF_LOGMSG_INFO) call ESMF_FieldRedistStore(fldsrc, flddst, routehandle=routehandle, & ignoreUnmatchedIndices = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (lmapfile /= 'unset') then if (mastertask) then - write(logunit,'(4A)') subname,trim(string),' RH '//trim(mapname)//' via input file ',trim(mapfile) + write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//& + ' via input file '//trim(mapfile)//' for '//trim(string) end if - call ESMF_LogWrite(subname // trim(string) //& - ' RH '//trim(mapname)//' via input file '//trim(mapfile), ESMF_LOGMSG_INFO) call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, routehandle=routehandle, & ignoreUnmatchedIndices=.true., & srcTermProcessing=srcTermProcessing_Value, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapbilnr) then + if (mastertask) then + write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) + end if call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & @@ -307,6 +310,9 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapconsf .or. mapindex == mapnstod_consf) then + if (mastertask) then + write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) + end if call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & @@ -318,6 +324,9 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapconsd .or. mapindex == mapnstod_consd) then + if (mastertask) then + write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) + end if call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & @@ -329,6 +338,9 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mappatch) then + if (mastertask) then + write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) + end if call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & @@ -339,6 +351,9 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else + if (mastertask) then + write(logunit,'(A)') trim(subname)//' mapindex '//trim(mapname)//' not supported for '//trim(string) + end if call ESMF_LogWrite(trim(subname)//' mapindex '//trim(mapname)//' not supported ', & ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) rc = ESMF_FAILURE @@ -407,7 +422,7 @@ logical function med_map_RH_is_created_RH1d(RHs,mapindex,rc) use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated use esmFlds , only : mapconsd, mapconsf, mapnstod - use esmFlds , only : mapnstod_consd, mapnstod_consf + use esmFlds , only : mapnstod_consd, mapnstod_consf ! input/output varaibes type(ESMF_RouteHandle) , intent(in) :: RHs(:) @@ -657,7 +672,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & ! for any given mapping type if ( fldsSrc(ns)%mapindex(destcomp) == mapindex .and. & trim(fldsSrc(ns)%shortname) == trim(fieldnamelist(nf))) then - ! Set the normalization to the input + ! Set the normalization to the input packed_data(mapindex)%mapnorm = fldsSrc(ns)%mapnorm(destcomp) end if end do @@ -752,7 +767,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet use ESMF , only : ESMF_FieldRedist, ESMF_RouteHandle - use esmFlds , only : nmappers, mapfcopy + use esmFlds , only : nmappers, mapfcopy, mappatch_uv3d use med_internalstate_mod , only : packed_data_type ! input/output variables @@ -768,7 +783,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d integer :: nf, nu, np, n integer :: fieldcount integer :: mapindex - integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields + integer :: ungriddedUBound(1) real(r8), pointer :: dataptr1d(:) => null() real(r8), pointer :: dataptr2d(:,:) => null() real(r8), pointer :: dataptr2d_packed(:,:) => null() @@ -776,12 +791,14 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d type(ESMF_Field) :: field_fracsrc type(ESMF_Field), pointer :: fieldlist_src(:) => null() type(ESMF_Field), pointer :: fieldlist_dst(:) => null() - character(CL), allocatable :: fieldNameList(:) + type(ESMF_Field) :: usrc, vsrc ! only used for 3d mapping of u,v + type(ESMF_Field) :: udst, vdst ! only used for 3d mapping of u,v real(r8), pointer :: data_norm(:) => null() real(r8), pointer :: data_dst(:,:) => null() character(len=*), parameter :: subname=' (module_MED_map:med_map_field_packed) ' !----------------------------------------------------------- + call t_startf('MED:'//subname) rc = ESMF_SUCCESS ! Get field count for both FBsrc and FBdst @@ -839,7 +856,22 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d ! ----------------------------------- call t_startf('MED:'//trim(subname)//' map') - if (mapindex == mapfcopy) then + + if (mapindex == mappatch_uv3d) then + + ! for mappatch_uv3d do not use packed field bundles + call ESMF_FieldBundleGet(FBSrc, fieldName='Sa_u', field=usrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBSrc, fieldName='Sa_v', field=vsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBDst, fieldName='Sa_u', field=udst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FBDst, fieldName='Sa_v', field=vdst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_uv_cart3d(usrc, vsrc, udst, vdst, routehandles, mapindex, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + else if (mapindex == mapfcopy) then ! Mapping is redistribution call ESMF_FieldRedist(& @@ -930,6 +962,8 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d deallocate(fieldlist_src) deallocate(fieldlist_dst) + call t_stopf('MED:'//subname) + end subroutine med_map_field_packed !================================================================================ @@ -1124,7 +1158,7 @@ subroutine med_map_field(field_src, field_dst, routehandles, maptype, fldname, r end subroutine med_map_field !================================================================================ - subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) + subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, routehandles, mapindex, rc) use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use ESMF , only : ESMF_Field, ESMF_FieldGet @@ -1137,7 +1171,7 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) type(ESMF_Field) , intent(in) :: vsrc type(ESMF_Field) , intent(inout) :: udst type(ESMF_Field) , intent(inout) :: vdst - type(ESMF_RouteHandle) , intent(inout) :: RouteHandles(:) + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) integer , intent(in) :: mapindex integer , intent(out) :: rc @@ -1149,8 +1183,6 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) real(r8) :: ux,uy,uz type(ESMF_Mesh) :: lmesh_src type(ESMF_Mesh) :: lmesh_dst - type(ESMF_Field) :: field3d_src - type(ESMF_Field) :: field3d_dst real(r8), pointer :: data_u_src(:) => null() real(r8), pointer :: data_u_dst(:) => null() real(r8), pointer :: data_v_src(:) => null() @@ -1161,16 +1193,13 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) real(r8), pointer :: ownedElemCoords_dst(:) => null() integer :: numOwnedElements integer :: spatialDim - logical :: checkflag = .false. real(r8), parameter :: deg2rad = shr_const_pi/180.0_R8 ! deg to rads + logical :: first_time = .true. character(len=*), parameter :: subname=' (module_MED_map:med_map_uv_cart3d) ' !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - ! Create two field bundles vec_src3d and vec_dst3d that contain - ! all three fields with undistributed dimensions for each - ! Get pointer to input u and v data source field data call ESMF_FieldGet(usrc, farrayPtr=data_u_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1184,7 +1213,7 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) call ESMF_FieldGet(vdst, farrayPtr=data_v_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get source mesh and coordinates + ! Get source mesh and coordinates call ESMF_FieldGet(usrc, mesh=lmesh_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_src, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) @@ -1193,7 +1222,7 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) call ESMF_MeshGet(lmesh_src, ownedElemCoords=ownedElemCoords_src) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get destination mesh and coordinates + ! Get destination mesh and coordinates call ESMF_FieldGet(udst, mesh=lmesh_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_MeshGet(lmesh_dst, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) @@ -1202,20 +1231,24 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) call ESMF_MeshGet(lmesh_dst, ownedElemCoords=ownedElemCoords_dst) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! create source field and destination fields - field3d_src = ESMF_FieldCreate(lmesh_src, ESMF_TYPEKIND_R8, name='src3d', & - ungriddedLbound=(/1/), ungriddedUbound=(/3/), gridToFieldMap=(/2/), & - meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field3d_dst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, name='dst3d', & - ungriddedLbound=(/1/), ungriddedUbound=(/3/), gridToFieldMap=(/2/), & - meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (first_time) then + ! Create two module fields - vec_src3d and vec_dst3d - that contain + ! all three fields with undistributed dimensions for each + uv3d_src = ESMF_FieldCreate(lmesh_src, ESMF_TYPEKIND_R8, name='src3d', & + ungriddedLbound=(/1/), ungriddedUbound=(/3/), gridToFieldMap=(/2/), & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + uv3d_dst = ESMF_FieldCreate(lmesh_dst, ESMF_TYPEKIND_R8, name='dst3d', & + ungriddedLbound=(/1/), ungriddedUbound=(/3/), gridToFieldMap=(/2/), & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + first_time = .false. + end if ! get pointers to source and destination data that will be filled in with rotation to cart3d - call ESMF_FieldGet(field3d_src, farrayPtr=data2d_src, rc=rc) + call ESMF_FieldGet(uv3d_src, farrayPtr=data2d_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field3d_dst, farrayPtr=data2d_dst, rc=rc) + call ESMF_FieldGet(uv3d_dst, farrayPtr=data2d_dst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Rotate Source data to cart3d @@ -1232,11 +1265,8 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) enddo ! Map all thee vector fields at once from source to destination grid - call med_map_field(& - field_src=field3d_src, & - field_dst=field3d_dst, & - routehandles=routehandles, & - maptype=mapindex, rc=rc) + call med_map_field(field_src=uv3d_src, field_dst=uv3d_dst, & + routehandles=routehandles, maptype=mapindex, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Rotate destination data back from cart3d to original @@ -1257,10 +1287,6 @@ subroutine med_map_uv_cart3d(usrc, vsrc, udst, vdst, RouteHandles, mapindex, rc) ! Deallocate data deallocate(ownedElemCoords_src) deallocate(ownedElemCoords_dst) - call ESMF_FieldDestroy(field3d_src, noGarbage=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldDestroy(field3d_dst, noGarbage=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return end subroutine med_map_uv_cart3d From dc41eab8ea7938cbbc1359b7767ddbcae5925978 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 1 Nov 2020 09:12:41 -0700 Subject: [PATCH 143/206] cleanup of med_methods_mod --- mediator/med_methods_mod.F90 | 1399 ++++------------------------------ 1 file changed, 158 insertions(+), 1241 deletions(-) diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index c30a9b9e2..ed360087f 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -7,10 +7,10 @@ module med_methods_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 : operator(<), operator(/=), operator(+), operator(-), operator(*) , operator(>=) use ESMF , only : operator(<=), operator(>), operator(==) - use ESMF , only : ESMF_GeomType_Flag, ESMF_FieldStatus_Flag, ESMF_PoleMethod_Flag + use ESMF , only : ESMF_FieldStatus_Flag use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING, ESMF_POLEMETHOD_ALLAVG + use ESMF , only : ESMF_MAXSTR, ESMF_LOGMSG_WARNING 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 : spval_init => med_constants_spval_init @@ -32,18 +32,12 @@ module med_methods_mod med_methods_FieldPtr_compare2 end interface - interface med_methods_UpdateTimestamp; module procedure & - med_methods_State_UpdateTimestamp, & - med_methods_Field_UpdateTimestamp - end interface - ! used/reused in module - logical :: isPresent - character(len=1024) :: msgString - type(ESMF_GeomType_Flag) :: geomtype - type(ESMF_FieldStatus_Flag) :: status - character(*) , parameter :: u_FILE_u = & + logical :: isPresent + character(len=1024) :: msgString + type(ESMF_FieldStatus_Flag) :: status + character(*) , parameter :: u_FILE_u = & __FILE__ public med_methods_FB_copy @@ -52,132 +46,36 @@ module med_methods_mod public med_methods_FB_init public med_methods_FB_init_pointer public med_methods_FB_reset - public med_methods_FB_clean public med_methods_FB_diagnose public med_methods_FB_FldChk public med_methods_FB_GetFldPtr public med_methods_FB_getNameN public med_methods_FB_getFieldN - public med_methods_FB_getFieldByName public med_methods_FB_getNumflds public med_methods_FB_Field_diagnose - public med_methods_Field_diagnose + public med_methods_FB_GeomPrint public med_methods_State_reset public med_methods_State_diagnose public med_methods_State_GeomPrint - public med_methods_State_GeomWrite - public med_methods_State_GetFldPtr public med_methods_State_SetScalar public med_methods_State_GetScalar public med_methods_State_GetNumFields - public med_methods_State_getFieldN - public med_methods_State_FldDebug + public med_methods_Field_diagnose public med_methods_Field_GeomPrint - public med_methods_Clock_TimePrint - public med_methods_UpdateTimestamp - public med_methods_Distgrid_Match public med_methods_FieldPtr_compare - public med_methods_States_GetSharedFlds + public med_methods_Clock_TimePrint - private med_methods_Grid_Write - private med_methods_Grid_Print private med_methods_Mesh_Print - private med_methods_Mesh_Write + private med_methods_Grid_Print private med_methods_Field_GetFldPtr - private med_methods_Field_GeomWrite - private med_methods_Field_UpdateTimestamp - private med_methods_FB_GeomPrint - private med_methods_FB_GeomWrite - private med_methods_FB_RWFields - private med_methods_FB_SetFldPtr private med_methods_FB_copyFB2FB private med_methods_FB_accumFB2FB - private med_methods_State_UpdateTimestamp - private med_methods_State_getNameN - private med_methods_State_getFieldByName - private med_methods_State_SetFldPtr private med_methods_Array_diagnose !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- - subroutine med_methods_FB_RWFields(mode,fname,FB,flag,rc) - - ! ---------------------------------------------- - ! Read or Write Field Bundles - ! ---------------------------------------------- - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleWrite - use ESMF, only : ESMF_FieldRead, ESMF_IOFMT_NETCDF, ESMF_FILESTATUS_REPLACE - - character(len=*) :: mode - character(len=*) :: fname - type(ESMF_FieldBundle) :: FB - logical,optional :: flag - integer,optional :: rc - - ! local variables - type(ESMF_Field) :: field - character(len=ESMF_MAXSTR) :: name - integer :: fieldcount, n - logical :: fexists - character(len=*), parameter :: subname='(med_methods_FB_RWFields)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//trim(fname)//": called", ESMF_LOGMSG_INFO) - endif - - if (mode == 'write') then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": write "//trim(fname), ESMF_LOGMSG_INFO) - end if - call ESMF_FieldBundleWrite(FB, fname, & - singleFile=.true., status=ESMF_FILESTATUS_REPLACE, iofmt=ESMF_IOFMT_NETCDF, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_FB_diagnose(FB, 'write '//trim(fname), rc) - - elseif (mode == 'read') then - inquire(file=fname,exist=fexists) - if (fexists) then - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": read "//trim(fname), ESMF_LOGMSG_INFO) - end if - !----------------------------------------------------------------------------------------------------- - ! tcraig, ESMF_FieldBundleRead fails if a field is not on the field bundle, but we really want to just - ! ignore that field and read the rest, so instead read each field one at a time through ESMF_FieldRead - ! call ESMF_FieldBundleRead (FB, fname, & - ! singleFile=.true., iofmt=ESMF_IOFMT_NETCDF, rc=rc) - ! if (chkerr(rc,__LINE__,u_FILE_u)) return - !----------------------------------------------------------------------------------------------------- - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,fieldCount - call med_methods_FB_getFieldByName(FB, name, field, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldRead (field, fname, iofmt=ESMF_IOFMT_NETCDF, rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - line=__LINE__, file=u_FILE_u)) call ESMF_LogWrite(trim(subname)//& - ' WARNING missing field '//trim(name)) - enddo - - call med_methods_FB_diagnose(FB, 'read '//trim(fname), rc) - if (present(flag)) flag = .true. - endif - - else - call ESMF_LogWrite(trim(subname)//": mode WARNING "//trim(fname)//" mode="//trim(mode), ESMF_LOGMSG_INFO) - endif - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//trim(fname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_RWFields - - !----------------------------------------------------------------------------- - subroutine med_methods_FB_init_pointer(StateIn, FBout, flds_scalar_name, name, rc) ! ---------------------------------------------- @@ -498,7 +396,9 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from FBgeom", ESMF_LOGMSG_INFO) end if elseif (present(STgeom)) then - call med_methods_State_getFieldN(STgeom, 1, lfield, rc=rc) + call med_methods_State_getNameN(STgeom, 1, lname, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(STgeom, itemName=lname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//":"//trim(lname)//" mesh from STgeom", ESMF_LOGMSG_INFO) @@ -548,7 +448,9 @@ subroutine med_methods_FB_init(FBout, flds_scalar_name, fieldNameList, FBgeom, S call med_methods_FB_getFieldN(FBflds, n, lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return elseif (present(STflds)) then - call med_methods_State_getFieldN(STflds, n, lfield, rc=rc) + call med_methods_State_getNameN(STflds, n, lname, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(STflds, itemName=lname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -645,22 +547,17 @@ subroutine med_methods_FB_getNameN(FB, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif - allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldname = lfieldnamelist(fieldnum) - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -709,40 +606,6 @@ end subroutine med_methods_FB_getFieldN !----------------------------------------------------------------------------- - subroutine med_methods_FB_getFieldByName(FB, fieldname, field, rc) - - ! ---------------------------------------------- - ! Get field associated with fieldname out of FB - ! ---------------------------------------------- - - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet - - ! input/output variables - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*) , intent(in) :: fieldname - type(ESMF_Field) , intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=*),parameter :: subname='(med_methods_FB_getFieldByName)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_getFieldByName - - !----------------------------------------------------------------------------- - subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) ! ---------------------------------------------- @@ -768,22 +631,17 @@ subroutine med_methods_State_getNameN(State, fieldnum, fieldname, rc) rc = ESMF_SUCCESS fieldname = ' ' - call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldnum > fieldCount) then call ESMF_LogWrite(trim(subname)//": ERROR fieldnum > fieldCount ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE return endif - allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldname = lfieldnamelist(fieldnum) - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -812,7 +670,6 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) integer :: n,itemCount type(ESMF_Field), pointer :: fieldList(:) => null() type(ESMF_StateItem_Flag), pointer :: itemTypeList(:) => null() - logical, parameter :: use_NUOPC_method = .true. character(len=*),parameter :: subname='(med_methods_State_getNumFields)' ! ---------------------------------------------- @@ -821,152 +678,20 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) endif rc = ESMF_SUCCESS - if (use_NUOPC_method) then - - nullify(fieldList) - call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - fieldnum = 0 - if (associated(fieldList)) then - fieldnum = size(fieldList) - deallocate(fieldList) - endif - - else - - fieldnum = 0 - call ESMF_StateGet(State, itemCount=itemCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (itemCount > 0) then - allocate(itemTypeList(itemCount)) - call ESMF_StateGet(State, itemTypeList=itemTypeList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,itemCount - if (itemTypeList(n) == ESMF_STATEITEM_FIELD) fieldnum=fieldnum+1 - enddo - deallocate(itemTypeList) - endif - - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_getNumFields - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_getFieldN(State, fieldnum, field, rc) - - ! ---------------------------------------------- - ! Get field number fieldnum in State - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State), intent(in) :: State - integer , intent(in) :: fieldnum - type(ESMF_Field), intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=ESMF_MAXSTR) :: name - character(len=*),parameter :: subname='(med_methods_State_getFieldN)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_State_getNameN(State, fieldnum, name, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_StateGet(State, itemName=name, field=field, rc=rc) + nullify(fieldList) + call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_getFieldN - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_getFieldByName(State, fieldname, field, rc) - ! ---------------------------------------------- - ! Get field associated with fieldname from State - ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State), intent(in) :: State - character(len=*), intent(in) :: fieldname - type(ESMF_Field), intent(inout) :: field - integer , intent(out) :: rc - - ! local variables - character(len=*),parameter :: subname='(med_methods_State_getFieldByName)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + fieldnum = 0 + if (associated(fieldList)) then + fieldnum = size(fieldList) + deallocate(fieldList) endif - rc = ESMF_SUCCESS - - call ESMF_StateGet(State, itemName=fieldname, field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif - end subroutine med_methods_State_getFieldByName - - !----------------------------------------------------------------------------- - - subroutine med_methods_FB_clean(FB, rc) - ! ---------------------------------------------- - ! Destroy fields in FB and FB - ! ---------------------------------------------- - - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldDestroy - use ESMF, only : ESMF_FieldBundleDestroy, ESMF_Field - - type(ESMF_FieldBundle), intent(inout) :: FB - integer , intent(out) :: rc - - ! local variables - integer :: i,j,n - integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() - type(ESMF_Field) :: field - character(len=*),parameter :: subname='(med_methods_FB_clean)' - ! ---------------------------------------------- - - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldCount)) - call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=lfieldnamelist(n), field=field, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldDestroy(field, rc=rc, noGarbage=.true.) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - - call ESMF_FieldBundleDestroy(FB, rc=rc, noGarbage=.true.) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(lfieldnamelist) - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - - end subroutine med_methods_FB_clean + end subroutine med_methods_State_getNumFields !----------------------------------------------------------------------------- @@ -976,7 +701,7 @@ subroutine med_methods_FB_reset(FB, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field ! intput/output variables type(ESMF_FieldBundle) , intent(inout) :: FB @@ -988,6 +713,10 @@ subroutine med_methods_FB_reset(FB, value, rc) integer :: fieldCount character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() real(R8) :: lvalue + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() character(len=*),parameter :: subname='(med_methods_FB_reset)' ! ---------------------------------------------- @@ -1006,12 +735,25 @@ subroutine med_methods_FB_reset(FB, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call med_methods_FB_SetFldPtr(FB, lfieldnamelist(n), lvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = lvalue + elseif (lrank == 2) then + fldptr2 = lvalue + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif + enddo deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -1029,7 +771,7 @@ subroutine med_methods_State_reset(State, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field ! intput/output variables type(ESMF_State) , intent(inout) :: State @@ -1039,8 +781,12 @@ subroutine med_methods_State_reset(State, value, rc) ! local variables integer :: i,j,n integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() real(R8) :: lvalue + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() character(len=*),parameter :: subname='(med_methods_State_reset)' ! ---------------------------------------------- @@ -1059,12 +805,24 @@ subroutine med_methods_State_reset(State, value, rc) allocate(lfieldnamelist(fieldCount)) call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call med_methods_State_SetFldPtr(State, lfieldnamelist(n), lvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = lvalue + elseif (lrank == 2) then + fldptr2 = lvalue + else + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif enddo - deallocate(lfieldnamelist) if (dbug_flag > 10) then @@ -1081,7 +839,7 @@ subroutine med_methods_FB_average(FB, count, rc) ! Set all fields to zero in FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -1094,6 +852,7 @@ subroutine med_methods_FB_average(FB, count, rc) character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() real(R8), pointer :: dataPtr1(:) => null() real(R8), pointer :: dataPtr2(:,:) => null() + type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_FB_average)' ! ---------------------------------------------- @@ -1119,8 +878,10 @@ subroutine med_methods_FB_average(FB, count, rc) call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, fieldCount - call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), dataPtr1, dataPtr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1, fldptr2=dataptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data @@ -1157,7 +918,7 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! Diagnose status of FB ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field type(ESMF_FieldBundle) , intent(inout) :: FB character(len=*) , intent(in), optional :: string @@ -1170,6 +931,7 @@ subroutine med_methods_FB_diagnose(FB, string, rc) character(len=CL) :: lstring real(R8), pointer :: dataPtr1d(:) => null() real(R8), pointer :: dataPtr2d(:,:) => null() + type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_diagnose)' ! ---------------------------------------------- @@ -1192,8 +954,9 @@ subroutine med_methods_FB_diagnose(FB, string, rc) ! For each field in the bundle, get its memory location and print out the field do n = 1, fieldCount - call med_methods_FB_GetFldPtr(FB, lfieldnamelist(n), & - fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then @@ -1288,8 +1051,9 @@ subroutine med_methods_State_diagnose(State, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_State, ESMF_StateGet + use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field + ! input/output variables type(ESMF_State), intent(in) :: State character(len=*), intent(in), optional :: string integer , intent(out) :: rc @@ -1301,6 +1065,7 @@ subroutine med_methods_State_diagnose(State, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) => null() real(R8), pointer :: dataPtr2d(:,:) => null() + type(ESMF_Field) :: lfield character(len=*),parameter :: subname='(med_methods_State_diagnose)' ! ---------------------------------------------- @@ -1316,19 +1081,16 @@ subroutine med_methods_State_diagnose(State, string, rc) call ESMF_StateGet(State, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(lfieldnamelist(fieldCount)) - call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - - call med_methods_State_GetFldPtr(State, lfieldnamelist(n), & - fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc) + call ESMF_StateGet(State, itemName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptr1d, fldptr2=dataptr2d, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (lrank == 0) then ! no local data - elseif (lrank == 1) then if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1337,7 +1099,6 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif - elseif (lrank == 2) then if (size(dataPtr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & @@ -1346,7 +1107,6 @@ subroutine med_methods_State_diagnose(State, string, rc) write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(lfieldnamelist(n)), & " no data" endif - else call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE @@ -1373,7 +1133,7 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) ! Diagnose status of State ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FB @@ -1386,7 +1146,9 @@ subroutine med_methods_FB_Field_diagnose(FB, 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)' + 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)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -1399,30 +1161,29 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) lstring = trim(string) endif - call med_methods_FB_GetFldPtr(FB, fieldname, dataPtr1d, dataPtr2d, lrank, rc=rc) + call ESMF_FieldBundleGet(FB, fieldName=fieldname, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - if (size(dataPtr1d) > 0) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (size(dataptr2d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) + minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - elseif (lrank == 2) then - if (size(dataPtr2d) > 0) then + else + call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (size(dataPtr1d) > 0) then write(msgString,'(A,3g14.7,i8)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname), & - minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d) + minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d) else write(msgString,'(A,a)') trim(subname)//' '//trim(lstring)//': '//trim(fieldname)," no data" endif - else - call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif + end if call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) if (dbug_flag > 10) then @@ -1538,9 +1299,9 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) ! If copy is passed in and true, the this is a copy ! ---------------------------------------------- - use ESMF , only : ESMF_FieldBundle - use ESMF , only : ESMF_FieldBundleGet + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + ! input/output variables type(ESMF_FieldBundle), intent(inout) :: FBout type(ESMF_FieldBundle), intent(in) :: FBin logical, optional , intent(in) :: copy @@ -1549,13 +1310,14 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) ! local variables integer :: i,j,n integer :: fieldCount, lranki, lranko - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() logical :: exists logical :: lcopy real(R8), pointer :: dataPtri1(:) => null() real(R8), pointer :: dataPtro1(:) => null() real(R8), pointer :: dataPtri2(:,:) => null() real(R8), pointer :: dataPtro2(:,:) => null() + type(ESMF_Field) :: lfield character(len=*), parameter :: subname='(med_methods_FB_accumFB2FB)' ! ---------------------------------------------- @@ -1579,12 +1341,17 @@ subroutine med_methods_FB_accumFB2FB(FBout, FBin, copy, rc) call ESMF_FieldBundleGet(FBin, fieldName=lfieldnamelist(n), isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (exists) then - call med_methods_FB_GetFldPtr(FBin, lfieldnamelist(n), dataPtri1, dataPtri2, lranki, rc=rc) + call ESMF_FieldBundleGet(FBin, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_FB_GetFldPtr(FBout, lfieldnamelist(n), dataPtro1, dataPtro2, lranko, rc=rc) + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptri1, fldptr2=dataptri2, rank=lranki, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (lranki == 1 .and. lranko == 1) then + call ESMF_FieldBundleGet(FBout, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_Field_GetFldPtr(lfield, fldptr1=dataptro1, fldptr2=dataptro2, rank=lranko, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (lranki == 1 .and. lranko == 1) then if (.not.med_methods_FieldPtr_Compare(dataPtro1, dataPtri1, subname, rc)) then call ESMF_LogWrite(trim(subname)//": ERROR in dataPtr1 size ", ESMF_LOGMSG_ERROR) @@ -1708,6 +1475,7 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) use ESMF , only : ESMF_Field,ESMF_Mesh, ESMF_FieldGet, ESMF_MeshGet use ESMF , only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_COMPLETE + use ESMF , only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field) , intent(in) :: field @@ -1718,9 +1486,10 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) integer , intent(out) , optional :: rc ! local variables - type(ESMF_Mesh) :: lmesh - integer :: lrank, nnodes, nelements - logical :: labort + type(ESMF_Mesh) :: lmesh + integer :: lrank, nnodes, nelements + logical :: labort + type(ESMF_GeomType_Flag) :: geomtype character(len=*), parameter :: subname='(med_methods_Field_GetFldPtr)' ! ---------------------------------------------- @@ -1763,7 +1532,6 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - elseif (geomtype == ESMF_GEOMTYPE_MESH) then call ESMF_FieldGet(field, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1772,10 +1540,8 @@ subroutine med_methods_Field_GetFldPtr(field, fldptr1, fldptr2, rank, abort, rc) call ESMF_MeshGet(lmesh, numOwnedNodes=nnodes, numOwnedElements=nelements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (nnodes == 0 .and. nelements == 0) lrank = 0 - else - call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", & - ESMF_LOGMSG_INFO) + call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return endif ! geomtype @@ -1869,9 +1635,7 @@ subroutine med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, rank, field, call ESMF_FieldBundleGet(FB, fieldName=trim(fldname), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Field_GetFldPtr(lfield, & - fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (present(rank)) then @@ -1888,151 +1652,6 @@ end subroutine med_methods_FB_GetFldPtr !----------------------------------------------------------------------------- - subroutine med_methods_FB_SetFldPtr(FB, fldname, val, rc) - - use ESMF, only : ESMF_FieldBundle, ESMF_Field - - ! input/output variables - type(ESMF_FieldBundle) , intent(in) :: FB - character(len=*) , intent(in) :: fldname - real(R8) , intent(in) :: val - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) => null() - real(R8), pointer :: fldptr2(:,:) => null() - character(len=*), parameter :: subname='(med_methods_FB_SetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_FB_GetFldPtr(FB, fldname, fldptr1, fldptr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = val - elseif (lrank == 2) then - fldptr2 = val - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_SetFldPtr - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, rank, rc) - ! ---------------------------------------------- - ! Get pointer to a state field - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - - type(ESMF_State) , intent(in) :: ST - character(len=*) , intent(in) :: fldname - real(R8) , pointer, intent(inout), optional :: fldptr1(:) - real(R8) , pointer, intent(inout), optional :: fldptr2(:,:) - integer , intent(out), optional :: rank - integer , intent(out), optional :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - character(len=*), parameter :: subname='(med_methods_State_GetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - - if (.not.present(rc)) then - call ESMF_LogWrite(trim(subname)//": ERROR rc not present "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - rc = ESMF_SUCCESS - - call ESMF_StateGet(ST, itemName=trim(fldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Field_GetFldPtr(lfield, & - fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (present(rank)) then - rank = lrank - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_GetFldPtr - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_SetFldPtr(ST, fldname, val, rc) - - use ESMF, only : ESMF_State, ESMF_Field - - type(ESMF_State) , intent(in) :: ST - character(len=*) , intent(in) :: fldname - real(R8), intent(in) :: val - integer , intent(out) :: rc - - ! local variables - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) => null() - real(R8), pointer :: fldptr2(:,:) => null() - character(len=*), parameter :: subname='(med_methods_State_SetFldPtr)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call med_methods_State_GetFldPtr(ST, fldname, fldptr1, fldptr2, lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = val - elseif (lrank == 2) then - fldptr2 = val - else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(fldname), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_SetFldPtr - - !----------------------------------------------------------------------------- - logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) ! input/output variables @@ -2051,8 +1670,7 @@ logical function med_methods_FieldPtr_Compare1(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare1 = .false. - if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & - ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,1) /= lbound(fldptr1,1) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr1 ',lbound(fldptr1),ubound(fldptr1) @@ -2073,11 +1691,11 @@ end function med_methods_FieldPtr_Compare1 logical function med_methods_FieldPtr_Compare2(fldptr1, fldptr2, cstring, rc) - ! input/output variables - real(R8) , pointer, intent(in) :: fldptr1(:,:) - real(R8) , pointer, intent(in) :: fldptr2(:,:) - character(len=*) , intent(in) :: cstring - integer , intent(out) :: rc + ! input/otuput variables + real(R8), pointer , intent(in) :: fldptr1(:,:) + real(R8), pointer , intent(in) :: fldptr2(:,:) + character(len=*) , intent(in) :: cstring + integer , intent(out) :: rc ! local variables character(len=*), parameter :: subname='(med_methods_FieldPtr_Compare2)' @@ -2089,10 +1707,8 @@ logical function med_methods_FieldPtr_Compare2(fldptr1, fldptr2, cstring, rc) rc = ESMF_SUCCESS med_methods_FieldPtr_Compare2 = .false. - if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. & - lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & - ubound(fldptr2,2) /= ubound(fldptr1,2) .or. & - ubound(fldptr2,1) /= ubound(fldptr1,1)) then + if (lbound(fldptr2,2) /= lbound(fldptr1,2) .or. lbound(fldptr2,1) /= lbound(fldptr1,1) .or. & + ubound(fldptr2,2) /= ubound(fldptr1,2) .or. ubound(fldptr2,1) /= ubound(fldptr1,1)) then call ESMF_LogWrite(trim(subname)//": ERROR in data size "//trim(cstring), ESMF_LOGMSG_ERROR, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return write(msgString,*) trim(subname)//': fldptr2 ',lbound(fldptr2),ubound(fldptr2) @@ -2115,12 +1731,16 @@ subroutine med_methods_State_GeomPrint(state, string, rc) use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet + ! input/output variables type(ESMF_State), intent(in) :: state character(len=*), intent(in) :: string integer , intent(out) :: rc - type(ESMF_Field) :: lfield - integer :: fieldcount + ! local variables + type(ESMF_Field) :: lfield + integer :: fieldcount + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() + character(ESMF_MAXSTR) :: name character(len=*),parameter :: subname='(med_methods_State_GeomPrint)' ! ---------------------------------------------- @@ -2131,12 +1751,17 @@ subroutine med_methods_State_GeomPrint(state, string, rc) call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldCount > 0) then - call med_methods_State_GetFieldN(state, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomPrint(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(lfieldnamelist(fieldCount)) + call ESMF_StateGet(State, itemNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(State, itemName=lfieldnamelist(1), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(lfieldnamelist) + call med_methods_Field_GeomPrint(lfield, string, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return else call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) endif ! fieldCount > 0 @@ -2169,9 +1794,7 @@ subroutine med_methods_FB_GeomPrint(FB, string, rc) call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (fieldCount > 0) then - call med_methods_Field_GeomPrint(lfield, string, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else @@ -2190,6 +1813,7 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh use ESMF, only : ESMF_FieldGet, ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_EMPTY + use ESMF, only : ESMF_GeomType_Flag ! input/output variables type(ESMF_Field), intent(in) :: field @@ -2197,11 +1821,12 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) integer , intent(out) :: rc ! local variables - type(ESMF_Grid) :: lgrid - type(ESMF_Mesh) :: lmesh - integer :: lrank - real(R8), pointer :: dataPtr1(:) => null() - real(R8), pointer :: dataPtr2(:,:) => null() + type(ESMF_Grid) :: lgrid + type(ESMF_Mesh) :: lmesh + integer :: lrank + real(R8), pointer :: dataPtr1(:) => null() + real(R8), pointer :: dataPtr2(:,:) => null() + type(ESMF_GeomType_Flag) :: geomtype character(len=*),parameter :: subname='(med_methods_Field_GeomPrint)' ! ---------------------------------------------- @@ -2221,7 +1846,6 @@ subroutine med_methods_Field_GeomPrint(field, string, rc) call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (geomtype == ESMF_GEOMTYPE_GRID) then call ESMF_FieldGet(field, grid=lgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2422,14 +2046,13 @@ subroutine med_methods_Mesh_Print(mesh, string, rc) end subroutine med_methods_Mesh_Print !----------------------------------------------------------------------------- - subroutine med_methods_Grid_Print(grid, string, rc) use ESMF, only : ESMF_Grid, ESMF_DistGrid, ESMF_StaggerLoc use ESMF, only : ESMF_GridGet, ESMF_DistGridGet, ESMF_GridGetCoord use ESMF, only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER - ! input/output variables + ! input/output variabes type(ESMF_Grid) , intent(in) :: grid character(len=*), intent(in) :: string integer , intent(out) :: rc @@ -2464,13 +2087,10 @@ subroutine med_methods_Grid_Print(grid, string, rc) ! get dimCount and tileCount call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, deCount=deCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,*) trim(subname)//":"//trim(string)//": dimCount=", dimCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": tileCount=", tileCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": deCount=", deCount call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) @@ -2482,30 +2102,12 @@ subroutine med_methods_Grid_Print(grid, string, rc) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, & maxIndexPTile=maxIndexPTile, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,*) trim(subname)//":"//trim(string)//": minIndexPTile=", minIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - write (msgString,*) trim(subname)//":"//trim(string)//": maxIndexPTile=", maxIndexPTile call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) - deallocate(minIndexPTile, maxIndexPTile) - ! get staggerlocCount, arbDimCount -! call ESMF_GridGet(grid, staggerlocCount=staggerlocCount, rc=rc) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! write (msgString,*) trim(subname)//":"//trim(string)//": staggerlocCount=", staggerlocCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! call ESMF_GridGet(grid, arbDimCount=arbDimCount, rc=rc) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - -! write (msgString,*) trim(subname)//":"//trim(string)//": arbDimCount=", arbDimCount -! call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) -! if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get rank call ESMF_GridGet(grid, rank=rank, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2534,12 +2136,14 @@ subroutine med_methods_Grid_Print(grid, string, rc) if (rank == 1) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr1,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr1),maxval(fldptr1) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& + n2,n3,minval(fldptr1),maxval(fldptr1) endif if (rank == 2) then call ESMF_GridGetCoord(grid,coordDim=n2,localDE=n3,staggerloc=staggerloc,farrayPtr=fldptr2,rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",n2,n3,minval(fldptr2),maxval(fldptr2) + write (msgString,'(a,2i4,2f16.8)') trim(subname)//":"//trim(staggerstr)//" coord=",& + n2,n3,minval(fldptr2),maxval(fldptr2) endif call ESMF_LogWrite(msgString, ESMF_LOGMSG_INFO) enddo @@ -2553,7 +2157,7 @@ subroutine med_methods_Grid_Print(grid, string, rc) end subroutine med_methods_Grid_Print -!----------------------------------------------------------------------------- + !----------------------------------------------------------------------------- subroutine med_methods_Clock_TimePrint(clock,string,rc) use ESMF , only : ESMF_Clock, ESMF_Time, ESMF_TimeInterval @@ -2614,467 +2218,6 @@ subroutine med_methods_Clock_TimePrint(clock,string,rc) end subroutine med_methods_Clock_TimePrint - !----------------------------------------------------------------------------- - - subroutine med_methods_Mesh_Write(mesh, string, rc) - - use ESMF, only : ESMF_Mesh, ESMF_MeshGet, ESMF_Array, ESMF_ArrayWrite, ESMF_DistGrid - - ! input/output variables - type(ESMF_Mesh) ,intent(in) :: mesh - character(len=*),intent(in) :: string - integer ,intent(out) :: rc - - ! local - integer :: n,l,i,lsize,ndims - character(len=CS) :: name - type(ESMF_DISTGRID) :: distgrid - type(ESMF_Array) :: array - real(R8), pointer :: rawdata(:) => null() - real(R8), pointer :: coord(:) => null() - character(len=*),parameter :: subname='(med_methods_Mesh_Write)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - -#if (1 == 0) - !--- elements --- - - call ESMF_MeshGet(mesh, spatialDim=ndims, numownedElements=lsize, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(rawdata(ndims*lsize)) - allocate(coord(lsize)) - - call ESMF_MeshGet(mesh, elementDistgrid=distgrid, ownedElemCoords=rawdata, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,ndims - name = "unknown" - if (n == 1) name = "lon_element" - if (n == 2) name = "lat_element" - do l = 1,lsize - i = 2*(l-1) + n - coord(l) = rawdata(i) - array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - enddo - - deallocate(rawdata,coord) - - !--- nodes --- - - call ESMF_MeshGet(mesh, spatialDim=ndims, numownedNodes=lsize, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(rawdata(ndims*lsize)) - allocate(coord(lsize)) - - call ESMF_MeshGet(mesh, nodalDistgrid=distgrid, ownedNodeCoords=rawdata, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do n = 1,ndims - name = "unknown" - if (n == 1) name = "lon_nodes" - if (n == 2) name = "lat_nodes" - do l = 1,lsize - i = 2*(l-1) + n - coord(l) = rawdata(i) - array = ESMF_ArrayCreate(distgrid, farrayPtr=coord, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - enddo - - deallocate(rawdata,coord) -#else - call ESMF_LogWrite(trim(subname)//": turned off right now", ESMF_LOGMSG_INFO) -#endif - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Mesh_Write - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_GeomWrite(state, string, rc) - use ESMF, only : ESMF_State, ESMF_Field, ESMF_StateGet - type(ESMF_State), intent(in) :: state - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - type(ESMF_Field) :: lfield - integer :: fieldcount - character(len=*),parameter :: subname='(med_methods_State_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (fieldCount > 0) then - call med_methods_State_getFieldN(state, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomWrite(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) - endif ! fieldCount > 0 - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_State_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_FB_GeomWrite(FB, string, rc) - use ESMF, only : ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet - - type(ESMF_FieldBundle), intent(in) :: FB - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - type(ESMF_Field) :: lfield - integer :: fieldcount - character(len=*),parameter :: subname='(med_methods_FB_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (fieldCount > 0) then - call med_methods_FB_getFieldN(FB, 1, lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GeomWrite(lfield, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": no fields", ESMF_LOGMSG_INFO) - endif ! fieldCount > 0 - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_FB_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_Field_GeomWrite(field, string, rc) - - use ESMF, only : ESMF_Field, ESMF_Grid, ESMF_Mesh, ESMF_FIeldGet, ESMF_FIELDSTATUS_EMPTY - use ESMF, only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID - - ! input/output variables - type(ESMF_Field), intent(in) :: field - character(len=*), intent(in) :: string - integer , intent(out) :: rc - - ! local variables - type(ESMF_Grid) :: lgrid - type(ESMF_Mesh) :: lmesh - character(len=*),parameter :: subname='(med_methods_Field_GeomWrite)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - rc = ESMF_SUCCESS - - call ESMF_FieldGet(field, status=status, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (status == ESMF_FIELDSTATUS_EMPTY) then - call ESMF_LogWrite(trim(subname)//":"//trim(string)//": ERROR field does not have a geom yet ") - rc = ESMF_FAILURE - return - endif - - call ESMF_FieldGet(field, geomtype=geomtype, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (geomtype == ESMF_GEOMTYPE_GRID) then - call ESMF_FieldGet(field, grid=lgrid, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Grid_Write(lgrid, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - elseif (geomtype == ESMF_GEOMTYPE_MESH) then - call ESMF_FieldGet(field, mesh=lmesh, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Mesh_Write(lmesh, string, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Field_GeomWrite - - !----------------------------------------------------------------------------- - - subroutine med_methods_Grid_Write(grid, string, rc) - - use ESMF , only : ESMF_Grid, ESMF_Array, ESMF_GridGetCoord, ESMF_ArraySet - use ESMF , only : ESMF_ArrayWrite, ESMF_GridGetItem, ESMF_GridGetCoord - use ESMF , only : ESMF_GRIDITEM_AREA, ESMF_GRIDITEM_MASK - use ESMF , only : ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER - - ! input/output variables - type(ESMF_Grid) ,intent(in) :: grid - character(len=*),intent(in) :: string - integer ,intent(out) :: rc - - ! local - type(ESMF_Array) :: array - character(len=CS) :: name - character(len=*),parameter :: subname='(med_methods_Grid_Write)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif - - ! -- centers -- - - call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - name = "lon_center" - call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - name = "lat_center" - call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CENTER, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - ! -- corners -- - - call ESMF_GridGetCoord(grid, staggerLoc=ESMF_STAGGERLOC_CORNER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - name = "lon_corner" - call ESMF_GridGetCoord(grid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) - if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - name = "lat_corner" - call ESMF_GridGetCoord(grid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CORNER, array=array, rc=rc) - if (.not. ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - endif - - ! -- mask -- - - name = "mask" - call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_MASK, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_MASK, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//"_"//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - ! -- area -- - - name = "area" - call ESMF_GridGetItem(grid, itemflag=ESMF_GRIDITEM_AREA, staggerLoc=ESMF_STAGGERLOC_CENTER, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, itemflag=ESMF_GRIDITEM_AREA, array=array, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArraySet(array, name=name, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call med_methods_Array_diagnose(array, string=trim(string)//trim(name), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_ArrayWrite(array, trim(string)//"_"//trim(name)//".nc", overwrite=.true., rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - endif - - if (dbug_flag > 10) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - - end subroutine med_methods_Grid_Write - - !----------------------------------------------------------------------------- - - logical function med_methods_Distgrid_Match(distGrid1, distGrid2, rc) - use ESMF, only : ESMF_DistGrid, ESMF_DistGridGet - ! Arguments - type(ESMF_DistGrid), intent(in) :: distGrid1 - type(ESMF_DistGrid), intent(in) :: distGrid2 - integer, intent(out), optional :: rc - - ! Local Variables - integer :: dimCount1, dimCount2 - integer :: tileCount1, tileCount2 - integer, allocatable :: minIndexPTile1(:,:), minIndexPTile2(:,:) - integer, allocatable :: maxIndexPTile1(:,:), maxIndexPTile2(:,:) - integer, allocatable :: elementCountPTile1(:), elementCountPTile2(:) - character(len=*), parameter :: subname='(med_methods_Distgrid_Match)' - ! ---------------------------------------------- - - if (dbug_flag > 10) then - call ESMF_LogWrite(subname//": called", ESMF_LOGMSG_INFO) - endif - - if(present(rc)) rc = ESMF_SUCCESS - med_methods_Distgrid_Match = .true. - - call ESMF_DistGridGet(distGrid1, & - dimCount=dimCount1, tileCount=tileCount1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_DistGridGet(distGrid2, & - dimCount=dimCount2, tileCount=tileCount2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if ( dimCount1 /= dimCount2) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid dimCount MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( tileCount1 /= tileCount2) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid tileCount MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - allocate(elementCountPTile1(tileCount1)) - allocate(elementCountPTile2(tileCount2)) - allocate(minIndexPTile1(dimCount1,tileCount1)) - allocate(minIndexPTile2(dimCount2,tileCount2)) - allocate(maxIndexPTile1(dimCount1,tileCount1)) - allocate(maxIndexPTile2(dimCount2,tileCount2)) - - call ESMF_DistGridGet(distGrid1, & - elementCountPTile=elementCountPTile1, & - minIndexPTile=minIndexPTile1, & - maxIndexPTile=maxIndexPTile1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_DistGridGet(distGrid2, & - elementCountPTile=elementCountPTile2, & - minIndexPTile=minIndexPTile2, & - maxIndexPTile=maxIndexPTile2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if ( ANY((elementCountPTile1 - elementCountPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid elementCountPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( ANY((minIndexPTile1 - minIndexPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid minIndexPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - if ( ANY((maxIndexPTile1 - maxIndexPTile2) .NE. 0) ) then - med_methods_Distgrid_Match = .false. - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": Grid maxIndexPTile MISMATCH ", & - ESMF_LOGMSG_INFO) - endif - endif - - deallocate(elementCountPTile1) - deallocate(elementCountPTile2) - deallocate(minIndexPTile1) - deallocate(minIndexPTile2) - deallocate(maxIndexPTile1) - deallocate(maxIndexPTile2) - - ! TODO: Optionally Check Coordinates - - if (dbug_flag > 10) then - call ESMF_LogWrite(subname//": done", ESMF_LOGMSG_INFO) - endif - - end function med_methods_Distgrid_Match - !================================================================================ subroutine med_methods_State_GetScalar(state, scalar_id, scalar_value, flds_scalar_name, flds_scalar_num, rc) @@ -3194,163 +2337,6 @@ end subroutine med_methods_State_SetScalar !----------------------------------------------------------------------------- - subroutine med_methods_State_UpdateTimestamp(state, time, rc) - - use NUOPC , only : NUOPC_GetStateMemberLists - use ESMF , only : ESMF_State, ESMF_Time, ESMF_Field, ESMF_SUCCESS - - ! input/output variables - type(ESMF_State) , intent(inout) :: state - type(ESMF_Time) , intent(in) :: time - integer , intent(out) :: rc - - ! local variables - integer :: i - type(ESMF_Field),pointer :: fieldList(:) => null() - character(len=*), parameter :: subname='(med_methods_State_UpdateTimestamp)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - call NUOPC_GetStateMemberLists(state, fieldList=fieldList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do i=1, size(fieldList) - call med_methods_Field_UpdateTimestamp(fieldList(i), time, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - enddo - - end subroutine med_methods_State_UpdateTimestamp - - !----------------------------------------------------------------------------- - - subroutine med_methods_Field_UpdateTimestamp(field, time, rc) - - use ESMF, only : ESMF_Field, ESMF_Time, ESMF_TimeGet, ESMF_AttributeSet, ESMF_ATTNEST_ON, ESMF_SUCCESS - - ! input/output variables - type(ESMF_Field) , intent(inout) :: field - type(ESMF_Time) , intent(in) :: time - integer , intent(out) :: rc - - ! local variables - integer :: yy, mm, dd, h, m, s, ms, us, ns - character(len=*), parameter :: subname='(med_methods_Field_UpdateTimestamp)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - call ESMF_TimeGet(time, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, ms=ms, us=us, & - ns=ns, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_AttributeSet(field, & - name="TimeStamp", valueList=(/yy,mm,dd,h,m,s,ms,us,ns/), & - convention="NUOPC", purpose="Instance", & - attnestflag=ESMF_ATTNEST_ON, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - end subroutine med_methods_Field_UpdateTimestamp - - !----------------------------------------------------------------------------- - - subroutine med_methods_State_FldDebug(state, flds_scalar_name, prefix, ymd, tod, logunit, rc) - - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_Field, ESMF_FieldGet - - ! input/output variables - type(ESMF_State) :: state - character(len=*) , intent(in) :: flds_scalar_name - character(len=*) , intent(in) :: prefix - integer , intent(in) :: ymd - integer , intent(in) :: tod - integer , intent(in) :: logunit - integer , intent(out) :: rc - - ! local variables - integer :: n, nfld, ungridded_index - integer :: lsize - real(R8), pointer :: dataPtr1d(:) => null() - real(R8), pointer :: dataPtr2d(:,:) => null() - integer :: fieldCount - integer :: ungriddedUBound(1) - integer :: gridToFieldMap(1) - character(len=ESMF_MAXSTR) :: string - type(ESMF_Field) , allocatable :: lfields(:) - integer , allocatable :: dimCounts(:) - character(len=ESMF_MAXSTR) , allocatable :: fieldNameList(:) - !----------------------------------------------------- - - ! Determine the list of fields and the dimension count for each field - call ESMF_StateGet(state, itemCount=fieldCount, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - allocate(fieldNameList(fieldCount)) - allocate(lfields(fieldCount)) - allocate(dimCounts(fieldCount)) - - call ESMF_StateGet(state, itemNameList=fieldNameList, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - do nfld=1, fieldCount - call ESMF_StateGet(state, itemName=trim(fieldNameList(nfld)), field=lfields(nfld), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfields(nfld), dimCount=dimCounts(nfld), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - - ! Determine local size of field - do nfld=1, fieldCount - if (dimCounts(nfld) == 1) then - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize = size(dataPtr1d) - exit - end if - end do - - ! Write out debug output - do n = 1,lsize - do nfld=1, fieldCount - if (dimCounts(nfld) == 1) then - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (trim(fieldNameList(nfld)) /= flds_scalar_name .and. dataPtr1d(n) /= 0.) then - string = trim(prefix) // ' ymd, tod, index, '// trim(fieldNameList(nfld)) //' = ' - write(logunit,100) trim(string), ymd, tod, n, dataPtr1d(n) - end if - else if (dimCounts(nfld) == 2) then - call ESMF_FieldGet(lfields(nfld), ungriddedUBound=ungriddedUBound, gridtoFieldMap=gridToFieldMap, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfields(nfld), farrayPtr=dataPtr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ungridded_index = 1,ungriddedUBound(1) - if (trim(fieldNameList(nfld)) /= flds_scalar_name) then - string = trim(prefix) // ' ymd, tod, lev, index, '// trim(fieldNameList(nfld)) //' = ' - if (gridToFieldMap(1) == 1) then - if (dataPtr2d(n,ungridded_index) /= 0.) then - write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(n,ungridded_index) - end if - else if (gridToFieldMap(1) == 2) then - if (dataPtr2d(ungridded_index,n) /= 0.) then - write(logunit,101) trim(string), ymd, tod, ungridded_index, n, dataPtr2d(ungridded_index,n) - end if - end if - end if - end do - end if - end do - end do -100 format(a60,3(i8,2x),d21.14) -101 format(a60,4(i8,2x),d21.14) - - deallocate(fieldNameList) - deallocate(lfields) - deallocate(dimCounts) - - end subroutine med_methods_State_FldDebug - - !----------------------------------------------------------------------------- - subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) ! ---------------------------------------------- @@ -3385,73 +2371,4 @@ subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) end subroutine med_methods_FB_getNumFlds - !----------------------------------------------------------------------------- - - subroutine med_methods_States_GetSharedFlds(State1, State2, flds_scalar_name, fldnames_shared, rc) - - ! ---------------------------------------------- - ! Get shared Fld names between State1 and State2 and - ! allocate the return array fldnames_shared - ! ---------------------------------------------- - - use ESMF, only : ESMF_State, ESMF_StateGet, ESMF_MAXSTR - - ! input/output variables - type(ESMF_State) , intent(in) :: State1 - type(ESMF_State) , intent(in) :: State2 - character(len=*) , intent(in) :: flds_scalar_name - character(len=ESMF_MAXSTR) , pointer :: fldnames_shared(:) - integer , intent(inout) :: rc - - ! local variables - integer :: ncnt1, ncnt2 - integer :: n1, n2, nshr - character(len=ESMF_MAXSTR), allocatable :: fldnames1(:) - character(len=ESMF_MAXSTR), allocatable :: fldnames2(:) - character(len=*), parameter :: subname='(med_methods_States_GetSharedFlds)' - ! ---------------------------------------------- - - rc = ESMF_SUCCESS - - if (associated(fldnames_shared)) then - call ESMF_LogWrite(trim(subname)//": ERROR fldnames_shared must not be associated ", ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - RETURN - end if - - call ESMF_StateGet(State1, itemCount=ncnt1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldnames1(ncnt1)) - call ESMF_StateGet(State1, itemNameList=fldnames1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call ESMF_StateGet(State2, itemCount=ncnt2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fldnames2(ncnt2)) - call ESMF_StateGet(State2, itemNameList=fldnames2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - nshr = 0 - do n1 = 1,ncnt1 - do n2 = 1,ncnt2 - if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then - nshr = nshr + 1 - end if - end do - end do - allocate(fldnames_shared(nshr)) - - nshr = 0 - do n1 = 1,ncnt1 - do n2 = 1,ncnt2 - if (trim(fldnames1(n1)) == trim(fldnames2(n2)) .and. trim(fldnames1(n1)) /= flds_scalar_name) then - nshr = nshr + 1 - fldnames_shared(nshr) = trim(fldnames1(n1)) - exit - end if - end do - end do - - end subroutine med_methods_States_GetSharedFlds - end module med_methods_mod From 2268e9ab15573aa8febb011b6853e1e4c86ed610 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 1 Nov 2020 17:12:19 -0700 Subject: [PATCH 144/206] fixed bug for nems_orig --- mediator/med_map_mod.F90 | 33 ++++++++++++++-------------- mediator/med_phases_prep_lnd_mod.F90 | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 627c3f91b..85e9a720d 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -135,7 +135,7 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, llogunit, rc) if (.not. mapexists) then mapfile = trim(fldListFr(n1)%flds(nf)%mapfile(n2)) call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, & - mapindex, is_local%wrap%rh(n1,n2,mapindex), mapfile=trim(mapfile), rc=rc) + mapindex, is_local%wrap%rh(n1,n2,:), mapfile=trim(mapfile), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -191,7 +191,7 @@ subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapin call med_methods_FB_getFieldN(FBDst, 1, flddst, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle(n1,n2,mapindex), rc=rc) + call med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle(n1,n2,:), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then @@ -202,7 +202,7 @@ subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapin end subroutine med_map_routehandles_initfrom_fieldbundle !================================================================================ - subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandle, mapfile, rc) + subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, routehandles, mapfile, rc) use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandlePrint, ESMF_Field, ESMF_MAXSTR use ESMF , only : ESMF_PoleMethod_Flag, ESMF_POLEMETHOD_ALLAVG @@ -210,7 +210,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, use ESMF , only : ESMF_REGRIDMETHOD_BILINEAR, ESMF_REGRIDMETHOD_PATCH use ESMF , only : ESMF_REGRIDMETHOD_CONSERVE, ESMF_NORMTYPE_DSTAREA, ESMF_NORMTYPE_FRACAREA use ESMF , only : ESMF_UNMAPPEDACTION_IGNORE, ESMF_REGRIDMETHOD_NEAREST_STOD - use esmFlds , only : mapbilnr, mapconsf, mapconsd, mappatch, mapfcopy + use esmFlds , only : mapbilnr, mapconsf, mapconsd, mappatch, mappatch_uv3d, mapfcopy use esmFlds , only : mapunset, mapnames, nmappers use esmFlds , only : mapnstod, mapnstod_consd, mapnstod_consf, mapnstod_consd use esmFlds , only : ncomps, compatm, compice, compocn, compname @@ -224,7 +224,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, type(ESMF_Field) , intent(inout) :: fldsrc type(ESMF_Field) , intent(inout) :: flddst integer , intent(in) :: mapindex - type(ESMF_RouteHandle) , intent(inout) :: RouteHandle + type(ESMF_RouteHandle) , intent(inout) :: routehandles(:) character(len=*), optional , intent(in) :: mapfile integer , intent(out) :: rc @@ -284,7 +284,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (mastertask) then write(logunit,'(A)') trim(subname)//' creating RH redist for '//trim(string) end if - call ESMF_FieldRedistStore(fldsrc, flddst, routehandle=routehandle, & + call ESMF_FieldRedistStore(fldsrc, flddst, routehandle=routehandles(mapfcopy), & ignoreUnmatchedIndices = .true., rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (lmapfile /= 'unset') then @@ -292,7 +292,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//& ' via input file '//trim(mapfile)//' for '//trim(string) end if - call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, routehandle=routehandle, & + call ESMF_FieldSMMStore(fldsrc, flddst, mapfile, routehandle=routehandles(mapindex), & ignoreUnmatchedIndices=.true., & srcTermProcessing=srcTermProcessing_Value, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -300,7 +300,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (mastertask) then write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) end if - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandles(mapbilnr), & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & @@ -313,7 +313,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (mastertask) then write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) end if - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandles(mapconsf), & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & @@ -327,7 +327,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (mastertask) then write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) end if - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandles(mapconsd), & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_CONSERVE, & @@ -337,11 +337,11 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - else if (mapindex == mappatch) then + else if (mapindex == mappatch .or. mapindex == mappatch_uv3d) then if (mastertask) then write(logunit,'(A)') trim(subname)//' creating RH '//trim(mapname)//' for '//trim(string) end if - call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandle, & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandles(mappatch), & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_PATCH, & @@ -362,8 +362,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, ! consd_nstod method requires a second routehandle if (mapindex == mapnstod .or. mapindex == mapnstod_consd .or. mapindex == mapnstod_consf) then - call ESMF_FieldRegridStore(fldsrc, flddst, & - routehandle=routehandle, & + call ESMF_FieldRegridStore(fldsrc, flddst, routehandle=routehandles(mapnstod), & srcMaskValues=(/srcMaskValue/), & dstMaskValues=(/dstMaskValue/), & regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD, & @@ -387,7 +386,7 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, if (mastertask) then write(logunit,'(a)') trim(subname)//trim(string)//": printing RH for "//trim(mapname) end if - call ESMF_RouteHandlePrint(routehandle, rc=rc) + call ESMF_RouteHandlePrint(routehandles(mapindex), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return endif @@ -767,7 +766,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldIsCreated use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet use ESMF , only : ESMF_FieldRedist, ESMF_RouteHandle - use esmFlds , only : nmappers, mapfcopy, mappatch_uv3d + use esmFlds , only : nmappers, mapfcopy, mappatch_uv3d, mappatch use med_internalstate_mod , only : packed_data_type ! input/output variables @@ -868,7 +867,7 @@ subroutine med_map_field_packed(FBSrc, FBDst, FBFracSrc, field_normOne, packed_d if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleGet(FBDst, fieldName='Sa_v', field=vdst, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_uv_cart3d(usrc, vsrc, udst, vdst, routehandles, mapindex, rc=rc) + call med_map_uv_cart3d(usrc, vsrc, udst, vdst, routehandles, mappatch, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return else if (mapindex == mapfcopy) then diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 7508431dc..d8290aa37 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -282,7 +282,7 @@ subroutine map_glc2lnd_init(gcomp, rc) ! 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, routehandle=is_local%wrap%rh(compglc,complnd,mapconsd), rc=rc) + mapindex=mapconsd, routehandles=is_local%wrap%rh(compglc,complnd,:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if From 7c22abecb18276c504d7b232d69ffd8dd7b372db Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 3 Nov 2020 21:34:25 -0700 Subject: [PATCH 145/206] backing out changes to med_io_mod.F90 should fix restart problem --- mediator/med_io_mod.F90 | 356 +++++++++++++++++++++++----------------- 1 file changed, 201 insertions(+), 155 deletions(-) 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 From 771eacdf691779d005c52a08eba677ec3c9ebf70 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Wed, 4 Nov 2020 16:05:39 -0500 Subject: [PATCH 146/206] update med_io_mod.F90 for latest fix --- .gitmodules | 4 - CMakeLists.txt | 48 ------ Makefile | 22 +-- cmake/FindESMF.cmake | 47 ------ cmake/FindPIO.cmake | 103 ------------ cmake/LibCheck.cmake | 104 ------------ cmake/LibFind.cmake | 333 --------------------------------------- mediator/CMakeLists.txt | 35 ---- mediator/Makefile | 4 +- nems/lib/Makefile | 52 ------ nems/lib/ParallelIO | 1 - nems/util/CMakeLists.txt | 7 - nems/util/Makefile | 8 +- 13 files changed, 9 insertions(+), 759 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 cmake/FindESMF.cmake delete mode 100644 cmake/FindPIO.cmake delete mode 100644 cmake/LibCheck.cmake delete mode 100644 cmake/LibFind.cmake delete mode 100644 mediator/CMakeLists.txt delete mode 100644 nems/lib/Makefile delete mode 160000 nems/lib/ParallelIO delete mode 100644 nems/util/CMakeLists.txt diff --git a/.gitmodules b/.gitmodules index cab59ea7b..9131d0ff2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "nems/lib/ParallelIO"] - path = nems/lib/ParallelIO - url = https://github.com/NCAR/ParallelIO.git - branch = master [submodule "nems/lib/genf90"] path = nems/lib/genf90 url = https://github.com/PARALLELIO/genf90 diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 14e0ef046..000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -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/Makefile b/Makefile index e778090f3..0f9eb808a 100644 --- a/Makefile +++ b/Makefile @@ -27,9 +27,6 @@ $(info INTERNAL_PIO_INIT is set to $(INTERNAL_PIO_INIT)) MEDIATOR_DIR := $(BASE_DIR)/mediator LIBRARY_MEDIATOR := $(MEDIATOR_DIR)/libcmeps.a LIBRARY_UTIL := $(BASE_DIR)/nems/util/libcmeps_util.a -PIO_INSTALL_DIR := $(BASE_DIR)/nems/lib/ParallelIO/install -PIO_INSTALL_LIBS := $(PIO_INSTALL_DIR)/lib/libpiof.a -PIO_INCLUDE_DIR := $(PIO_INSTALL_DIR)/include all default: install @@ -44,11 +41,9 @@ else @echo "ESMF_DEP_FRONT = MED" >> cmeps.mk.install @echo "ESMF_DEP_INCPATH = $(INSTALLDIR)/include" >> cmeps.mk.install @echo "ESMF_DEP_CMPL_OBJS = " >> cmeps.mk.install - @echo "ESMF_DEP_LINK_OBJS = $(INSTALLDIR)/libcmeps.a $(INSTALLDIR)/libcmeps_util.a $(INSTALLDIR)/libpiof.a $(INSTALLDIR)/libpioc.a $(PNETCDF_LD_OPTS)" >> cmeps.mk.install + @echo "ESMF_DEP_LINK_OBJS = $(INSTALLDIR)/libcmeps.a $(INSTALLDIR)/libcmeps_util.a $(PIO_ROOT)/lib/libpiof.a $(PIO_ROOT)/lib/libpioc.a $(PNETCDF_LD_OPTS)" >> cmeps.mk.install mkdir -p $(INSTALLDIR) mkdir -p $(INSTALLDIR)/include - cp -f $(PIO_INSTALL_DIR)/lib/*.a $(INSTALLDIR) - cp -f $(PIO_INSTALL_DIR)/include/* $(INSTALLDIR)/include cp -f $(LIBRARY_UTIL) $(INSTALLDIR) cp -f $(LIBRARY_MEDIATOR) $(INSTALLDIR) cp -f mediator/*.mod $(INSTALLDIR)/include @@ -60,21 +55,14 @@ $(LIBRARY_MEDIATOR): $(LIBRARY_UTIL) .FORCE cd mediator ;\ exec $(MAKE) PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) INTERNAL_PIO_INIT=$(INTERNAL_PIO_INIT) -$(LIBRARY_UTIL): $(PIO_INSTALL_LIBS) .FORCE +$(LIBRARY_UTIL): .FORCE cd nems/util ;\ - exec $(MAKE) PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) - -$(PIO_INSTALL_LIBS): - cd nems/lib ;\ - exec $(MAKE) install FC="$(FC)" CC="$(CC)" CXX="$(CXX)" PIO_INSTALL_DIR=$(PIO_INSTALL_DIR) + exec $(MAKE) .FORCE: clean: cd mediator; \ - exec $(MAKE) clean PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) + exec $(MAKE) clean cd nems/util; \ - exec $(MAKE) clean PIO_INCLUDE_DIR=$(PIO_INCLUDE_DIR) - cd nems/lib; \ - exec $(MAKE) clean PIO_INSTALL_DIR=$(PIO_INSTALL_DIR) - + exec $(MAKE) clean diff --git a/cmake/FindESMF.cmake b/cmake/FindESMF.cmake deleted file mode 100644 index 175a39488..000000000 --- a/cmake/FindESMF.cmake +++ /dev/null @@ -1,47 +0,0 @@ - -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 deleted file mode 100644 index 2a7af648a..000000000 --- a/cmake/FindPIO.cmake +++ /dev/null @@ -1,103 +0,0 @@ -# - 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 deleted file mode 100644 index 3f12bdf79..000000000 --- a/cmake/LibCheck.cmake +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index 61cd93aa3..000000000 --- a/cmake/LibFind.cmake +++ /dev/null @@ -1,333 +0,0 @@ -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 deleted file mode 100644 index be5b89670..000000000 --- a/mediator/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -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) - -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 574d19357..acf5cb68c 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -22,8 +22,8 @@ all default: $(LIBRARY) $(LIBRARY): $(OBJ) $(AR) $(ARFLAGS) $@ $? -%.o: %.F90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.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 diff --git a/nems/lib/Makefile b/nems/lib/Makefile deleted file mode 100644 index 0da2ec4e0..000000000 --- a/nems/lib/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -ifndef NETCDF -ifndef PNETCDF -$(error NETCDF or PNETCDF must be set to build PIO) -endif -endif - -ifndef PIO_INSTALL_DIR -$(error PIO_INSTALL_DIR must be set) -endif - -BASE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) -PIO_SRC_DIR := "$(BASE_DIR)/ParallelIO" -PIO_BUILD_DIR := "$(BASE_DIR)/ParallelIO/build" - -CMAKE_ENV_VARS := CC="$(CC)" \ - CXX="$(CXX)" \ - FC="$(FC)" - -CMAKE_OPTS := -D CMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -D PIO_ENABLE_TESTS:BOOL=OFF \ - -D PIO_ENABLE_TIMING:BOOL=OFF \ - -D PIO_USE_MALLOC:BOOL=ON \ - -D GENF90_PATH=$(BASE_DIR)/genf90 \ - -D USER_CMAKE_MODULE_PATH=$(PIO_SRC_DIR)/cmake \ - -D CMAKE_INSTALL_PREFIX=$(PIO_INSTALL_DIR) - -ifdef NETCDF -CMAKE_OPTS += -D NetCDF_PATH:PATH=$(NETCDF) -endif - -ifdef PNETCDF -CMAKE_OPTS += -D PnetCDF_PATH:STRING=$(PNETCDF) -else -CMAKE_OPTS += -D WITH_PNETCDF=OFF -endif - -.PHONY: install build clean - -install: build - -build: $(PIO_BUILD_DIR)/Makefile - cd $(PIO_BUILD_DIR); \ - exec $(MAKE) install - -$(PIO_BUILD_DIR)/Makefile: - mkdir -p $(PIO_BUILD_DIR); \ - cd $(PIO_BUILD_DIR); \ - $(CMAKE_ENV_VARS) cmake $(CMAKE_OPTS) ../ - -clean: - rm -rf $(PIO_BUILD_DIR) - rm -rf $(PIO_INSTALL_DIR) diff --git a/nems/lib/ParallelIO b/nems/lib/ParallelIO deleted file mode 160000 index 86ad4463a..000000000 --- a/nems/lib/ParallelIO +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 86ad4463ab46e706aca632c2c4c2ffd48854113b diff --git a/nems/util/CMakeLists.txt b/nems/util/CMakeLists.txt deleted file mode 100644 index e99cfda83..000000000 --- a/nems/util/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -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}) diff --git a/nems/util/Makefile b/nems/util/Makefile index 665bcb136..58b97df4f 100644 --- a/nems/util/Makefile +++ b/nems/util/Makefile @@ -4,10 +4,6 @@ endif include $(ESMFMKFILE) -ifndef PIO_INCLUDE_DIR -$(error PIO_INCLUDE_DIR should point to PIO include directory.) -endif - LIBRARY = libcmeps_util.a OBJ1= \ @@ -30,10 +26,10 @@ $(LIBRARY): $(OBJ1) %.o: %.F90.in perl genf90.pl $< > $(@:.o=.F90) - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) -I$(PIO_INCLUDE_DIR) -DFORTRANUNDERSCORE -DCPRINTEL $(@:.o=.F90) + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) -I$(PIO_ROOT)/include -DFORTRANUNDERSCORE -DCPRINTEL $(@:.o=.F90) %.o: %.F90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) -I$(PIO_INCLUDE_DIR) -I. $*.F90 + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) -I$(PIO_ROOT)/include -I. $*.F90 clean: $(RM) -f $(LIBRARY) *.f90 *.i90 *.o *.mod From 6770ed6a061b1111ed0e29db4c79ef3bd04acd71 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 6 Nov 2020 15:57:12 -0700 Subject: [PATCH 147/206] fixed the order of glc mapping and land merge - the calls were incorrect - and added new optimizations for performance --- cime_config/runseq/runseq_general.py | 11 +- mediator/med.F90 | 74 ++++++++- mediator/med_diag_mod.F90 | 216 ++++++++++++++++++--------- mediator/med_map_mod.F90 | 3 - mediator/med_phases_prep_lnd_mod.F90 | 81 ++++++++-- 5 files changed, 282 insertions(+), 103 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index e0a4cfb36..e68a57624 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -88,10 +88,12 @@ def gen_runseq(case, coupling_times): 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_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) runseq.add_action("MED med_phases_prep_ocn_merge" , med_to_ocn) runseq.add_action("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset) + runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) + runseq.add_action("MED med_phases_prep_lnd" , med_to_lnd) runseq.add_action("MED -> LND :remapMethod=redist" , med_to_lnd) runseq.add_action("MED med_phases_prep_ice" , med_to_ice) @@ -108,18 +110,21 @@ def gen_runseq(case, coupling_times): 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) else: runseq.add_action("OCN -> MED :remapMethod=redist" , 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_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("MED med_phases_diag_ocn" , run_ocn and diag_mode) + runseq.add_action("LND -> MED :remapMethod=redist" , run_lnd) runseq.add_action("ICE -> MED :remapMethod=redist" , run_ice) runseq.add_action("MED med_phases_diag_ice_ice2med" , run_ice and diag_mode) diff --git a/mediator/med.F90 b/mediator/med.F90 index d65d935f1..cfb71f5cf 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -73,7 +73,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 @@ -190,6 +190,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 +204,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,6 +218,9 @@ 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 @@ -234,6 +243,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_prep_ocn_map", specRoutine=med_phases_prep_ocn_map, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_prep_ocn_map", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_prep_ocn_merge"/), userRoutine=mediator_routine_Run, rc=rc) @@ -241,6 +253,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_prep_ocn_merge", specRoutine=med_phases_prep_ocn_merge, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_prep_ocn_merge", specRoutine=NUOPC_NoOp, rc=rc) + 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) @@ -248,6 +263,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_prep_ocn_accum_fast", specRoutine=med_phases_prep_ocn_accum_fast, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_prep_ocn_accum_fast", specRoutine=NUOPC_NoOp, rc=rc) + 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) @@ -295,6 +313,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_prep_rof_accum", specRoutine=med_phases_prep_rof_accum, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_prep_rof_accum", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! prep routines for wav @@ -324,6 +345,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_prep_glc_accum", specRoutine=med_phases_prep_glc_accum, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_prep_glc_accum", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! phase routine for ocean albedo computation @@ -335,6 +359,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 +373,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 +387,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 +400,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) @@ -2382,15 +2442,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..f303c3fc9 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -22,16 +22,16 @@ 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_FieldBundleGet, 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 perf_mod , only : t_startf, t_stopf implicit none private @@ -380,6 +380,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 +409,6 @@ end function get_diag_attribute end subroutine med_diag_init !=============================================================================== - subroutine med_diag_zero( gcomp, mode, rc) ! ------------------------------------------------------------------ @@ -428,6 +428,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 +496,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 +515,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 +544,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 +563,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 +589,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,11 +601,17 @@ 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 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), '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 FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', fldptr1=ifrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ofrac', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', fldptr1=ofrac, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compatm)%areas @@ -690,10 +702,9 @@ subroutine med_phases_diag_atm(gcomp, rc) f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + contains subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -709,21 +720,26 @@ 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() + real(r8) :: term ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=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) + term = areas(n)*data(n) + budget(nf,c_atm_send,ip) = budget(nf,c_atm_send,ip) - term*afrac(n) + budget(nf,c_lnd_asend,ip) = budget(nf,c_lnd_asend,ip) + term*lfrac(n) + budget(nf,c_ocn_asend,ip) = budget(nf,c_ocn_asend,ip) + term*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_asend,ip) = budget(nf,c_inh_asend,ip) + term*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_asend,ip) = budget(nf,c_ish_asend,ip) + term*ifrac(n) end if end do end if @@ -747,11 +763,14 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data, dim=2) @@ -788,10 +807,9 @@ end subroutine diag_atm_wiso end subroutine med_phases_diag_atm !=============================================================================== - subroutine med_phases_diag_lnd( gcomp, rc) - ! ------------------------------------------------------------------ + ! ------------------------------------------------------------------ ! Compute global lnd input/output flux diagnostics ! ------------------------------------------------------------------ @@ -806,9 +824,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 +836,9 @@ 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 ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), '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 areas => is_local%wrap%mesh_info(complnd)%areas @@ -887,10 +909,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 +926,15 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -937,12 +962,15 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -962,7 +990,6 @@ end subroutine diag_lnd_wiso end subroutine med_phases_diag_lnd !=============================================================================== - subroutine med_phases_diag_rof( gcomp, rc) ! ------------------------------------------------------------------ @@ -982,6 +1009,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 +1059,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 +1076,15 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -1081,12 +1112,15 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1106,7 +1140,6 @@ end subroutine diag_rof_wiso end subroutine med_phases_diag_rof !=============================================================================== - subroutine med_phases_diag_glc( gcomp, rc) ! ------------------------------------------------------------------ @@ -1126,6 +1159,7 @@ subroutine med_phases_diag_glc( gcomp, rc) character(*), parameter :: subName = '(med_phases_diag_glc) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) @@ -1147,10 +1181,9 @@ subroutine med_phases_diag_glc( gcomp, 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_glc(FB, fldname, nf, ic, areas, budget, minus, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1163,11 +1196,14 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -1183,7 +1219,6 @@ end subroutine diag_glc end subroutine med_phases_diag_glc !=============================================================================== - subroutine med_phases_diag_ocn( gcomp, rc) ! ------------------------------------------------------------------ @@ -1205,18 +1240,24 @@ 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 ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), '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(compocn), 'ofrac', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ofrac', fldptr1=ofrac, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(sfrac(size(ofrac))) sfrac(:) = ifrac(:) + ofrac(:) @@ -1234,7 +1275,9 @@ subroutine med_phases_diag_ocn( gcomp, rc) 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) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(ifrac) wgt_o = areas(n) * ofrac(n) @@ -1293,10 +1336,10 @@ 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 - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + + contains subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1309,11 +1352,14 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -1337,12 +1383,14 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1356,7 +1404,6 @@ end subroutine diag_ocn_wiso end subroutine med_phases_diag_ocn !=============================================================================== - subroutine med_phases_diag_ice_ice2med( gcomp, rc) ! ------------------------------------------------------------------ @@ -1376,18 +1423,24 @@ 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 ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), '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 FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), 'ofrac', field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1427,10 +1480,10 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) 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', & f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, areas, lats, ifrac, budget_local, rc=rc) - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + + contains subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1445,11 +1498,14 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data) @@ -1491,12 +1547,14 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1518,11 +1576,9 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac end if end subroutine diag_ice_wiso - end subroutine med_phases_diag_ice_ice2med !=============================================================================== - subroutine med_phases_diag_ice_med2ice( gcomp, rc) ! ------------------------------------------------------------------ @@ -1544,18 +1600,24 @@ 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 ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), '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), 'ofrac', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1583,8 +1645,11 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) 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) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), 'Fioo_q', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(data) wgt_o = areas(n) * ofrac(n) wgt_i = areas(n) * ifrac(n) @@ -1607,10 +1672,9 @@ 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 - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + contains subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1625,11 +1689,14 @@ 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data) @@ -1671,12 +1738,14 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac ! 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) + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1701,7 +1770,6 @@ end subroutine diag_ice_wiso end subroutine med_phases_diag_ice_med2ice !=============================================================================== - subroutine med_phases_diag_print(gcomp, rc) ! ------------------------------------------------------------------ @@ -1756,10 +1824,12 @@ subroutine med_phases_diag_print(gcomp, rc) write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) endif #endif + if(firstcall) then firstcall = .false. return endif + sumdone = .false. do ip = 1,size(budget_diags%periods) @@ -1848,7 +1918,6 @@ subroutine med_phases_diag_print(gcomp, rc) end subroutine med_phases_diag_print !=============================================================================== - subroutine med_diag_print_atm(data, ip, cdate, curr_tod) ! --------------------------------------------------------- @@ -1997,7 +2066,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) ! --------------------------------------------------------- @@ -2160,7 +2228,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 +2265,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 +2420,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_map_mod.F90 b/mediator/med_map_mod.F90 index 85e9a720d..69e1947f4 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -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 diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index d8290aa37..63cdf85f7 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -5,6 +5,7 @@ module med_phases_prep_lnd_mod !----------------------------------------------------------------------------- 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 @@ -57,6 +58,8 @@ module med_phases_prep_lnd_mod ! 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. + character(*) , parameter :: u_FILE_u = & __FILE__ @@ -76,6 +79,8 @@ subroutine med_phases_prep_lnd(gcomp, rc) integer :: n1,ncnt real(r8) :: nextsw_cday logical :: first_call = .true. + logical :: isPresent + character(CL) :: cvalue character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- @@ -91,6 +96,20 @@ subroutine med_phases_prep_lnd(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! determine if coupling to CISM is 2-way + if (first_call) then + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", value=cvalue, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read (cvalue,*) cism_evolve + if (mastertask) then + write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve + end if + end if + end if + ! 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 @@ -104,8 +123,10 @@ subroutine med_phases_prep_lnd(gcomp, rc) ! map to create FBimp(:,complnd) !--------------------------------------- + call t_startf('MED:'//trim(subname)//' map') do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,complnd)) then + ! Skip glc here and handle it below + if (is_local%wrap%med_coupling_active(n1,complnd) .and. n1 /= compglc) then call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,complnd), & @@ -116,6 +137,44 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do + call t_stopf('MED:'//trim(subname)//' map') + + ! 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 + call t_startf('MED:'//trim(subname)//' glc2lnd init') + if (first_call) then + call map_glc2lnd_init(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call t_stopf('MED:'//trim(subname)//' glc2lnd init') + + ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) + if (cism_evolve) then + call t_startf('MED:'//trim(subname)//' glc2lnd ') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc,compglc), & + FBDst=is_local%wrap%FBImp(compglc,complnd), & + FBFracSrc=is_local%wrap%FBFrac(compglc), & + field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & + packed_data=is_local%wrap%packed_data(compglc,complnd,:), & + routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd') + else if (first_call) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc,compglc), & + FBDst=is_local%wrap%FBImp(compglc,complnd), & + FBFracSrc=is_local%wrap%FBFrac(compglc), & + field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & + packed_data=is_local%wrap%packed_data(compglc,complnd,:), & + routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if !--------------------------------------- ! auto merges to create FBExp(complnd) @@ -123,6 +182,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) ! 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,21 +190,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) is_local%wrap%FBImp(:,complnd), & fldListTo(complnd), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! 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 + call t_stopf('MED:'//trim(subname)//' merge') !--------------------------------------- ! update scalar data @@ -152,6 +198,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then + call t_startf('MED:'//trim(subname)//' nextsw_cday') ! send nextsw_cday to land - first obtain it from atm import call State_GetScalar(& scalar_value=nextsw_cday, & @@ -167,6 +214,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) 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 t_stopf('MED:'//trim(subname)//' nextsw_cday') end if ! diagnose @@ -177,6 +225,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) end if end if + ! Reset first call logical first_call = .false. if (dbug_flag > 5) then From fd5e23c30a933e156ca67aa79ddc4b63ed381461 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 9 Nov 2020 20:10:57 -0700 Subject: [PATCH 148/206] fixed bug in budget calculations --- mediator/med_diag_mod.F90 | 281 +++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 94 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index f303c3fc9..faeea6e50 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -39,6 +39,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 +47,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 +56,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 +93,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 +206,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) @@ -618,11 +621,13 @@ subroutine med_phases_diag_atm(gcomp, rc) 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) @@ -635,32 +640,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 @@ -684,28 +692,67 @@ 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 + 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 ( FB_fldchk(FB, trim(fldname), rc=rc)) then + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1,size(data) + 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_arecv,ip) = budget(nf,c_inh_arecv,ip) + areas(n)*data(n)*ifrac(n) + else + 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_recv + + 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 @@ -732,20 +779,19 @@ subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, bu if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data) - term = areas(n)*data(n) - budget(nf,c_atm_send,ip) = budget(nf,c_atm_send,ip) - term*afrac(n) - budget(nf,c_lnd_asend,ip) = budget(nf,c_lnd_asend,ip) + term*lfrac(n) - budget(nf,c_ocn_asend,ip) = budget(nf,c_ocn_asend,ip) + term*ofrac(n) + 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) + term*ifrac(n) + 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) + term*ifrac(n) + 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 + end subroutine diag_atm_send - subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & + 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 @@ -802,7 +848,66 @@ 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 ( FB_fldchk(FB, trim(fldname), rc=rc)) then + call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=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 @@ -1315,7 +1420,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) @@ -1340,7 +1446,8 @@ subroutine med_phases_diag_ocn( gcomp, rc) 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 @@ -1349,6 +1456,7 @@ 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 @@ -1363,7 +1471,11 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, 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 @@ -1457,34 +1569,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 @@ -1498,7 +1611,7 @@ 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 + type(ESMF_Field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS @@ -1529,9 +1642,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 @@ -1544,13 +1657,13 @@ 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 + type(ESMF_Field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS + if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1574,7 +1687,7 @@ 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 @@ -1634,22 +1747,16 @@ 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_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) + 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) if ( FB_fldchk(is_local%wrap%FBExp(compice), 'Fioo_q', rc=rc)) then call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), 'Fioo_q', field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayptr=data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(data) wgt_o = areas(n) * ofrac(n) wgt_i = areas(n) * ifrac(n) @@ -1672,10 +1779,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 @@ -1684,8 +1797,6 @@ 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 @@ -1693,36 +1804,24 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS + ip = period_inst if ( FB_fldchk(FB, trim(fldname), rc=rc)) then call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayptr=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 @@ -1733,7 +1832,6 @@ 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 @@ -1750,22 +1848,16 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac 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 @@ -1825,7 +1917,7 @@ subroutine med_phases_diag_print(gcomp, rc) endif #endif - if(firstcall) then + if (firstcall) then firstcall = .false. return endif @@ -1908,6 +2000,7 @@ subroutine med_phases_diag_print(gcomp, rc) deallocate(datagpr) endif ! output_level > 0 and mastertask end if ! if mastertask + !------------------------------------------------------------------------------- ! Zero budget data !------------------------------------------------------------------------------- From 208202428d526a704b4264c141bdb5facfd77d20 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 12 Nov 2020 20:05:08 -0700 Subject: [PATCH 149/206] first set of changes to have multiple ice sheets --- mediator/esmFlds.F90 | 37 +- mediator/esmFldsExchange_cesm_mod.F90 | 173 +++---- mediator/med.F90 | 220 ++++---- mediator/med_phases_history_mod.F90 | 2 +- mediator/med_phases_prep_glc_mod.F90 | 713 +++++++++++++++----------- mediator/med_phases_prep_lnd_mod.F90 | 482 +++++++++-------- 6 files changed, 899 insertions(+), 728 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 6f2396923..593146e9f 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -9,18 +9,23 @@ 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 ! greenland + integer, public, parameter :: compglc2 = 9 ! antarctica + integer, public, parameter :: ncomps = 9 character(len=*), public, parameter :: compname(ncomps) = & - (/'med','atm','lnd','ocn','ice','rof','wav','glc'/) + (/'med ','atm ','lnd ','ocn ','ice ','rof ','wav ','glc1','glc2'/) + + integer, public :: num_icesheets = 1 + integer, public, parameter :: max_icesheets = 2 + integer, public :: compglc(max_icesheets) = (/compglc1,compglc2/) !----------------------------------------------- ! Set mappers @@ -36,11 +41,13 @@ 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 :: nmappers = 13 + 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_glc12ocn_liq = 12 ! custom smoothing map to map liq from glc->ocn (cesm only) + integer , public, parameter :: map_glc22ocn_liq = 13 ! custom smoothing map to map liq from glc->ocn (cesm only) + integer , public, parameter :: map_glc12ocn_ice = 14 ! custom smoothing map to map ice from glc->ocn (cesm only) + integer , public, parameter :: map_glc22ocn_ice = 15 ! custom smoothing map to map ice from glc->ocn (cesm only) + integer , public, parameter :: nmappers = 15 character(len=*) , public, parameter :: mapnames(nmappers) = & (/'bilnr ',& diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 1040f6c46..3646ee713 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -67,7 +67,7 @@ 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, compglc1, compglc2, ncomps 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 @@ -82,6 +82,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! local variables: type(InternalState) :: is_local integer :: n + integer :: compglc + logical :: is_lnd, is_glc character(len=5) :: iso(2) character(len=CL) :: cvalue character(len=CS) :: name, fldname @@ -434,53 +436,27 @@ 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 + ! The suffix _elev on land fields designates fields with elevation classes ! fields from glc->med do NOT have elevation classes ! fields from med->lnd are BROKEN into 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 n = 1, num_icesheets + compglc = compglc1 + n - 1 + call addfld(fldListFr(compglc)%flds, 'Sg_icemask') ! ice sheet grid coverage + call addfld(fldListFr(compglc)%flds, 'Sg_icemask_coupled_fluxes') + 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 + 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 - end if + ! custom map and merge in med_phases_prep_lnd end if !===================================================================== @@ -1251,8 +1227,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! 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)) + ! TODO: multiple ice sheets to ocn - how to handle this + do n = 1, num_icesheets + compglc = compglc1 + n - 1 + call addfld(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n)) + call addfld(fldListFr(compglc)%flds, 'Fogg_rofi'//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)) @@ -1261,54 +1241,51 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) end do else do n = 1,size(iso) + + nflds = 0 + fld_indices(9) = 0 + fld_names(9) = '' + ! 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 runoff from rof + 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) + nflds = nflds + 1 + index_array(nflds) = comprof + fld_names(nflds) = 'Forr_rofl'//iso(n) + end if + ! liquid runoff from flood + 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) + nflds = nflds + 1 + index_array(nflds) = comprof + fld_names(nflds) = 'Flrr_flood'//iso(n) + end if + ! liquid runoff from glc - do the merge over ice sheets explicitly + if (fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then + do ns = 1, num_icesheets + compglc = compglc1 + ns - 1 + ! TODO: this custom map needs to be different for every ice sheet - how will this be handled? + call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n) , compocn, map_glc2ocn_liq, 'one' , glc2ocn_liq_rmap) + end do + end if + + ! Do the merge over ice sheets explicitly in prep_ocn_mod.F90 - but handle all the other merges here + ! So in prep_ocn_mod - Foxx_rofl would need to have the glc->ocn runoff added from each of the ice sheets + if (nflds == 1) then + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum') + else if (nflds == 2) then + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum', & + mrg_from2=fld_indices(2), mrg_fld2=fld_names(2), mrg_type2='sum') + else if (nflds == 3) then + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum', & + mrg_from1=fld_indices(2), mrg_fld1=fld_names(2), mrg_type1='sum', & + mrg_from1=fld_indices(3), mrg_fld1=fld_names(3), mrg_type3='sum') + end if end if ! ice runoff from both rof and glc to ocn @@ -1726,23 +1703,15 @@ 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 n = 1,num_icesheets + compglc = compglc1 + n - 1 + call addfld(fldListTo(compglc)%flds, 'Sl_tsrf') + call addfld(fldListTo(compglc)%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) - end if + ! custom mapping and merging will be done in prep_glc_mod.F90 end if !===================================================================== diff --git a/mediator/med.F90 b/mediator/med.F90 index cfb71f5cf..76e612350 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -32,7 +32,7 @@ module MED 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 : compice, complnd, comprof, compwav, compglc1, compglc2 use esmFlds , only : fldListMed_ocnalb, fldListMed_aoflux use esmFlds , only : med_fldList_GetNumFlds use esmFlds , only : med_fldList_GetFldNames @@ -43,6 +43,10 @@ module MED use esmFldsExchange_cesm_mod , only : esmFldsExchange_cesm use esmFldsExchange_hafs_mod , only : esmFldsExchange_hafs + ! TODO: how do you determine how many ice sheets are active and which ones they are??? + ! in env_run.xml determine have entries for every possible ice sheet - and if the mesh is unset - that + ! ice sheet is not present - for now limit the number of ice sheets to 2 + implicit none private @@ -597,19 +601,19 @@ 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 + 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, compglc1, compglc2, 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 ! input/output variables type(ESMF_GridComp) :: gcomp @@ -623,6 +627,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) 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 @@ -658,34 +663,44 @@ 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 n = 1,num_icesheets + write(cnum,'(i0)') n + call NUOPC_AddNamespace(importState, namespace="GLC"//trim(cnum), nestedStateName="GlcImp"//trim(cnum), & + nestedState=is_local%wrap%NStateImp(compglc1), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="GLC"//trim(cnum), nestedStateName="GlcExp"//trim(cnum), & + nestedState=is_local%wrap%NStateExp(compglc1), rc=rc) + end do !------------------ ! Initialize mediator flds (should be identical to the list in esmDict_Init) @@ -727,6 +742,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 @@ -1649,14 +1665,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. @@ -1693,23 +1709,38 @@ 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 (masterproc) then + write(logunit,'(a)') trim(subname) // "Initializing present flags" + end if + + is_local%wrap%comp_present(:) = .false. - 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) + do n1 = 1,ncomps + cname = trim(compname(n1)) + if (cname(1:3) == 'glc') then + call ESMF_AttributeGet(gcomp, name="glc_present", value=cvalue, defaultValue="false", & + convention="NUOPC", purpose="Instance", rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(cvalue == 'true')) then + do ns = 1,max_icesheets + is_local%wrap%comp_present(ns) = .true. + end do + end if + else + 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 + is_local%wrap%comp_present(n1) = (trim(cvalue) == "true") + end if + if (masterproc) 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 enddo !---------------------------------------------------------- @@ -1717,12 +1748,12 @@ subroutine DataInitialize(gcomp, rc) ! 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() + if (masterproc) then + write(logunit,'(a)') trim(subname) // "Initializing active coupling flags" + end if ! initialize med_coupling_active 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 @@ -1742,55 +1773,37 @@ subroutine DataInitialize(gcomp, rc) endif enddo - ! create tables of output + ! create table of active coupling flags 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) - 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,*) ' ' + 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 + 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), & @@ -1835,8 +1848,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), & @@ -1887,25 +1902,31 @@ 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' 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' 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 @@ -1918,12 +1939,15 @@ 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' 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 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_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 24dc79e2b..854ef72df 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -4,6 +4,9 @@ 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 ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE @@ -17,7 +20,8 @@ module med_phases_prep_glc_mod 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 esmFlds , only : complnd, mapbilnr, mapconsd, mapconsf, compname + use esmFlds , only : max_icesheets, compglc 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 @@ -45,30 +49,35 @@ module med_phases_prep_glc_mod ! - 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 + ! Needed for standard lnd->glc mapping + 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 '/) - 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 + type, public :: ice_sheet_toglc_type + character(CS) :: name + logical :: is_active + 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 + real(r8), pointer :: aream_g(:) => null() ! cell areas on glc grid, for mapping + type(ESMF_Mesh) :: mesh_g + end type ice_sheet_toglc_type + type(ice_sheet_toglc_type) :: ice_sheet_toglc(max_icesheets) + + 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' @@ -99,9 +108,8 @@ 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,ncnt,ns,nf + type(ESMF_Mesh) :: lmesh_l type(ESMF_Field) :: lfield real(r8), pointer :: data2d_in(:,:) => null() real(r8), pointer :: data2d_out(:,:) => null() @@ -153,6 +161,47 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (ncnt > 0) 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 + + ! 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) + + ! 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 + + ! Determine which ice sheets are active + do ns = 1,max_icesheets + if (is_local%wrap%med_coupling_active(complnd,compglc(ns))) then + ice_sheet_toglc(ns)%is_active = .true. + else + ice_sheet_toglc(ns)%is_active = .false. + end if + end do + ! Create accumulation field bundle from land on the land grid (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 @@ -166,92 +215,67 @@ subroutine med_phases_prep_glc_init(gcomp, rc) 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) + call ESMF_FieldGet(fieldlist(1), mesh=lmesh_l, rc=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(lmesh_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 FB_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 the glc meses ! 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) - - 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) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBlndAccum_glc, (/lfield/), 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 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 - - ! 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) - ! 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 + do ns = 1,max_icesheets + if (ice_sheet_toglc(ns)%is_active) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=ice_sheet_toglc(ns)%mesh_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist) + + ice_sheet_toglc(ns)%FBlndAccum_g = ESMF_FieldBundleCreate(rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do nf = 1,size(fldnames_fr_lnd) + lfield = ESMF_FieldCreate(ice_sheet_toglc(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(ice_sheets(ns)%FBlndAccum_g(nf), (/lfield/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do - 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. + call FB_reset(ice_sheets(ns)%FBlndAccum_g, 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) + ice_sheet_toglc(ns)%field_lfrac_g = ESMF_FieldCreate(ice_sheet_toglc(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(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 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 + end do ! ------------------------------- ! If smb will be renormalized then... @@ -259,59 +283,74 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (smb_renormalize) then ! determine areas on land mesh - call ESMF_MeshGet(lmesh_lnd, numOwnedElements=lsize, elementDistGrid=ldistgrid, rc=rc) + call ESMF_MeshGet(lmesh_l, 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) + call ESMF_MeshGet(lmesh_l, 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) + ! ice mask without elevation classes on lnd + field_icemask_l = ESMF_FieldCreate(lmesh_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) - 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(lmesh_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, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + ! ice fraction in multiple elevation classes on lnd - NOTE that this includes bare land + field_frac_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, 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) - 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 - end if + ! Loop over ice sheets + do ns = 1,max_icesheets + ! Determine if ice sheets ns is active + if (ice_sheet_toglc(ns)%is_active) then + + ! determine areas on glc mesh + call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g(ns), numOwnedElements=lsize, & + elementDistGrid=ldistgrid, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + allocate(ice_sheet_toglc(ns)%aream_g(lsize), dataptr1d(lsize)) + lArray = ESMF_ArrayCreate(ldistgrid, dataptr1d, rc=rc) + call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g(n), elemMaskArray=lArray, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + ice_sheet_toglc(ns)%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 + ice_sheet_toglc(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_toglc(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 + ice_sheet_toglc(ns)%field_frac_g = ESMF_FieldCreate(ice_sheet_toglc(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 + ice_sheet_toglc(ns)%field_frac_g_ec(n) = ESMF_FieldCreate(ice_sheet_toglc(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,:),mapconsf,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=mapconsf, & + RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + end do end if end if @@ -385,11 +424,12 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) 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) + 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) + call ESMF_FieldBundleGet(FBlndAccum_l, 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 @@ -401,7 +441,7 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) FBlndAccumCnt = FBlndAccumCnt + 1 if (dbug_flag > 1) then - call FB_diagnose(FBlndAccum_lnd, string=trim(subname)// ' FBlndAccum_lnd ', rc=rc) + call FB_diagnose(FBlndAccum_l, string=trim(subname)// ' FBlndAccum_l ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if end if @@ -429,7 +469,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) type(ESMF_Clock) :: clock type(ESMF_Alarm) :: alarm type(ESMF_Field) :: lfield - integer :: i, n, ncnt ! counters + integer :: i,n,ncnt,ns real(r8), pointer :: data2d(:,:) => null() real(r8), pointer :: data2d_import(:,:) => null() character(len=*) , parameter :: subname='(med_phases_prep_glc_avg)' @@ -457,19 +497,21 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! 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(compglc), fieldCount=ncnt, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,max_icesheets + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), 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(compglc), returning", & - ESMF_LOGMSG_INFO) - call t_stopf('MED:'//subname) - RETURN - end if + 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 + end if + end do ! 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 @@ -491,8 +533,12 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) 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 + do ns = 1,max_icesheets + if (ice_sheets(ns)%is_active) then + call FB_reset(is_local%wrap%FBExp(compglc(ns)), value=0.0_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + end do ! turn on stop timer and return call t_stopf('MED:'//subname) ! return @@ -503,10 +549,11 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! 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) + 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) + call ESMF_FieldBundleGet(FBlndAccum_l, 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 @@ -525,13 +572,13 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) end do if (dbug_flag > 1) then - call FB_diagnose(FBlndAccum_lnd, string=trim(subname)//' FBlndAccum for after avg for field bundle ', rc=rc) + call FB_diagnose(FBlndAccum_l, 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 + ! and set FBExp(compglc(ns)) data !--------------------------------------- call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) @@ -541,8 +588,10 @@ subroutine med_phases_prep_glc_avg(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 + do ns = 1,max_icesheets + call FB_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 !--------------------------------------- @@ -551,10 +600,14 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) FBlndAccumCnt = 0 - 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) + call FB_reset(FBlndAccum_l, value=0.0_r8, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,max_icesheets + if (ice_sheet_toglc(ns)%is_active) then + call FB_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if + end do !--------------------------------------- ! update local scalar data - set valid input flag to .true. TODO: @@ -596,13 +649,14 @@ 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 type(ESMF_Field), pointer :: fieldlist_lnd(:) => null() type(ESMF_Field), pointer :: fieldlist_glc(:) => null() + character(len=3) :: cnum character(len=*) , parameter :: subname='(med_phases_prep_glc_mod:med_phases_prep_glc_map_lnd2glc)' !--------------------------------------- @@ -624,14 +678,12 @@ subroutine map_lnd2glc(gcomp, rc) ! 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 @@ -639,173 +691,202 @@ subroutine map_lnd2glc(gcomp, 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,max_icesheets + if (ice_sheet_toglc(ns)%is_active) then + call FB_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if + 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,max_icesheets + if (ice_sheet_toglc(ns)%is_active) then + call ESMF_FieldBundleGet(ice_sheet_toglc(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=ice_sheet_toglc(ns)%field_lfrac_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + 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) + call FB_diagnose(FBlndAccum_l, string=trim(subname)//' FBlndAccum_l ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return call FB_diagnose(is_local%wrap%FBfrac(complnd), string=trim(subname)//' FBFrac ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call FB_diagnose(FBlndAccum_glc, string=trim(subname)//' FBlndAccum_glc ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,max_icesheets + if (ice_sheet_toglc(ns)%is_active) then + call FB_diagnose(ice_sheet_toglc(s)%FBlndAccum_g, string=trim(subname)//& + ' FBlndAccum_glc '//compname(compglc(ns)), rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if + 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 - ! ------------------------------------------------------------------------ - - 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,max_icesheets - ! ------------------------------------------------------------------------ - ! Loop over fields in export field bundle to GLC - ! ------------------------------------------------------------------------ - - ! 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. - - allocate(data_ice_covered_g(lsize_g)) - do nfld = 1, size(fldnames_to_glc) - - ! ------------------------------------------------------------------------ - ! 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)), & + if (dbug_flag > 1) then + write(cnum,'(a3)') ns + call FB_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 + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=trim(Sg_frac_fieldname), & field=lfield, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=ice_covered_g, 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)), & + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=trim(Sg_topo_fieldname), & field=lfield, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataexp_g, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=topoglc_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 + ! 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) - ! Now overwrite with valid values - do n = 1, lsize_g + ! ------------------------------------------------------------------------ + ! Determine topo field in multiple elevation classes on the glc grid + ! ------------------------------------------------------------------------ - ! For each ice sheet point, find bounding EC values... - if (topoglc_g(n) < topolnd_g_ec(2,n)) then + call ESMF_FieldBundleGet(ice_sheet_toglc(ns)%FBlndAccum_g, 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 - ! lower than lowest mean EC elevation value - data_ice_covered_g(n) = dataptr2d(2,n) + ! ------------------------------------------------------------------------ + ! Loop over fields in export field bundle to glc for ice sheet ns + ! ------------------------------------------------------------------------ - else if (topoglc_g(n) >= topolnd_g_ec(ungriddedCount, n)) then + ! 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. - ! higher than highest mean EC elevation value - data_ice_covered_g(n) = dataptr2d(ungriddedCount,n) + allocate(data_ice_covered_g(lsize_g)) + do nfld = 1, size(fldnames_to_glc) - else + ! ------------------------------------------------------------------------ + ! 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 + ! ------------------------------------------------------------------------ - ! 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) + ! Get a pointer to the land data in multiple elevation classes on the glc grid + call ESMF_FieldBundleGet(ice_sheet_toglc(ns)%FBlndAccum_g, 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 - 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)) + ! 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(ns)), 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 + + ! Now 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) + + 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 + + ! ------------------------------------------------------------------------ + ! 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, ns, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return end if - end do ! lsize_g - - ! ------------------------------------------------------------------------ - ! 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 + end do ! end loop over fields (nflds) - if (smb_renormalize) then - call med_phases_prep_glc_renormalize_smb(gcomp, rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if + ! clean up memory that is ice sheet dependent + deallocate(elevclass_g) + deallocate(data_ice_covered_g) - end do ! end of loop over fields + end do ! end of loop ice sheets (ns) - ! clean up memory - deallocate(elevclass_g) - deallocate(data_ice_covered_g) end subroutine map_lnd2glc !================================================================================================ - subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) + subroutine med_phases_prep_glc_renormalize_smb(gcomp, ns, rc) !------------------ ! Renormalizes surface mass balance (smb, here named qice_g) so that the global @@ -843,8 +924,9 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !------------------ ! input/output variables - type(ESMF_GridComp) :: gcomp - integer , intent(out) :: rc ! return error code + type(ESMF_GridComp) :: gcomp + integer , intent(in) :: ns ! ice sheet index + 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. @@ -900,11 +982,12 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !--------------------------------------- ! 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) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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) + call ESMF_FieldGet(ice_sheet_toglc(ns)%field_icemask_g, farrayptr=Sg_icemask_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return Sg_icemask_g(:) = dataptr1d(:) @@ -912,9 +995,9 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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,:), & + field_src=ice_sheet_toglc(ns)%field_icemask_g, & + field_dst=ice_sheet_toglc(ns)%field_icemask_l, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & maptype=mapconsf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -927,17 +1010,20 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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) + + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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 + call ESMF_FieldGet(ice_sheet_toglc(ns)%field_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 + call ESMF_FieldGet(ice_sheet_toglc(ns)%field_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 @@ -946,16 +1032,16 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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,:), & + field_src=ice_sheet_toglc(ns)%field_frac_g_ec, & + field_dst=ice_sheet_toglc(ns)%field_frac_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & maptype=mapconsf, & - field_normsrc=field_glc_icemask_g, & - field_normdst=field_glc_icemask_l, rc=rc) + field_normsrc=ice_sheet_toglc(ns)%field_icemask_g, & + field_normdst=ice_sheet_toglc(ns)%field_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) + call ESMF_FieldGet(field_frac_l_ec, farrayptr=glc_frac_l_ec, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine fraction on land grid, lfrac(:) @@ -965,11 +1051,11 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, 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) + call ESMF_FieldGet(field_icemask_l, farrayptr=Sg_icemask_l, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine qice_l_ec - call ESMF_FieldBundleGet(FBlndAccum_lnd, trim(qice_fieldname)//'_elev', field=lfield, rc=rc) + call ESMF_FieldBundleGet(FBlndAccum_l, 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 @@ -994,9 +1080,11 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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) + 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) + 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 !--------------------------------------- @@ -1012,7 +1100,8 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), 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 @@ -1026,8 +1115,10 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) local_ablat_glc(1) = local_ablat_glc(1) + Sg_icemask_g(n) * aream_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) + 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 diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 63cdf85f7..0526beef7 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -14,7 +14,9 @@ module med_phases_prep_lnd_mod 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 : complnd, compatm, ncomps, compname + use esmFlds , only : max_icesheets, num_icesheets, compglc1, compglc2 + use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname 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 @@ -46,14 +48,22 @@ module med_phases_prep_lnd_mod 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 + 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_icemask_coupled_fluxes_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) @@ -103,7 +113,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) 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 + read (cvalue,*) cism_evolve if (mastertask) then write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve end if @@ -126,62 +136,50 @@ subroutine med_phases_prep_lnd(gcomp, rc) call t_startf('MED:'//trim(subname)//' map') do n1 = 1,ncomps ! Skip glc here and handle it below - if (is_local%wrap%med_coupling_active(n1,complnd) .and. n1 /= compglc) 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 + if (is_local%wrap%med_coupling_active(n1,complnd)) then + if (n1 /= compglc1 .and. n1 /= compglc2) then ! TODO: improve this logic + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(n1,n1), & + FBDst=is_local%wrap%FBImp(n1,complnd), & + FBFracSrc=is_local%wrap%FBFrac(n1), & + field_normOne=is_local%wrap%field_normOne(n1,complnd,:), & + packed_data=is_local%wrap%packed_data(n1,complnd,:), & + routehandles=is_local%wrap%RH(n1,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if end if end do call t_stopf('MED:'//trim(subname)//' map') ! The following is only done if glc->lnd coupling is active - if (is_local%wrap%comp_present(compglc) .and. (is_local%wrap%med_coupling_active(compglc,complnd))) then - call t_startf('MED:'//trim(subname)//' glc2lnd init') - if (first_call) then - call map_glc2lnd_init(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call t_stopf('MED:'//trim(subname)//' glc2lnd init') - - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - if (cism_evolve) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc,compglc), & - FBDst=is_local%wrap%FBImp(compglc,complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc), & - field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & - packed_data=is_local%wrap%packed_data(compglc,complnd,:), & - routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - else if (first_call) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc,compglc), & - FBDst=is_local%wrap%FBImp(compglc,complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc), & - field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & - packed_data=is_local%wrap%packed_data(compglc,complnd,:), & - routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + if (first_call) then + call t_startf('MED:'//trim(subname)//' glc2lnd init') + call map_glc2lnd_init(gcomp, ns, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call map_glc2lnd(gcomp, ns, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd init') + else + if (cism_evolve) then + call t_startf('MED:'//trim(subname)//' glc2lnd ') + call map_glc2lnd(gcomp, ns, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd') + end if + end if end if - end if + end do ! end of loop over ice sheets (ns) !--------------------------------------- ! auto merges to create FBExp(complnd) !--------------------------------------- ! The following will merge all fields in fldsSrc - ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) + ! Note that there is no merge for glc Sg_icemask and Sg_icemask_coupled_fluxes) + ! these are mapped and set directly in map_glc2lnd + call t_startf('MED:'//trim(subname)//' merge') call med_merge_auto(complnd, & is_local%wrap%med_coupling_active(:,complnd), & @@ -195,6 +193,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) !--------------------------------------- ! update scalar data !--------------------------------------- + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then @@ -246,10 +245,10 @@ subroutine map_glc2lnd_init(gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield - type(ESMF_Mesh) :: lmesh_lnd - type(ESMF_Mesh) :: lmesh_glc + type(ESMF_Mesh) :: mesh_l integer :: ungriddedUBound_output(1) integer :: fieldCount + integer :: s type(ESMF_Field), pointer :: fieldlist(:) => null() character(len=*) , parameter :: subname='(map_glc2lnd_mod:map_glc2lnd_init)' !--------------------------------------- @@ -285,55 +284,79 @@ subroutine map_glc2lnd_init(gcomp, rc) 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) + call ESMF_FieldGet(fieldlist(1), mesh=mesh_l, 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) + do ns = 1,max_icesheets + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=ice_sheet_tolnd(ns)%mesh_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist) + end do ! ------------------------------- - ! Create module field bundles + ! Create module fields on land mesh ! ------------------------------- - 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) + 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_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) + field_icemask_coupled_fluxes_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, 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, & + 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_topo_x_icemask_g_ec = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + 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(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + + 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 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 + ! ------------------------------- + ! Create module fields on glc mesh + ! ------------------------------- + + do ns = 1,max_icesheets + 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 do ! 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 @@ -361,14 +384,16 @@ subroutine map_glc2lnd( gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield - integer :: ec, l, g + integer :: ec, l, g, ns 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 :: 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 :: frac_l_ec_sum(:,:) => 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 :: topo_l_ec_sum(:,:) => 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() @@ -393,138 +418,193 @@ subroutine map_glc2lnd( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------- - ! Map fractional ice coverage to the land grid (multiple elevation classes) + ! Get pointers into land export field bundle (this is summed over all ice sheets) !--------------------------------- - ! 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) + 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=topo_g, rc=rc) + call ESMF_fieldGet(lfield, farrayptr=frac_l_ec_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_l_ec_sum(:,:) = 0._r8 - ! 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) + 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(field_frac_g_ec, farrayptr=frac_g_ec, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=topo_l_ec_sum, 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) + topo_l_ec_sum(:,) = 0._r8 - ! compute icemask_g - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_icemask), field=lfield, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask) + field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=sg_icemask_sum, 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(:) + sg_icemask_sum(:) = 0._r8 - ! 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) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask_coupled_fluxes), & + field=lfield, 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) + call ESMF_FieldGet(lfield, farrayptr=sg_icemask_coupled_fluxes_sum, 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(:,:) + sg_icemask_coupled_fluxes_sum(:) = 0._r8 !--------------------------------- - ! Map topo to the land grid (multiple elevation classes) + ! Map fractional ice coverage 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 + do ns = 1,max_icesheets - 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) + ! Map Sg_icemask (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns),compglc(ns)), & + fieldname=trim(Sg_icemask), field=field_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field( & + field_src=field_src, & + 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 + call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + sg_icemask_sum(:) = sg_icemask_sum(:) + icemask_l(:) + + ! Map Sg_icemask_coupled_fluxes (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns),compglc(ns)), & + fieldname=trim(Sg_icemask_coupled_fluxes), field=fieldsrc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field( & + field_src=field_src, & + field_dst=field_dst, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! 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(ns),compglc(ns)), 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(ns),compglc(ns)), 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(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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(ice_sheet_tolnd(ns)%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 - 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 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 - ! 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 + ! now set values in land export state for Sg_frac_elev (this is summed over all ice sheets) + call ESMF_fieldGet(field_frac_l_ec, farrayptr=frac_l_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_l_ec_sum(:,:) = frac_l_ec_sum(:,:) + frac_l_ec(:,:) - ! 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 + !--------------------------------- + ! 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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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=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 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=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 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. + 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 - dataptr2d(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) + 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 if + end do end do end do From 12708969351862f4484d543b696d936c09c3bf2d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 14 Nov 2020 14:32:25 -0700 Subject: [PATCH 150/206] successfully completed a TG run with just 1 ice sheets - results were roundoff from nov06 --- mediator/esmFlds.F90 | 96 ++--- mediator/esmFldsExchange_cesm_mod.F90 | 506 ++++++++++++++------------ mediator/esmFldsExchange_nems_mod.F90 | 10 +- mediator/med.F90 | 257 ++++++++----- mediator/med_diag_mod.F90 | 15 +- mediator/med_fraction_mod.F90 | 98 ++--- mediator/med_internalstate_mod.F90 | 32 +- mediator/med_phases_prep_glc_mod.F90 | 372 ++++++++++--------- mediator/med_phases_prep_lnd_mod.F90 | 444 +++++++++++----------- 9 files changed, 947 insertions(+), 883 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 593146e9f..e97bcc301 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -16,16 +16,15 @@ module esmflds integer, public, parameter :: compice = 5 integer, public, parameter :: comprof = 6 integer, public, parameter :: compwav = 7 - integer, public, parameter :: compglc1 = 8 ! greenland - integer, public, parameter :: compglc2 = 9 ! antarctica - integer, public, parameter :: ncomps = 9 + integer, public, parameter :: compglc1 = 8 + integer, public, parameter :: ncomps = 8 character(len=*), public, parameter :: compname(ncomps) = & - (/'med ','atm ','lnd ','ocn ','ice ','rof ','wav ','glc1','glc2'/) + (/'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 - integer, public, parameter :: max_icesheets = 2 - integer, public :: compglc(max_icesheets) = (/compglc1,compglc2/) !----------------------------------------------- ! Set mappers @@ -43,11 +42,9 @@ module esmflds integer , public, parameter :: mappatch_uv3d = 9 ! rotate u,v to 3d cartesian space, map from src->dest, then rotate back 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_glc12ocn_liq = 12 ! custom smoothing map to map liq from glc->ocn (cesm only) - integer , public, parameter :: map_glc22ocn_liq = 13 ! custom smoothing map to map liq from glc->ocn (cesm only) - integer , public, parameter :: map_glc12ocn_ice = 14 ! custom smoothing map to map ice from glc->ocn (cesm only) - integer , public, parameter :: map_glc22ocn_ice = 15 ! custom smoothing map to map ice from glc->ocn (cesm only) - integer , public, parameter :: nmappers = 15 + 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) = & (/'bilnr ',& @@ -218,43 +215,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_from1, mrg_fld1, mrg_type1, mrg_fracname1) ! ---------------------------------------------- ! 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_from1 + character(len=*) , intent(in) :: mrg_fld1 + character(len=*) , intent(in) :: mrg_type1 + character(len=*) , intent(in), optional :: mrg_fracname1 ! local variables integer :: n, id - integer :: rc - character(len=*), parameter :: subname='(med_fldList_MrgFld)' + character(len=*), parameter :: subname='(med_fldList_AddMrg)' ! ---------------------------------------------- id = 0 @@ -268,42 +247,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_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 subroutine med_fldList_AddMrg diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 3646ee713..8fd062765 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -44,9 +44,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 +67,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, compglc1, compglc2, ncomps + use esmflds , only : compice, comprof, compwav, ncomps + use esmflds , only : compglc, num_icesheets ! 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,8 +82,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! local variables: type(InternalState) :: is_local - integer :: n - integer :: compglc + integer :: n, ns logical :: is_lnd, is_glc character(len=5) :: iso(2) character(len=CL) :: cvalue @@ -341,8 +341,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)) @@ -352,7 +359,8 @@ 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') end if @@ -386,9 +394,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)) @@ -396,9 +415,10 @@ 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') end if @@ -412,8 +432,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)) @@ -423,7 +447,8 @@ 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') end if @@ -442,16 +467,15 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! fields from med->lnd are BROKEN into multiple elevation classes if (phase == 'advertise') then - do n = 1, num_icesheets - compglc = compglc1 + n - 1 - call addfld(fldListFr(compglc)%flds, 'Sg_icemask') ! ice sheet grid coverage - call addfld(fldListFr(compglc)%flds, 'Sg_icemask_coupled_fluxes') - 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_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') @@ -480,7 +504,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 @@ -489,25 +516,25 @@ 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 + 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_from1=complnd, mrg_fld1='Sl_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='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_from1=compice, mrg_fld1='Si_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='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_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + end if end if end if end do @@ -520,7 +547,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 @@ -529,25 +559,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_from1=complnd, mrg_fld1='Sl_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='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_from1=compice, mrg_fld1='Si_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='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_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + end if end if end if end do @@ -563,33 +591,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_from1=complnd, mrg_fld1='Fall_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac') + end if + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_'//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=compice, mrg_fld1='Faii_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') + end if + if (fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_'//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_from1=compmed, mrg_fld1='Faox_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + end if end if end if end do @@ -605,27 +637,24 @@ 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_from1=complnd, mrg_fld1='Sl_t', mrg_type1='merge', mrg_fracname1='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_from1=compice, mrg_fld1='Si_t', mrg_type1='merge', mrg_fracname1='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_from1=compocn, mrg_fld1='So_t', mrg_type1='merge', mrg_fracname1='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') end if @@ -637,7 +666,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)) @@ -647,7 +678,8 @@ 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') end if @@ -661,7 +693,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)) @@ -671,7 +705,8 @@ 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') end if @@ -685,7 +720,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)) @@ -695,7 +732,8 @@ 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') end if @@ -805,7 +843,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)) @@ -816,8 +858,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_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ofrac') end if end if end do @@ -851,8 +893,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_from1=compmed, mrg_fld1='Faox_lwup', mrg_type1='merge', mrg_fracname1='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & + mrg_from1=compatm, mrg_fld1='Faxa_lwdn', mrg_type1='merge', mrg_fracname1='ofrac') end if end if @@ -947,12 +990,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_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') ! Note that 'Sf_afrac, 'Sf_afracr' and 'Foxx_swnet_afracr' will have explicit merging in med_phases_prep_ocn end if end if @@ -1003,8 +1048,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=compatm, mrg_fld1='Faxa_rain'//iso(n), mrg_type1='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. & @@ -1023,8 +1068,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=compatm, mrg_fld1='Faxa_snow'//iso(n), mrg_type1='copy') end if end do end if @@ -1162,8 +1207,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_from1=compmed, mrg_fld1='Faox_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & + mrg_from1=compice, mrg_fld1='Fioi_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') end if end if end do @@ -1197,7 +1243,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)) @@ -1226,89 +1276,66 @@ 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 - - ! TODO: multiple ice sheets to ocn - how to handle this - do n = 1, num_icesheets - compglc = compglc1 + n - 1 - 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) - - nflds = 0 - fld_indices(9) = 0 - fld_names(9) = '' - - ! liquid runoff from rof, flood and glc to ocn - if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc)) then - ! liquid runoff from rof + if ( fldchk(is_local%wrap%FBExp(compocn), 'Foxx_rofl'//iso(n) , rc=rc)) then + ! liquid from river and possibly flood from river 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) - nflds = nflds + 1 - index_array(nflds) = comprof - fld_names(nflds) = 'Forr_rofl'//iso(n) - end if - ! liquid runoff from flood - 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) - nflds = nflds + 1 - index_array(nflds) = comprof - fld_names(nflds) = 'Flrr_flood'//iso(n) + 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:F'//iso(n), & + mrg_from1=comprof, mrg_fld1='Forr_rofl:Flrr_flood', mrg_type1='sum') + else + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from1=comprof, mrg_fld1='Forr_rofl', mrg_type1='sum') + end if end if - ! liquid runoff from glc - do the merge over ice sheets explicitly - if (fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - do ns = 1, num_icesheets - compglc = compglc1 + ns - 1 + ! 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)%flds, 'Fogg_rofl'//iso(n) , compocn, map_glc2ocn_liq, 'one' , glc2ocn_liq_rmap) - end do - end if - - ! Do the merge over ice sheets explicitly in prep_ocn_mod.F90 - but handle all the other merges here - ! So in prep_ocn_mod - Foxx_rofl would need to have the glc->ocn runoff added from each of the ice sheets - if (nflds == 1) then - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum') - else if (nflds == 2) then - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum', & - mrg_from2=fld_indices(2), mrg_fld2=fld_names(2), mrg_type2='sum') - else if (nflds == 3) then - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=fld_indices(1), mrg_fld1=fld_names(1), mrg_type1='sum', & - mrg_from1=fld_indices(2), mrg_fld1=fld_names(2), mrg_type1='sum', & - mrg_from1=fld_indices(3), mrg_fld1=fld_names(3), mrg_type3='sum') - end if + 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_from1=compglc(ns), mrg_fld1='Fogg_rofl'//iso(n), mrg_type1='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') + end do + do n = 1,size(iso) + 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_liq, 'none', rof2ocn_ice_rmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & + mrg_from1=comprof, mrg_fld1='Forr_rofi', mrg_type1='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_liq, 'one' , glc2ocn_ice_rmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & + mrg_from1=compglc(ns), mrg_fld1='Fogg_rofi'//iso(n), mrg_type1='sum') + end if + end do end if end do end if @@ -1320,7 +1347,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)) @@ -1330,7 +1360,8 @@ 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') end if @@ -1537,7 +1568,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_from1=compocn, mrg_fld1='Fioo_q', mrg_type1='copy') end if end if @@ -1551,7 +1583,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_from1=compocn, mrg_fld1='So_roce_wiso', mrg_type1='copy') end if end if @@ -1561,25 +1594,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_from1=comprof, mrg_fld1='Firr_rofi'//iso(n), mrg_type1='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_from1=compglc(ns), mrg_fld1='Figg_rofi'//iso(n), mrg_type1='sum') + end if + end do end if end if end do @@ -1622,7 +1656,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_from1=compocn, mrg_fld1=trim(fldname), mrg_type1='copy') end if end if end do @@ -1705,13 +1740,24 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Sl_tsrf_elev') ! surface temperature of glacier (1->glc_nec+1) call addfld(fldListFr(complnd)%flds, 'Sl_topo_elev') ! surface heights of glacier (1->glc_nec+1) call addfld(fldListFr(complnd)%flds, 'Flgl_qice_elev') ! glacier ice flux (1->glc_nec+1) - do n = 1,num_icesheets - compglc = compglc1 + n - 1 - call addfld(fldListTo(compglc)%flds, 'Sl_tsrf') - call addfld(fldListTo(compglc)%flds, 'Flgl_qice') + do ns = 1,num_icesheets + call addfld(fldListTo(compglc(ns))%flds, 'Sl_tsrf') + call addfld(fldListTo(compglc(ns))%flds, 'Flgl_qice') end do else ! custom mapping 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 !===================================================================== diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index cc61512b8..8938cf3d7 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -237,8 +237,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_from1=compmed, mrg_fld1='Faox_'//trim(flds(n)), mrg_type1='merge', mrg_fracname1='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(flds(n)), & + mrg_from1=compice, mrg_fld1='Fioi_'//trim(flds(n)), mrg_type1='merge', mrg_fracname1='ifrac') end do deallocate(flds) @@ -247,8 +248,9 @@ 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_from1=compmed, mrg_fld1='Faox_lwup', mrg_type1='merge', mrg_fracname1='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & + mrg_from1=compatm, mrg_fld1='Faxa_lwdn', mrg_type1='merge', mrg_fracname1='ofrac') ! to ocn: sensible heat flux from mediator via auto merge call addfld(fldListTo(compocn)%flds, 'Faox_sen') diff --git a/mediator/med.F90 b/mediator/med.F90 index 76e612350..3b29c08ee 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -4,49 +4,44 @@ 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, compglc1, compglc2 - 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 ! 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 use esmFldsExchange_hafs_mod , only : esmFldsExchange_hafs - ! TODO: how do you determine how many ice sheets are active and which ones they are??? - ! in env_run.xml determine have entries for every possible ice sheet - and if the mesh is unset - that - ! ice sheet is not present - for now limit the number of ice sheets to 2 - implicit none private @@ -601,19 +596,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, compglc1, compglc2, 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 @@ -623,7 +609,7 @@ 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 @@ -694,23 +680,28 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) nestedState=is_local%wrap%NStateExp(compwav), rc=rc) ! Only create nested states for active ice sheets - do n = 1,num_icesheets - write(cnum,'(i0)') n - call NUOPC_AddNamespace(importState, namespace="GLC"//trim(cnum), nestedStateName="GlcImp"//trim(cnum), & - nestedState=is_local%wrap%NStateImp(compglc1), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="GLC"//trim(cnum), nestedStateName="GlcExp"//trim(cnum), & - nestedState=is_local%wrap%NStateExp(compglc1), rc=rc) + 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 @@ -831,7 +822,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 @@ -853,9 +845,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 @@ -870,6 +866,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 @@ -878,7 +877,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 @@ -1712,47 +1710,100 @@ subroutine DataInitialize(gcomp, rc) !---------------------------------------------------------- ! Initialize mediator present flags !---------------------------------------------------------- - - if (masterproc) then - write(logunit,'(a)') trim(subname) // "Initializing present flags" - end if - - is_local%wrap%comp_present(:) = .false. + + if (mastertask) then + write(logunit,'(a)') trim(subname) // "Initializing present flags" + end if do n1 = 1,ncomps - cname = trim(compname(n1)) - if (cname(1:3) == 'glc') then - call ESMF_AttributeGet(gcomp, name="glc_present", value=cvalue, defaultValue="false", & - convention="NUOPC", purpose="Instance", rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (trim(cvalue == 'true')) then - do ns = 1,max_icesheets - is_local%wrap%comp_present(ns) = .true. - end do - end if - else - 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 - is_local%wrap%comp_present(n1) = (trim(cvalue) == "true") - end if - if (masterproc) 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 - enddo + 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 !---------------------------------------------------------- - if (masterproc) then - write(logunit,'(a)') trim(subname) // "Initializing active coupling flags" - end if + ! 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. + + if (mastertask) then + write(logunit,'(a)') trim(subname) // "Initializing active coupling flags" + end if - ! initialize med_coupling_active + ! 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(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. + + ! 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. + 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 @@ -1774,6 +1825,10 @@ subroutine DataInitialize(gcomp, rc) enddo ! create table of 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 write(logunit,*) ' ' write(logunit,'(A)') trim(subname)//' Allowed coupling flags' @@ -1837,7 +1892,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 @@ -1885,8 +1940,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. @@ -1904,12 +1958,14 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return 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) then - write(logunit,'(a')) trim(subname)//' initializing FB FBMed_ocnalb_o' + 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 @@ -1941,6 +1997,7 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return 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) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index faeea6e50..2966dba63 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -1251,7 +1251,7 @@ 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 @@ -1259,7 +1259,7 @@ 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) ' ! ------------------------------------------------------------------ @@ -1271,18 +1271,21 @@ subroutine med_phases_diag_glc( gcomp, rc) 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 diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 8cc6152d7..f63d150cd 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -89,11 +89,11 @@ 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) ! !----------------------------------------------------------------------------- @@ -106,7 +106,7 @@ module med_fraction_mod use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk 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 +171,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 +201,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 @@ -490,47 +492,49 @@ 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 'gfrac' in FBFrac(compglc(ns)) + if ( FB_FldChk(is_local%wrap%FBfrac(compglc(ns)) , 'gfrac', rc=rc) .and. & + FB_FldChk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'frac' , rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), '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(ns)), '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(ns)) to 1. + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc(ns)), '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 - ! 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 '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 - 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 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) diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 149d10374..7c4cf7fbf 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -17,31 +17,9 @@ 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() real(r8), pointer :: lats(:) => 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_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 854ef72df..f2b0ed1de 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -21,7 +21,7 @@ module med_phases_prep_glc_mod use ESMF , only : ESMF_DistGrid, ESMF_AttributeSet use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use esmFlds , only : complnd, mapbilnr, mapconsd, mapconsf, compname - use esmFlds , only : max_icesheets, compglc + use esmFlds , only : max_icesheets, num_icesheets, compglc 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 @@ -239,6 +239,8 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! However FBlndAccum_glc has the fields fldnames_fr_lnd BUT ON the glc grid do ns = 1,max_icesheets if (ice_sheet_toglc(ns)%is_active) then + + ! get mesh on glc grid call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(fieldlist(fieldcount)) @@ -248,6 +250,20 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(fieldlist) + ! get glc mesh areas + call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g, numOwnedElements=lsize, & + elementDistGrid=ldistgrid, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + allocate(ice_sheet_toglc(ns)%aream_g(lsize), dataptr1d(lsize)) + lArray = ESMF_ArrayCreate(ldistgrid, dataptr1d, rc=rc) + call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g, elemMaskArray=lArray, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + ice_sheet_toglc(ns)%aream_g(:) = dataptr1d(:) + call ESMF_ArrayDestroy(larray, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + deallocate(dataptr1d) + + ! create accumulation field bundle on glc grid ice_sheet_toglc(ns)%FBlndAccum_g = ESMF_FieldBundleCreate(rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do nf = 1,size(fldnames_fr_lnd) @@ -255,19 +271,20 @@ subroutine med_phases_prep_glc_init(gcomp, rc) meshloc=ESMF_MESHLOC_ELEMENT, & ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(ice_sheets(ns)%FBlndAccum_g(nf), (/lfield/), rc=rc) + call ESMF_FieldBundleAdd(ice_sheet_toglc(ns)%FBlndAccum_g, (/lfield/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do - call FB_reset(ice_sheets(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + ! reset accumulation field bundle to 0 + call FB_reset(ice_sheet_toglc(ns)%FBlndAccum_g, 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) + ! create land fraction field on glc mesh (this is just needed for normalization mapping) ice_sheet_toglc(ns)%field_lfrac_g = ESMF_FieldCreate(ice_sheet_toglc(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 + ! 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) @@ -311,19 +328,6 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! Determine if ice sheets ns is active if (ice_sheet_toglc(ns)%is_active) then - ! determine areas on glc mesh - call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g(ns), numOwnedElements=lsize, & - elementDistGrid=ldistgrid, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - allocate(ice_sheet_toglc(ns)%aream_g(lsize), dataptr1d(lsize)) - lArray = ESMF_ArrayCreate(ldistgrid, dataptr1d, rc=rc) - call ESMF_MeshGet(ice_sheet_toglc(ns)%mesh_g(n), elemMaskArray=lArray, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - ice_sheet_toglc(ns)%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 ice_sheet_toglc(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_toglc(ns)%mesh_g, & ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) @@ -335,7 +339,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! ice fraction in multiple elevation classes on glc - NOTE that this includes bare land - ice_sheet_toglc(ns)%field_frac_g_ec(n) = ESMF_FieldCreate(ice_sheet_toglc(ns)%mesh_g, & + ice_sheet_toglc(ns)%field_frac_g_ec = ESMF_FieldCreate(ice_sheet_toglc(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 @@ -349,7 +353,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - end do + end if end do end if end if @@ -497,10 +501,9 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! 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 - do ns = 1,max_icesheets + do ns = 1,num_icesheets call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), 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(compglc), returning", & ESMF_LOGMSG_INFO) @@ -534,7 +537,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) call ESMF_LogWrite(trim(subname)//": glc_avg alarm is not ringing - returning", ESMF_LOGMSG_INFO) ! Reset export field bundle to zero do ns = 1,max_icesheets - if (ice_sheets(ns)%is_active) then + if (ice_sheet_toglc(ns)%is_active) then call FB_reset(is_local%wrap%FBExp(compglc(ns)), value=0.0_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -581,8 +584,10 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! and set FBExp(compglc(ns)) data !--------------------------------------- - 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 FB_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do call map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return @@ -713,7 +718,7 @@ subroutine map_lnd2glc(gcomp, rc) field_normdst=ice_sheet_toglc(ns)%field_lfrac_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end do - end do + end if end do deallocate(fieldlist_lnd) @@ -726,7 +731,7 @@ subroutine map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return do ns = 1,max_icesheets if (ice_sheet_toglc(ns)%is_active) then - call FB_diagnose(ice_sheet_toglc(s)%FBlndAccum_g, string=trim(subname)//& + call FB_diagnose(ice_sheet_toglc(ns)%FBlndAccum_g, string=trim(subname)//& ' FBlndAccum_glc '//compname(compglc(ns)), rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if @@ -869,7 +874,7 @@ subroutine map_lnd2glc(gcomp, rc) ! scaling in the CISM NUOPC cap if (smb_renormalize) then - call med_phases_prep_glc_renormalize_smb(gcomp, ns, rc) + call med_phases_prep_glc_renormalize_smb(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if @@ -886,7 +891,7 @@ end subroutine map_lnd2glc !================================================================================================ - subroutine med_phases_prep_glc_renormalize_smb(gcomp, ns, rc) + subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !------------------ ! Renormalizes surface mass balance (smb, here named qice_g) so that the global @@ -925,7 +930,6 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, ns, rc) ! input/output variables type(ESMF_GridComp) :: gcomp - integer , intent(in) :: ns ! ice sheet index integer , intent(out) :: rc ! return error code ! local variables @@ -945,7 +949,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, ns, rc) 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 + 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) @@ -977,174 +981,178 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, ns, 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(ns),compglc(ns)), 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(ice_sheet_toglc(ns)%field_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=ice_sheet_toglc(ns)%field_icemask_g, & - field_dst=ice_sheet_toglc(ns)%field_icemask_l, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsf, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + !--------------------------------------- + ! Map Sg_icemask_g from the glc grid to the land grid. + !--------------------------------------- + + ! determine Sg_icemask_g and set as contents of FBglc_icemask + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_toglc(ns)%field_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=ice_sheet_toglc(ns)%field_icemask_g, & + field_dst=field_icemask_l, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsf, 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 - ! ------------------------------------------------------------------------ + ! ------------------------------------------------------------------------ + ! Map frac_field on glc grid without elevation classes to frac_field on land grid with elevation classes + ! ------------------------------------------------------------------------ - ! 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(ns),compglc(ns)), 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(ns),compglc(ns)), 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(ice_sheet_toglc(ns)%field_frac_g, farrayptr=glc_frac_g, rc=rc) ! module field - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(ice_sheet_toglc(ns)%field_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=ice_sheet_toglc(ns)%field_frac_g_ec, & - field_dst=ice_sheet_toglc(ns)%field_frac_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsf, & - field_normsrc=ice_sheet_toglc(ns)%field_icemask_g, & - field_normdst=ice_sheet_toglc(ns)%field_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_frac_l_ec, farrayptr=glc_frac_l_ec, rc=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 - ! 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 + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ns),compglc(ns)), 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(ice_sheet_toglc(ns)%field_frac_g, farrayptr=glc_frac_g, rc=rc) ! module field + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(ice_sheet_toglc(ns)%field_frac_g_ec, farrayptr=glc_frac_g_ec, rc=rc) ! module field + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get Sg_icemask_l(:) - call ESMF_FieldGet(field_icemask_l, farrayptr=Sg_icemask_l, rc=rc) - 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=ice_sheet_toglc(ns)%field_frac_g_ec, & + field_dst=field_frac_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsf, & + field_normsrc=ice_sheet_toglc(ns)%field_icemask_g, & + field_normdst=field_icemask_l, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! determine qice_l_ec - call ESMF_FieldBundleGet(FBlndAccum_l, 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 fractional ice coverage for each elevation class on the land grid, glc_frac_l_ec(:,:) + call ESMF_FieldGet(field_frac_l_ec, farrayptr=glc_frac_l_ec, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum - !--------------------------------------- + ! 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 Sg_icemask_l(:) + call ESMF_FieldGet(field_icemask_l, farrayptr=Sg_icemask_l, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + + ! determine qice_l_ec + call ESMF_FieldBundleGet(FBlndAccum_l, 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 + + !--------------------------------------- + ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum + !--------------------------------------- + + 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) + + 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 + + !--------------------------------------- + ! Sum qice_g over local glc grid cells. + !--------------------------------------- + + ! 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 + ! then it would be appropriate to use the native CISM areas in this sum. - 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) + ! determine qice_g + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), 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 - 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) + 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) * ice_sheet_toglc(ns)%aream_g(n) * qice_g(n) else - local_ablat_lnd(1) = local_ablat_lnd(1) + effective_area * glc_frac_l_ec(ec,n) * qice_l_ec(ec,n) + local_ablat_glc(1) = local_ablat_glc(1) + Sg_icemask_g(n) * ice_sheet_toglc(ns)%aream_g(n) * qice_g(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 - - !--------------------------------------- - ! Sum qice_g over local glc grid cells. - !--------------------------------------- + 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 - ! 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(ns)), 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) + if (global_ablat_glc(1) < 0.0_r8) then ! negative by definition + ablat_renorm_factor = global_ablat_lnd(1) / global_ablat_glc(1) else - local_ablat_glc(1) = local_ablat_glc(1) + Sg_icemask_g(n) * aream_g(n) * qice_g(n) + ablat_renorm_factor = 0.0_r8 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 - 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,*) 'accum_renorm_factor = ', accum_renorm_factor + write(logunit,*) 'ablat_renorm_factor = ', ablat_renorm_factor + endif - if (mastertask) then - write(logunit,*) 'accum_renorm_factor = ', accum_renorm_factor - write(logunit,*) 'ablat_renorm_factor = ', ablat_renorm_factor - endif + 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 - 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) diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 0526beef7..32dc288a8 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -15,7 +15,7 @@ module med_phases_prep_lnd_mod use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated use esmFlds , only : complnd, compatm, ncomps, compname - use esmFlds , only : max_icesheets, num_icesheets, compglc1, compglc2 + use esmFlds , only : max_icesheets, num_icesheets, compglc use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname use esmFlds , only : fldListTo use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose @@ -42,11 +42,12 @@ module med_phases_prep_lnd_mod 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_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' + character(len =*), parameter :: Sg_topo = 'Sg_topo' + character(len =*), parameter :: Flgg_hflx = 'Flgg_hflx' type, public :: ice_sheet_tolnd_type character(CS) :: name @@ -68,6 +69,7 @@ module med_phases_prep_lnd_mod ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + logical :: glc2lnd_coupling = .false. logical :: cism_evolve = .false. character(*) , parameter :: u_FILE_u = & @@ -86,7 +88,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) ! local variables type(ESMF_StateItem_Flag) :: itemType type(InternalState) :: is_local - integer :: n1,ncnt + integer :: n1,ncnt,ns real(r8) :: nextsw_cday logical :: first_call = .true. logical :: isPresent @@ -135,9 +137,10 @@ subroutine med_phases_prep_lnd(gcomp, rc) call t_startf('MED:'//trim(subname)//' map') do n1 = 1,ncomps - ! Skip glc here and handle it below + ! Skip glc here and handle it below - only components that are allowed to couple to + ! land are atm, rof and glc if (is_local%wrap%med_coupling_active(n1,complnd)) then - if (n1 /= compglc1 .and. n1 /= compglc2) then ! TODO: improve this logic + if (n1 == compatm .or. n1 == complnd) then call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,complnd), & @@ -151,26 +154,34 @@ subroutine med_phases_prep_lnd(gcomp, rc) end do call t_stopf('MED:'//trim(subname)//' map') - ! The following is only done if glc->lnd coupling is active - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - if (first_call) then - call t_startf('MED:'//trim(subname)//' glc2lnd init') - call map_glc2lnd_init(gcomp, ns, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, ns, rc=rc) + ! determine if there will be any glc to lnd coupling + if (first_call) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + glc2lnd_coupling = .true. + exit + end if + end do + end if + + ! the following is only done if glc->lnd coupling is active + if (glc2lnd_coupling) then + if (first_call) then + call t_startf('MED:'//trim(subname)//' glc2lnd init') + call map_glc2lnd_init(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd init') + else + if (cism_evolve) then + call t_startf('MED:'//trim(subname)//' glc2lnd ') + call map_glc2lnd(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd init') - else - if (cism_evolve) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call map_glc2lnd(gcomp, ns, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - end if + call t_stopf('MED:'//trim(subname)//' glc2lnd') end if end if - end do ! end of loop over ice sheets (ns) + end if !--------------------------------------- ! auto merges to create FBExp(complnd) @@ -248,7 +259,7 @@ subroutine map_glc2lnd_init(gcomp, rc) type(ESMF_Mesh) :: mesh_l integer :: ungriddedUBound_output(1) integer :: fieldCount - integer :: s + integer :: ns type(ESMF_Field), pointer :: fieldlist(:) => null() character(len=*) , parameter :: subname='(map_glc2lnd_mod:map_glc2lnd_init)' !--------------------------------------- @@ -275,9 +286,9 @@ subroutine map_glc2lnd_init(gcomp, rc) ungriddedCount = ungriddedUBound_output(1) ! TODO: check that ungriddedCount = glc_nec+1 - !--------------------------------------- - ! Get the glc and land meshes - !--------------------------------------- + ! ------------------------------- + ! Create module fields on land mesh + ! ------------------------------- call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -288,23 +299,6 @@ subroutine map_glc2lnd_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(fieldlist) - do ns = 1,max_icesheets - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=ice_sheet_tolnd(ns)%mesh_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) - end do - - ! ------------------------------- - ! Create module fields on land mesh - ! ------------------------------- - field_icemask_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -323,38 +317,52 @@ subroutine map_glc2lnd_init(gcomp, rc) ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! ------------------------------- - ! Create module fields on glc mesh - ! ------------------------------- + !--------------------------------------- + ! create module fields on glc mesh + !--------------------------------------- do ns = 1,max_icesheets - 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 + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=ice_sheet_tolnd(ns)%mesh_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist) - 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_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_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 + 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 - ! 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 + 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 @@ -384,22 +392,25 @@ subroutine map_glc2lnd( gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield + type(ESMF_Field) :: field_src integer :: ec, l, g, ns 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 :: frac_l_ec_sum(:,:) => 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 :: topo_l_ec_sum(:,:) => 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 :: icemask_l_sum(:) => null() + real(r8), pointer :: icemask_coupled_fluxes_l_sum(:) => null() character(len=*), parameter :: subname = 'map_glc2lnd' !----------------------------------------------------------------------- @@ -433,179 +444,184 @@ subroutine map_glc2lnd( gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayptr=topo_l_ec_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - topo_l_ec_sum(:,) = 0._r8 + topo_l_ec_sum(:,:) = 0._r8 - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask), & field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=sg_icemask_sum, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=icemask_l_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - sg_icemask_sum(:) = 0._r8 + icemask_l_sum(:) = 0._r8 call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask_coupled_fluxes), & field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=sg_icemask_coupled_fluxes_sum, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=icemask_coupled_fluxes_l_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - sg_icemask_coupled_fluxes_sum(:) = 0._r8 + icemask_coupled_fluxes_l_sum(:) = 0._r8 !--------------------------------- ! Map fractional ice coverage to the land grid (multiple elevation classes) !--------------------------------- do ns = 1,max_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - ! Map Sg_icemask (no elevation classes) - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns),compglc(ns)), & - fieldname=trim(Sg_icemask), field=field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field( & - field_src=field_src, & - 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 - call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - sg_icemask_sum(:) = sg_icemask_sum(:) + icemask_l(:) + ! Map Sg_icemask (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + fieldname=trim(Sg_icemask), field=field_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field( & + field_src=field_src, & + 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 + call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + icemask_l_sum(:) = icemask_l_sum(:) + dataptr1d(:) - ! Map Sg_icemask_coupled_fluxes (no elevation classes) - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns),compglc(ns)), & - fieldname=trim(Sg_icemask_coupled_fluxes), field=fieldsrc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field( & - field_src=field_src, & - field_dst=field_dst, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Map Sg_icemask_coupled_fluxes (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns), compglc(ns)), & + fieldname=trim(Sg_icemask_coupled_fluxes), field=field_src, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field( & + field_src=field_src, & + field_dst=field_icemask_coupled_fluxes_l, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + icemask_coupled_fluxes_l_sum(:) = icemask_coupled_fluxes_l_sum(:) + dataptr1d(:) - ! Set contents of FBglc_ec to contain frac_g_ec - ! (fractional ice coverage for each elevation class on the glc grid) + ! 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(ns),compglc(ns)), 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 + ! 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(ns),compglc(ns)), 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(ns),compglc(ns)), 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 frac_g_ec + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%field_icemask_g, farrayptr=icemask_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_g(:) = dataptr1d(:) + ! compute icemask_g + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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(ice_sheet_tolnd(ns)%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 + ! 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(ice_sheet_tolnd(ns)%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=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 + ! 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 ESMF_fieldGet(field_frac_l_ec, farrayptr=frac_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = frac_l_ec_sum(:,:) + frac_l_ec(:,:) + ! now set values in land export state for Sg_frac_elev (this is summed over all ice sheets) + call ESMF_fieldGet(field_frac_l_ec, farrayptr=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) - !--------------------------------- + !--------------------------------- + ! 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 + ! 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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ice_sheet_tolnd(ns)%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 - 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 ESMF_FieldGet(field_topo_x_icemask_l_ec, farrayptr=topo_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! 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 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=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 ESMF_FieldGet(field_frac_x_icemask_l_ec, farrayptr=frac_x_icemask_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 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. - 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) + ! 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 if + end do end do - end do + end if end do if (dbug_flag > 5) then From ec373dc47cf66c26ecdd29694da4bd1fa3815a4a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 15 Nov 2020 12:47:57 -0700 Subject: [PATCH 151/206] cleaned up interface for addmrg to remove 1 index --- mediator/esmFlds.F90 | 29 ++-- mediator/esmFldsExchange_cesm_mod.F90 | 188 +++++++++++++------------- mediator/esmFldsExchange_hafs_mod.F90 | 56 +++++--- mediator/esmFldsExchange_nems_mod.F90 | 36 ++--- 4 files changed, 164 insertions(+), 145 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index e97bcc301..154bac8d2 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -20,7 +20,14 @@ module esmflds 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/) @@ -215,7 +222,7 @@ end subroutine med_fldList_AddFld !================================================================================ - subroutine med_fldList_AddMrg(flds, fldname, mrg_from1, mrg_fld1, mrg_type1, mrg_fracname1) + subroutine med_fldList_AddMrg(flds, fldname, mrg_from1, mrg_fld1, mrg_type1, mrg_fracname) ! ---------------------------------------------- ! Determine mrg entry or entries in flds aray @@ -226,10 +233,10 @@ subroutine med_fldList_AddMrg(flds, fldname, mrg_from1, mrg_fld1, mrg_type1, mrg ! input/output variables type(med_fldList_entry_type) , pointer :: flds(:) character(len=*) , intent(in) :: fldname - integer , intent(in) :: mrg_from1 - character(len=*) , intent(in) :: mrg_fld1 - character(len=*) , intent(in) :: mrg_type1 - character(len=*) , intent(in), optional :: mrg_fracname1 + 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 @@ -251,11 +258,11 @@ subroutine med_fldList_AddMrg(flds, fldname, mrg_from1, mrg_fld1, mrg_type1, mrg call ESMF_Finalize(endflag=ESMF_END_ABORT) end if - 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 + 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 diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 8fd062765..8e747f9aa 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -362,7 +362,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -420,7 +420,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -450,7 +450,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -521,19 +521,19 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n)), & compatm, mapconsf, 'lfrin', lnd2atm_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_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_from1=compice, mrg_fld1='Si_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') + 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_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='So_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') end if end if end if @@ -563,18 +563,18 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=complnd, mrg_fld1='Sl_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac') + 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_from1=compice, mrg_fld1='Si_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') + 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_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='So_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') end if end if end if @@ -610,17 +610,17 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=complnd, mrg_fld1='Fall_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac') + 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(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_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=compice, mrg_fld1='Faii_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') + 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(fldListFr(compice)%flds , 'Faii_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_fmap) + 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') + mrg_from=compmed, mrg_fld='Faox_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') end if end if end if @@ -641,22 +641,22 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=complnd, mrg_fld1='Sl_t', mrg_type1='merge', mrg_fracname1='lfrac') + 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_from1=compice, mrg_fld1='Si_t', mrg_type1='merge', mrg_fracname1='ifrac') + 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_from1=compocn, mrg_fld1='So_t', mrg_type1='merge', mrg_fracname1='ofrac') + 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 @@ -681,7 +681,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -708,7 +708,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -735,7 +735,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -753,7 +753,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 @@ -769,7 +769,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 @@ -786,7 +786,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 @@ -800,7 +800,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 @@ -816,7 +816,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 @@ -832,7 +832,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 ! --------------------------------------------------------------------- @@ -859,7 +859,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), 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 @@ -875,7 +875,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 @@ -893,9 +893,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_from=compmed, mrg_fld='Faox_lwup', mrg_type='merge', mrg_fracname='ofrac') call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compatm, mrg_fld1='Faxa_lwdn', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld='Faxa_lwdn', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -910,7 +910,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 @@ -993,11 +993,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') + 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_from1=compice, mrg_fld1='Fioi_swpen_ifrac_n', mrg_type1='copy') + 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 @@ -1038,18 +1038,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') + 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. & @@ -1058,18 +1058,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') + mrg_from=compatm, mrg_fld='Faxa_snow'//iso(n), mrg_type='copy') end if end do end if @@ -1086,7 +1086,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 @@ -1104,12 +1104,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 @@ -1120,7 +1120,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 @@ -1136,7 +1136,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 @@ -1154,7 +1154,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 @@ -1184,7 +1184,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 @@ -1207,9 +1207,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_from=compmed, mrg_fld='Faox_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & - mrg_from1=compice, mrg_fld1='Fioi_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ifrac') + mrg_from=compice, mrg_fld='Fioi_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ifrac') end if end if end do @@ -1227,7 +1227,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 @@ -1259,7 +1259,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 @@ -1298,11 +1298,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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:F'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofl:Flrr_flood', mrg_type1='sum') + 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_from1=comprof, mrg_fld1='Forr_rofl', mrg_type1='sum') + mrg_from=comprof, mrg_fld='Forr_rofl', mrg_type='sum') end if end if ! liquid from glc to ocean @@ -1312,7 +1312,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_from1=compglc(ns), mrg_fld1='Fogg_rofl'//iso(n), mrg_type1='sum') + mrg_from=compglc(ns), mrg_fld='Fogg_rofl'//iso(n), mrg_type='sum') end if end do end if @@ -1324,7 +1324,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n) , & compocn, map_rof2ocn_liq, 'none', rof2ocn_ice_rmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofi', mrg_type1='sum') + mrg_from=comprof, mrg_fld='Forr_rofi', mrg_type='sum') end if ! ice from glc to ocean do ns = 1, num_icesheets @@ -1333,7 +1333,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compglc(ns))%flds, 'Fogg_rofi'//iso(n), & compocn, map_glc2ocn_liq, 'one' , glc2ocn_ice_rmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & - mrg_from1=compglc(ns), mrg_fld1='Fogg_rofi'//iso(n), mrg_type1='sum') + mrg_from=compglc(ns), mrg_fld='Fogg_rofi'//iso(n), mrg_type='sum') end if end do end if @@ -1363,7 +1363,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 @@ -1408,7 +1408,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 @@ -1435,12 +1435,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. & @@ -1448,12 +1448,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 @@ -1474,12 +1474,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. & @@ -1487,12 +1487,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 @@ -1525,7 +1525,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 @@ -1552,7 +1552,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 @@ -1569,7 +1569,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') + mrg_from=compocn, mrg_fld='Fioo_q', mrg_type='copy') end if end if @@ -1584,7 +1584,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') + mrg_from=compocn, mrg_fld='So_roce_wiso', mrg_type='copy') end if end if @@ -1604,14 +1604,14 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') + 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_from1=compglc(ns), mrg_fld1='Figg_rofi'//iso(n), mrg_type1='sum') + mrg_from=compglc(ns), mrg_fld='Figg_rofi'//iso(n), mrg_type='sum') end if end do end if @@ -1634,7 +1634,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 @@ -1657,7 +1657,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(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') + mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1680,7 +1680,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 @@ -1716,7 +1716,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 @@ -1792,9 +1792,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 ! --------------------------------------------------------------------- @@ -1809,9 +1809,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 @@ -1825,7 +1825,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 ! --------------------------------------------------------------------- @@ -1837,7 +1837,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 ! --------------------------------------------------------------------- @@ -1849,7 +1849,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 @@ -1866,9 +1866,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 ! --------------------------------------------------------------------- @@ -1883,9 +1883,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 ! --------------------------------------------------------------------- @@ -1897,7 +1897,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 ! --------------------------------------------------------------------- @@ -1920,7 +1920,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 8938cf3d7..07a577d74 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -121,9 +121,9 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) ! to atm: unmerged from ice ! - zonal surface stress, meridional surface stress - ! - surface latent heat flux, + ! - surface latent heat flux, ! - surface sensible heat flux - ! - surface upward longwave heat flux + ! - surface upward longwave heat flux ! - evaporation water flux from water ! - mean ice volume per unit area ! - mean snow volume per unit area @@ -137,7 +137,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) @@ -145,7 +145,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) @@ -155,7 +155,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 @@ -195,7 +195,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) @@ -217,7 +217,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') @@ -237,30 +237,30 @@ 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_from=compmed, mrg_fld='Faox_'//trim(flds(n)), mrg_type='merge', mrg_fracname='ofrac') call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(flds(n)), & - mrg_from1=compice, mrg_fld1='Fioi_'//trim(flds(n)), mrg_type1='merge', mrg_fracname1='ifrac') + mrg_from=compice, mrg_fld='Fioi_'//trim(flds(n)), mrg_type='merge', mrg_fracname='ifrac') end do deallocate(flds) - ! to ocn: long wave net via auto merge + ! to ocn: long wave net via auto merge call addfld(fldListTo(compocn)%flds, 'Foxx_lwnet') 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_from=compmed, mrg_fld='Faox_lwup', mrg_type='merge', mrg_fracname='ofrac') call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compatm, mrg_fld1='Faxa_lwdn', mrg_type1='merge', mrg_fracname1='ofrac') + 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 @@ -274,7 +274,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) @@ -299,7 +299,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) @@ -317,7 +317,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) @@ -336,7 +336,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) From c45fa5554e40ba6d72966b210708f4f3a9f46b5f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 15 Nov 2020 14:37:58 -0700 Subject: [PATCH 152/206] fixed compilation issue --- mediator/esmFlds.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 154bac8d2..6451389a1 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -222,7 +222,7 @@ end subroutine med_fldList_AddFld !================================================================================ - subroutine med_fldList_AddMrg(flds, fldname, mrg_from1, mrg_fld1, mrg_type1, mrg_fracname) + subroutine med_fldList_AddMrg(flds, fldname, mrg_from, mrg_fld, mrg_type, mrg_fracname) ! ---------------------------------------------- ! Determine mrg entry or entries in flds aray From f5146b2b0548d12fafee6c4aae9a1f2868479193 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 15 Nov 2020 20:52:12 -0700 Subject: [PATCH 153/206] more updates and fixes for multiple ice sheets --- mediator/esmFldsExchange_cesm_mod.F90 | 2 +- mediator/med.F90 | 22 ++++++- mediator/med_phases_prep_lnd_mod.F90 | 82 ++++++++++++++------------- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 8e747f9aa..4ec6222d1 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1291,7 +1291,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else do n = 1,size(iso) if ( fldchk(is_local%wrap%FBExp(compocn), 'Foxx_rofl'//iso(n) , rc=rc)) then - ! liquid from river and possibly flood from river + ! 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) diff --git a/mediator/med.F90 b/mediator/med.F90 index 3b29c08ee..ebacfb7d3 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1779,6 +1779,7 @@ subroutine DataInitialize(gcomp, rc) ! 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 @@ -1789,6 +1790,10 @@ subroutine DataInitialize(gcomp, rc) 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. @@ -1824,7 +1829,7 @@ subroutine DataInitialize(gcomp, rc) endif enddo - ! create table of active coupling flags + ! 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. @@ -1834,7 +1839,20 @@ subroutine DataInitialize(gcomp, rc) 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) + 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) + 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 diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 32dc288a8..4a1e109ea 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -14,7 +14,7 @@ module med_phases_prep_lnd_mod 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, ncomps, compname + use esmFlds , only : complnd, compatm, comprof, ncomps, compname use esmFlds , only : max_icesheets, num_icesheets, compglc use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname use esmFlds , only : fldListTo @@ -132,7 +132,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then !--------------------------------------- - ! map to create FBimp(:,complnd) + ! map to create FBimp(:,complnd) - other than glc->lnd !--------------------------------------- call t_startf('MED:'//trim(subname)//' map') @@ -140,7 +140,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) ! Skip glc here and handle it below - only components that are allowed to couple to ! land are atm, rof and glc if (is_local%wrap%med_coupling_active(n1,complnd)) then - if (n1 == compatm .or. n1 == complnd) then + if (n1 == comprof .or. n1 == compatm) then call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(n1,n1), & FBDst=is_local%wrap%FBImp(n1,complnd), & @@ -154,6 +154,28 @@ subroutine med_phases_prep_lnd(gcomp, rc) end do call t_stopf('MED:'//trim(subname)//' map') + !--------------------------------------- + ! auto merges to create FBExp(complnd) - other than glc->lnd + !--------------------------------------- + + ! The following will merge all fields in fldsSrc + ! Note that there is no merge for glc Sg_icemask and Sg_icemask_coupled_fluxes) + ! these are mapped and set directly in map_glc2lnd + + call t_startf('MED:'//trim(subname)//' merge') + call med_merge_auto(complnd, & + is_local%wrap%med_coupling_active(:,complnd), & + is_local%wrap%FBExp(complnd), & + is_local%wrap%FBFrac(complnd), & + is_local%wrap%FBImp(:,complnd), & + fldListTo(complnd), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' merge') + + !--------------------------------------- + ! mapping and merging for glc->lnd + !--------------------------------------- + ! determine if there will be any glc to lnd coupling if (first_call) then do ns = 1,num_icesheets @@ -174,33 +196,15 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' glc2lnd init') else - if (cism_evolve) then + !if (cism_evolve) then call t_startf('MED:'//trim(subname)//' glc2lnd ') call map_glc2lnd(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' glc2lnd') - end if + !end if end if end if - !--------------------------------------- - ! auto merges to create FBExp(complnd) - !--------------------------------------- - - ! The following will merge all fields in fldsSrc - ! Note that there is no merge for glc Sg_icemask and Sg_icemask_coupled_fluxes) - ! these are mapped and set directly in map_glc2lnd - - call t_startf('MED:'//trim(subname)//' merge') - call med_merge_auto(complnd, & - is_local%wrap%med_coupling_active(:,complnd), & - is_local%wrap%FBExp(complnd), & - is_local%wrap%FBFrac(complnd), & - is_local%wrap%FBImp(:,complnd), & - fldListTo(complnd), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' merge') - !--------------------------------------- ! update scalar data !--------------------------------------- @@ -259,7 +263,7 @@ subroutine map_glc2lnd_init(gcomp, rc) type(ESMF_Mesh) :: mesh_l integer :: ungriddedUBound_output(1) integer :: fieldCount - integer :: ns + integer :: ns,n type(ESMF_Field), pointer :: fieldlist(:) => null() character(len=*) , parameter :: subname='(map_glc2lnd_mod:map_glc2lnd_init)' !--------------------------------------- @@ -323,6 +327,7 @@ subroutine map_glc2lnd_init(gcomp, rc) do ns = 1,max_icesheets if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -334,7 +339,6 @@ subroutine map_glc2lnd_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return deallocate(fieldlist) - 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 @@ -393,7 +397,7 @@ subroutine map_glc2lnd( gcomp, rc) type(InternalState) :: is_local type(ESMF_Field) :: lfield type(ESMF_Field) :: field_src - integer :: ec, l, g, ns + 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 @@ -432,39 +436,39 @@ subroutine map_glc2lnd( gcomp, rc) ! Get pointers into land export field bundle (this is summed over all ice sheets) !--------------------------------- - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_frac)//'_elev', & + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask), & field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_fieldGet(lfield, farrayptr=frac_l_ec_sum, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=icemask_l_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = 0._r8 + icemask_l_sum(:) = 0._r8 - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_topo)//'_elev', & + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask_coupled_fluxes), & field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=topo_l_ec_sum, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=icemask_coupled_fluxes_l_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - topo_l_ec_sum(:,:) = 0._r8 + icemask_coupled_fluxes_l_sum(:) = 0._r8 - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask), & + 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=icemask_l_sum, rc=rc) + call ESMF_fieldGet(lfield, farrayptr=frac_l_ec_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_l_sum(:) = 0._r8 + frac_l_ec_sum(:,:) = 0._r8 - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask_coupled_fluxes), & + 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=icemask_coupled_fluxes_l_sum, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=topo_l_ec_sum, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_coupled_fluxes_l_sum(:) = 0._r8 + topo_l_ec_sum(:,:) = 0._r8 !--------------------------------- ! Map fractional ice coverage to the land grid (multiple elevation classes) !--------------------------------- - do ns = 1,max_icesheets + do ns = 1,num_icesheets if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then ! Map Sg_icemask (no elevation classes) From ab8b4fdb46dbac4230aa8321ae829940f3a507a2 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 16 Nov 2020 08:53:15 -0700 Subject: [PATCH 154/206] fix preplnd bug --- mediator/med_phases_prep_lnd_mod.F90 | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 63cdf85f7..bcb0b6ce7 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -149,31 +149,16 @@ subroutine med_phases_prep_lnd(gcomp, rc) call t_stopf('MED:'//trim(subname)//' glc2lnd init') ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - if (cism_evolve) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc,compglc), & - FBDst=is_local%wrap%FBImp(compglc,complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc), & - field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & - packed_data=is_local%wrap%packed_data(compglc,complnd,:), & - routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - else if (first_call) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc,compglc), & - FBDst=is_local%wrap%FBImp(compglc,complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc), & - field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & - packed_data=is_local%wrap%packed_data(compglc,complnd,:), & - routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if + call t_startf('MED:'//trim(subname)//' glc2lnd ') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc,compglc), & + FBDst=is_local%wrap%FBImp(compglc,complnd), & + FBFracSrc=is_local%wrap%FBFrac(compglc), & + field_normOne=is_local%wrap%field_normOne(compglc,complnd,:), & + packed_data=is_local%wrap%packed_data(compglc,complnd,:), & + routehandles=is_local%wrap%RH(compglc,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd') end if !--------------------------------------- @@ -192,6 +177,21 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' merge') + !--------------------------------------- + ! glc-lnd custom mapping and merging + !--------------------------------------- + + ! 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 !--------------------------------------- From 51562ca0bb13dd650749156400e2fa1bf7b2a5d5 Mon Sep 17 00:00:00 2001 From: jedwards4b Date: Fri, 4 Sep 2020 10:04:32 -0600 Subject: [PATCH 155/206] Merge pull request #99 from danrosen25/fix/esmfversion Fix CPP ESMF_VERSION_MAJOR and ESMF_VERSION_MINOR definitions. --- mediator/Makefile | 5 +++++ mediator/esmFlds.F90 | 21 ++++++++++++--------- mediator/med.F90 | 12 +++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/mediator/Makefile b/mediator/Makefile index 574d19357..abdf9826e 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -13,6 +13,11 @@ ifeq ($(INTERNAL_PIO_INIT),1) CPPDEFS += -DINTERNAL_PIO_INIT endif +ESMF_VERSION_MAJOR ?= 0 +ESMF_VERSION_MINOR ?= 0 +CPPDEFS += -DESMF_VERSION_MAJOR=$(ESMF_VERSION_MAJOR) +CPPDEFS += -DESMF_VERSION_MINOR=$(ESMF_VERSION_MINOR) + LIBRARY := libcmeps.a OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 6f2396923..82dd03fdd 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -373,9 +373,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 +395,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 +464,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 +480,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 +491,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/med.F90 b/mediator/med.F90 index cfb71f5cf..4953d5e57 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -882,9 +882,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 @@ -916,9 +918,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, & @@ -926,9 +930,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, & From a3d734503f896254a6686d57b459f115d6ce4e8f Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 16 Nov 2020 15:00:32 -0700 Subject: [PATCH 156/206] updates to get I2000 compset identical to the nov15 baseline --- mediator/esmFldsExchange_cesm_mod.F90 | 19 ++++- mediator/med_phases_prep_lnd_mod.F90 | 117 +++++++++++++------------- 2 files changed, 76 insertions(+), 60 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 4ec6222d1..e382e435a 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -468,7 +468,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if (phase == 'advertise') then 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') ! 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 @@ -480,7 +480,22 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListTo(complnd)%flds, 'Sg_topo_elev') call addfld(fldListTo(complnd)%flds, 'Flgg_hflx_elev') else - ! custom map and merge in med_phases_prep_lnd + 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 + ! 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 end if !===================================================================== diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 4a1e109ea..11c19f3f4 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -60,8 +60,7 @@ module med_phases_prep_lnd_mod 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_icemask_coupled_fluxes_l ! no elevation classes + 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 @@ -192,17 +191,13 @@ subroutine med_phases_prep_lnd(gcomp, rc) call t_startf('MED:'//trim(subname)//' glc2lnd init') call map_glc2lnd_init(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' glc2lnd init') - else - !if (cism_evolve) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - !end if end if + ! 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') + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd') end if !--------------------------------------- @@ -259,7 +254,7 @@ subroutine map_glc2lnd_init(gcomp, rc) ! local variables type(InternalState) :: is_local - type(ESMF_Field) :: lfield + type(ESMF_Field) :: lfield_l type(ESMF_Mesh) :: mesh_l integer :: ungriddedUBound_output(1) integer :: fieldCount @@ -283,9 +278,9 @@ subroutine map_glc2lnd_init(gcomp, rc) !--------------------------------------- ! 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) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname='Sg_topo_elev', field=lfield_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) + 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 @@ -306,9 +301,6 @@ subroutine map_glc2lnd_init(gcomp, rc) 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_icemask_coupled_fluxes_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 @@ -361,8 +353,7 @@ subroutine map_glc2lnd_init(gcomp, rc) ! 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, & + ice_sheet_tolnd(ns)%field_icemask_g, lfield_l, & mapindex=mapconsd, & routehandles=is_local%wrap%rh(compglc(ns),complnd,:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -396,7 +387,8 @@ subroutine map_glc2lnd( gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield - type(ESMF_Field) :: field_src + 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 @@ -413,8 +405,8 @@ subroutine map_glc2lnd( gcomp, rc) real(r8), pointer :: dataptr2d(:,:) => null() real(r8), pointer :: frac_l_ec_sum(:,:) => null() real(r8), pointer :: topo_l_ec_sum(:,:) => null() - real(r8), pointer :: icemask_l_sum(:) => null() - real(r8), pointer :: icemask_coupled_fluxes_l_sum(:) => null() + real(r8), pointer :: dataptr1d_src(:) => null() + real(r8), pointer :: dataptr1d_dst(:) => null() character(len=*), parameter :: subname = 'map_glc2lnd' !----------------------------------------------------------------------- @@ -436,20 +428,6 @@ subroutine map_glc2lnd( gcomp, rc) ! Get pointers into land export field bundle (this is summed over all ice sheets) !--------------------------------- - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask), & - field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=icemask_l_sum, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_l_sum(:) = 0._r8 - - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_icemask_coupled_fluxes), & - field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=icemask_coupled_fluxes_l_sum, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_coupled_fluxes_l_sum(:) = 0._r8 - 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 @@ -468,37 +446,60 @@ subroutine map_glc2lnd( gcomp, rc) ! 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 - ! Map Sg_icemask (no elevation classes) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - fieldname=trim(Sg_icemask), field=field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field( & - field_src=field_src, & - field_dst=field_icemask_l, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) + ! Get Sg_icemask on land as sum of all ice sheets (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), Sg_icemask, & + field=lfield_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_dst, farrayPtr=dataptr1d_dst, rc=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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask, & + field=lfield_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) + call ESMF_FieldGet(lfield_src, farrayPtr=dataptr1d_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_l_sum(:) = icemask_l_sum(:) + dataptr1d(:) + dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) + end if + end do - ! Map Sg_icemask_coupled_fluxes (no elevation classes) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns), compglc(ns)), & - fieldname=trim(Sg_icemask_coupled_fluxes), field=field_src, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_map_field( & - field_src=field_src, & - field_dst=field_icemask_coupled_fluxes_l, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) + ! Get Sg_icemask_coupled_fluxes on land as sum of all ice sheets (no elevation classes) + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), Sg_icemask_coupled_fluxes, & + field=lfield_dst, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_dst, farrayPtr=dataptr1d_dst, rc=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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask_coupled_fluxes, & + field=lfield_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_fieldGet(field_icemask_l, farrayptr=dataptr1d, rc=rc) + call ESMF_FieldGet(lfield_src, farrayPtr=dataptr1d_src, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_coupled_fluxes_l_sum(:) = icemask_coupled_fluxes_l_sum(:) + dataptr1d(:) + 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 contents of FBglc_ec to contain frac_g_ec ! (fractional ice coverage for each elevation class on the glc grid) From 7de506d20d63409633721591f10434326d335ed2 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 17 Nov 2020 07:58:40 -0700 Subject: [PATCH 157/206] cleanup merge issue --- mediator/Makefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mediator/Makefile b/mediator/Makefile index abdf9826e..f1c9b5ea1 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 @@ -13,11 +15,6 @@ ifeq ($(INTERNAL_PIO_INIT),1) CPPDEFS += -DINTERNAL_PIO_INIT endif -ESMF_VERSION_MAJOR ?= 0 -ESMF_VERSION_MINOR ?= 0 -CPPDEFS += -DESMF_VERSION_MAJOR=$(ESMF_VERSION_MAJOR) -CPPDEFS += -DESMF_VERSION_MINOR=$(ESMF_VERSION_MINOR) - LIBRARY := libcmeps.a OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) From 3810a7a000e993267e1774c9a985891db3f9d137 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 21 Nov 2020 15:57:34 -0700 Subject: [PATCH 158/206] Call GLC at the end of the day rather than the start Previously, CISM was being called at the start of December 31, with data from December 31 of the previous year through December 30 of the current year. The desired behavior is for CISM to be called at the end of December 31, with data from January 1 of the current year through December 31 of the current year. This commit fixes that behavior. --- cime_config/runseq/runseq_general.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index e68a57624..4b277dee3 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -61,11 +61,6 @@ 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) #------------------ @@ -166,4 +161,9 @@ def gen_runseq(case, coupling_times): runseq.leave_time_loop(rof_outer_loop) #------------------ + 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) + shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) From f04a4fdc91cbb0acca086897689f6e2b08a182c7 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 24 Nov 2020 13:05:08 -0700 Subject: [PATCH 159/206] pass areag for smb normalization --- cime_config/runseq/runseq_general.py | 10 +- mediator/esmFldsExchange_cesm_mod.F90 | 1 + mediator/fd_cesm.yaml | 4 + mediator/med.F90 | 85 +--- mediator/med_internalstate_mod.F90 | 1 + mediator/med_phases_prep_glc_mod.F90 | 591 +++++++++++++------------- 6 files changed, 318 insertions(+), 374 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index e68a57624..4b277dee3 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -61,11 +61,6 @@ 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) #------------------ @@ -166,4 +161,9 @@ def gen_runseq(case, coupling_times): runseq.leave_time_loop(rof_outer_loop) #------------------ + 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) + shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 1040f6c46..9c37b4d8d 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -262,6 +262,7 @@ 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') + call addfld(fldlistFr(compglc)%flds, 'Sg_area') else call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') end if diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 08cba35a1..8d5812804 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) diff --git a/mediator/med.F90 b/mediator/med.F90 index 4953d5e57..8ce2b2bbd 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -882,11 +882,9 @@ 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_MAJOR >= 8 -#if ESMF_VERSION_MINOR > 0 +#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 @@ -918,11 +916,9 @@ 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_MAJOR >= 8 -#if ESMF_VERSION_MINOR > 0 +#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, & @@ -930,11 +926,9 @@ 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_MAJOR >= 8 -#if ESMF_VERSION_MINOR > 0 +#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, & @@ -2236,6 +2230,7 @@ subroutine DataInitialize(gcomp, rc) call med_phases_restart_read(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif + call med_phases_profile(gcomp, rc) else ! Not all done @@ -2273,10 +2268,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) ' !----------------------------------------------------------- @@ -2311,47 +2302,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 !-------------------------------- @@ -2386,8 +2336,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(:) @@ -2398,34 +2346,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 @@ -2435,6 +2381,11 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) end do deallocate(ownedElemCoords) + ! Obtain mesh mask + allocate(mesh_info%mask(numOwnedElements)) + call ESMF_MeshGet(lmesh, elementMask=mesh_info%mask, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end subroutine med_meshinfo_create !----------------------------------------------------------------------------- diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 149d10374..80bc97b3d 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -43,6 +43,7 @@ module med_internalstate_mod ! med atm lnd ocn ice rof wav glc type, public :: mesh_info_type + integer , pointer :: mask(:) => null() real(r8), pointer :: areas(:) => null() real(r8), pointer :: lats(:) => null() real(r8), pointer :: lons(:) => null() diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 24dc79e2b..610111ad6 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -6,18 +6,19 @@ module med_phases_prep_glc_mod 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 + use esmFlds , only : compglc, complnd, mapbilnr, mapconsf, compname 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 @@ -25,10 +26,13 @@ module med_phases_prep_glc_mod 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_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_elevation_classes, glc_get_elevation_class 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 + use shr_mpi_mod , only : shr_mpi_sum implicit none private @@ -58,28 +62,22 @@ module med_phases_prep_glc_mod 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_icemask_g + type(ESMF_Field) :: field_icemask_l + type(ESMF_Field) :: field_frac_g + type(ESMF_Field) :: field_frac_l + type(ESMF_Field) :: field_frac_g_ec + type(ESMF_Field) :: field_frac_l_ec 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 + 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) + logical :: init_prep_glc = .false. + type(ESMF_Clock) :: prepglc_clock character(*), parameter :: u_FILE_u = & __FILE__ @@ -108,14 +106,18 @@ subroutine med_phases_prep_glc_init(gcomp, rc) 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,6 +127,41 @@ subroutine med_phases_prep_glc_init(gcomp, rc) endif rc = ESMF_SUCCESS + ! First 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 + + ! 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 + 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 + !--------------------------------------- ! Get the internal state !--------------------------------------- @@ -252,53 +289,32 @@ 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) + 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_glc_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_icemask_l = ESMF_FieldCreate(lmesh_lnd, 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) + field_frac_g = ESMF_FieldCreate(lmesh_glc, 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) + field_frac_l = ESMF_FieldCreate(lmesh_lnd, 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, & + 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_glc_frac_l_ec = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + 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 @@ -327,8 +343,9 @@ subroutine med_phases_prep_glc_accum(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 + ! Accumulation and averaging is done on the land input field to glc on the land grid + ! Mapping from the land to the glc grid is then done after the accumulated fields have been + ! time averaged !--------------------------------------- ! input/output variables @@ -338,10 +355,11 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield + type(ESMF_Alarm) :: alarm integer :: i,n,ncnt 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) @@ -351,59 +369,47 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) 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 - !--------------------------------------- - ! 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) - 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 + ! Advance prepglc_clock - this will make the prepglc_clock in sync with the mediator clock + call ESMF_ClockAdvance(prepglc_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - 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 + ! Accumulate fields + 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 + end do - FBlndAccumCnt = FBlndAccumCnt + 1 + ! Increment accumulation counter + 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 + 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 if (dbug_flag > 5) then @@ -425,14 +431,18 @@ 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_Clock) :: med_clock + type(ESMF_Time) :: med_currtime + type(ESMF_Time) :: prepglc_currtime + integer :: yr_med, mon_med, day_med, sec_med + integer :: yr_prepglc, mon_prepglc, day_prepglc, sec_prepglc + 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) ' !--------------------------------------- call t_startf('MED:'//subname) @@ -442,126 +452,102 @@ subroutine med_phases_prep_glc_avg(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 - !--------------------------------------- - - ! 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(compglc), 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(compglc), returning", & - ESMF_LOGMSG_INFO) - call t_stopf('MED:'//subname) - RETURN - end if - - ! 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 + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + !--------------------------------------- ! Determine if avg alarm is ringing - and if not ringing then return !--------------------------------------- - call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + 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_ClockGetAlarm(clock, alarmname='alarm_glc_avg', alarm=alarm, rc=rc) + 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) + + 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 ! If the is ringing - turn it off and continue - otherwise reset field bundle to zero and return + call ESMF_ClockGetAlarm(prepglc_clock, alarmname='alarm_glc_avg', alarm=alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) 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) + ! 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) + if (mastertask) then + write(logunit,'(a)') trim(subname)//"glc_avg alarm is ringing - averaging input from lnd to glc" + end if + 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_import, rc=rc) + call ESMF_FieldGet(lfield, farrayptr=data2d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - data2d(:,:) = data2d_import(:,:) + 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) + 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 - 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 + ! Initialize accumulated field bundle on the glc grid to zero before doing the mapping + call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=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) + ! Map accumulated field bundle from land grid (with elevation + ! classes) to glc grid (without elevation classes) and set FBExp(compglc) data + call map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - endif - !--------------------------------------- - ! zero accumulator and accumulated field bundles - !--------------------------------------- + ! zero accumulator and accumulated field bundles on both land grid + FBlndAccumCnt = 0 + call FB_reset(FBlndAccum_lnd, value=0.0_r8, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - FBlndAccumCnt = 0 + 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 - 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 + else - !--------------------------------------- - ! update local scalar data - set valid input flag to .true. TODO: - !--------------------------------------- + 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 med_infodata_set_valid_glc_input(.true., med_infodata, rc=rc) ! TODO: fix this - !if (chkErr(rc,__LINE__,u_FILE_u)) return + end if if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) @@ -603,7 +589,7 @@ subroutine map_lnd2glc(gcomp, rc) type(ESMF_Field) :: field_lfrac_l 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=' (map_lnd2glc) ' !--------------------------------------- !--------------------------------------- @@ -664,7 +650,7 @@ subroutine map_lnd2glc(gcomp, rc) endif ! ------------------------------------------------------------------------ - ! Determine elevation class of each glc point on glc grid (output is topoglc_g) + ! Determine elevation class of each glc grid gridcell (elevclass_g) ! ------------------------------------------------------------------------ if (dbug_flag > 1) then @@ -672,16 +658,18 @@ subroutine map_lnd2glc(gcomp, rc) 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) + 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) + 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 + ! 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)) @@ -780,22 +768,17 @@ subroutine map_lnd2glc(gcomp, rc) end if end do ! lsize_g - ! ------------------------------------------------------------------------ - ! 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 + end do ! end of loop over fields - if (smb_renormalize) then - call med_phases_prep_glc_renormalize_smb(gcomp, rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if + ! ------------------------------------------------------------------------ + ! 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. + ! ------------------------------------------------------------------------ - end do ! end of loop over fields + if (smb_renormalize) then + call med_phases_prep_glc_renormalize_smb(gcomp, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if ! clean up memory deallocate(elevclass_g) @@ -838,6 +821,9 @@ 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.) ! + ! 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 !------------------ @@ -847,37 +833,35 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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 + 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 ! 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) @@ -896,24 +880,25 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - ! Map Sg_icemask_g from the glc grid to the land grid. + ! Map icemask_g from the glc grid to the land grid. !--------------------------------------- - ! 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) + ! determine icemask_g and set as contents of field_icemask_g + 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) + call ESMF_FieldGet(field_icemask_g, farrayptr=icemask_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - Sg_icemask_g(:) = dataptr1d(:) + 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, & + field_src=field_icemask_g, & + field_dst=field_icemask_l, & routehandles=is_local%wrap%RH(compglc,complnd,:), & maptype=mapconsf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -922,40 +907,46 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! Map frac_field on glc grid without elevation classes to frac_field on land grid with elevation classes ! ------------------------------------------------------------------------ - ! 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) + ! get topo_g(:), the topographic height of each glc gridcell + 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) + call ESMF_FieldGet(lfield, farrayptr=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) + + ! get frac_g(:), the total ice fraction in each glc gridcell + 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(field_glc_frac_g, farrayptr=glc_frac_g, rc=rc) ! module field + call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) 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 + call ESMF_FieldGet(field_frac_g, farrayptr=frac_g, rc=rc) ! module field if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_g(:) = dataptr1d(:) - ! note that nec = ungriddedCount - 1 - call glc_get_fractional_icecov(ungriddedCount-1, glc_topo_g, glc_frac_g, glc_frac_g_ec, logunit) + ! 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 ESMF_FieldGet(field_frac_g_ec, farrayptr=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) - ! map fraction in each elevation class from the glc grid to the land grid and normalize by the icemask on the - ! glc grid + ! map the 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, & + field_src=field_frac_g_ec, & + field_dst=field_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) + field_normsrc=field_icemask_g, & + field_normdst=field_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) + !--------------------------------------- + ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum + !--------------------------------------- + + ! get fractional ice coverage for each elevation class on the land grid, frac_l_ec(:,:) + call ESMF_FieldGet(field_frac_l_ec, farrayptr=frac_l_ec, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine fraction on land grid, lfrac(:) @@ -964,37 +955,36 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call ESMF_FieldGet(lfield, farrayptr=lfrac, rc=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) + ! get icemask_l + call ESMF_FieldGet(field_icemask_l, farrayptr=icemask_l, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - ! determine qice_l_ec + ! get 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 - !--------------------------------------- - ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum - !--------------------------------------- - 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) - - 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 + if (is_local%wrap%mesh_info(complnd)%mask(n) /= 0) then + ! 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) + + 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) + call ESMF_VMAllreduce(vm, senddata=local_accum_lnd, recvdata=global_accum_lnd, count=1, reduceflag=ESMF_REDUCE_MAX, 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 @@ -1003,31 +993,30 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! Sum qice_g over local glc grid cells. !--------------------------------------- - ! 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 + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname='Sg_area', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=area_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) + 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) + Sg_icemask_g(n) * aream_g(n) * qice_g(n) + 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) + 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 @@ -1035,16 +1024,14 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) else 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,*) 'accum_renorm_factor = ', accum_renorm_factor - write(logunit,*) 'ablat_renorm_factor = ', ablat_renorm_factor + write(logunit,'(a,d13.5)') trim(subname)//'accum_renorm_factor = ', accum_renorm_factor + write(logunit,'(a,d13.5)') trim(subname)//'ablat_renorm_factor = ', ablat_renorm_factor endif do n = 1, size(qice_g) From a9483bb97732fa9d2c1b01f667299c94f340fd99 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 24 Nov 2020 15:07:53 -0700 Subject: [PATCH 160/206] more fixes for glc renormalization --- mediator/esmFldsExchange_cesm_mod.F90 | 6 +++--- mediator/med_phases_prep_glc_mod.F90 | 31 +++++++++++++++++---------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 9c37b4d8d..460e14b4a 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -476,9 +476,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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) + call addmap(FldListFr(compglc)%flds, 'Sg_ice_covered' , complnd, mapconsd, 'unset' , glc2lnd_fmap) + call addmap(FldListFr(compglc)%flds, 'Sg_topo' , compglc, mapconsd, 'custom', glc2lnd_fmap) + call addmap(FldListFr(compglc)%flds, 'Flgg_hflx' , compglc, mapconsd, 'custom', glc2lnd_fmap) ! Custom merge in med_phases_prep_lnd end if diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 610111ad6..1f0950449 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -18,7 +18,7 @@ module med_phases_prep_glc_mod use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_Mesh, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use esmFlds , only : compglc, complnd, mapbilnr, mapconsf, compname + use esmFlds , only : compglc, complnd, mapbilnr, mapconsd, compname 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 @@ -319,11 +319,11 @@ subroutine med_phases_prep_glc_init(gcomp, 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 + if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsd,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, & + mapindex=mapconsd, & RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -900,7 +900,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) field_src=field_icemask_g, & field_dst=field_icemask_l, & routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsf, rc=rc) + maptype=mapconsd, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! ------------------------------------------------------------------------ @@ -936,7 +936,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) field_src=field_frac_g_ec, & field_dst=field_frac_l_ec, & routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsf, & + maptype=mapconsd, & field_normsrc=field_icemask_g, & field_normdst=field_icemask_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -968,10 +968,9 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) local_accum_lnd(1) = 0.0_r8 local_ablat_lnd(1) = 0.0_r8 do n = 1, size(lfrac) - if (is_local%wrap%mesh_info(complnd)%mask(n) /= 0) then - ! 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) - + ! 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) @@ -984,10 +983,16 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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_MAX, rc=rc) + 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) + 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,d13.5)') trim(subname)//'global_accum_lnd = ', global_accum_lnd + write(logunit,'(a,d13.5)') trim(subname)//'global_ablat_lnd = ', global_ablat_lnd + endif !--------------------------------------- ! Sum qice_g over local glc grid cells. @@ -1017,6 +1022,10 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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,d13.5)') trim(subname)//'global_accum_glc = ', global_accum_glc + write(logunit,'(a,d13.5)') trim(subname)//'global_ablat_glc = ', global_ablat_glc + endif ! Renormalize if (global_accum_glc(1) > 0.0_r8) then From ce1148b9d0901c7a159da7fb28cefd6cbfb233bd Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 25 Nov 2020 10:29:19 -0700 Subject: [PATCH 161/206] cleanup and refactor of testlist_drv.xml to include new tests and consolidate ERS and SMS tests --- cime_config/testdefs/testlist_drv.xml | 76 +++++---------------------- mediator/med.F90 | 19 +++---- mediator/med_internalstate_mod.F90 | 1 - mediator/med_phases_prep_glc_mod.F90 | 6 --- 4 files changed, 22 insertions(+), 80 deletions(-) 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/mediator/med.F90 b/mediator/med.F90 index 8ce2b2bbd..ed14643b8 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -882,9 +882,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 @@ -916,9 +918,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, & @@ -926,9 +930,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, & @@ -2367,7 +2373,7 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) 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)) @@ -2381,11 +2387,6 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) end do deallocate(ownedElemCoords) - ! Obtain mesh mask - allocate(mesh_info%mask(numOwnedElements)) - call ESMF_MeshGet(lmesh, elementMask=mesh_info%mask, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end subroutine med_meshinfo_create !----------------------------------------------------------------------------- diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 80bc97b3d..149d10374 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -43,7 +43,6 @@ module med_internalstate_mod ! med atm lnd ocn ice rof wav glc type, public :: mesh_info_type - integer , pointer :: mask(:) => null() real(r8), pointer :: areas(:) => null() real(r8), pointer :: lats(:) => null() real(r8), pointer :: lons(:) => null() diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 1f0950449..1cfaaa967 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -540,13 +540,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) endif 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 - end if if (dbug_flag > 5) then From 9043f001abdfe13acb7f1c39e0ebf3b571dbbc26 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 25 Nov 2020 19:48:30 -0700 Subject: [PATCH 162/206] new wrapper interfaces for readability for getting pointers to field bundle fields --- mediator/med_diag_mod.F90 | 152 +++++++++------------------ mediator/med_fraction_mod.F90 | 131 ++++++++--------------- mediator/med_methods_mod.F90 | 52 ++++----- mediator/med_phases_prep_glc_mod.F90 | 24 ++--- mediator/med_phases_prep_lnd_mod.F90 | 4 +- mediator/med_phases_prep_rof_mod.F90 | 126 ++++++++-------------- 6 files changed, 171 insertions(+), 318 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 2966dba63..d58bd02c2 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -23,14 +23,16 @@ module med_diag_mod 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, ESMF_AlarmRingerOff - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + 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_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 @@ -604,17 +606,11 @@ subroutine med_phases_diag_atm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get fractions on atm mesh - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'lfrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, 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(compatm), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), '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(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=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compatm)%areas @@ -733,10 +729,8 @@ subroutine diag_atm_recv(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifra real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -772,10 +766,8 @@ subroutine diag_atm_send(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifra real(r8) :: term ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -813,10 +805,8 @@ subroutine diag_atm_wiso_recv(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -872,10 +862,8 @@ subroutine diag_atm_wiso_send(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -941,9 +929,7 @@ subroutine med_phases_diag_lnd( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! get fractions on lnd mesh - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), '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=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(complnd)%areas @@ -1036,10 +1022,8 @@ subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1072,10 +1056,8 @@ subroutine diag_lnd_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, lfrac, ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1186,10 +1168,8 @@ subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1222,10 +1202,8 @@ subroutine diag_rof_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, budget, ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1308,10 +1286,8 @@ subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1359,13 +1335,9 @@ subroutine med_phases_diag_ocn( gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), '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(compocn), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compocn), '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(compocn), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(sfrac(size(ofrac))) sfrac(:) = ifrac(:) + ofrac(:) @@ -1382,10 +1354,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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1467,10 +1437,8 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, scale, rc) real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1502,10 +1470,8 @@ subroutine diag_ocn_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, frac, b real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1549,13 +1515,9 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), 'ifrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ifrac', ifrac, 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), '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(compice), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1618,10 +1580,8 @@ subroutine diag_ice_recv(FB, fldname, nf, areas, lats, ifrac, budget, minus, sca real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1667,10 +1627,8 @@ subroutine diag_ice_recv_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1727,13 +1685,9 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compice), '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), 'ofrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compice), 'ifrac', ifrac, 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(compice), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1755,10 +1709,8 @@ subroutine med_phases_diag_ice_med2ice( gcomp, 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) - if ( FB_fldchk(is_local%wrap%FBExp(compice), 'Fioo_q', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), 'Fioo_q', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) @@ -1808,10 +1760,8 @@ subroutine diag_ice_send(FB, fldname, nf, areas, lats, ifrac, budget, rc) ! ------------------------------------------------------------------ rc = ESMF_SUCCESS ip = period_inst - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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 do n = 1,size(data) if (lats(n) > 0.0_r8) then @@ -1843,10 +1793,8 @@ subroutine diag_ice_send_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call ESMF_FieldBundleGet(FB, trim(fldname), field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=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) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index f63d150cd..5b289b88c 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -97,14 +97,17 @@ module med_fraction_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 : 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_mesh + 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, max_icesheets, num_icesheets @@ -215,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 @@ -231,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) + call fldbun_getdata1d(is_local%wrap%FBImp(complnd,complnd) , 'Sl_lfrin', Sl_lfrin, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=Sl_lfrin, rc=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 @@ -251,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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice) , fieldname='ifrac', & - field=lfield, 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_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(:) @@ -300,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) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compocn,compocn), 'So_omask', if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldName='ofrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ChkErr(rc,__LINE__,u_FILE_u)) return ofrac, rc) 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 @@ -368,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) ! --------------------------------------- @@ -381,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) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, 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 if (is_local%wrap%comp_present(complnd)) then do n = 1,size(lfrac) @@ -417,20 +400,16 @@ subroutine med_fraction_init(gcomp, rc) end if end if end if - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc) + call fldbun_getdata1d(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(compatm), '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,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) @@ -451,20 +430,13 @@ subroutine med_fraction_init(gcomp, rc) ! 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) + 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 @@ -494,24 +466,18 @@ subroutine med_fraction_init(gcomp, rc) do ns = 1,num_icesheets if (is_local%wrap%comp_present(compglc(ns))) then + ! Set 'gfrac' in FBFrac(compglc(ns)) - if ( FB_FldChk(is_local%wrap%FBfrac(compglc(ns)) , 'gfrac', rc=rc) .and. & + if ( FB_FldChk(is_local%wrap%FBfrac(compglc(ns)) , 'gfrac', rc=rc) .and. & FB_FldChk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'frac' , rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'frac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'frac', frac, 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(ns)), 'gfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=gfrac, rc=rc) + 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 ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc(ns)), '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 + 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 @@ -542,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 @@ -556,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) @@ -570,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) @@ -591,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 @@ -667,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) - 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), fieldName='Si_ifrac', Si_ifrac, 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) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), fieldName='Si_imask', Si_imask, 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), fieldName='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), fieldName='ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! set ifrac = Si_ifrac * Si_imask @@ -767,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_methods_mod.F90 b/mediator/med_methods_mod.F90 index 6627c9e6f..10389fc24 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -703,7 +703,7 @@ subroutine med_methods_FB_reset(FB, value, rc) ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet ! intput/output variables type(ESMF_FieldBundle) , intent(inout) :: FB @@ -711,52 +711,44 @@ subroutine med_methods_FB_reset(FB, value, rc) integer , intent(out) :: rc ! local variables - integer :: i,j,n - integer :: fieldCount - character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() - real(R8) :: lvalue - type(ESMF_Field) :: lfield - integer :: lrank - real(R8), pointer :: fldptr1(:) => null() - real(R8), pointer :: fldptr2(:,:) => null() - character(len=*),parameter :: subname='(med_methods_FB_reset)' + integer :: n + real(R8) :: lvalue + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + type(ESMF_Field), pointer :: fieldlist(:) => null() + integer :: fieldcount + integer :: ungriddedUBound(1) + character(len=*),parameter:: subname='(med_methods_FB_reset)' ! ---------------------------------------------- if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif + rc = ESMF_SUCCESS lvalue = czero if (present(value)) then - lvalue = value + lvalue = value endif call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(lfieldnamelist(fieldCount)) - call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) do n = 1, fieldCount - call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(n)), field=lfield, rc=rc) + call ESMF_FieldGet(fieldlist(n), ungriddedUBound=ungriddedUBound, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (lrank == 0) then - ! no local data - elseif (lrank == 1) then - fldptr1 = lvalue - elseif (lrank == 2) then - fldptr2 = lvalue + if (ungriddedUbound(1) > 0) then + call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = lvalue else - call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - endif + call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = lvalue + end if enddo - deallocate(lfieldnamelist) + deallocate(fieldlist) if (dbug_flag > 10) 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 dac87b3d1..a5e329e81 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -460,9 +460,9 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) ! Accumulate fields do n = 1, size(fldnames_fr_lnd) - call fldbun_getdata2d(is_local%wrap%FBImp(complnd,complnd), fieldname=fldnames_fr_lnd(n), data2d_in, rc) + call fldbun_getdata2d(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(n), data2d_in, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call fldbun_getdata2d(FBlndAccum_l, fieldname=fldnames_fr_lnd(n), data2d_out, rc) + 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) @@ -562,7 +562,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) write(logunit,'(a)') trim(subname)//"glc_avg alarm is ringing - averaging input from lnd to glc" end if do n = 1, size(fldnames_fr_lnd) - call fldbun_getdata2d(FBlndAccum_l, fieldname=fldnames_fr_lnd(n), data2d, rc) + call fldbun_getdata2d(FBlndAccum_l, fldnames_fr_lnd(n), data2d, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (FBlndAccumCnt > 0) then ! If accumulation count is greater than 0, do the averaging @@ -570,7 +570,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) 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), fieldname=fldnames_fr_lnd(n), data2d_import, rc) + 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 @@ -681,7 +681,7 @@ subroutine map_lnd2glc(gcomp, 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? @@ -957,7 +957,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !--------------------------------------- ! determine icemask_g and set as contents of field_icemask_g - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=Sg_icemask_fieldname, dataptr1d, rc) + 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(ice_sheet_toglc(ns)%field_icemask_g, icemask_g, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -978,11 +978,11 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! ------------------------------------------------------------------------ ! get topo_g(:), the topographic height of each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=Sg_topo_fieldname, topo_g, rc) + 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 frac_g(:), the total ice fraction in each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=Sg_frac_fieldname, dataptr1d, rc) + 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(ice_sheet_toglc(ns)%field_lfrac_g, frac_g, rc) ! module field frac_g(:) = dataptr1d(:) @@ -1013,7 +1013,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine fraction on land grid, lfrac(:) - call fldbun_getdata1d(is_local%wrap%FBFrac(complnd), fieldname='lfrac', lfrac, rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(complnd), 'lfrac', lfrac, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! get icemask_l @@ -1024,12 +1024,12 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call fldbun_getdata2d(FBlndAccum_l, trim(qice_fieldname)//'_elev', qice_l_ec, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), fieldname=trim(Sg_topo_fieldname), & + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ns),compglc(ns)), fieldname=trim(Sg_frac_fieldname), & + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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) @@ -1073,7 +1073,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !--------------------------------------- ! determine qice_g - call fldbun_getdata1d(is_local%wrap%FBExp(compglc(ns)), fieldname=qice_fieldname, qice_g, rc) + call fldbun_getdata1d(is_local%wrap%FBExp(compglc(ns)), qice_fieldname, qice_g, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! get areas internal to glc grid diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 7f8c88df2..0970d4569 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -296,7 +296,7 @@ subroutine map_glc2lnd_init(gcomp, rc) !--------------------------------------- ! 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_l, rc=rc) + 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 @@ -432,7 +432,7 @@ subroutine map_glc2lnd( gcomp, rc) ! Get pointers into land export field bundle (this is summed over all ice sheets) !--------------------------------- - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_frac)//'_elev', frac_l_ec_sum, rc) + 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 diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 483be2693..62da09deb 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -14,12 +14,16 @@ module med_phases_prep_rof_mod 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_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_accum => med_methods_FB_accum + use med_methods_mod , only : fldbun_average => med_methods_FB_average use perf_mod , only : t_startf, t_stopf implicit none @@ -116,15 +120,13 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) ! only a few will actaully be sent to the river model if (ncnt > 0) then - call FB_accum(& - is_local%wrap%FBImpAccum(complnd,complnd), & - is_local%wrap%FBImp(complnd,complnd), rc=rc) + call fldbun_accum(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImp(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), & + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & string=trim(subname)//' FBImpAccum(complnd,complnd) ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -144,13 +146,13 @@ subroutine med_phases_prep_rof_avg(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 ! input/output variables type(ESMF_GridComp) :: gcomp @@ -203,11 +205,11 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) ! average import from land accumuled FB !--------------------------------------- - call FB_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) + call fldbun_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & + 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 @@ -230,7 +232,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & + 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 @@ -241,12 +243,8 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return 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) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 0._r8 + call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), irrig_flux_field, dataptr, rc) + dataptr(:) = czero end if endif @@ -255,7 +253,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBFrac(comprof), & + 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 @@ -269,7 +267,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(comprof), & + 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 @@ -279,26 +277,8 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) !--------------------------------------- is_local%wrap%FBImpAccumCnt(complnd) = 0 - - 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 (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUbound(1) > 0) then - call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(:,:) = czero - else - call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = czero - end if - end do - deallocate(fieldlist) + call fldbun_reset(is_local%wrap%FBImpAccum(complnd,complnd), czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return endif if (dbug_flag > 20) then @@ -407,23 +387,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 @@ -455,12 +422,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 @@ -479,7 +443,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 ! ------------------------------------------------------------------------ @@ -498,16 +462,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) @@ -527,6 +488,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, & @@ -535,6 +497,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, & @@ -543,18 +506,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) From 607c38e83f60a9b099aee3c8533410467fa22d68 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Wed, 25 Nov 2020 20:07:42 -0700 Subject: [PATCH 163/206] Add a comment about the areas used in the global sums --- mediator/med_phases_prep_glc_mod.F90 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 1cfaaa967..444699946 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -815,6 +815,22 @@ 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. ! From 93b0da3a29023666d54b91231a32fb79143480a9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 25 Nov 2020 20:15:04 -0700 Subject: [PATCH 164/206] fix use statement --- mediator/med_phases_prep_glc_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 444699946..544295e25 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -28,7 +28,7 @@ module med_phases_prep_glc_mod 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, glc_get_elevation_class + 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 From 34b67b6b00721fcc05af258aeff3149b50703da0 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 26 Nov 2020 13:07:00 -0700 Subject: [PATCH 165/206] udpates for PR #139 --- mediator/esmFldsExchange_cesm_mod.F90 | 10 ++- mediator/med_diag_mod.F90 | 3 +- mediator/med_fraction_mod.F90 | 26 ++++---- mediator/med_methods_mod.F90 | 95 ++++++++++++++++----------- mediator/med_phases_prep_glc_mod.F90 | 38 ++++------- mediator/med_phases_prep_lnd_mod.F90 | 26 ++++---- mediator/med_phases_prep_rof_mod.F90 | 2 + 7 files changed, 105 insertions(+), 95 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 36ee13b8d..992e66f3e 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -264,7 +264,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') - call addfld(fldlistFr(compglc)%flds, 'Sg_area') + 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 @@ -486,14 +488,16 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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') + 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') + call addmap(fldListFr(compglc(ns))%flds, 'Sg_icemask_coupled_fluxes', & + complnd, mapconsd, 'one', 'unset') end if end do end if diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index d58bd02c2..7c907adb4 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -763,11 +763,10 @@ subroutine diag_atm_send(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifra integer :: n, ip type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() - real(r8) :: term ! ------------------------------------------------------------------ rc = ESMF_SUCCESS if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then - call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) + 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) diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index 5b289b88c..2cb1904bb 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -103,7 +103,7 @@ module med_fraction_mod 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_mesh + 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 @@ -291,10 +291,10 @@ 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), 'So_omask', + call fldbun_getdata1d(is_local%wrap%FBImp(compocn,compocn), 'So_omask', So_omask, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call fldbun_getdata1d(is_local%wrap%FBFrac(compocn), 'ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldName='ofrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return ofrac, rc) ofrac(:) = So_omask(:) ! Set 'ofrac' in FBFrac(compatm) - at this point this is the ocean mask mapped to the atm grid @@ -400,7 +400,7 @@ subroutine med_fraction_init(gcomp, rc) end if end if end if - call fldbun_getdata1d(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc) + 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(compatm), 'lfrac', field=field_dst, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -428,8 +428,8 @@ 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 + 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) @@ -468,8 +468,8 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compglc(ns))) then ! Set 'gfrac' in FBFrac(compglc(ns)) - if ( FB_FldChk(is_local%wrap%FBfrac(compglc(ns)) , 'gfrac', rc=rc) .and. & - FB_FldChk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'frac' , rc=rc)) then + 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 call fldbun_getdata1d(is_local%wrap%FBfrac(compglc(ns)), 'gfrac', gfrac, rc) @@ -630,13 +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 fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), fieldName='Si_ifrac', Si_ifrac, rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), 'Si_ifrac', Si_ifrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), fieldName='Si_imask', Si_imask, rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), 'Si_imask', Si_imask, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call fldbun_getdata1d(is_local%wrap%FBFrac(compice), fieldName='ifrac', ifrac, rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ifrac', ifrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call fldbun_getdata1d(is_local%wrap%FBFrac(compice), fieldName='ofrac', ofrac, 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 diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index 10389fc24..fbfed3ffb 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -56,15 +56,21 @@ module med_methods_mod 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 @@ -696,14 +702,13 @@ 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 ! If value is not provided, reset to 0.0 ! ---------------------------------------------- - use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field ! intput/output variables type(ESMF_FieldBundle) , intent(inout) :: FB @@ -711,44 +716,52 @@ subroutine med_methods_FB_reset(FB, value, rc) integer , intent(out) :: rc ! local variables - integer :: n - real(R8) :: lvalue - real(r8), pointer :: dataptr1d(:) => null() - real(r8), pointer :: dataptr2d(:,:) => null() - type(ESMF_Field), pointer :: fieldlist(:) => null() - integer :: fieldcount - integer :: ungriddedUBound(1) - character(len=*),parameter:: subname='(med_methods_FB_reset)' + integer :: i,j,n + integer :: fieldCount + character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:) => null() + real(R8) :: lvalue + type(ESMF_Field) :: lfield + integer :: lrank + real(R8), pointer :: fldptr1(:) => null() + real(R8), pointer :: fldptr2(:,:) => null() + character(len=*),parameter :: subname='(med_methods_FB_reset)' ! ---------------------------------------------- if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif - rc = ESMF_SUCCESS lvalue = czero if (present(value)) then - lvalue = value + lvalue = value endif call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) + allocate(lfieldnamelist(fieldCount)) + call ESMF_FieldBundleGet(FB, fieldNameList=lfieldnamelist, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1, fieldCount - call ESMF_FieldGet(fieldlist(n), ungriddedUBound=ungriddedUBound, rc=rc) + call ESMF_FieldBundleGet(FB, fieldName=trim(lfieldnamelist(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) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(:,:) = lvalue + call med_methods_Field_GetFldPtr(lfield, fldptr1=fldptr1, fldptr2=fldptr2, rank=lrank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (lrank == 0) then + ! no local data + elseif (lrank == 1) then + fldptr1 = lvalue + elseif (lrank == 2) then + fldptr2 = lvalue else - call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = lvalue - end if + call ESMF_LogWrite(trim(subname)//": ERROR in rank "//trim(lfieldnamelist(n)), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + endif enddo - deallocate(fieldlist) + deallocate(lfieldnamelist) if (dbug_flag > 10) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) @@ -2345,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 @@ -2365,10 +2377,12 @@ subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) end subroutine med_methods_FB_getNumFlds !----------------------------------------------------------------------------- - subroutine med_methods_FB_getdata2d(FldBun, dataptr2d, rc) + 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) :: FldBun + type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fieldname real(r8) , pointer :: dataptr2d(:,:) integer , intent(inout) :: rc @@ -2376,7 +2390,6 @@ subroutine med_methods_FB_getdata2d(FldBun, dataptr2d, rc) ! local variables type(ESMF_Field) :: lfield ! ---------------------------------------------- - rc = ESMF_SUCCESS call ESMF_FieldBundleGet(FB, fieldname=trim(fieldname), field=lfield, rc=rc) @@ -2387,10 +2400,12 @@ subroutine med_methods_FB_getdata2d(FldBun, dataptr2d, rc) end subroutine med_methods_FB_getdata2d !----------------------------------------------------------------------------- - subroutine med_methods_FB_getdata1d(FldBun, dataptr1d, rc) + 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) :: FldBun + type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fieldname real(r8) , pointer :: dataptr1d(:) integer , intent(inout) :: rc @@ -2398,7 +2413,6 @@ subroutine med_methods_FB_getdata1d(FldBun, dataptr1d, rc) ! local variables type(ESMF_Field) :: lfield ! ---------------------------------------------- - rc = ESMF_SUCCESS call ESMF_FieldBundleGet(FB, fieldname=trim(fieldname), field=lfield, rc=rc) @@ -2411,12 +2425,13 @@ 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) @@ -2427,12 +2442,13 @@ 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) @@ -2443,27 +2459,28 @@ 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 + 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(is_local%wrap%FBExp(complnd), fieldCount=fieldCount, rc=rc) + call ESMF_FieldBundleGet(FB, 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) + 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_Field_getdata1d + end subroutine med_methods_FB_getmesh end module med_methods_mod diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 5bcd52378..2c1fa5925 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -21,12 +21,13 @@ module med_phases_prep_glc_mod use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_Mesh, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use esmFlds , only : compglc, complnd, mapbilnr, mapconsd, compname + use esmFlds , only : complnd, mapbilnr, mapconsd, mapconsf, compname + use esmFlds , only : max_icesheets, num_icesheets, compglc 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 : fldbun_getmesh => med_methods_FB_mesh + 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 @@ -68,6 +69,7 @@ module med_phases_prep_glc_mod character(len=14) :: fldnames_fr_lnd(3) = (/'Flgl_qice_elev','Sl_tsrf_elev ','Sl_topo_elev '/) character(len=14) :: fldnames_to_glc(2) = (/'Flgl_qice ','Sl_tsrf '/) + type, public :: ice_sheet_toglc_type character(CS) :: name logical :: is_active @@ -280,6 +282,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (ice_sheet_toglc(ns)%is_active) then ! get mesh on glc grid call fldbun_getmesh(is_local%wrap%FBExp(compglc(ns)), ice_sheet_toglc(ns)%mesh_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return ! create accumulation field bundle on glc grid ice_sheet_toglc(ns)%FBlndAccum_g = ESMF_FieldBundleCreate(rc=rc) @@ -318,7 +321,7 @@ subroutine med_phases_prep_glc_init(gcomp, 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 @@ -503,7 +506,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) integer :: yr_prepglc, mon_prepglc, day_prepglc, sec_prepglc type(ESMF_Alarm) :: alarm type(ESMF_Field) :: lfield - integer :: i, n, ncnt ! counters + integer :: i, n, ncnt, ns real(r8), pointer :: data2d(:,:) => null() real(r8), pointer :: data2d_import(:,:) => null() character(len=*) , parameter :: subname=' (med_phases_prep_glc_avg) ' @@ -594,7 +597,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! zero accumulator and accumulated field bundles on land grid FBlndAccumCnt = 0 - call fldbun_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 if (dbug_flag > 1) then @@ -741,9 +744,9 @@ subroutine map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if - call fldbun_getdata1d(is_local%wrap%FBImp(compglc,compglc), Sg_frac_fieldname, ice_covered_g, rc) + 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,compglc), Sg_topo_fieldname, topoglc_g, rc) + 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 ! get elevation classes including bare land @@ -775,7 +778,7 @@ subroutine map_lnd2glc(gcomp, 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 fldbun_getdata2d(is_local%wrap%FBExp(compglc(ns)), fldnames_to_glc(nfld), farrayptr=dataexp_g, rc) + call fldbun_getdata1d(is_local%wrap%FBExp(compglc(ns)), fldnames_to_glc(nfld), dataexp_g, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! First set data_ice_covered_g to bare land everywehre @@ -1025,7 +1028,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !--------------------------------------- ! get fractional ice coverage for each elevation class on the land grid, frac_l_ec(:,:) - call call field_getdata2d(field_frac_l_ec, frac_l_ec, rc) + call field_getdata2d(field_frac_l_ec, frac_l_ec, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! determine fraction on land grid, lfrac(:) @@ -1040,21 +1043,6 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call fldbun_getdata2d(FBlndAccum_l, trim(qice_fieldname)//'_elev', qice_l_ec, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 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(ns),compglc(ns)), 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(ice_sheet_toglc(ns)%field_frac_g, farrayptr=glc_frac_g, rc=rc) ! module field - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(ice_sheet_toglc(ns)%field_frac_g_ec, farrayptr=glc_frac_g_ec, rc=rc) ! module field - 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) @@ -1093,7 +1081,7 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! get areas internal to glc grid - call fldbun_getdata1d(is_local%FBImp(compglc(ns),compglc(ns)), 'Sg_area', area_g, rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'Sg_area', area_g, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return local_accum_glc(1) = 0.0_r8 diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 0970d4569..20f38a8b2 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -20,11 +20,11 @@ module med_phases_prep_lnd_mod 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_mesh - use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + 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 : field_getdata2d => med_methods_Field_getdata2d + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d + use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar use med_utils_mod , only : chkerr => med_utils_ChkErr @@ -107,6 +107,11 @@ subroutine med_phases_prep_lnd(gcomp, rc) 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 + ! 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 @@ -116,11 +121,6 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then - ! Get the internal state - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! determine if coupling to CISM is 2-way if (first_call) then call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) @@ -296,7 +296,7 @@ subroutine map_glc2lnd_init(gcomp, rc) !--------------------------------------- ! 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) + 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 @@ -436,7 +436,7 @@ subroutine map_glc2lnd( gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return frac_l_ec_sum(:,:) = 0._r8 - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_topo)//'_elev', topo_l_ec_sum, rc) + 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 @@ -477,7 +477,7 @@ subroutine map_glc2lnd( gcomp, 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_coupled_fluxes, data1d_src, rc) + 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 @@ -497,7 +497,7 @@ subroutine map_glc2lnd( gcomp, 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, farrayptr=frac_g_ec, rc=rc) + 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) @@ -531,7 +531,7 @@ subroutine map_glc2lnd( gcomp, 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 med_methods_field_getdata2d(field_frac_l_ec, frac_l_ec, rc=rc) + 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(:,:) diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 62da09deb..0baf8c784 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -24,6 +24,8 @@ module med_phases_prep_rof_mod use med_methods_mod , only : fldbun_reset => med_methods_FB_reset use med_methods_mod , only : fldbun_accum => med_methods_FB_accum use med_methods_mod , only : fldbun_average => med_methods_FB_average + use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d + use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d use perf_mod , only : t_startf, t_stopf implicit none From 23896d4555eb8df7d071a562b764d7f7d90b519d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 26 Nov 2020 19:51:20 -0700 Subject: [PATCH 166/206] bug fix --- mediator/med_phases_prep_glc_mod.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 2c1fa5925..3ca1ccd04 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -364,7 +364,8 @@ subroutine med_phases_prep_glc_init(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! ice fraction in multiple elevation classes on lnd - NOTE that this includes bare land - field_frac_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_frac_l_ec = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Loop over ice sheets From 37bde42d0e8e148900ad1614e9ddc9707439b4f9 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 27 Nov 2020 11:34:23 -0700 Subject: [PATCH 167/206] replace mapconsf with mapconsd in prep_glc_mod.F90 --- mediator/esmFlds.F90 | 2 +- mediator/med_internalstate_mod.F90 | 4 +-- mediator/med_phases_prep_glc_mod.F90 | 39 ++++++++++++++-------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index dd4358d95..2daf8eb02 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -16,7 +16,7 @@ module esmflds integer, public, parameter :: compice = 5 integer, public, parameter :: comprof = 6 integer, public, parameter :: compwav = 7 - integer, public, parameter :: compglc1 = 8 + integer, public, parameter :: compglc1 = 8 integer, public, parameter :: ncomps = 8 character(len=*), public, parameter :: compname(ncomps) = & diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index 7c4cf7fbf..83558c9d1 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -19,7 +19,7 @@ module med_internalstate_mod ! 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() real(r8), pointer :: lats(:) => null() @@ -27,7 +27,7 @@ module med_internalstate_mod end type mesh_info_type type, public :: packed_data_type - integer, allocatable :: fldindex(:) ! size of number of packed fields + integer, allocatable :: fldindex(:) ! size of number of packed fields character(len=CS) :: mapnorm ! normalization for packed field type(ESMF_Field) :: field_src ! packed sourced field type(ESMF_Field) :: field_dst ! packed destination field diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 3ca1ccd04..3bdda2391 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -6,7 +6,6 @@ module med_phases_prep_glc_mod ! 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 @@ -21,7 +20,7 @@ module med_phases_prep_glc_mod use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_Mesh, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use esmFlds , only : complnd, mapbilnr, mapconsd, mapconsf, compname + use esmFlds , only : complnd, mapbilnr, mapconsd, compname use esmFlds , only : max_icesheets, num_icesheets, compglc use med_internalstate_mod , only : InternalState, mastertask, logunit use med_constants_mod , only : dbug_flag=>med_constants_dbug_flag @@ -82,6 +81,7 @@ module med_phases_prep_glc_mod end type ice_sheet_toglc_type type(ice_sheet_toglc_type) :: ice_sheet_toglc(max_icesheets) + 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 @@ -355,6 +355,9 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! ------------------------------- if (smb_renormalize) then + field_normdst_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! ice mask without elevation classes on lnd field_icemask_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -390,11 +393,11 @@ subroutine med_phases_prep_glc_init(gcomp, 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,:),mapconsf,rc=rc)) then + 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=mapconsf, & + mapindex=mapconsd, & RouteHandle=is_local%wrap%RH, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if @@ -984,15 +987,17 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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=ice_sheet_toglc(ns)%field_icemask_g, & field_dst=field_icemask_l, & routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsf, rc=rc) + maptype=mapconsd, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! get icemask_l + call field_getdata1d(field_icemask_l, icemask_l, 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 ! ------------------------------------------------------------------------ @@ -1019,9 +1024,9 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) field_src=ice_sheet_toglc(ns)%field_frac_g_ec, & field_dst=field_frac_l_ec, & routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsf, & + maptype=mapconsd, & field_normsrc=ice_sheet_toglc(ns)%field_icemask_g, & - field_normdst=field_icemask_l, rc=rc) + field_normdst=field_normdst_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- @@ -1036,10 +1041,6 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call fldbun_getdata1d(is_local%wrap%FBFrac(complnd), 'lfrac', lfrac, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - ! get icemask_l - call field_getdata1d(field_icemask_l, icemask_l, rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - ! 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 @@ -1069,8 +1070,8 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) reduceflag=ESMF_REDUCE_SUM, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (mastertask) then - write(logunit,'(a,d13.5)') trim(subname)//'global_accum_lnd = ', global_accum_lnd - write(logunit,'(a,d13.5)') trim(subname)//'global_ablat_lnd = ', global_ablat_lnd + 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 !--------------------------------------- @@ -1099,8 +1100,8 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, 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,d13.5)') trim(subname)//'global_accum_glc = ', global_accum_glc - write(logunit,'(a,d13.5)') trim(subname)//'global_ablat_glc = ', global_ablat_glc + 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 @@ -1115,8 +1116,8 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ablat_renorm_factor = 0.0_r8 endif if (mastertask) then - write(logunit,'(a,d13.5)') trim(subname)//'accum_renorm_factor = ', accum_renorm_factor - write(logunit,'(a,d13.5)') trim(subname)//'ablat_renorm_factor = ', ablat_renorm_factor + 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 do n = 1, size(qice_g) From 8c1a42f365efca223741c0ed9354841225a7ce94 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 28 Nov 2020 12:57:17 -0700 Subject: [PATCH 168/206] added med_phases_post_glc_mod.F90 which carries out the mapping for glc->lnd for now - but also upcoming glc->ocn and glc->ice but only after a receive from glc --- mediator/med.F90 | 33 +- mediator/med_merge_mod.F90 | 32 +- mediator/med_phases_post_glc_mod.F90 | 540 +++++++++++++++++++++++++++ mediator/med_phases_prep_lnd_mod.F90 | 460 +---------------------- 4 files changed, 593 insertions(+), 472 deletions(-) create mode 100644 mediator/med_phases_post_glc_mod.F90 diff --git a/mediator/med.F90 b/mediator/med.F90 index 7ea0c1376..428fa13e2 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -89,6 +89,7 @@ subroutine SetServices(gcomp, rc) 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_post_glc_mod , only: med_phases_post_glc 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 @@ -348,6 +349,20 @@ subroutine SetServices(gcomp, rc) specPhaselabel="med_phases_prep_glc_accum", specRoutine=NUOPC_NoOp, 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_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_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 + !------------------ ! phase routine for ocean albedo computation !------------------ @@ -1648,6 +1663,7 @@ subroutine DataInitialize(gcomp, rc) 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_post_glc_mod , only : med_phases_post_glc use med_phases_prep_atm_mod , only : med_phases_prep_atm use med_phases_ocnalb_mod , only : med_phases_ocnalb_run use med_phases_aofluxes_mod , only : med_phases_aofluxes_run @@ -1716,7 +1732,7 @@ subroutine DataInitialize(gcomp, rc) !---------------------------------------------------------- ! Initialize mediator present flags !---------------------------------------------------------- - + if (mastertask) then write(logunit,'(a)') trim(subname) // "Initializing present flags" end if @@ -1761,7 +1777,7 @@ subroutine DataInitialize(gcomp, rc) ! This defines the med_coupling_allowed is a starting point for what is ! allowed in this coupled system. It will be revised further after the system - ! starts, but any coupling set to false will never be allowed. + ! starts, but any coupling set to false will never be allowed. ! are allowed, just update the table below. if (mastertask) then @@ -1809,7 +1825,7 @@ subroutine DataInitialize(gcomp, rc) med_coupling_allowed(compocn,compwav) = .true. med_coupling_allowed(compice,compwav) = .true. - ! to land-ice + ! to land-ice do ns = 1,num_icesheets med_coupling_allowed(complnd,compglc(ns)) = .true. end do @@ -2321,6 +2337,17 @@ subroutine DataInitialize(gcomp, rc) call med_diag_zero(gcomp, mode='all', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + !--------------------------------------- + ! If appropriate, Map initial glc->lnd before run phase of glc is called + !--------------------------------------- + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + write(6,*)'DEBUG: calling med_phases_post_glc for ice sheet ',ns + call med_phases_post_glc(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + !--------------------------------------- ! read mediator restarts !--------------------------------------- diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index 8b85a4a86..f08d633da 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -80,6 +80,8 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis real(r8), pointer :: dataptr1d(:) => null() real(r8), pointer :: dataptr2d(:,:) => null() character(CL) :: msg + logical :: zero_output + character(CL) :: fldname character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_auto)' !--------------------------------------- @@ -110,19 +112,7 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis ! Loop over all fields in field bundle FBOut do nfld_out = 1,fieldcount - - ! Initialize initial output field data to zero - call ESMF_FieldGet(fieldlist(nfld_out), ungriddedUBound=ungriddedUbound_out, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound_out(1) > 0) then - call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(:,:) = czero - else - call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = czero - end if + zero_output = .true. ! Loop over the field in fldListTo do nfld_in = 1,med_fldList_GetNumFlds(fldListTo) @@ -168,6 +158,22 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! end of error check + ! Initialize initial output field data to zero before doing merge + if (zero_output) then + call ESMF_FieldGet(fieldlist(nfld_out), ungriddedUBound=ungriddedUbound_out, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound_out(1) > 0) then + call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + else + call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + end if + zero_output = .false. + end if + ! Perform merge if ((present(FBMed1) .or. present(FBMed2)) .and. compsrc == compmed) then if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 new file mode 100644 index 000000000..18c200674 --- /dev/null +++ b/mediator/med_phases_post_glc_mod.F90 @@ -0,0 +1,540 @@ +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 : complnd, compatm, comprof, ncomps, compname + use esmFlds , only : max_icesheets, num_icesheets, compglc + use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname + use esmFlds , only : fldListTo + use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose + use med_methods_mod , only : fldbun_fldchk => med_methods_FB_fldchk + use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh + use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d + use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d + use med_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 :: glc2lnd_coupling = .false. + logical :: cism_evolve = .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 > 5) 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 + + ! 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(complnd), fieldCount=ncnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (ncnt > 0) then + + ! determine if coupling to CISM is 2-way + if (first_call) then + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", value=cvalue, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read (cvalue,*) cism_evolve + if (mastertask) then + write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve + end if + end if + end if + + !--------------------------------------- + ! glc->lnd mapping and merging + !--------------------------------------- + + ! determine if there will be any glc to lnd coupling + if (first_call) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + glc2lnd_coupling = .true. + exit + end if + end do + end if + + if (glc2lnd_coupling) then + ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) + write(6,*)'DEBUG: num_icesheets = ',num_icesheets + call t_startf('MED:'//trim(subname)//' glc2lnd ') + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + write(6,*)'DEBUG: calling med_map_field_packed for glc->lnd for ice sheet ',ns + 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 + write(6,*)'DEBUG: calling map_glc2lnd_init ' + 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) + write(6,*)'DEBUG: calling map_glc2lnd ' + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + end if + + ! Reset first call logical + first_call = .false. + + 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_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, lfield_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_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 20f38a8b2..cfd59b302 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -11,31 +11,17 @@ module med_phases_prep_lnd_mod use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet use ESMF , only : ESMF_GridComp, ESMF_GridCompGet use ESMF , only : ESMF_StateGet, ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND - use ESMF , only : ESMF_Mesh, ESMF_MeshLoc, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated use esmFlds , only : complnd, compatm, comprof, ncomps, compname - use esmFlds , only : max_icesheets, num_icesheets, compglc - use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname use esmFlds , only : fldListTo use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose use med_methods_mod , only : fldbun_fldchk => med_methods_FB_fldchk - use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh - use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d - use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d - use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d - use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar use med_utils_mod , only : chkerr => med_utils_ChkErr use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_internalstate_mod , only : InternalState, mastertask, logunit - use med_map_mod , only : med_map_rh_is_created, med_map_routehandles_init use med_map_mod , only : med_map_field_packed, med_map_field_normalized, med_map_field use med_merge_mod , only : med_merge_auto - use glc_elevclass_mod , only : glc_get_num_elevation_classes - use glc_elevclass_mod , only : glc_mean_elevation_virtual - use glc_elevclass_mod , only : glc_get_fractional_icecov use perf_mod , only : t_startf, t_stopf implicit none @@ -43,39 +29,6 @@ module med_phases_prep_lnd_mod public :: med_phases_prep_lnd - private :: map_glc2lnd_init - private :: map_glc2lnd - - ! private module variables - character(len =*), parameter :: Sg_icemask = 'Sg_icemask' - character(len =*), parameter :: Sg_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - character(len =*), parameter :: Sg_frac = 'Sg_ice_covered' - character(len =*), parameter :: Sg_frac_x_icemask = 'Sg_frac_times_icemask' - character(len =*), parameter :: Sg_topo = 'Sg_topo' - character(len =*), parameter :: Flgg_hflx = 'Flgg_hflx' - - type, public :: ice_sheet_tolnd_type - character(CS) :: name - logical :: is_active - type(ESMF_Field) :: field_icemask_g ! no elevation classes - type(ESMF_Field) :: field_frac_g_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_g_ec ! elevation classes - type(ESMF_Field) :: field_topo_x_icemask_g_ec ! elevation classes - type(ESMF_Mesh) :: mesh_g - end type ice_sheet_tolnd_type - type(ice_sheet_tolnd_type) :: ice_sheet_tolnd(max_icesheets) - - type(ESMF_field) :: field_icemask_l ! no elevation classes - type(ESMF_Field) :: field_frac_l_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_l_ec ! elevation classes - type(ESMF_Field) :: field_topo_x_icemask_l_ec ! elevation classes - - ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 - integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) - - logical :: glc2lnd_coupling = .false. - logical :: cism_evolve = .false. - character(*) , parameter :: u_FILE_u = & __FILE__ @@ -121,30 +74,15 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then - ! determine if coupling to CISM is 2-way - if (first_call) then - call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", value=cvalue, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read (cvalue,*) cism_evolve - if (mastertask) then - write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve - end if - end if - end if - !--------------------------------------- ! map to create FBimp(:,complnd) - other than glc->lnd !--------------------------------------- call t_startf('MED:'//trim(subname)//' map') do n1 = 1,ncomps - ! Skip glc here and handle it below - only components that are allowed to couple to - ! land are atm, rof and glc - if (is_local%wrap%med_coupling_active(n1,complnd)) then - if (n1 == comprof .or. n1 == compatm) then + ! Skip glc here and handle it below + if (n1 == compatm .or. n1 == comprof) then + 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), & @@ -158,30 +96,11 @@ subroutine med_phases_prep_lnd(gcomp, rc) end do call t_stopf('MED:'//trim(subname)//' map') - ! The following is only done if glc->lnd coupling is active - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call t_startf('MED:'//trim(subname)//' glc2lnd ') - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & - field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & - packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do - call t_stopf('MED:'//trim(subname)//' glc2lnd') - !--------------------------------------- ! auto merges to create FBExp(complnd) - other than glc->lnd !--------------------------------------- ! The following will merge all fields in fldsSrc - ! Note that there is no merge for glc Sg_icemask and Sg_icemask_coupled_fluxes) - ! these are mapped and set directly in map_glc2lnd call t_startf('MED:'//trim(subname)//' merge') call med_merge_auto(complnd, & @@ -193,31 +112,6 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' merge') - !--------------------------------------- - ! glc-lnd custom mapping and merging - !--------------------------------------- - - ! determine if there will be any glc to lnd coupling - if (first_call) then - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - glc2lnd_coupling = .true. - exit - end if - end do - end if - - ! The following is only done if glc->lnd coupling is active - if (glc2lnd_coupling) then - if (first_call) then - call map_glc2lnd_init(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - !--------------------------------------- ! update scalar data !--------------------------------------- @@ -252,7 +146,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) end if end if - ! Reset first call logical + ! Set first call logical to false first_call = .false. if (dbug_flag > 5) then @@ -262,350 +156,4 @@ subroutine med_phases_prep_lnd(gcomp, rc) end subroutine med_phases_prep_lnd - !================================================================================================ - - subroutine map_glc2lnd_init(gcomp, rc) - - ! input/output variables - type(ESMF_GridComp) , intent(inout) :: gcomp - integer , intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - type(ESMF_Field) :: lfield_l - type(ESMF_Mesh) :: mesh_l - integer :: ungriddedUBound_output(1) - integer :: fieldCount - integer :: ns,n - type(ESMF_Field), pointer :: fieldlist(:) => null() - character(len=*) , parameter :: subname='(map_glc2lnd_mod:map_glc2lnd_init)' - !--------------------------------------- - - rc = ESMF_SUCCESS - - !--------------------------------------- - ! Get the internal state - !--------------------------------------- - - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! Set the module variable for the number of elevation classes - !--------------------------------------- - - ! Determine number of elevation classes by querying a field that has elevation classes in it - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), 'Sg_topo_elev', field=lfield_l, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_l, ungriddedUBound=ungriddedUBound_output, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ungriddedCount = ungriddedUBound_output(1) - ! TODO: check that ungriddedCount = glc_nec+1 - - ! ------------------------------- - ! Create module fields on land mesh - ! ------------------------------- - - call fldbun_getmesh(is_local%wrap%FBExp(complnd), mesh_l, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_icemask_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_frac_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_frac_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_topo_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! create module fields on glc mesh - !--------------------------------------- - - do ns = 1,max_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - - call fldbun_getmesh(is_local%wrap%FBImp(compglc(ns),compglc(ns)), ice_sheet_tolnd(ns)%mesh_g, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_frac_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create route handle if it has not been created - if (.not. ESMF_RouteHandleIsCreated(is_local%wrap%RH(compglc(ns),complnd,mapconsd), rc=rc)) then - call med_map_routehandles_init( compglc(ns), complnd, & - ice_sheet_tolnd(ns)%field_icemask_g, lfield_l, & - mapindex=mapconsd, & - routehandles=is_local%wrap%rh(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - end do - - ! Currently cannot map hflx in multiple elevation classes from glc to land - if (fldbun_fldchk(is_local%wrap%FBExp(complnd), trim(Flgg_hflx), rc=rc)) then - call ESMF_LogWrite(trim(subname)//'ERROR: Flgg_hflx to land has not been implemented yet', & - ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) - rc = ESMF_FAILURE - return - end if - - end subroutine map_glc2lnd_init - - !================================================================================================ - subroutine map_glc2lnd( gcomp, rc) - - !------------------ - ! Maps fields from the GLC grid to the LND grid. - ! On the GLC grid the fields will not have elevation classes. - ! On the LND grid they will have elevation classes. - !------------------ - - ! input/output variables - type(ESMF_GridComp) , intent(inout) :: gcomp - integer , intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - type(ESMF_Field) :: lfield - type(ESMF_Field) :: lfield_src - type(ESMF_Field) :: lfield_dst - integer :: ec, l, g, ns, n - real(r8) :: topo_virtual - real(r8), pointer :: icemask_g(:) => null() ! glc ice mask field on glc grid - real(r8), pointer :: frac_g(:) => null() ! total ice fraction in each glc cell - real(r8), pointer :: frac_g_ec(:,:) => null() ! glc fractions on the glc grid - real(r8), pointer :: frac_l_ec(:,:) => null() ! glc fractions on the land grid - real(r8), pointer :: topo_g(:) => null() ! topo height of each glc cell (no elev classes) - real(r8), pointer :: topo_l_ec(:,:) => null() ! topo height in each land gridcell for each elev class - real(r8), pointer :: frac_x_icemask_g_ec(:,:) => null() ! (glc fraction) x (icemask), on the glc grid - real(r8), pointer :: frac_x_icemask_l_ec(:,:) => null() - real(r8), pointer :: topo_x_icemask_g_ec(:,:) => null() - real(r8), pointer :: topo_x_icemask_l_ec(:,:) => null() - real(r8), pointer :: dataptr1d(:) => null() - real(r8), pointer :: dataptr2d(:,:) => null() - real(r8), pointer :: frac_l_ec_sum(:,:) => null() - real(r8), pointer :: topo_l_ec_sum(:,:) => null() - real(r8), pointer :: dataptr1d_src(:) => null() - real(r8), pointer :: dataptr1d_dst(:) => null() - character(len=*), parameter :: subname = 'map_glc2lnd' - !----------------------------------------------------------------------- - - call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - end if - rc = ESMF_SUCCESS - - !--------------------------------------- - ! Get the internal state - !--------------------------------------- - - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------- - ! Get pointers into land export field bundle (this is summed over all ice sheets) - !--------------------------------- - - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_frac)//'_elev', frac_l_ec_sum, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = 0._r8 - - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_topo)//'_elev', topo_l_ec_sum, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - topo_l_ec_sum(:,:) = 0._r8 - - !--------------------------------- - ! Map fractional ice coverage to the land grid (multiple elevation classes) - !--------------------------------- - - ! Map Sg_icemask and Sg_icemask_coupled_fluxes (no elevation classes) - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & - field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & - packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - end if - end do - - ! Get Sg_icemask on land as sum of all ice sheets (no elevation classes) - call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask, dataptr1d_dst, rc) - dataptr1d_dst(:) = 0._r8 - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask, dataptr1d_src, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) - end if - end do - - ! Get Sg_icemask_coupled_fluxes on land as sum of all ice sheets (no elevation classes) - call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask_coupled_fluxes, dataptr1d_dst, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = 0._r8 - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask_coupled_fluxes, dataptr1d_src, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) - end if - end do - - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - - ! Set (fractional ice coverage for each elevation class on the glc grid) - - ! get topo_g(:) - the topographic height of each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! get frac_g(:) - the total ice fraction in each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_frac, frac_g, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! compute frac_g_ec(:,:) - the glc fractions on the glc grid for each elevation class (inner dimension) - call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_g_ec, frac_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call glc_get_fractional_icecov(ungriddedCount-1, topo_g, frac_g, frac_g_ec, logunit) - - ! compute icemask_g - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_icemask, dataptr1d, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata1d(ice_sheet_tolnd(ns)%field_icemask_g, icemask_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_g(:) = dataptr1d(:) - - ! compute frac_x_icemask_g_ec - ! only include grid cells that are both (a) within the icemask and (b) in this elevation class - call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, frac_x_icemask_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ec = 1, ungriddedCount - frac_x_icemask_g_ec(ec,:) = frac_g_ec(ec,:) * icemask_g(:) - end do - - ! map frac_g_ec to frac_l_ec and normalize by icemask_g - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping elevation class fractions from glc to land", & - ESMF_LOGMSG_INFO) - end if - call med_map_field_normalized( & - field_src=ice_sheet_tolnd(ns)%field_frac_g_ec, & - field_dst=field_frac_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, & - field_normsrc=ice_sheet_tolnd(ns)%field_icemask_g, & - field_normdst=field_icemask_l, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! now set values in land export state for Sg_frac_elev (this is summed over all ice sheets) - call field_getdata2d(field_frac_l_ec, frac_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = frac_l_ec_sum(:,:) + frac_l_ec(:,:) - - !--------------------------------- - ! Map topo to the land grid (multiple elevation classes) - !--------------------------------- - - ! Note that all topo values in FBimp(compglc(ns),compglc(ns)) do not have elevation class dependence - ! Normalize by frac_x_icemask_g_ec - this is what introduces - ! elevation class information from the glc grid (without elevation classes) to the - ! land grid (with elevation classes) - ! Note that bare land values are mapped in the same way as ice-covered values - - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, topo_x_icemask_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ec = 1,ungriddedCount - do l = 1,size(topo_g) - topo_x_icemask_g_ec(ec,l) = topo_g(l) * frac_x_icemask_g_ec(ec,l) - end do - end do - - ! map field_topo_x_icemask_g_ec from glc to land (with multiple elevation classes) - no normalization - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping of topo from glc to land", ESMF_LOGMSG_INFO) - end if - call med_map_field( & - field_src=ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, & - field_dst=field_topo_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(field_topo_x_icemask_l_ec, topo_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! map FBglc_frac_x_icemask from glc to land (with multiple elevation classes) - no normalization - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping of frac_x_icemask from glc to land", ESMF_LOGMSG_INFO) - end if - call med_map_field( & - field_src=ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, & - field_dst=field_frac_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(field_frac_x_icemask_l_ec, frac_x_icemask_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! set Sg_topo values in export state to land (in multiple elevation classes) - ! also set the topo field for virtual columns, in a given elevation class. - ! This is needed because virtual columns (i.e., elevation classes that have no - ! contributing glc grid cells) won't have any topographic information mapped onto - ! them, so would otherwise end up with an elevation of 0. - do ec = 1,ungriddedCount - topo_virtual = glc_mean_elevation_virtual(ec-1) ! glc_mean_elevation_virtual uses 0:glc_nec - do l = 1,size(frac_x_icemask_l_ec, dim=2) - if (frac_l_ec_sum(ec,l) <= 0._r8) then - topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_virtual - else - if (frac_x_icemask_l_ec(ec,l) /= 0.0_r8) then - topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) - end if - end if - end do - end do - end if - end do - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - end if - call t_stopf('MED:'//subname) - - end subroutine map_glc2lnd - end module med_phases_prep_lnd_mod From b494a25e9005f588a2e985623ff766e344a4e534 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 28 Nov 2020 13:00:06 -0700 Subject: [PATCH 169/206] added med_phases_post_glc to run sequence --- cime_config/runseq/runseq_general.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 4b277dee3..0699e4dc1 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -150,7 +150,6 @@ def gen_runseq(case, coupling_times): else: runseq.add_action("OCN -> MED :remapMethod=redist" , run_ocn and ocn_outer_loop) - #------------------ runseq.leave_time_loop(ocn_outer_loop) #------------------ @@ -165,5 +164,6 @@ def gen_runseq(case, coupling_times): 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) shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) From 6452bece4a4349551bc4c245e8d6bc64a005ecc1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 29 Nov 2020 20:07:47 -0700 Subject: [PATCH 170/206] bug fixes in testing --- mediator/esmFldsExchange_cesm_mod.F90 | 8 +++----- mediator/med_phases_prep_lnd_mod.F90 | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 992e66f3e..2f7322b10 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -1336,13 +1336,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) end if end do end if - end do - do n = 1,size(iso) 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_liq, 'none', rof2ocn_ice_rmap) + 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 @@ -1351,7 +1349,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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_liq, 'one' , glc2ocn_ice_rmap) + 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 diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 20f38a8b2..88a6fecc8 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -357,7 +357,7 @@ subroutine map_glc2lnd_init(gcomp, rc) ! 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, lfield_l, & + 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 From 5bc6ffa4e38e089dc5d7475d06960feb9bfb7ff4 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 29 Nov 2020 22:41:56 -0700 Subject: [PATCH 171/206] aded a post rof phase --- mediator/med.F90 | 35 +++++++--- mediator/med_phases_post_glc_mod.F90 | 74 ++++++++++++++-------- mediator/med_phases_post_rof_mod.F90 | 95 ++++++++++++++++++++++++++++ mediator/med_phases_prep_ice_mod.F90 | 45 ++++++++----- mediator/med_phases_prep_lnd_mod.F90 | 36 +++++------ mediator/med_phases_prep_ocn_mod.F90 | 40 ++++++++---- 6 files changed, 243 insertions(+), 82 deletions(-) create mode 100644 mediator/med_phases_post_rof_mod.F90 diff --git a/mediator/med.F90 b/mediator/med.F90 index 428fa13e2..4b6e74dd2 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -92,6 +92,7 @@ subroutine SetServices(gcomp, rc) use med_phases_post_glc_mod , only: med_phases_post_glc 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_post_rof_mod , only: med_phases_post_rof 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 @@ -317,6 +318,20 @@ subroutine SetServices(gcomp, rc) specPhaselabel="med_phases_prep_rof_accum", specRoutine=NUOPC_NoOp, 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_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_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 !------------------ @@ -1664,6 +1679,7 @@ subroutine DataInitialize(gcomp, rc) 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_post_glc_mod , only : med_phases_post_glc + use med_phases_post_rof_mod , only : med_phases_post_rof use med_phases_prep_atm_mod , only : med_phases_prep_atm use med_phases_ocnalb_mod , only : med_phases_ocnalb_run use med_phases_aofluxes_mod , only : med_phases_aofluxes_run @@ -2338,15 +2354,18 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - ! If appropriate, Map initial glc->lnd before run phase of glc is called + ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice + ! before run phase of glc is called !--------------------------------------- - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - write(6,*)'DEBUG: calling med_phases_post_glc for ice sheet ',ns - call med_phases_post_glc(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do + call med_phases_post_glc(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------------- + ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice + ! before run phase of glc is called + !--------------------------------------- + call med_phases_post_rof(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- ! read mediator restarts diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 18c200674..55e2fb560 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -14,7 +14,7 @@ module med_phases_post_glc_mod use ESMF , only : ESMF_Mesh, ESMF_MeshLoc, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated - use esmFlds , only : complnd, compatm, comprof, ncomps, compname + use esmFlds , only : compatm, compice, complnd, comprof, compocn, ncomps, compname use esmFlds , only : max_icesheets, num_icesheets, compglc use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname use esmFlds , only : fldListTo @@ -71,8 +71,10 @@ module med_phases_post_glc_mod ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) - logical :: glc2lnd_coupling = .false. logical :: cism_evolve = .false. + logical :: glc2lnd_coupling = .false. + logical :: glc2ocn_coupling = .false. + logical :: glc2ice_coupling = .false. character(*) , parameter :: u_FILE_u = & __FILE__ @@ -110,14 +112,28 @@ subroutine med_phases_post_glc(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 - ! 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(complnd), fieldCount=ncnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (ncnt > 0) then + 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 ! determine if coupling to CISM is 2-way if (first_call) then @@ -132,28 +148,25 @@ subroutine med_phases_post_glc(gcomp, rc) end if end if end if + end if + + ! 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(complnd), fieldCount=ncnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (ncnt > 0) then !--------------------------------------- ! glc->lnd mapping and merging !--------------------------------------- - - ! determine if there will be any glc to lnd coupling - if (first_call) then - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - glc2lnd_coupling = .true. - exit - end if - end do - end if - if (glc2lnd_coupling) then ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - write(6,*)'DEBUG: num_icesheets = ',num_icesheets call t_startf('MED:'//trim(subname)//' glc2lnd ') do ns = 1,num_icesheets if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - write(6,*)'DEBUG: calling med_map_field_packed for glc->lnd for ice sheet ',ns call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & @@ -168,17 +181,28 @@ subroutine med_phases_post_glc(gcomp, rc) ! The following is only done if glc->lnd coupling is active if (first_call) then - write(6,*)'DEBUG: calling map_glc2lnd_init ' 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) - write(6,*)'DEBUG: calling map_glc2lnd ' call map_glc2lnd(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + !--------------------------------------- + ! glc->ocn mapping, not sure about merging? + !--------------------------------------- + if (glc2ocn_coupling) then + ! Fill this in + end if + + !--------------------------------------- + ! glc->ice mapping, not sure about merging? + !--------------------------------------- + if (glc2ice_coupling) then + ! Fill this in + end if end if ! Reset first call logical diff --git a/mediator/med_phases_post_rof_mod.F90 b/mediator/med_phases_post_rof_mod.F90 new file mode 100644 index 000000000..b75942fa8 --- /dev/null +++ b/mediator/med_phases_post_rof_mod.F90 @@ -0,0 +1,95 @@ +module med_phases_post_rof_mod + + ! Map to import data from rof to land, sea-ice and ocean + + 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 + + implicit none + private + + public :: med_phases_post_rof + + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================================ +contains +!================================================================================================ + + subroutine med_phases_post_rof(gcomp, rc) + + ! 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 > 5) 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 + + 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 + + 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 + + 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 > 5) 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_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index a65680681..7a8a19f3b 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -14,7 +14,7 @@ module med_phases_prep_ice_mod 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 : compatm, compice, compocn, comprof, compglc, ncomps, compname use esmFlds , only : fldListFr, fldListTo use esmFlds , only : mapnames use esmFlds , only : coupling_mode @@ -91,20 +91,35 @@ subroutine med_phases_prep_ice(gcomp, rc) 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 - end if - end do - + ! 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 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 + ! rof->ice is mapped in med_phases_post_rof + ! glc->ice is mapped in med_phases_post_glc + !--------------------------------------- !--- auto merges to create FBExp(compice) !--------------------------------------- diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index cfd59b302..42b981df0 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -48,8 +48,6 @@ subroutine med_phases_prep_lnd(gcomp, rc) integer :: n1,ncnt,ns real(r8) :: nextsw_cday logical :: first_call = .true. - logical :: isPresent - character(CL) :: cvalue character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- @@ -75,26 +73,24 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then !--------------------------------------- - ! map to create FBimp(:,complnd) - other than glc->lnd + ! map to atm2lnd !--------------------------------------- - call t_startf('MED:'//trim(subname)//' map') - do n1 = 1,ncomps - ! Skip glc here and handle it below - if (n1 == compatm .or. n1 == comprof) then - 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 if - end do - call t_stopf('MED:'//trim(subname)//' map') + ! rof2lnd is done in med_phases_post_rof + ! glc2lnd is done in med_phases_post_glc + + 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 !--------------------------------------- ! auto merges to create FBExp(complnd) - other than glc->lnd diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 4352239b9..5e7f7be54 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -20,7 +20,7 @@ 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, comprof, compglc, ncomps, compname use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -79,20 +79,32 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) 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 + ! map all fields in FBImp that have active ocean coupling other than compglc and comprof 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 + 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 + 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 endif call t_stopf('MED:'//subname) From 3786519d066f8a0083ec282fae2a8f2cb1f44286 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 30 Nov 2020 09:47:06 -0700 Subject: [PATCH 172/206] clarified comments --- mediator/esmFldsExchange_cesm_mod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 2f7322b10..05346bc7e 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -466,8 +466,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! --------------------------------------------------------------------- ! The suffix _elev on land fields designates fields with elevation classes - ! fields from glc->med do NOT have elevation classes - ! fields from med->lnd are BROKEN into multiple 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 do ns = 1, num_icesheets @@ -537,6 +537,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n))) else 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) From f520ad9200857ffab628a1ed644e4d7927a32a9f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 30 Nov 2020 16:12:56 -0700 Subject: [PATCH 173/206] fix avgdt variable and add nthreads value to gcomp --- drivers/cime/esm.F90 | 20 +++++++++++++++----- mediator/med_phases_profile_mod.F90 | 16 ++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/cime/esm.F90 b/drivers/cime/esm.F90 index 821e7e8de..1b436f8a7 100644 --- a/drivers/cime/esm.F90 +++ b/drivers/cime/esm.F90 @@ -644,7 +644,7 @@ end subroutine CheckAttributes !=============================================================================== - subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, rc) + subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, nthreads, rc) ! Add specific set of attributes to components from driver attributes @@ -659,6 +659,7 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, r integer , intent(in) :: compid character(len=*) , intent(in) :: compname character(len=*) , intent(in) :: inst_suffix + integer , intent(in) :: nthreads integer , intent(inout) :: rc ! local variables @@ -684,6 +685,15 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, r call NUOPC_CompAttributeSet(gcomp, name='MCTID', value=trim(cvalue), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + !------ + ! Add thread count to gcomp attributes + !------ + write(cvalue,*) nthreads + call NUOPC_CompAttributeAdd(gcomp, attrList=(/'nthreads'/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeSet(gcomp, name='nthreads', value=trim(cvalue), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + !------ ! Add restart flag a to gcomp attributes !------ @@ -693,7 +703,7 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, r call NUOPC_CompAttributeGet(driver, name="mediator_read_restart", value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) lvalue - if (.not. lvalue) then + if (.not. lvalue) then call NUOPC_CompAttributeGet(driver, name=trim(attribute), value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if @@ -887,7 +897,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) logical, allocatable :: comp_iamin(:) character(len=5) :: inst_suffix character(CL) :: cvalue - logical :: found_comp + logical :: found_comp character(len=*), parameter :: subname = "(esm_pelayout.F90:esm_init_pelayout)" !--------------------------------------- @@ -1062,7 +1072,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) return endif - call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, rc=rc) + call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, nthrds, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ESMF_GridCompIsPetLocal(child, rc=rc)) then @@ -1072,7 +1082,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) call ESMF_VMGet(vm, mpiCommunicator=comms(i+1), localPet=comp_comm_iam(i), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, rc=rc) + call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, nthrds, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! This code is not supported, we need an optional arg to NUOPC_DriverAddComp to include the diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index f69696733..447b1e4c2 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -9,7 +9,7 @@ module med_phases_profile_mod use med_utils_mod , only : med_utils_chkerr, med_memcheck use med_internalstate_mod , only : mastertask, logunit use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_time_mod , only : alarmInit => med_time_alarmInit + use med_time_mod , only : alarmInit => med_time_alarmInit use perf_mod , only : t_startf, t_stopf use shr_mem_mod , only : shr_mem_getusage @@ -38,7 +38,7 @@ subroutine med_phases_profile(gcomp, rc) use ESMF , only : ESMF_TimeSyncToRealTime, ESMF_Time, ESMF_TimeSet use ESMF , only : ESMF_TimeInterval, ESMF_AlarmGet, ESMF_TimeIntervalGet use ESMF , only : ESMF_ClockGetNextTime, ESMF_TimeGet, ESMF_ClockGet - use ESMF , only : ESMF_ClockAdvance, ESMF_ClockSet, ESMF_ClockIsStopTime + use ESMF , only : ESMF_ClockAdvance, ESMF_ClockSet, ESMF_ClockIsStopTime use ESMF , only : operator(-) use NUOPC , only : NUOPC_CompAttributeGet @@ -102,7 +102,7 @@ subroutine med_phases_profile(gcomp, rc) call ESMF_ClockSet(clock, currTime=currtime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! intialize + ! intialize call ESMF_VMWtime(previous_time, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -150,21 +150,18 @@ subroutine med_phases_profile(gcomp, rc) wallclockelapsed = current_time - previous_time accumulated_time = accumulated_time + wallclockelapsed - + ringdays = timestep_length if (alarmison) then call ESMF_AlarmGet( alarm, ringInterval=ringInterval, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_TimeIntervalGet(ringInterval, d_r8=ringdays, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return - avgdt = accumulated_time/(ringdays*real(iterations-1)) else if (stopalarmison) then ! Here we need the interval since the last call to this function call ESMF_TimeIntervalGet(nexttime-prevtime, d_r8=ringdays, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return - else - avgdt = wallclockelapsed/timestep_length - ringdays = timestep_length endif + avgdt = accumulated_time/(timestep_length*real(iterations-1, kind=r8)) prevtime = nexttime call ESMF_TimeGet(nexttime, timestring=nexttimestr, rc=rc) if (med_utils_ChkErr(rc,__LINE__,u_FILE_u)) return @@ -177,12 +174,11 @@ subroutine med_phases_profile(gcomp, rc) call ESMF_TimeGet(wallclocktime,timeString=walltimestr, rc=rc) if (med_utils_ChkErr(rc,__LINE__,u_FILE_u)) return - ! 1 model day/ x seconds = 1/365 yrs/ (wallclockelapsed s/86400spd ypd = ringdays*86400.0_R8/(365.0_R8*wallclockelapsed) write(logunit,101) 'Model Date: ',trim(nexttimestr), ' wall clock = ',trim(walltimestr),' avg dt = ', & - avgdt, 's/day, dt = ',wallclockelapsed/ringdays,'s/day, rate = ',ypd,' ypd' + avgdt, ' s/day, dt = ',wallclockelapsed/ringdays,' s/day, rate = ',ypd,' ypd' call shr_mem_getusage(msize,mrss,.true.) write(logunit,105) ' memory_write: model date = ',trim(nexttimestr), & From e045da767657b9be08f77f874c86bc99522209da Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 30 Nov 2020 20:24:48 -0700 Subject: [PATCH 174/206] major performance update for I2000 compset --- mediator/med_phases_post_glc_mod.F90 | 4 +- mediator/med_phases_prep_glc_mod.F90 | 1 - mediator/med_phases_prep_rof_mod.F90 | 324 ++++++++++++++++----------- 3 files changed, 194 insertions(+), 135 deletions(-) diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 55e2fb560..930d6dbe1 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -16,7 +16,7 @@ module med_phases_post_glc_mod 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, mapconsf, compname + 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 @@ -310,7 +310,7 @@ subroutine map_glc2lnd_init(gcomp, rc) ! 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, lfield_l, & + 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 diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 3bdda2391..80c13f381 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -67,7 +67,6 @@ module med_phases_prep_glc_mod integer :: FBlndAccumCnt character(len=14) :: fldnames_fr_lnd(3) = (/'Flgl_qice_elev','Sl_tsrf_elev ','Sl_topo_elev '/) character(len=14) :: fldnames_to_glc(2) = (/'Flgl_qice ','Sl_tsrf '/) - type, public :: ice_sheet_toglc_type character(CS) :: name diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 0baf8c784..8d24a0284 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -13,7 +13,7 @@ module med_phases_prep_rof_mod use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 use ESMF , only : ESMF_FieldBundle, ESMF_Field use esmFlds , only : ncomps, complnd, comprof, compname, mapconsf, mapconsd - use med_internalstate_mod , only : InternalState, mastertask + use med_internalstate_mod , only : InternalState, mastertask, logunit use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_constants_mod , only : czero => med_constants_czero use med_utils_mod , only : chkerr => med_utils_chkerr @@ -22,7 +22,6 @@ module med_phases_prep_rof_mod use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose use med_methods_mod , only : fldbun_reset => med_methods_FB_reset - use med_methods_mod , only : fldbun_accum => med_methods_FB_accum use med_methods_mod , only : fldbun_average => med_methods_FB_average use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d @@ -50,6 +49,10 @@ module med_phases_prep_rof_mod character(len=*), parameter :: irrig_normalized_field = 'Flrl_irrig_normalized' character(len=*), parameter :: irrig_volr0_field = 'Flrl_irrig_volr0 ' + ! the following are the fields that will be accumulated from the land + character(CS) :: lnd2rof_flds(6) = (/'Flrl_rofsur','Flrl_rofgwl','Flrl_rofsub', & + 'Flrl_rofdto','Flrl_rofi ','Flrl_irrig '/) + character(*) , parameter :: u_FILE_u = & __FILE__ @@ -66,10 +69,11 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) ! Mapping from the land to the rof grid is then done with the time averaged fields !------------------------------------ - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet, ESMF_StateIsCreated, ESMF_StateGet - use ESMF , only : ESMF_FieldBundleIsCreated + use NUOPC , only : NUOPC_IsConnected + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FieldBundleGet, ESMF_StateIsCreated, ESMF_StateGet + use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_Field, ESMF_FieldGet ! input/output variables type(ESMF_GridComp) :: gcomp @@ -77,8 +81,20 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - integer :: i,j,n,ncnt + type(InternalState) :: is_local + integer :: i,j,n,ncnt + integer :: fieldCount + integer :: ungriddedUBound(1) + logical :: exists + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: dataptr1d_accum(:) => null() + real(r8), pointer :: dataptr2d_accum(:,:) => null() + type(ESMF_Field) :: lfield + type(ESMF_Field) :: lfield_accum + type(ESMF_Field), pointer :: fieldlist(:) => null() + type(ESMF_Field), pointer :: fieldlist_accum(:) => null() + character(CL), pointer :: lfieldnamelist(:) => null() character(len=*), parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_accum)' !--------------------------------------- @@ -89,49 +105,48 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end if rc = ESMF_SUCCESS - !--------------------------------------- ! Get the internal state - !--------------------------------------- - nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Count the number of fields outside of scalar data, if zero, then return - !--------------------------------------- - - if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,complnd))) then - ncnt = 0 - call ESMF_LogWrite(trim(subname)//": FBImp(complnd,complnd) is not created", & - ESMF_LOGMSG_INFO) - else - ! The scalar field has been removed from all mediator field bundles - so check if the fieldCount is - ! 0 and not 1 here - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=ncnt, rc=rc) + ! Accumulate lnd input on lnd grid for fields that will be sent to rof + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBimp(complnd), returning", & - ESMF_LOGMSG_INFO) - end if - - !--------------------------------------- - ! Accumulate lnd input on lnd grid - !--------------------------------------- + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBImpaccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata2d(lfield_accum, dataptr2d_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d_accum(:,:) = dataptr2d_accum(:,:) + dataptr2d(:,:) + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(lfield_accum, dataptr1d_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d_accum(:) = dataptr1d_accum(:) + dataptr1d(:) + end if + end if + end do - ! Note that all import fields from the land are accumulated - but - ! only a few will actaully be sent to the river model + ! Accumulate counter + is_local%wrap%FBImpAccumCnt(complnd) = is_local%wrap%FBImpAccumCnt(complnd) + 1 - if (ncnt > 0) then - call fldbun_accum(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImp(complnd,complnd), rc=rc) + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & + string=trim(subname)//' FBImpAccum(complnd,complnd) ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - is_local%wrap%FBImpAccumCnt(complnd) = is_local%wrap%FBImpAccumCnt(complnd) + 1 - - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & - string=trim(subname)//' FBImpAccum(complnd,complnd) ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if end if if (dbug_flag > 20) then @@ -148,13 +163,14 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) ! Prepare the ROF export Fields from the mediator !------------------------------------ - use NUOPC , only : NUOPC_IsConnected - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use esmFlds , only : fldListTo - use med_map_mod , only : med_map_field_packed - use med_merge_mod , only : med_merge_auto + use NUOPC , only : NUOPC_IsConnected + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use esmFlds , only : fldListTo + use med_map_mod , only : med_map_field_packed + use med_merge_mod , only : med_merge_auto + use med_constants_mod , only : czero => med_constants_czero ! input/output variables type(ESMF_GridComp) :: gcomp @@ -163,14 +179,17 @@ 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) + integer :: ungriddedUBound(1) + character(CL), pointer :: lfieldnamelist(:) => null() character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_avg)' !--------------------------------------- @@ -181,7 +200,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) rc = ESMF_SUCCESS !--------------------------------------- - ! --- Get the internal state + ! Get the internal state !--------------------------------------- nullify(is_local%wrap) @@ -189,100 +208,141 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - ! Count the number of fields outside of scalar data, if zero, then return + ! Average import from land accumuled FB !--------------------------------------- - ! Note - the scalar field has been removed from all mediator field bundles - so this is why we check if the - ! fieldCount is 0 and not 1 here - call ESMF_FieldBundleGet(is_local%wrap%FBExp(comprof), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + count = is_local%wrap%FBImpAccumCnt(complnd) + if (count == 0) then + if (mastertask) then + write(logunit,'(a)')trim(subname)//'accumulation count for land input averging to river is 0 '// & + ' accumulation field is set to zero' + end if + end if - if (ncnt == 0) then + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (count == 0) then + dataptr2d(:,:) = czero + else + dataptr2d(:,:) = dataptr2d(:,:) / real(count, r8) + end if + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (count == 0) then + dataptr1d(:) = czero + else + dataptr1d(:) = dataptr1d(:) / real(count, r8) + end if + end if + end if + end do - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(comprof), returning", & - ESMF_LOGMSG_INFO) - else + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & + string=trim(subname)//' FBImpAccum(complnd,complnd) after avg ', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - !--------------------------------------- - ! average import from land accumuled FB - !--------------------------------------- + !--------------------------------------- + ! Map to create FBImpAccum(complnd,comprof) + !--------------------------------------- - call fldbun_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! The following assumes that only land import fields are needed to create the + ! export fields for the river component and that ALL mappings are done with mapconsf + + if (is_local%wrap%med_coupling_active(complnd,comprof)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & + FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & + FBFracSrc=is_local%wrap%FBFrac(complnd), & + field_normOne=is_local%wrap%field_normOne(complnd,comprof,:), & + packed_data=is_local%wrap%packed_data(complnd,comprof,:), & + routehandles=is_local%wrap%RH(complnd,comprof,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & - string=trim(subname)//' FBImpAccum(complnd,complnd) after avg ', rc=rc) + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & + string=trim(subname)//' FBImpAccum(complnd,comprof) after map ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - ! map to create FBImpAccum(complnd,comprof) - !--------------------------------------- - - ! The following assumes that only land import fields are needed to create the - ! export fields for the river component and that ALL mappings are done with mapconsf - - if (is_local%wrap%med_coupling_active(complnd,comprof)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & - FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & - FBFracSrc=is_local%wrap%FBFrac(complnd), & - field_normOne=is_local%wrap%field_normOne(complnd,comprof,:), & - packed_data=is_local%wrap%packed_data(complnd,comprof,:), & - routehandles=is_local%wrap%RH(complnd,comprof,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & - string=trim(subname)//' FBImpAccum(complnd,comprof) after map ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + ! Reset the irrig_flux_field with the map_lnd2rof_irrig calculation below if appropriate + if ( NUOPC_IsConnected(is_local%wrap%NStateImp(complnd), fieldname=trim(irrig_flux_field))) then + call med_phases_prep_rof_irrig( gcomp, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + ! This will ensure that no irrig is sent from the land + call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), irrig_flux_field, dataptr, rc) + dataptr(:) = czero + end if + endif - ! Reset the irrig_flux_field with the map_lnd2rof_irrig calculation below if appropriate - if ( NUOPC_IsConnected(is_local%wrap%NStateImp(complnd), fieldname=trim(irrig_flux_field))) then - call med_phases_prep_rof_irrig( gcomp, rc=rc ) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - ! This will ensure that no irrig is sent from the land - call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), irrig_flux_field, dataptr, rc) - dataptr(:) = czero - end if - endif + !--------------------------------------- + ! auto merges to create FBExp(comprof) + !--------------------------------------- - !--------------------------------------- - ! auto merges to create FBExp(comprof) - !--------------------------------------- + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBFrac(comprof), & + string=trim(subname)//' FBFrac(comprof) before merge ', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBFrac(comprof), & - string=trim(subname)//' FBFrac(comprof) before merge ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + call med_merge_auto(comprof, & + is_local%wrap%med_coupling_active(:,comprof), & + is_local%wrap%FBExp(comprof), & + is_local%wrap%FBFrac(comprof), & + is_local%wrap%FBImpAccum(:,comprof), & + fldListTo(comprof), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_merge_auto(comprof, & - is_local%wrap%med_coupling_active(:,comprof), & - is_local%wrap%FBExp(comprof), & - is_local%wrap%FBFrac(comprof), & - is_local%wrap%FBImpAccum(:,comprof), & - fldListTo(comprof), rc=rc) + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBExp(comprof), & + string=trim(subname)//' FBexp(comprof) ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBExp(comprof), & - string=trim(subname)//' FBexp(comprof) ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + !--------------------------------------- + ! zero accumulator and FBAccum + !--------------------------------------- - !--------------------------------------- - ! zero accumulator and FBAccum - !--------------------------------------- + ! zero counter + is_local%wrap%FBImpAccumCnt(complnd) = 0 - is_local%wrap%FBImpAccumCnt(complnd) = 0 - call fldbun_reset(is_local%wrap%FBImpAccum(complnd,complnd), czero, rc) + ! zero lnd2rof fields in FBImpAccum + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImpaccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + end if + end if + end do - endif if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if @@ -314,12 +374,12 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! (non-volr-normalized) flux on the rof grid. !--------------------------------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldIsCreated - use ESMF , only : ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR - use med_map_mod , only : med_map_rh_is_created, med_map_field, med_map_field_normalized + use ESMF , only : ESMF_GridComp, ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldIsCreated + use ESMF , only : ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR + use med_map_mod , only : med_map_rh_is_created, med_map_field, med_map_field_normalized ! input/output variables type(ESMF_GridComp) :: gcomp @@ -356,7 +416,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) rc = ESMF_SUCCESS !--------------------------------------- - ! --- Get the internal state + ! Get the internal state !--------------------------------------- nullify(is_local%wrap) From 59ec4d1b9ebc161780bc77ea679c70561bb63993 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 1 Dec 2020 13:38:22 -0700 Subject: [PATCH 175/206] reworked how scalar data was set in med_phases_prep_lnd --- mediator/med_phases_prep_lnd_mod.F90 | 61 ++++++++++++---------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 42b981df0..75575b332 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -8,15 +8,13 @@ module med_phases_prep_lnd_mod 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_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, comprof, ncomps, 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 : 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 @@ -43,11 +41,15 @@ subroutine med_phases_prep_lnd(gcomp, rc) 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. + 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 :: dataptr(:,:) + logical :: first_call = .true. character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- @@ -70,15 +72,13 @@ subroutine med_phases_prep_lnd(gcomp, rc) call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldCount=ncnt, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (ncnt > 0) then - !--------------------------------------- ! map to atm2lnd - !--------------------------------------- - ! rof2lnd is done in med_phases_post_rof ! glc2lnd is done in med_phases_post_glc - if (is_local%wrap%med_coupling_active(compatm,complnd)) then call t_startf('MED:'//trim(subname)//' map_atm2lnd') call med_map_field_packed( & @@ -92,12 +92,8 @@ subroutine med_phases_prep_lnd(gcomp, rc) call t_stopf('MED:'//trim(subname)//' map_atm2lnd') end if - !--------------------------------------- ! auto merges to create FBExp(complnd) - other than glc->lnd - !--------------------------------------- - ! The following will merge all fields in fldsSrc - call t_startf('MED:'//trim(subname)//' merge') call med_merge_auto(complnd, & is_local%wrap%med_coupling_active(:,complnd), & @@ -108,29 +104,24 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' merge') - !--------------------------------------- - ! 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 and send it to lnd + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & + trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then call t_startf('MED:'//trim(subname)//' nextsw_cday') - ! send nextsw_cday to land - first obtain it from atm import - call State_GetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateImp(compatm), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) + 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, 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) + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr(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 + dataptr(scalar_id,1) = tmp(1) call t_stopf('MED:'//trim(subname)//' nextsw_cday') end if From bfd5ca7b2340b7c052749cda7bde4fed91039b9b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Dec 2020 13:26:33 -0700 Subject: [PATCH 176/206] more performance improvements --- cime_config/config_component.xml | 1 + cime_config/namelist_definition_drv.xml | 18 +++--- mediator/med.F90 | 16 ++++-- mediator/med_phases_prep_ice_mod.F90 | 73 +++++++++++++------------ mediator/med_phases_prep_lnd_mod.F90 | 31 +++++++---- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index dbffe661f..85e53351e 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -1020,6 +1020,7 @@ Determines the profiling level in ESMF log files by default, it is set to 0 (only run method execution timings) + For maximum profiling set it to 65535. diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 3bbc58483..1ea7ea455 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -18,15 +18,6 @@ - - char - nuopc - DRIVER_attributes - - $ESMF_PROFILING_LEVEL - - - char nuopc @@ -393,6 +384,15 @@ + + char + nuopc + ALLCOMP_attributes + + $ESMF_PROFILING_LEVEL + + + char orbital diff --git a/mediator/med.F90 b/mediator/med.F90 index 4b6e74dd2..f06ce798d 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -590,16 +590,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) diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 7a8a19f3b..39a644cdf 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -5,12 +5,10 @@ module med_phases_prep_ice_mod !----------------------------------------------------------------------------- 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_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_map_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, logunit, mastertask @@ -41,6 +39,7 @@ subroutine med_phases_prep_ice(gcomp, rc) use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet, ESMF_Field use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE use ESMF , only : ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND + use ESMF , only : ESMF_VMBroadCast use NUOPC , only : NUOPC_IsConnected ! input/output variables @@ -51,15 +50,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,ncnt + real(R8), pointer :: dataptr1d(:) => null() + real(R8), pointer :: dataptr2d(:,:) => 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_precip_fact_call = .true. character(len=*),parameter :: subname='(med_phases_prep_ice)' !--------------------------------------- @@ -157,9 +156,9 @@ subroutine med_phases_prep_ice(gcomp, rc) 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) + call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = dataptr(:) * precip_fact + dataptr1d(:) = dataptr1d(:) * precip_fact end if end do deallocate(fldnames) @@ -172,35 +171,37 @@ subroutine med_phases_prep_ice(gcomp, rc) end if !--------------------------------------- - !--- update scalar data + ! obtain nextsw_cday from atm and send it to ice !--------------------------------------- - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) + ! obtain nextsw_cday from atm 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 - 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 + call t_startf('MED:'//trim(subname)//' nextsw_cday') + ! obtain nextsw_cday from atm import on all tasks + 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=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr2d(scalar_id,1) end if - end if + call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - !--- clean up - !--------------------------------------- + ! set nextsw_cday on all ice export tasks + 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=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(scalar_id,1) = tmp(1) + call t_stopf('MED:'//trim(subname)//' nextsw_cday') + end if end if diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 75575b332..65293b449 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -27,6 +27,9 @@ module med_phases_prep_lnd_mod public :: med_phases_prep_lnd + real(r8), pointer :: dataptr_scalar_lnd(:,:) + real(r8), pointer :: dataptr_scalar_atm(:,:) + character(*) , parameter :: u_FILE_u = & __FILE__ @@ -48,7 +51,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) real(r8) :: nextsw_cday integer :: scalar_id real(r8) :: tmp(1) - real(r8), pointer :: dataptr(:,:) + real(r8), pointer :: dataptr2d(:,:) logical :: first_call = .true. character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- @@ -72,8 +75,6 @@ subroutine med_phases_prep_lnd(gcomp, rc) call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldCount=ncnt, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (ncnt > 0) then ! map to atm2lnd @@ -110,18 +111,28 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then call t_startf('MED:'//trim(subname)//' nextsw_cday') - 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, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + 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_id,1) + 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 - dataptr(scalar_id,1) = tmp(1) + ! 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 From 4589a194ce4dbac27becfa54fe251d03e918bfa5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 2 Dec 2020 20:53:03 -0700 Subject: [PATCH 177/206] fixed bug introduced in prep_ocn_mod with skipping wave mapping and added post_rof to run sequence --- cime_config/runseq/runseq_general.py | 35 ++++++++++++++-------------- mediator/med_phases_prep_ocn_mod.F90 | 16 ++++++++++++- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 0699e4dc1..87306fb5f 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -65,10 +65,6 @@ def gen_runseq(case, coupling_times): runseq.enter_time_loop(rof_cpl_time, newtime=rof_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_rof_avg" , med_to_rof and rof_outer_loop) - runseq.add_action("MED -> ROF :remapMethod=redist" , med_to_rof and rof_outer_loop) - runseq.add_action("ROF" , rof_outer_loop) - #------------------ runseq.enter_time_loop(ocn_cpl_time, newtime=ocn_outer_loop) #------------------ @@ -107,9 +103,9 @@ def gen_runseq(case, coupling_times): 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) if (cpl_seq_option == 'TIGHT'): runseq.add_action("MED med_phases_prep_ocn_map" , med_to_ocn) @@ -133,28 +129,33 @@ def gen_runseq(case, coupling_times): 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_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.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_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" , 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) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 5e7f7be54..15b82467e 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -20,7 +20,7 @@ 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, comprof, compglc, ncomps, compname + use esmFlds , only : compocn, compatm, compice, comprof, compglc, compwav, ncomps, compname use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -80,6 +80,8 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! map all fields in FBImp that have active ocean coupling other than compglc and comprof + ! compglc is mapped to compocn in med_phases_post_glc + ! comprof is mapped to compocn in med_phases_post_rof if (ncnt > 0) then if (is_local%wrap%med_coupling_active(compatm,compocn)) then call t_startf('MED:'//trim(subname)//' map_atm2ocn') @@ -105,6 +107,18 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' map_ice2ocn') end if + if (is_local%wrap%med_coupling_active(compwav,compocn)) then + call t_startf('MED:'//trim(subname)//' map_wav2ocn') + 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 + call t_stopf('MED:'//trim(subname)//' map_wav2ocn') + end if endif call t_stopf('MED:'//subname) From a7224796cd838f75b3bb76d77bd2a9acabde70d6 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Thu, 3 Dec 2020 20:42:11 -0700 Subject: [PATCH 178/206] updates for mapping glc->ocn --- mediator/esmFlds.F90 | 6 +- mediator/esmFldsExchange_cesm_mod.F90 | 11 ++++ mediator/med_phases_post_glc_mod.F90 | 39 ++++++++----- mediator/med_phases_prep_glc_mod.F90 | 2 +- mediator/med_phases_prep_ice_mod.F90 | 84 ++++++++++++--------------- mediator/med_phases_prep_lnd_mod.F90 | 2 +- 6 files changed, 79 insertions(+), 65 deletions(-) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 2daf8eb02..842a8e138 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -63,10 +63,10 @@ module esmflds 'nstod_consd',& 'nstod_consf',& 'patch_uv3d ',& - 'glc2ocn_ice',& - 'glc2ocn_liq',& 'rof2ocn_ice',& - 'rof2ocn_liq'/) + 'rof2ocn_liq',& + 'glc2ocn_ice',& + 'glc2ocn_liq') !----------------------------------------------- ! Set coupling mode diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 2f7322b10..5386e0de2 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -150,12 +150,15 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_fmapname = '// trim(atm2ice_fmap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_smapname = '// trim(atm2ice_smap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_vmapname = '// trim(atm2ice_vmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ice_rmapname', value=glc2ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ice_rmapname = '// trim(glc2ice_rmap) @@ -164,27 +167,35 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_fmapname = '// trim(atm2ocn_fmap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_smapname = '// trim(atm2ocn_smap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_vmapname = '// trim(atm2ocn_vmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_liq_rmapname', value=glc2ocn_liq_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ocn_liq_rmapname = '// trim(glc2ocn_liq_rmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_ice_rmapname', value=glc2ocn_ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ocn_ice_rmapname = '// trim(glc2ocn_ice_rmap) + call NUOPC_CompAttributeGet(gcomp, name='wav2ocn_smapname', value=wav2ocn_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'wav2ocn_smapname = '// trim(wav2ocn_smap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_fmapname', value=rof2ocn_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_fmapname = '// trim(rof2ocn_fmap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_liq_rmapname', value=rof2ocn_liq_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_liq_rmapname = '// trim(rof2ocn_liq_rmap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_ice_rmapname', value=rof2ocn_ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_ice_rmapname = '// trim(rof2ocn_ice_rmap) diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 930d6dbe1..2f0b6a475 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -160,7 +160,31 @@ subroutine med_phases_post_glc(gcomp, rc) if (ncnt > 0) then !--------------------------------------- - ! glc->lnd mapping and merging + ! glc->ocn mapping - + ! merging with rof->ocn fields is done in med_phases_prep_ocn + !--------------------------------------- + if (glc2ocn_coupling) then + 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 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) @@ -190,19 +214,6 @@ subroutine med_phases_post_glc(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - ! glc->ocn mapping, not sure about merging? - !--------------------------------------- - if (glc2ocn_coupling) then - ! Fill this in - end if - - !--------------------------------------- - ! glc->ice mapping, not sure about merging? - !--------------------------------------- - if (glc2ice_coupling) then - ! Fill this in - end if end if ! Reset first call logical diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 80c13f381..a89ff7ee5 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -105,7 +105,7 @@ module med_phases_prep_glc_mod subroutine med_phases_prep_glc_init(gcomp, rc) !--------------------------------------- - ! Create land accumulation field bundles on and and glc grid and initialize accumulation count + ! Create land accumulation field bundles on lnd and and glc mesh and initialize accumulation count !--------------------------------------- ! input/output variables diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 39a644cdf..9239e5426 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -13,8 +13,7 @@ module med_phases_prep_ice_mod use med_map_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, logunit, mastertask use esmFlds , only : compatm, compice, compocn, comprof, compglc, ncomps, compname - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : mapnames + use esmFlds , only : fldListTo use esmFlds , only : coupling_mode use esmFlds , only : med_fldList_GetFldInfo use perf_mod , only : t_startf, t_stopf @@ -24,6 +23,9 @@ module med_phases_prep_ice_mod public :: med_phases_prep_ice + real(r8), pointer :: dataptr_scalar_lnd(:,:) + real(r8), pointer :: dataptr_scalar_atm(:,:) + character(*), parameter :: u_FILE_u = & __FILE__ @@ -52,13 +54,13 @@ subroutine med_phases_prep_ice(gcomp, rc) type(ESMF_Field) :: lfield integer :: i,n,ncnt real(R8), pointer :: dataptr1d(:) => null() - real(R8), pointer :: dataptr2d(:,:) => 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)' !--------------------------------------- @@ -70,29 +72,26 @@ 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 - !--------------------------------------- - + ! 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) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - ! map atm->ice + ! map atm and ocn to ice + ! rof->ice is mapped in med_phases_post_rof + ! glc->ice is mapped in med_phases_post_glc if (is_local%wrap%med_coupling_active(compatm,compice)) then call t_startf('MED:'//trim(subname)//' map_atm2ice') + ! map atm->ice call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(compatm,compatm), & FBDst=is_local%wrap%FBImp(compatm,compice), & @@ -103,9 +102,9 @@ subroutine med_phases_prep_ice(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' map_atm2ice') end if - ! map ocn->ice if (is_local%wrap%med_coupling_active(compocn,compice)) then call t_startf('MED:'//trim(subname)//' map_ocn2ice') + ! map ocn->ice call med_map_field_packed( & FBSrc=is_local%wrap%FBImp(compocn,compocn), & FBDst=is_local%wrap%FBImp(compocn,compice), & @@ -116,13 +115,8 @@ subroutine med_phases_prep_ice(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' map_ocn2ice') end if - ! rof->ice is mapped in med_phases_post_rof - ! glc->ice is mapped in med_phases_post_glc - !--------------------------------------- - !--- auto merges to create FBExp(compice) - !--------------------------------------- - + ! auto merges to create FBExp(compice) call med_merge_auto(compice, & is_local%wrap%med_coupling_active(:,compice), & is_local%wrap%FBExp(compice), & @@ -131,10 +125,7 @@ subroutine med_phases_prep_ice(gcomp, rc) fldListTo(compice), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - + ! custom calculations if (trim(coupling_mode) == 'cesm') then ! application of precipitation factor from ocean @@ -165,46 +156,47 @@ subroutine med_phases_prep_ice(gcomp, rc) 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 - - !--------------------------------------- - ! obtain nextsw_cday from atm and send it to ice - !--------------------------------------- - - ! obtain nextsw_cday from atm and send it to lnd + ! obtain nextsw_cday from atm if it is in the import state and send it to ice call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then call t_startf('MED:'//trim(subname)//' nextsw_cday') + if (first_call) then + ! determine module pointer data for performance reasons + call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & + itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_atm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(is_local%wrap%NStateExp(compice), & + trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ice, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if ! obtain nextsw_cday from atm import on all tasks - 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=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday if (mastertask) then - tmp(1) = dataptr2d(scalar_id,1) + tmp(1) = dataptr_scalar_atm(scalar_id,1) end if call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! set nextsw_cday on all ice export tasks - 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=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(scalar_id,1) = tmp(1) + dataptr_scalar_ice(scalar_id,1) = tmp(1) call t_stopf('MED:'//trim(subname)//' nextsw_cday') 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 + 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 65293b449..907abc558 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -105,7 +105,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' merge') - ! obtain nextsw_cday from atm and send it to lnd + ! 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 From de28293fb15bc16ed75b6508595ba4b2932723c4 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 4 Dec 2020 09:27:45 -0700 Subject: [PATCH 179/206] removal of nems configuration - since nems driver is used in the future --- cime_config/buildnml | 5 -- cime_config/config_component.xml | 11 ---- cime_config/namelist_definition_drv.xml | 9 --- cime_config/runseq/runseq_NEMS.py | 82 ------------------------- drivers/cime/esm.F90 | 9 --- mediator/esmFlds.F90 | 2 +- 6 files changed, 1 insertion(+), 117 deletions(-) delete mode 100644 cime_config/runseq/runseq_NEMS.py diff --git a/cime_config/buildnml b/cime_config/buildnml index 9d18d7136..896698a33 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -76,11 +76,6 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): #---------------------------------------------------- nmlgen.init_defaults(infile, config) - if case.get_value('MEDIATOR_READ_RESTART'): - nmlgen.set_value('mediator_read_restart', value='.true.') - else: - nmlgen.set_value('mediator_read_restart', value='.false.') - #-------------------------------- # Overwrite: set brnch_retain_casename #-------------------------------- diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 85e53351e..30f9b9a70 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -483,17 +483,6 @@ - - logical - TRUE,FALSE - FALSE - run_begin_stop_restart - env_run.xml - - A setting of TRUE implies a continuation run for mediator only - - - integer 0 diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 1ea7ea455..8abc05fea 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -596,15 +596,6 @@ - - logical - expdef - DRIVER_attributes - - only have the mediator reads the restart file regardless of start type - - - char expdef 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/drivers/cime/esm.F90 b/drivers/cime/esm.F90 index 1b436f8a7..fbabb66dc 100644 --- a/drivers/cime/esm.F90 +++ b/drivers/cime/esm.F90 @@ -700,15 +700,6 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n attribute = 'read_restart' call NUOPC_CompAttributeAdd(gcomp, (/trim(attribute)/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(driver, name="mediator_read_restart", value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) lvalue - if (.not. lvalue) then - call NUOPC_CompAttributeGet(driver, name=trim(attribute), value=cvalue, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - call NUOPC_CompAttributeSet(gcomp, name=trim(attribute), value=trim(cvalue), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return !------ ! Add component specific attributes diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 842a8e138..8747cdaca 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -66,7 +66,7 @@ module esmflds 'rof2ocn_ice',& 'rof2ocn_liq',& 'glc2ocn_ice',& - 'glc2ocn_liq') + 'glc2ocn_liq'/) !----------------------------------------------- ! Set coupling mode From 7417a5ae19d4a284bdae21993869c83872e8e00b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Fri, 4 Dec 2020 17:50:56 -0700 Subject: [PATCH 180/206] fixed compile and restart problem for B compsets --- cime_config/runseq/runseq_general.py | 11 ++++++- mediator/esmFlds.F90 | 2 +- mediator/med.F90 | 46 ++++++++++++++-------------- mediator/med_phases_prep_ice_mod.F90 | 2 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 87306fb5f..044e0efbc 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -35,6 +35,15 @@ 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 # Note: assume that atm_cpl_dt, lnd_cpl_dt, ice_cpl_dt and wav_cpl_dt are the same @@ -165,6 +174,6 @@ def gen_runseq(case, coupling_times): 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) + runseq.add_action("MED med_phases_post_glc" , run_glc and post_glc) shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 842a8e138..8747cdaca 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -66,7 +66,7 @@ module esmflds 'rof2ocn_ice',& 'rof2ocn_liq',& 'glc2ocn_ice',& - 'glc2ocn_liq') + 'glc2ocn_liq'/) !----------------------------------------------- ! Set coupling mode diff --git a/mediator/med.F90 b/mediator/med.F90 index f06ce798d..75c7e02a2 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -63,6 +63,11 @@ module MED __FILE__ logical :: profile_memory = .false. + character(len=8) :: atm_present, lnd_present + character(len=8) :: ice_present, rof_present + character(len=8) :: glc_present, med_present + character(len=8) :: ocn_present, wav_present + !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -652,10 +657,6 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) character(len=8) :: cnum type(InternalState) :: is_local integer :: stat - character(len=8) :: atm_present, lnd_present - character(len=8) :: ice_present, rof_present - character(len=8) :: glc_present, med_present - character(len=8) :: ocn_present, wav_present character(len=CS) :: attrList(8) character(len=*),parameter :: subname=' (module_MED:InitializeIPDv03p1) ' !----------------------------------------------------------- @@ -2347,47 +2348,46 @@ 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) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice - ! before run phase of glc is called - !--------------------------------------- - call med_phases_post_glc(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice - ! before run phase of glc is called - !--------------------------------------- - call med_phases_post_rof(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- ! 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) read(cvalue,*) read_restart - if (read_restart) then call med_phases_restart_read(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif + !--------------------------------------- + ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice + ! before run phase of glc is called + !--------------------------------------- + if (trim(glc_present) == 'true') then + call med_phases_post_glc(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + !--------------------------------------- + ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice + ! before run phase of glc is called + !--------------------------------------- + if (trim(rof_present) == 'true') then + call med_phases_post_rof(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call med_phases_profile(gcomp, rc) else ! Not all done diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 9239e5426..9263292ed 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -23,7 +23,7 @@ module med_phases_prep_ice_mod public :: med_phases_prep_ice - real(r8), pointer :: dataptr_scalar_lnd(:,:) + real(r8), pointer :: dataptr_scalar_ice(:,:) real(r8), pointer :: dataptr_scalar_atm(:,:) character(*), parameter :: u_FILE_u = & From 7868fba9fb307fc1987c64a7fdba08cbec4062e8 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 5 Dec 2020 13:55:09 -0700 Subject: [PATCH 181/206] added post phases for ocn and atm --- cime_config/buildnml | 5 ++ cime_config/config_component.xml | 12 ++- cime_config/namelist_definition_drv.xml | 9 +++ cime_config/runseq/runseq_general.py | 4 + drivers/cime/esm.F90 | 27 +++---- mediator/med.F90 | 77 +++++++++++++----- mediator/med_phases_aofluxes_mod.F90 | 11 --- mediator/med_phases_post_atm_mod.F90 | 103 ++++++++++++++++++++++++ mediator/med_phases_post_ocn_mod.F90 | 74 +++++++++++++++++ mediator/med_phases_post_rof_mod.F90 | 27 ++++--- mediator/med_phases_prep_atm_mod.F90 | 2 +- mediator/med_phases_prep_ice_mod.F90 | 71 +++++----------- mediator/med_phases_prep_lnd_mod.F90 | 48 +++++------ mediator/med_phases_prep_ocn_mod.F90 | 41 +++------- 14 files changed, 340 insertions(+), 171 deletions(-) create mode 100644 mediator/med_phases_post_atm_mod.F90 create mode 100644 mediator/med_phases_post_ocn_mod.F90 diff --git a/cime_config/buildnml b/cime_config/buildnml index 896698a33..9d18d7136 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -76,6 +76,11 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): #---------------------------------------------------- nmlgen.init_defaults(infile, config) + if case.get_value('MEDIATOR_READ_RESTART'): + nmlgen.set_value('mediator_read_restart', value='.true.') + else: + nmlgen.set_value('mediator_read_restart', value='.false.') + #-------------------------------- # Overwrite: set brnch_retain_casename #-------------------------------- diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 30f9b9a70..dbffe661f 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -483,6 +483,17 @@ + + logical + TRUE,FALSE + FALSE + run_begin_stop_restart + env_run.xml + + A setting of TRUE implies a continuation run for mediator only + + + integer 0 @@ -1009,7 +1020,6 @@ Determines the profiling level in ESMF log files by default, it is set to 0 (only run method execution timings) - For maximum profiling set it to 65535. diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 8abc05fea..1ea7ea455 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -596,6 +596,15 @@ + + logical + expdef + DRIVER_attributes + + only have the mediator reads the restart file regardless of start type + + + char expdef diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 044e0efbc..10b9ed552 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -115,6 +115,7 @@ def gen_runseq(case, coupling_times): 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("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) @@ -136,6 +137,8 @@ def gen_runseq(case, coupling_times): 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 and (med_to_ocn or med_to_atm)) + runseq.add_action("WAV -> MED :remapMethod=redist" , run_wav) runseq.add_action("ROF -> MED :remapMethod=redist" , run_rof and not rof_outer_loop) @@ -155,6 +158,7 @@ def gen_runseq(case, coupling_times): 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("MED med_phases_post_ocn", run_ocn and ocn_outer_loop) #------------------ runseq.leave_time_loop(ocn_outer_loop) diff --git a/drivers/cime/esm.F90 b/drivers/cime/esm.F90 index fbabb66dc..821e7e8de 100644 --- a/drivers/cime/esm.F90 +++ b/drivers/cime/esm.F90 @@ -644,7 +644,7 @@ end subroutine CheckAttributes !=============================================================================== - subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, nthreads, rc) + subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, rc) ! Add specific set of attributes to components from driver attributes @@ -659,7 +659,6 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n integer , intent(in) :: compid character(len=*) , intent(in) :: compname character(len=*) , intent(in) :: inst_suffix - integer , intent(in) :: nthreads integer , intent(inout) :: rc ! local variables @@ -685,21 +684,21 @@ subroutine AddAttributes(gcomp, driver, config, compid, compname, inst_suffix, n call NUOPC_CompAttributeSet(gcomp, name='MCTID', value=trim(cvalue), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - !------ - ! Add thread count to gcomp attributes - !------ - write(cvalue,*) nthreads - call NUOPC_CompAttributeAdd(gcomp, attrList=(/'nthreads'/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeSet(gcomp, name='nthreads', value=trim(cvalue), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - !------ ! Add restart flag a to gcomp attributes !------ attribute = 'read_restart' call NUOPC_CompAttributeAdd(gcomp, (/trim(attribute)/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(driver, name="mediator_read_restart", value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) lvalue + if (.not. lvalue) then + call NUOPC_CompAttributeGet(driver, name=trim(attribute), value=cvalue, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + call NUOPC_CompAttributeSet(gcomp, name=trim(attribute), value=trim(cvalue), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return !------ ! Add component specific attributes @@ -888,7 +887,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) logical, allocatable :: comp_iamin(:) character(len=5) :: inst_suffix character(CL) :: cvalue - logical :: found_comp + logical :: found_comp character(len=*), parameter :: subname = "(esm_pelayout.F90:esm_init_pelayout)" !--------------------------------------- @@ -1063,7 +1062,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) return endif - call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, nthrds, rc=rc) + call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ESMF_GridCompIsPetLocal(child, rc=rc)) then @@ -1073,7 +1072,7 @@ subroutine esm_init_pelayout(driver, maxthreads, rc) call ESMF_VMGet(vm, mpiCommunicator=comms(i+1), localPet=comp_comm_iam(i), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, nthrds, rc=rc) + call AddAttributes(child, driver, config, i+1, trim(compLabels(i)), inst_suffix, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! This code is not supported, we need an optional arg to NUOPC_DriverAddComp to include the diff --git a/mediator/med.F90 b/mediator/med.F90 index 75c7e02a2..f3bf2633c 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -94,9 +94,11 @@ subroutine SetServices(gcomp, rc) 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_post_glc_mod , only: med_phases_post_glc 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_post_atm_mod , only: med_phases_post_atm + 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_prep_ocn_mod , only: med_phases_prep_ocn_map use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_merge @@ -229,7 +231,7 @@ subroutine SetServices(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ - ! prep routines for atm + ! prep and post routines for atm !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -239,8 +241,15 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_atm", specRoutine=med_phases_prep_atm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_post_atm"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_post_atm", specRoutine=med_phases_post_atm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ - ! prep routines for ocn + ! prep and post routines for ocn !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -280,6 +289,16 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_ocn_accum_avg", specRoutine=med_phases_prep_ocn_accum_avg, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + 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_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 !------------------ @@ -303,7 +322,7 @@ subroutine SetServices(gcomp, 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, & @@ -323,10 +342,7 @@ subroutine SetServices(gcomp, rc) specPhaselabel="med_phases_prep_rof_accum", specRoutine=NUOPC_NoOp, 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_post_rof"/), userRoutine=mediator_routine_Run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -349,7 +365,7 @@ subroutine SetServices(gcomp, 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, & @@ -369,10 +385,7 @@ subroutine SetServices(gcomp, rc) specPhaselabel="med_phases_prep_glc_accum", specRoutine=NUOPC_NoOp, 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_post_glc"/), userRoutine=mediator_routine_Run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1684,10 +1697,12 @@ 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_atm_mod , only : med_phases_prep_atm use med_phases_prep_glc_mod , only : med_phases_prep_glc_init + use med_phases_post_atm_mod , only : med_phases_post_atm 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_prep_atm_mod , only : med_phases_prep_atm 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 @@ -2299,9 +2314,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 Failed for "//& + trim(compname(n1)) + end if end if endif enddo @@ -2321,7 +2338,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, & @@ -2363,16 +2383,25 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- 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 + !--------------------------------------- + ! If appropriate, map initial atm->ocn, atm->ice, atm->lnd + !--------------------------------------- + if (trim(atm_present) == 'true') then + call med_phases_post_atm(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + !--------------------------------------- ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice - ! before run phase of glc is called !--------------------------------------- if (trim(glc_present) == 'true') then call med_phases_post_glc(gcomp, rc) @@ -2380,12 +2409,20 @@ subroutine DataInitialize(gcomp, rc) end if !--------------------------------------- - ! If appropriate, map initial glc->lnd, glc->ocn and glc->ice - ! before run phase of glc is called + ! If appropriate, map initial ocn->ice + !--------------------------------------- + if (trim(ocn_present) == 'true') then + call med_phases_post_ocn(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + !--------------------------------------- + ! If appropriate, map initial rof->lnd, rof->ocn, rof->ice !--------------------------------------- if (trim(rof_present) == 'true') then call med_phases_post_rof(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(6,*)'DEBUG: here1' end if call med_phases_profile(gcomp, rc) diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 8ab54e4fd..e45cd70bc 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -152,17 +152,6 @@ subroutine med_phases_aofluxes_run(gcomp, rc) call memcheck(subname, 5, mastertask) - ! TODO(mvertens, 2019-01-12): ONLY regrid atm import fields that are needed for the atm/ocn flux calculation - ! Regrid atm import field bundle from atm to ocn grid as input for ocn/atm flux calculation - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,compocn), & - FBFracSrc=is_local%wrap%FBFrac(compatm), & - field_normOne=is_local%wrap%field_normOne(compatm,compocn,:), & - packed_data=is_local%wrap%packed_data(compatm,compocn,:), & - routehandles=is_local%wrap%RH(compatm,compocn,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Calculate atm/ocn fluxes on the destination grid call med_aofluxes_run(gcomp, aoflux, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_phases_post_atm_mod.F90 b/mediator/med_phases_post_atm_mod.F90 new file mode 100644 index 000000000..b4de09239 --- /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 + + 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_atm + +end module med_phases_post_atm_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..47e7c2459 --- /dev/null +++ b/mediator/med_phases_post_ocn_mod.F90 @@ -0,0 +1,74 @@ +module med_phases_post_ocn_mod + + !----------------------------------------------------------------------------- + ! Mediator post ocn phase - maps ocn->ice + !----------------------------------------------------------------------------- + + 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_post_ocn + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_ocn(gcomp, rc) + + use ESMF , only : ESMF_GridComp + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, logunit, mastertask + use esmFlds , only : compice, compocn + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*),parameter :: subname='(med_phases_prep_ice)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map ocn->ice + if (is_local%wrap%med_coupling_active(compocn,compice)) then + call t_startf('MED:'//trim(subname)//' map_ocn2ice') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compice), & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compice,:), & + packed_data=is_local%wrap%packed_data(compocn,compice,:), & + routehandles=is_local%wrap%RH(compocn,compice,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_ocn2ice') + end if + + 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_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 index b75942fa8..6aa4619f6 100644 --- a/mediator/med_phases_post_rof_mod.F90 +++ b/mediator/med_phases_post_rof_mod.F90 @@ -1,16 +1,6 @@ module med_phases_post_rof_mod - ! Map to import data from rof to land, sea-ice and ocean - - 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 + ! Post rof phase, if appropriate, map initial rof->lnd, rof->ocn, rof->ice implicit none private @@ -26,6 +16,16 @@ module med_phases_post_rof_mod 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 @@ -46,6 +46,7 @@ subroutine med_phases_post_rof(gcomp, rc) 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( & @@ -58,7 +59,7 @@ subroutine med_phases_post_rof(gcomp, 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( & @@ -71,7 +72,7 @@ subroutine med_phases_post_rof(gcomp, 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( & diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index bacb7af31..448d0c118 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__ diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 9263292ed..be693a0d8 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -4,19 +4,7 @@ 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_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, compocn, comprof, compglc, ncomps, compname - use esmFlds , only : fldListTo - 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 @@ -35,14 +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 ESMF , only : ESMF_VMBroadCast - 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 @@ -85,36 +82,10 @@ subroutine med_phases_prep_ice(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (ncnt > 0) then - - ! map atm and ocn to ice - ! rof->ice is mapped in med_phases_post_rof + ! atm->ice is mapped in med_phases_post_atm ! glc->ice is mapped in med_phases_post_glc - if (is_local%wrap%med_coupling_active(compatm,compice)) then - call t_startf('MED:'//trim(subname)//' map_atm2ice') - ! map atm->ice - 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 - if (is_local%wrap%med_coupling_active(compocn,compice)) then - call t_startf('MED:'//trim(subname)//' map_ocn2ice') - ! map ocn->ice - 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 + ! 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, & diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 907abc558..5ea85a5c3 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -4,23 +4,7 @@ module med_phases_prep_lnd_mod ! Mediator phases for preparing land export from mediator !----------------------------------------------------------------------------- - use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use NUOPC , only : NUOPC_CompAttributeGet - use ESMF , only : operator(/=) - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, 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, comprof, ncomps, compname - 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_map_mod , only : med_map_field_packed, med_map_field_normalized, med_map_field - use med_merge_mod , only : med_merge_auto - 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 @@ -39,6 +23,22 @@ 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 @@ -77,21 +77,9 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then - ! map to atm2lnd + ! atm2lnd is done in med_phases_post_atm ! rof2lnd is done in med_phases_post_rof ! glc2lnd is done in med_phases_post_glc - 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 ! auto merges to create FBExp(complnd) - other than glc->lnd ! The following will merge all fields in fldsSrc diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 15b82467e..1568eab74 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -80,21 +80,10 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! map all fields in FBImp that have active ocean coupling other than compglc and comprof + ! compatm is mapped to compocn in med_phases_post_atm ! compglc is mapped to compocn in med_phases_post_glc ! comprof is mapped to compocn in med_phases_post_rof if (ncnt > 0) then - 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 if (is_local%wrap%med_coupling_active(compice,compocn)) then call t_startf('MED:'//trim(subname)//' map_ice2ocn') call med_map_field_packed( & @@ -219,7 +208,6 @@ 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 @@ -227,8 +215,6 @@ subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) 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)' @@ -246,24 +232,17 @@ subroutine med_phases_prep_ocn_accum_fast(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 - ! 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 + ! 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 - 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 + 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 if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if From 386e300cbd1a94962d5456a12e2d4ef859df81c3 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 5 Dec 2020 19:37:26 -0700 Subject: [PATCH 182/206] added med_phases_post_lnd --- mediator/med.F90 | 51 ++++-- mediator/med_phases_post_lnd.F90 | 68 +++++++ mediator/med_phases_prep_atm_mod.F90 | 254 +++++++++++++-------------- 3 files changed, 224 insertions(+), 149 deletions(-) create mode 100644 mediator/med_phases_post_lnd.F90 diff --git a/mediator/med.F90 b/mediator/med.F90 index f3bf2633c..b3ff94928 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -97,6 +97,7 @@ subroutine SetServices(gcomp, rc) 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_post_atm_mod , only: med_phases_post_atm + 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 @@ -321,6 +322,16 @@ 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 and post routines for rof !------------------ @@ -1700,6 +1711,7 @@ subroutine DataInitialize(gcomp, rc) use med_phases_prep_atm_mod , only : med_phases_prep_atm use med_phases_prep_glc_mod , only : med_phases_prep_glc_init use med_phases_post_atm_mod , only : med_phases_post_atm + 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 @@ -2271,6 +2283,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(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 @@ -2393,37 +2410,43 @@ subroutine DataInitialize(gcomp, rc) endif !--------------------------------------- - ! If appropriate, map initial atm->ocn, atm->ice, atm->lnd + ! 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 appropriate, map initial glc->lnd, glc->ocn and glc->ice - !--------------------------------------- + ! 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 appropriate, map initial ocn->ice - !--------------------------------------- + if (trim(lnd_present) == 'true') then + ! map initial lnd->atm + call med_phases_post_lnd(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 appropriate, map initial rof->lnd, rof->ocn, rof->ice - !--------------------------------------- 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 - write(6,*)'DEBUG: here1' 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) diff --git a/mediator/med_phases_post_lnd.F90 b/mediator/med_phases_post_lnd.F90 new file mode 100644 index 000000000..981ac516a --- /dev/null +++ b/mediator/med_phases_post_lnd.F90 @@ -0,0 +1,68 @@ +module med_phases_post_lnd_mod + + implicit none + private + + public :: med_phases_post_lnd + + 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 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 + +end module med_phases_post_lnd_mod diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index 448d0c118..ce69921f3 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -64,146 +64,130 @@ subroutine med_phases_prep_atm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - !--- Count the number of fields outside of scalar data, if zero, then return + ! --- map ocn and ice to atm !--------------------------------------- + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compatm), & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_NormOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data(compocn,compatm,:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compatm), & + FBFracSrc=is_local%wrap%FBFrac(compice), & + field_NormOne=is_local%wrap%field_normOne(compice,compatm,:), & + packed_data=is_local%wrap%packed_data(compice,compatm,:), & + routehandles=is_local%wrap%RH(compice,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - ! Note - the scalar field has been removed from all mediator field bundles - so this is why we check if the - ! fieldCount is 0 and not 1 here + !--------------------------------------- + !--- map ocean albedos from ocn to atm grid if appropriate + !--------------------------------------- + if (trim(coupling_mode) == 'cesm') then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBMed_ocnalb_o, & + FBDst=is_local%wrap%FBMed_ocnalb_a, & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data_ocnalb_o2a(:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldCount=ncnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (ncnt == 0) then - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(compatm), returning", & - ESMF_LOGMSG_INFO) - else - - !--------------------------------------- - !--- map import field bundles from n1 grid to atm grid - FBimp(:,compatm) - !--------------------------------------- - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,compatm)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,compatm), & - FBFracSrc=is_local%wrap%FBFrac(n1), & - field_NormOne=is_local%wrap%field_normOne(n1,compatm,:), & - packed_data=is_local%wrap%packed_data(n1,compatm,:), & - routehandles=is_local%wrap%RH(n1,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do + !--------------------------------------- + !--- map atm/ocn fluxes from ocn to atm grid if appropriate + !--------------------------------------- + if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then + ! Assumption here is that fluxes are computed on the ocean grid + call med_map_field_packed( & + FBSrc=is_local%wrap%FBMed_aoflux_o, & + FBDst=is_local%wrap%FBMed_aoflux_a, & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data_aoflux_o2a(:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif - !--------------------------------------- - !--- map ocean albedos from ocn to atm grid if appropriate - !--------------------------------------- - if (trim(coupling_mode) == 'cesm') then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBMed_ocnalb_o, & - FBDst=is_local%wrap%FBMed_ocnalb_a, & - FBFracSrc=is_local%wrap%FBFrac(compocn), & - field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & - packed_data=is_local%wrap%packed_data_ocnalb_o2a(:), & - routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - !--- map atm/ocn fluxes from ocn to atm grid if appropriate - !--------------------------------------- - if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - ! Assumption here is that fluxes are computed on the ocean grid - call med_map_field_packed( & - FBSrc=is_local%wrap%FBMed_aoflux_o, & - FBDst=is_local%wrap%FBMed_aoflux_a, & - FBFracSrc=is_local%wrap%FBFrac(compocn), & - field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & - packed_data=is_local%wrap%packed_data_aoflux_o2a(:), & - routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - - !--------------------------------------- - !--- merge all fields to atm - !--------------------------------------- - if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - call med_merge_auto(compatm, & - is_local%wrap%med_coupling_active(:,compatm), & - is_local%wrap%FBExp(compatm), & - is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), & - fldListTo(compatm), & - FBMed1=is_local%wrap%FBMed_ocnalb_a, & - FBMed2=is_local%wrap%FBMed_aoflux_a, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then - call med_merge_auto(compatm, & - is_local%wrap%med_coupling_active(:,compatm), & - is_local%wrap%FBExp(compatm), & - is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), & - fldListTo(compatm), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compatm),string=trim(subname)//' FBexp(compatm) ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - - ! set fractions to send back to atm - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'So_ofrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='So_ofrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ofrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Si_ifrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Si_ifrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ifrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Sl_lfrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Sl_lfrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='lfrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - - !--------------------------------------- - !--- update local scalar data - !--------------------------------------- - - !--------------------------------------- - !--- clean up - !--------------------------------------- + !--------------------------------------- + !--- merge all fields to atm + !--------------------------------------- + if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then + call med_merge_auto(compatm, & + is_local%wrap%med_coupling_active(:,compatm), & + is_local%wrap%FBExp(compatm), & + is_local%wrap%FBFrac(compatm), & + is_local%wrap%FBImp(:,compatm), & + fldListTo(compatm), & + FBMed1=is_local%wrap%FBMed_ocnalb_a, & + FBMed2=is_local%wrap%FBMed_aoflux_a, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then + call med_merge_auto(compatm, & + is_local%wrap%med_coupling_active(:,compatm), & + is_local%wrap%FBExp(compatm), & + is_local%wrap%FBFrac(compatm), & + is_local%wrap%FBImp(:,compatm), & + fldListTo(compatm), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - endif + if (dbug_flag > 1) then + call FB_diagnose(is_local%wrap%FBExp(compatm),string=trim(subname)//' FBexp(compatm) ', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + !--------------------------------------- + !--- custom calculations + !--------------------------------------- + + ! set fractions to send back to atm + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'So_ofrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='So_ofrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ofrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Si_ifrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Si_ifrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ifrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Sl_lfrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Sl_lfrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='lfrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) From 9ea5b9467ae94254ff60115b1ba05b8e2ef8ab46 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 5 Dec 2020 19:54:35 -0700 Subject: [PATCH 183/206] added post wave phase --- mediator/med.F90 | 24 ++++++--- mediator/med_phases_post_atm_mod.F90 | 2 +- mediator/med_phases_post_glc_mod.F90 | 4 +- mediator/med_phases_post_ocn_mod.F90 | 5 +- mediator/med_phases_post_rof_mod.F90 | 4 +- mediator/med_phases_post_wav_mod.F90 | 79 ++++++++++++++++++++++++++++ mediator/med_phases_prep_ocn_mod.F90 | 40 +++++--------- 7 files changed, 117 insertions(+), 41 deletions(-) create mode 100644 mediator/med_phases_post_wav_mod.F90 diff --git a/mediator/med.F90 b/mediator/med.F90 index b3ff94928..5ac9dbb0b 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -101,6 +101,7 @@ subroutine SetServices(gcomp, rc) 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_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 @@ -365,7 +366,7 @@ subroutine SetServices(gcomp, 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, & @@ -375,6 +376,16 @@ 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 and post routines for glc !------------------ @@ -1715,6 +1726,7 @@ subroutine DataInitialize(gcomp, rc) 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 @@ -2442,11 +2454,11 @@ subroutine DataInitialize(gcomp, rc) 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 + 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) diff --git a/mediator/med_phases_post_atm_mod.F90 b/mediator/med_phases_post_atm_mod.F90 index b4de09239..bd6b93230 100644 --- a/mediator/med_phases_post_atm_mod.F90 +++ b/mediator/med_phases_post_atm_mod.F90 @@ -93,10 +93,10 @@ subroutine med_phases_post_atm(gcomp, rc) call t_stopf('MED:'//trim(subname)//' map_atm2lnd') end if - call t_stopf('MED:'//subname) 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 diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 2f0b6a475..439b92810 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -103,7 +103,7 @@ subroutine med_phases_post_glc(gcomp, rc) rc = ESMF_SUCCESS call t_startf('MED:'//subname) - if (dbug_flag > 5) then + if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if @@ -219,7 +219,7 @@ subroutine med_phases_post_glc(gcomp, rc) ! Reset first call logical first_call = .false. - if (dbug_flag > 5) then + if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) diff --git a/mediator/med_phases_post_ocn_mod.F90 b/mediator/med_phases_post_ocn_mod.F90 index 47e7c2459..8b8de5865 100644 --- a/mediator/med_phases_post_ocn_mod.F90 +++ b/mediator/med_phases_post_ocn_mod.F90 @@ -4,8 +4,6 @@ module med_phases_post_ocn_mod ! Mediator post ocn phase - maps ocn->ice !----------------------------------------------------------------------------- - use med_kind_mod, only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - implicit none private @@ -20,6 +18,7 @@ module med_phases_post_ocn_mod 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 @@ -64,10 +63,10 @@ subroutine med_phases_post_ocn(gcomp, rc) call t_stopf('MED:'//trim(subname)//' map_ocn2ice') end if - call t_stopf('MED:'//subname) 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 diff --git a/mediator/med_phases_post_rof_mod.F90 b/mediator/med_phases_post_rof_mod.F90 index 6aa4619f6..93e73ac3e 100644 --- a/mediator/med_phases_post_rof_mod.F90 +++ b/mediator/med_phases_post_rof_mod.F90 @@ -38,7 +38,7 @@ subroutine med_phases_post_rof(gcomp, rc) rc = ESMF_SUCCESS call t_startf('MED:'//subname) - if (dbug_flag > 5) then + if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if @@ -86,7 +86,7 @@ subroutine med_phases_post_rof(gcomp, rc) call t_stopf('MED:'//trim(subname)//' map_rof2ice') end if - if (dbug_flag > 5) then + if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) 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_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 1568eab74..7e8fc365a 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -20,7 +20,7 @@ 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, comprof, compglc, compwav, ncomps, compname + use esmFlds , only : compocn, compatm, compice, comprof, compglc, ncomps, compname use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf @@ -83,32 +83,18 @@ subroutine med_phases_prep_ocn_map(gcomp, rc) ! compatm is mapped to compocn in med_phases_post_atm ! compglc is mapped to compocn in med_phases_post_glc ! comprof is mapped to compocn in med_phases_post_rof - if (ncnt > 0) then - 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 - if (is_local%wrap%med_coupling_active(compwav,compocn)) then - call t_startf('MED:'//trim(subname)//' map_wav2ocn') - 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 - call t_stopf('MED:'//trim(subname)//' map_wav2ocn') - end if - endif + 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 call t_stopf('MED:'//subname) if (dbug_flag > 20) then From c310ff33f8253ccadc6f64543508406df4421c6c Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Dec 2020 11:10:12 -0700 Subject: [PATCH 184/206] added post ice phase and fixed call to post atm phase --- cime_config/runseq/runseq_general.py | 38 +++++----- mediator/med_phases_post_ice_mod.F90 | 104 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 mediator/med_phases_post_ice_mod.F90 diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 10b9ed552..133d65f59 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -86,7 +86,6 @@ def gen_runseq(case, coupling_times): #------------------ 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) @@ -118,7 +117,6 @@ def gen_runseq(case, coupling_times): 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) @@ -126,21 +124,27 @@ def gen_runseq(case, coupling_times): runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm) and not xcompset) runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) - runseq.add_action("LND -> MED :remapMethod=redist" , run_lnd) - runseq.add_action("ICE -> MED :remapMethod=redist" , run_ice) - runseq.add_action("MED med_phases_diag_ice_ice2med" , run_ice and diag_mode) - runseq.add_action("MED med_fraction_set" , run_ice) - - runseq.add_action("MED med_phases_prep_rof_accum" , med_to_rof) - runseq.add_action("MED med_phases_prep_glc_accum" , med_to_glc) - runseq.add_action("MED med_phases_prep_atm" , med_to_atm) - runseq.add_action("MED -> ATM :remapMethod=redist" , med_to_atm) - runseq.add_action("ATM" , run_atm) - runseq.add_action("ATM -> MED :remapMethod=redist" , run_atm) - runseq.add_action("MED med_phases_post_atm" , run_atm and (med_to_ocn or med_to_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("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_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("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) 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 From f2edb0f1ecc95557a2f1668156894bcf16e78111 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Dec 2020 11:59:26 -0700 Subject: [PATCH 185/206] more cleanup of post run phases --- cime_config/runseq/runseq_D.py | 35 ++++--- cime_config/runseq/runseq_general.py | 44 ++++---- mediator/med.F90 | 93 +++++++---------- mediator/med_phases_post_lnd.F90 | 86 ++++++++++++++- mediator/med_phases_prep_glc_mod.F90 | 22 ++-- mediator/med_phases_prep_ice_mod.F90 | 150 ++++++++++++--------------- mediator/med_phases_prep_ocn_mod.F90 | 69 +----------- mediator/med_phases_prep_rof_mod.F90 | 10 +- 8 files changed, 252 insertions(+), 257 deletions(-) diff --git a/cime_config/runseq/runseq_D.py b/cime_config/runseq/runseq_D.py index 5b7bcdf39..aa5d9c83a 100644 --- a/cime_config/runseq/runseq_D.py +++ b/cime_config/runseq/runseq_D.py @@ -36,27 +36,34 @@ def gen_runseq(case, coupling_times): 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_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_general.py b/cime_config/runseq/runseq_general.py index 133d65f59..45b7d0353 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -93,22 +93,27 @@ def gen_runseq(case, coupling_times): runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset) runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) - runseq.add_action("MED med_phases_prep_lnd" , med_to_lnd) - runseq.add_action("MED -> LND :remapMethod=redist" , med_to_lnd) - runseq.add_action("MED med_phases_prep_ice" , med_to_ice) - runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice) - runseq.add_action("MED med_phases_diag_ice_med2ice" , run_ice and diag_mode) - runseq.add_action("MED med_phases_prep_wav" , med_to_wav) - runseq.add_action("MED -> WAV :remapMethod=redist" , med_to_wav) - runseq.add_action("MED med_phases_prep_rof_avg" , med_to_rof and not rof_outer_loop) - runseq.add_action("MED -> ROF :remapMethod=redist" , med_to_rof and not rof_outer_loop) - runseq.add_action("MED med_phases_prep_ocn_accum_avg" , med_to_ocn and not ocn_outer_loop) - runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn and not ocn_outer_loop) - runseq.add_action("ICE" , run_ice) - runseq.add_action("LND" , run_lnd) - runseq.add_action("ROF" , run_rof and not rof_outer_loop) - runseq.add_action("WAV" , run_wav) - runseq.add_action("OCN" , run_ocn and not ocn_outer_loop) + runseq.add_action("MED med_phases_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_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) if coupling_mode == 'hafs': runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true", run_ocn and not ocn_outer_loop) @@ -131,10 +136,7 @@ def gen_runseq(case, coupling_times): 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_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) @@ -168,7 +170,7 @@ def gen_runseq(case, coupling_times): runseq.leave_time_loop(ocn_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_rof_avg" , med_to_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) @@ -178,7 +180,7 @@ def gen_runseq(case, coupling_times): runseq.leave_time_loop(rof_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_glc_avg" , med_to_glc) + runseq.add_action("MED med_phases_prep_glc" , med_to_glc) runseq.add_action("MED -> GLC :remapMethod=redist" , med_to_glc) runseq.add_action("GLC" , run_glc and med_to_glc) runseq.add_action("GLC -> MED :remapMethod=redist" , run_glc) diff --git a/mediator/med.F90 b/mediator/med.F90 index 5ac9dbb0b..628d8cec3 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -63,10 +63,10 @@ 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 + 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 @@ -92,20 +92,18 @@ 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_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_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_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_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_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 @@ -254,16 +252,6 @@ subroutine SetServices(gcomp, rc) ! prep and post routines for ocn !------------------ - call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_map"/), userRoutine=mediator_routine_Run, rc=rc) - 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_ocn_map", specRoutine=NUOPC_NoOp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_prep_ocn_merge"/), userRoutine=mediator_routine_Run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -300,9 +288,9 @@ subroutine SetServices(gcomp, rc) 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, & @@ -312,6 +300,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 !------------------ @@ -338,20 +337,10 @@ subroutine SetServices(gcomp, rc) !------------------ 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_rof_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_rof_accum", specRoutine=med_phases_prep_rof_accum, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_rof_accum", specRoutine=NUOPC_NoOp, rc=rc) + specPhaseLabel="med_phases_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) @@ -391,20 +380,10 @@ subroutine SetServices(gcomp, rc) !------------------ 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_glc_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_glc_accum", specRoutine=med_phases_prep_glc_accum, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_glc_accum", specRoutine=NUOPC_NoOp, rc=rc) + specPhaseLabel="med_phases_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) @@ -1720,9 +1699,9 @@ subroutine DataInitialize(gcomp, rc) 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_atm_mod , only : med_phases_prep_atm - use med_phases_prep_glc_mod , only : med_phases_prep_glc_init use med_phases_post_atm_mod , only : med_phases_post_atm - use med_phases_post_lnd_mod , only : med_phases_post_lnd + 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 @@ -2297,7 +2276,7 @@ subroutine DataInitialize(gcomp, rc) if (.not. compDone(compatm)) then ! atmdone is not true if (trim(lnd_present) == 'true') then ! map initial lnd->atm - call med_phases_post_lnd(gcomp, rc) + 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 @@ -2429,11 +2408,11 @@ subroutine DataInitialize(gcomp, rc) 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(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) @@ -2441,7 +2420,7 @@ subroutine DataInitialize(gcomp, rc) end if if (trim(lnd_present) == 'true') then ! map initial lnd->atm - call med_phases_post_lnd(gcomp, rc) + call med_phases_post_lnd_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if if (trim(ocn_present) == 'true') then diff --git a/mediator/med_phases_post_lnd.F90 b/mediator/med_phases_post_lnd.F90 index 981ac516a..edab8c27b 100644 --- a/mediator/med_phases_post_lnd.F90 +++ b/mediator/med_phases_post_lnd.F90 @@ -3,8 +3,11 @@ 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__ @@ -14,6 +17,87 @@ module med_phases_post_lnd_mod subroutine med_phases_post_lnd(gcomp, rc) + use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, mastertask + use med_phases_prep_rof_mod , only : med_phases_prep_rof_accum + use med_phases_prep_glc_mod , only : med_phases_prep_glc_accum + use esmFlds , only : complnd, compatm, comprof, compglc, num_icesheets + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + integer :: ns + logical :: first_call = .true. + character(len=*),parameter :: subname='(med_phases_post_lnd)' + !------------------------------------------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map lnd to atm + if (is_local%wrap%med_coupling_active(complnd,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compatm), & + FBFracSrc=is_local%wrap%FBFrac(complnd), & + field_NormOne=is_local%wrap%field_normOne(complnd,compatm,:), & + packed_data=is_local%wrap%packed_data(complnd,compatm,:), & + routehandles=is_local%wrap%RH(complnd,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! accumulate lnd input for rof + if (is_local%wrap%med_coupling_active(complnd,comprof)) then + call med_phases_prep_rof_accum(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! first determine if there will be any lnd to glc coupling + if (first_call) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + lnd2glc_coupling = .true. + exit + end if + end do + first_call = .false. + end if + + ! accumulate lnd input for glc + if (lnd2glc_coupling) then + call med_phases_prep_glc_accum(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_lnd + + !=============================================================================== + subroutine med_phases_post_lnd_init(gcomp, rc) + use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS use ESMF , only : ESMF_GridComp @@ -63,6 +147,6 @@ subroutine med_phases_post_lnd(gcomp, rc) end if call t_stopf('MED:'//subname) - end subroutine med_phases_post_lnd + end subroutine med_phases_post_lnd_init end module med_phases_post_lnd_mod diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index a89ff7ee5..d53424cc0 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -45,11 +45,11 @@ module med_phases_prep_glc_mod implicit none private - public :: med_phases_prep_glc_init - public :: med_phases_prep_glc_accum - public :: med_phases_prep_glc_avg + public :: med_phases_prep_glc_accum ! called from med_phases_post_lnd + public :: med_phases_prep_glc - private :: map_lnd2glc + private :: med_phases_prep_glc_init + private :: med_phases_prep_glc_map_lnd2glc private :: med_phases_prep_glc_renormalize_smb ! glc fields with multiple elevation classes: lnd->glc @@ -490,7 +490,7 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) end subroutine med_phases_prep_glc_accum !================================================================================================ - subroutine med_phases_prep_glc_avg(gcomp, rc) + subroutine med_phases_prep_glc(gcomp, rc) !--------------------------------------- ! Prepare the GLC export Fields from the mediator @@ -595,7 +595,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! Map accumulated field bundle from land grid (with elevation classes) to glc grid (without elevation classes) ! and set FBExp(compglc(ns)) data - call map_lnd2glc(gcomp, rc) + call med_phases_prep_glc_map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! zero accumulator and accumulated field bundles on land grid @@ -621,11 +621,10 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) endif call t_stopf('MED:'//subname) - end subroutine med_phases_prep_glc_avg + end subroutine med_phases_prep_glc !================================================================================================ - - subroutine map_lnd2glc(gcomp, rc) + subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) !--------------------------------------- ! map accumulated land fields from the land to the glc mesh @@ -657,7 +656,7 @@ subroutine map_lnd2glc(gcomp, rc) character(len=3) :: cnum type(ESMF_Field), pointer :: fieldlist_lnd(:) => null() type(ESMF_Field), pointer :: fieldlist_glc(:) => null() - character(len=*) , parameter :: subname=' (map_lnd2glc) ' + character(len=*) , parameter :: subname=' (med_phases_prep_glc_map_lnd2glc) ' !--------------------------------------- !--------------------------------------- @@ -861,10 +860,9 @@ subroutine map_lnd2glc(gcomp, rc) end do ! end of loop over ice sheets - end subroutine map_lnd2glc + end subroutine med_phases_prep_glc_map_lnd2glc !================================================================================================ - subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !------------------ diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index be693a0d8..58bf907c5 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -49,7 +49,7 @@ subroutine med_phases_prep_ice(gcomp, rc) type(ESMF_StateItem_Flag) :: itemType type(InternalState) :: is_local type(ESMF_Field) :: lfield - integer :: i,n,ncnt + integer :: i,n real(R8), pointer :: dataptr1d(:) => null() real(R8) :: precip_fact character(len=CS) :: cvalue @@ -70,99 +70,87 @@ subroutine med_phases_prep_ice(gcomp, rc) 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 - ! 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 - ! 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 - - ! 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. - 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=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = dataptr1d(:) * precip_fact - end if - end do - deallocate(fldnames) + ! 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 + 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 + end do + deallocate(fldnames) end if + end if - ! obtain nextsw_cday from atm if it is in the import state and send it to ice - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & - trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (itemType /= ESMF_STATEITEM_NOTFOUND) then - call t_startf('MED:'//trim(subname)//' nextsw_cday') - if (first_call) then - ! determine module pointer data for performance reasons - call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & - itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_atm, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_StateGet(is_local%wrap%NStateExp(compice), & - trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ice, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - ! 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) + ! obtain nextsw_cday from atm if it is in the import state and send it to ice + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & + trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (itemType /= ESMF_STATEITEM_NOTFOUND) then + call t_startf('MED:'//trim(subname)//' nextsw_cday') + if (first_call) then + ! determine module pointer data for performance reasons + call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & + itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! set nextsw_cday on all ice export tasks - dataptr_scalar_ice(scalar_id,1) = tmp(1) - call t_stopf('MED:'//trim(subname)//' nextsw_cday') - end if - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compice), string=trim(subname)//' FBexp(compice) ', rc=rc) + call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_atm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(is_local%wrap%NStateExp(compice), & + trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ice, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if + ! obtain nextsw_cday from atm import on all tasks + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr_scalar_atm(scalar_id,1) + end if + call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! set nextsw_cday on all ice export tasks + dataptr_scalar_ice(scalar_id,1) = tmp(1) + call t_stopf('MED:'//trim(subname)//' nextsw_cday') + end if + 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 diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 7e8fc365a..fbed72330 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,14 +20,13 @@ 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, comprof, compglc, ncomps, compname + 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 @@ -42,68 +41,6 @@ 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 other than compglc and comprof - ! compatm is mapped to compocn in med_phases_post_atm - ! compglc is mapped to compocn in med_phases_post_glc - ! comprof is mapped to compocn in med_phases_post_rof - 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 - - 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) use ESMF , only : ESMF_GridComp, ESMF_FieldBundleGet diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 8d24a0284..9592b7a22 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -30,8 +30,8 @@ module med_phases_prep_rof_mod implicit none private - public :: med_phases_prep_rof_accum - public :: med_phases_prep_rof_avg + public :: med_phases_prep_rof ! called by run sequence + public :: med_phases_prep_rof_accum ! called by med_phases_post_lnd private :: med_phases_prep_rof_irrig @@ -157,7 +157,7 @@ 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 @@ -190,7 +190,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) type(ESMF_Field), pointer :: fieldlist(:) => null() integer :: ungriddedUBound(1) character(CL), pointer :: lfieldnamelist(:) => null() - character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_avg)' + character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof)' !--------------------------------------- call t_startf('MED:'//subname) @@ -348,7 +348,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) 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) From 435bb527ac9eba5395c0e23167c201d7b0b39124 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 6 Dec 2020 12:23:24 -0700 Subject: [PATCH 186/206] unified merge and accum ocn phase and renamed ocn phases to be consistent with other phases and fixed bugs in run sequence for D and TG compsets --- cime_config/runseq/runseq_D.py | 11 ++--- cime_config/runseq/runseq_TG.py | 5 +- cime_config/runseq/runseq_general.py | 26 +++++------ mediator/med.F90 | 25 +++------- mediator/med_phases_post_lnd.F90 | 2 +- mediator/med_phases_prep_ocn_mod.F90 | 68 +++++----------------------- 6 files changed, 39 insertions(+), 98 deletions(-) diff --git a/cime_config/runseq/runseq_D.py b/cime_config/runseq/runseq_D.py index aa5d9c83a..3048b1bef 100644 --- a/cime_config/runseq/runseq_D.py +++ b/cime_config/runseq/runseq_D.py @@ -31,15 +31,14 @@ 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" , 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_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_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) 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 45b7d0353..7191be373 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -78,8 +78,8 @@ def gen_runseq(case, coupling_times): 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" , 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) @@ -87,11 +87,10 @@ def gen_runseq(case, coupling_times): if (cpl_seq_option == 'RASM'): if cpl_add_aoflux: - runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) - runseq.add_action("MED med_phases_prep_ocn_merge" , med_to_ocn) - runseq.add_action("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) - runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset) - runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) + runseq.add_action("MED med_phases_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) @@ -106,8 +105,8 @@ def gen_runseq(case, coupling_times): 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_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("MED med_phases_prep_ocn" , 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) @@ -123,11 +122,10 @@ def gen_runseq(case, coupling_times): if (cpl_seq_option == 'TIGHT'): if cpl_add_aoflux: - runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm) - runseq.add_action("MED med_phases_prep_ocn_merge" , med_to_ocn) - runseq.add_action("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) - runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm) and not xcompset) - runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) + runseq.add_action("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) diff --git a/mediator/med.F90 b/mediator/med.F90 index 628d8cec3..d7c7864f9 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -94,9 +94,8 @@ subroutine SetServices(gcomp, rc) use med_phases_prep_wav_mod , only: med_phases_prep_wav 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_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_ocn_mod , only: med_phases_prep_ocn_accum + use med_phases_prep_ocn_mod , only: med_phases_prep_ocn 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 @@ -253,30 +252,20 @@ subroutine SetServices(gcomp, rc) !------------------ 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_merge", specRoutine=NUOPC_NoOp, rc=rc) + specPhaselabel="med_phases_prep_ocn_accum", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_accum_fast"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_ocn"/), userRoutine=mediator_routine_Run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & - specPhaseLabel="med_phases_prep_ocn_accum_fast", specRoutine=med_phases_prep_ocn_accum_fast, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_ocn_accum_fast", specRoutine=NUOPC_NoOp, rc=rc) - 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) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & - specPhaseLabel="med_phases_prep_ocn_accum_avg", specRoutine=med_phases_prep_ocn_accum_avg, rc=rc) + specPhaseLabel="med_phases_prep_ocn", specRoutine=med_phases_prep_ocn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & diff --git a/mediator/med_phases_post_lnd.F90 b/mediator/med_phases_post_lnd.F90 index edab8c27b..1f168dfa2 100644 --- a/mediator/med_phases_post_lnd.F90 +++ b/mediator/med_phases_post_lnd.F90 @@ -74,7 +74,7 @@ subroutine med_phases_post_lnd(gcomp, rc) ! 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(compglc(ns),complnd)) then + if (is_local%wrap%med_coupling_active(complnd,compglc(ns))) then lnd2glc_coupling = .true. exit end if diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index fbed72330..07b70f739 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -27,9 +27,8 @@ module med_phases_prep_ocn_mod implicit none private - 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 ! merge and accumulate export fields to ocn + public :: med_phases_prep_ocn ! average accumulated fields private :: med_phases_prep_ocn_custom_cesm private :: med_phases_prep_ocn_custom_nems @@ -41,7 +40,7 @@ module med_phases_prep_ocn_mod contains !----------------------------------------------------------------------------- - 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 @@ -110,6 +109,11 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + ! accumulat ocean export fields + 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 + ! diagnose output if (dbug_flag > 1) then call FB_diagnose(is_local%wrap%FBExp(compocn), string=trim(subname)//' FBexp(compocn) ', rc=rc) @@ -123,58 +127,10 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - ! local variables - 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 - - ! Get the internal state - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! 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 - - 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 - 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(gcomp, rc) ! Prepare the OCN import Fields. @@ -188,7 +144,7 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: ncnt - character(len=*),parameter :: subname='(med_phases_prep_ocn_accum_avg)' + character(len=*),parameter :: subname='(med_phases_prep_ocn)' !--------------------------------------- rc = ESMF_SUCCESS @@ -241,7 +197,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 !----------------------------------------------------------------------------- subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) From c570780840fdc11db049a0d47b5b5194f63cf601 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 10:20:50 -0700 Subject: [PATCH 187/206] fixed problems encountered in PR testing --- cime_config/runseq/runseq_D.py | 2 +- cime_config/runseq/runseq_general.py | 7 +- mediator/med.F90 | 10 +-- mediator/med_phases_post_glc_mod.F90 | 104 +++++++++++++-------------- mediator/med_phases_prep_ocn_mod.F90 | 95 +++++++++++------------- 5 files changed, 101 insertions(+), 117 deletions(-) diff --git a/cime_config/runseq/runseq_D.py b/cime_config/runseq/runseq_D.py index 3048b1bef..3d108fe30 100644 --- a/cime_config/runseq/runseq_D.py +++ b/cime_config/runseq/runseq_D.py @@ -31,7 +31,7 @@ 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" , 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))) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 7191be373..3bc307488 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -44,6 +44,9 @@ def gen_runseq(case, coupling_times): 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 @@ -78,7 +81,7 @@ def gen_runseq(case, coupling_times): runseq.enter_time_loop(ocn_cpl_time, newtime=ocn_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_ocn" , 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) #------------------ @@ -105,7 +108,7 @@ def gen_runseq(case, coupling_times): 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" , med_to_ocn and not ocn_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) diff --git a/mediator/med.F90 b/mediator/med.F90 index d7c7864f9..19f73a59e 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -95,7 +95,7 @@ subroutine SetServices(gcomp, rc) 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 + 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 @@ -262,10 +262,10 @@ subroutine SetServices(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn"/), 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", specRoutine=med_phases_prep_ocn, 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, & @@ -2313,7 +2313,7 @@ subroutine DataInitialize(gcomp, rc) allDone=.false. if (dbug_flag > 0) then if (mastertask) then - write(logunit,'(A)') trim(subname)//" MED - Initialize-Data-Dependency check Failed for "//& + write(logunit,'(A)') trim(subname)//" MED - Initialize-Data-Dependency check not yet satisfied for "//& trim(compname(n1)) end if end if @@ -2433,7 +2433,7 @@ subroutine DataInitialize(gcomp, rc) else ! Not all done call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="false", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check Failed, another loop is required", & + call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check not yet satisfied, another loop is required", & ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 439b92810..6facc4433 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -134,36 +134,31 @@ subroutine med_phases_post_glc(gcomp, rc) 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 - if (first_call) then - call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) + 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 - 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 + read (cvalue,*) cism_evolve + if (mastertask) then + write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve end if end if end if - ! 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(complnd), fieldCount=ncnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (ncnt > 0) then - - !--------------------------------------- - ! glc->ocn mapping - - ! merging with rof->ocn fields is done in med_phases_prep_ocn - !--------------------------------------- - if (glc2ocn_coupling) then + !--------------------------------------- + ! 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)), & @@ -174,46 +169,45 @@ subroutine med_phases_post_glc(gcomp, rc) routehandles=is_local%wrap%RH(compglc(ns),compocn,:), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - end if - - !--------------------------------------- - ! glc->ice mapping - !--------------------------------------- - if (glc2ice_coupling) then - ! Fill this in - end if + end do + 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') + !--------------------------------------- + ! glc->ice mapping + !--------------------------------------- + if (glc2ice_coupling) then + ! Fill this in + end if - ! The following is only done if glc->lnd coupling is active - if (first_call) then - call map_glc2lnd_init(gcomp, rc=rc) + !--------------------------------------- + ! 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 will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call map_glc2lnd(gcomp, rc=rc) + ! 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 diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 07b70f739..3f971b0d4 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -27,8 +27,8 @@ module med_phases_prep_ocn_mod implicit none private - public :: med_phases_prep_ocn_accum ! merge and accumulate export fields to ocn - public :: med_phases_prep_ocn ! average accumulated fields + 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 @@ -68,60 +68,47 @@ subroutine med_phases_prep_ocn_accum(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 - - ! accumulat ocean export fields - call FB_accum(is_local%wrap%FBExpAccum(compocn), is_local%wrap%FBExp(compocn), rc=rc) + ! 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 - is_local%wrap%FBExpAccumCnt(compocn) = is_local%wrap%FBExpAccumCnt(compocn) + 1 + 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 - ! 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 + ! 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 - endif + ! 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 + ! 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 + end if if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if @@ -130,7 +117,7 @@ subroutine med_phases_prep_ocn_accum(gcomp, rc) end subroutine med_phases_prep_ocn_accum !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn(gcomp, rc) + subroutine med_phases_prep_ocn_avg(gcomp, rc) ! Prepare the OCN import Fields. @@ -197,7 +184,7 @@ subroutine med_phases_prep_ocn(gcomp, rc) end if call t_stopf('MED:'//subname) - end subroutine med_phases_prep_ocn + end subroutine med_phases_prep_ocn_avg !----------------------------------------------------------------------------- subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) From 4a82768e814bb6fa7e94fde39101e5961e720a4a Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 10:53:40 -0700 Subject: [PATCH 188/206] update to pull request template --- .github/pull_request_template.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 56d960517..7922b5303 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -16,18 +16,21 @@ 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): From bb8214c464b767f98a74d7a79a19c0c1bcce484d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 11:22:23 -0700 Subject: [PATCH 189/206] updated Makefile new post phase modules --- mediator/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mediator/Makefile b/mediator/Makefile index f1c9b5ea1..98783174a 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -57,6 +57,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 From 94cde1516eb29eb5ece8a3078fc5adc0f892ae6b Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 11:25:04 -0700 Subject: [PATCH 190/206] updated pr template to add HAFS --- .github/pull_request_template.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7922b5303..4c5d6f02f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -34,6 +34,11 @@ Testing performed if application target is UFS-S2S: - description: - details (e.g. failed tests): +Testing performed if application target is UFS-HAFS: +- [ ] (recommended) UFS-HAFS testing + - description: + - details (e.g. failed tests): + Hashes used for testing: - [ ] CESM: - repository to check out: https://github.com/ESCOMP/CESM.git @@ -43,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: From 920bc97d2888edfd5571a4c97277780fcf84b7d5 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 11:32:28 -0700 Subject: [PATCH 191/206] updated module arrays to be initialized to null --- mediator/med_phases_prep_ice_mod.F90 | 4 ++-- mediator/med_phases_prep_lnd_mod.F90 | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 58bf907c5..f987488f3 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -11,8 +11,8 @@ module med_phases_prep_ice_mod public :: med_phases_prep_ice - real(r8), pointer :: dataptr_scalar_ice(:,:) - real(r8), pointer :: dataptr_scalar_atm(:,:) + real(r8), pointer :: dataptr_scalar_ice(:,:) => null() + real(r8), pointer :: dataptr_scalar_atm(:,:) => null() character(*), parameter :: u_FILE_u = & __FILE__ diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 5ea85a5c3..fd2a32c95 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -11,8 +11,8 @@ module med_phases_prep_lnd_mod public :: med_phases_prep_lnd - real(r8), pointer :: dataptr_scalar_lnd(:,:) - real(r8), pointer :: dataptr_scalar_atm(:,:) + real(r8), pointer :: dataptr_scalar_lnd(:,:) => null() + real(r8), pointer :: dataptr_scalar_atm(:,:) => null() character(*) , parameter :: u_FILE_u = & __FILE__ @@ -51,7 +51,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) real(r8) :: nextsw_cday integer :: scalar_id real(r8) :: tmp(1) - real(r8), pointer :: dataptr2d(:,:) + real(r8), pointer :: dataptr2d(:,:) => null() logical :: first_call = .true. character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- From ab8b90c6441c288ca0d3aca55dd507512dc0031e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 7 Dec 2020 12:06:30 -0700 Subject: [PATCH 192/206] update med.F90 dependancies --- mediator/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediator/Makefile b/mediator/Makefile index 98783174a..4177bd19e 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -40,7 +40,9 @@ med.o : med_kind_mod.o med_phases_profile_mod.o med_utils_mod.o med_phases_prep_ med_phases_prep_ice_mod.o med_fraction_mod.o med_map_mod.o med_constants_mod.o med_phases_prep_wav_mod.o \ med_phases_prep_lnd_mod.o med_phases_history_mod.o med_phases_ocnalb_mod.o med_phases_restart_mod.o \ med_time_mod.o med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_nems_mod.o \ - esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o + esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o \ + med_phases_post_atm_mod.o med_phases_post_ice_mod.o med_phases_post_lnd_mod.o med_phases_post_glc_mod.o med_phases_post_rof_mod.o \ + med_phases_post_wav_mod.o med_fraction_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o esmFlds.o med_internalstate_mod.o : med_kind_mod.o esmFlds.o med_io_mod.o : med_kind_mod.o med_methods_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o From 70b5aac7037f9e3355830de2d51aed2e23b3b15d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 7 Dec 2020 12:41:24 -0700 Subject: [PATCH 193/206] update cmake file --- mediator/CMakeLists.txt | 29 ++++++++++++++++------------- mediator/Makefile | 6 +++--- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index be5b89670..895027e6b 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -1,18 +1,21 @@ project(cmeps Fortran) set(SRCFILES esmFldsExchange_cesm_mod.F90 med_fraction_mod.F90 - med_methods_mod.F90 med_phases_prep_ice_mod.F90 - med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90 - med_internalstate_mod.F90 med_phases_aofluxes_mod.F90 - med_phases_prep_lnd_mod.F90 med_time_mod.F90 - esmFldsExchange_nems_mod.F90 med_io_mod.F90 - med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90 - med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90 - med_phases_ocnalb_mod.F90 med_phases_prep_rof_mod.F90 - med_constants_mod.F90 med_map_mod.F90 - med_phases_prep_atm_mod.F90 med_phases_prep_wav_mod.F90 - med.F90 med_merge_mod.F90 med_phases_prep_glc_mod.F90 - med_phases_profile_mod.F90 med_diag_mod.F90) + med_methods_mod.F90 med_phases_prep_ice_mod.F90 + med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90 + med_internalstate_mod.F90 med_phases_aofluxes_mod.F90 + med_phases_prep_lnd_mod.F90 med_time_mod.F90 + esmFldsExchange_nems_mod.F90 med_io_mod.F90 + med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90 + med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90 + med_phases_ocnalb_mod.F90 med_phases_prep_rof_mod.F90 + med_constants_mod.F90 med_map_mod.F90 + med_phases_prep_atm_mod.F90 med_phases_prep_wav_mod.F90 + med.F90 med_merge_mod.F90 med_phases_prep_glc_mod.F90 + med_phases_profile_mod.F90 med_diag_mod.F90 + med_phases_post_atm_mod.F90 med_phases_post_ice_mod.F90 + med_phases_post_lnd_mod.F90 med_phases_post_glc_mod.F90 + med_phases_post_rof_mod.F90 med_phases_post_wav_mod.F90) foreach(FILE ${SRCFILES}) if(EXISTS "${CASEROOT}/SourceMods/src.cmeps/${FILE}") @@ -32,4 +35,4 @@ target_include_directories (cmeps PUBLIC "${CMAKE_BINARY_DIR}/nems/util") target_include_directories (cmeps PUBLIC ${PIO_Fortran_INCLUDE_DIR}) install(TARGETS cmeps - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib) diff --git a/mediator/Makefile b/mediator/Makefile index 4177bd19e..a3de3ce6c 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -22,13 +22,13 @@ OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) all default: $(LIBRARY) $(LIBRARY): $(OBJ) - $(AR) $(ARFLAGS) $@ $? + $(AR) $(ARFLAGS) $@ $? %.o: %.F90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.F90 + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.F90 clean: - $(RM) -f $(LIBRARY) *.i90 *.o *.mod + $(RM) -f $(LIBRARY) *.i90 *.o *.mod med_kind_mod.o : med_constants_mod.o : med_kind_mod.o From c6b58ce9f6dfc881b7a12d26443688dba65035d1 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Mon, 7 Dec 2020 12:51:45 -0700 Subject: [PATCH 194/206] corrected file name --- mediator/{med_phases_post_lnd.F90 => med_phases_post_lnd_mod.F90} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mediator/{med_phases_post_lnd.F90 => med_phases_post_lnd_mod.F90} (100%) diff --git a/mediator/med_phases_post_lnd.F90 b/mediator/med_phases_post_lnd_mod.F90 similarity index 100% rename from mediator/med_phases_post_lnd.F90 rename to mediator/med_phases_post_lnd_mod.F90 From 3a059679060c979353e2a8d0024cabca5e68d11c Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 7 Dec 2020 12:55:57 -0700 Subject: [PATCH 195/206] add post_ocn_mod --- mediator/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index 895027e6b..91f2921e9 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -13,6 +13,7 @@ set(SRCFILES esmFldsExchange_cesm_mod.F90 med_fraction_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) From 8746b78c0c7307a12058d25809d9c06f31f5a245 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 13 Dec 2020 22:23:49 -0700 Subject: [PATCH 196/206] changes needed to transfer ocean to glc coupling - now just from pop --- cime_config/namelist_definition_drv.xml | 25 + mediator/esmFldsExchange_cesm_mod.F90 | 50 +- mediator/fd_cesm.yaml | 10 + mediator/med.F90 | 1 + mediator/med_phases_post_lnd_mod.F90 | 4 +- mediator/med_phases_post_ocn_mod.F90 | 46 +- mediator/med_phases_prep_glc_mod.F90 | 617 +++++++++++++++--------- 7 files changed, 511 insertions(+), 242 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 1ea7ea455..775904e2f 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -768,6 +768,31 @@ + + logical + flds + ALLCOMP_attributes + + .true. if ocean is sends fields at multiple ocean levels to the land-ice component + + + .false. + + + + + char + flds + ALLCOMP_attributes + + if ocean is 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 diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 09c7c0dc5..1b4ee913a 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 @@ -43,6 +44,7 @@ module esmFldsExchange_cesm_mod character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' character(len=CX) :: wav2ocn_smap='unset' logical :: mapuv_with_cart3d + logical :: ocn2glc_coupling logical :: flds_i2o_per_cat logical :: flds_co2a logical :: flds_co2b @@ -240,14 +242,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 @@ -1776,7 +1789,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListTo(compglc(ns))%flds, 'Flgl_qice') end do else - ! custom mapping and merging will be done in prep_glc_mod.F90 + ! 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') @@ -1791,6 +1804,31 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) 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 + !===================================================================== ! CO2 EXCHANGE !===================================================================== diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 8d5812804..ab4c5cd9a 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -815,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 @@ -824,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 19f73a59e..d26d5dbda 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -1858,6 +1858,7 @@ subroutine DataInitialize(gcomp, rc) ! 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 diff --git a/mediator/med_phases_post_lnd_mod.F90 b/mediator/med_phases_post_lnd_mod.F90 index 1f168dfa2..21f4f243e 100644 --- a/mediator/med_phases_post_lnd_mod.F90 +++ b/mediator/med_phases_post_lnd_mod.F90 @@ -26,7 +26,7 @@ subroutine med_phases_post_lnd(gcomp, rc) use med_map_mod , only : med_map_field_packed use med_internalstate_mod , only : InternalState, mastertask use med_phases_prep_rof_mod , only : med_phases_prep_rof_accum - use med_phases_prep_glc_mod , only : med_phases_prep_glc_accum + use 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 @@ -84,7 +84,7 @@ subroutine med_phases_post_lnd(gcomp, rc) ! accumulate lnd input for glc if (lnd2glc_coupling) then - call med_phases_prep_glc_accum(gcomp, rc) + call med_phases_prep_glc_accum_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if diff --git a/mediator/med_phases_post_ocn_mod.F90 b/mediator/med_phases_post_ocn_mod.F90 index 8b8de5865..d0d00b970 100644 --- a/mediator/med_phases_post_ocn_mod.F90 +++ b/mediator/med_phases_post_ocn_mod.F90 @@ -1,7 +1,7 @@ module med_phases_post_ocn_mod !----------------------------------------------------------------------------- - ! Mediator post ocn phase - maps ocn->ice + ! Mediator post ocn phase - maps ocn->ice, accumulate glc input from ocn !----------------------------------------------------------------------------- implicit none @@ -9,6 +9,8 @@ module med_phases_post_ocn_mod public :: med_phases_post_ocn + logical :: ocn2glc_coupling + character(*), parameter :: u_FILE_u = & __FILE__ @@ -18,23 +20,26 @@ module med_phases_post_ocn_mod subroutine med_phases_post_ocn(gcomp, rc) - use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use ESMF , only : ESMF_GridComp - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_map_mod , only : med_map_field_packed - use med_internalstate_mod , only : InternalState, logunit, mastertask - use esmFlds , only : compice, compocn - use perf_mod , only : t_startf, t_stopf + 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 - character(len=*),parameter :: subname='(med_phases_prep_ice)' + type(InternalState) :: is_local + integer :: ns + logical :: first_call = .true. + character(len=*),parameter :: subname='(med_phases_post_ocn)' !--------------------------------------- rc = ESMF_SUCCESS @@ -49,7 +54,7 @@ subroutine med_phases_post_ocn(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! map ocn->ice + ! 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( & @@ -63,6 +68,21 @@ subroutine med_phases_post_ocn(gcomp, rc) 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 diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index d53424cc0..294148bd7 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -19,13 +19,16 @@ module med_phases_prep_glc_mod 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_Mesh, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use esmFlds , only : complnd, mapbilnr, mapconsd, 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 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_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 @@ -39,19 +42,24 @@ module med_phases_prep_glc_mod 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 + 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_accum ! called from med_phases_post_lnd - public :: med_phases_prep_glc + 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 :: 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 @@ -62,23 +70,21 @@ module med_phases_prep_glc_mod ! Does not need to be true for 1-way coupling. logical :: smb_renormalize - ! Needed for standard lnd->glc mapping 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 :: ice_sheet_toglc_type + type, public :: toglc_frlnd_type character(CS) :: name - logical :: is_active 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 ice_sheet_toglc_type - type(ice_sheet_toglc_type) :: ice_sheet_toglc(max_icesheets) + 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 @@ -91,8 +97,21 @@ module med_phases_prep_glc_mod 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' + integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + + ! ----------------- + ! ocn -> glc + ! ----------------- - integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + 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 :: ocn2glc_coupling = .true. logical :: init_prep_glc = .false. type(ESMF_Clock) :: prepglc_clock character(*), parameter :: u_FILE_u = & @@ -105,7 +124,8 @@ module med_phases_prep_glc_mod subroutine med_phases_prep_glc_init(gcomp, rc) !--------------------------------------- - ! Create land accumulation field bundles on lnd and and glc mesh 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 @@ -114,18 +134,14 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! local variables type(InternalState) :: is_local - integer :: i,n,ncnt,ns,nf - type(ESMF_Mesh) :: lmesh_l + 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 - 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 type(ESMF_Clock) :: med_clock type(ESMF_ALARM) :: glc_avg_alarm @@ -143,7 +159,16 @@ subroutine med_phases_prep_glc_init(gcomp, rc) endif rc = ESMF_SUCCESS - ! First prepglc_clock from mclock - THIS CALL DOES NOT COPY ALARMS + ! 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 + ! ------------------------------- + + ! 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) @@ -178,33 +203,17 @@ subroutine med_phases_prep_glc_init(gcomp, rc) call ESMF_AlarmSet(glc_avg_alarm, clock=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) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - ! Create field bundles for the fldnames_fr_lnd that have an - ! undistributed dimension corresponding to elevation classes - !--------------------------------------- + ! ------------------------------- + ! If lnd->glc couplng is active + ! ------------------------------- - if (ncnt > 0) 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 + if (lnd2glc_coupling) then ! Determine if renormalize smb call NUOPC_CompAttributeGet(gcomp, name='glc_renormalize_smb', value=glc_renormalize_smb, rc=rc) @@ -238,16 +247,8 @@ subroutine med_phases_prep_glc_init(gcomp, rc) return end select - ! Determine which ice sheets are active - do ns = 1,max_icesheets - if (is_local%wrap%med_coupling_active(complnd,compglc(ns))) then - ice_sheet_toglc(ns)%is_active = .true. - else - ice_sheet_toglc(ns)%is_active = .false. - end if - end do - - ! Create accumulation field bundle from land on the land grid (including bare land) + ! 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) @@ -256,13 +257,13 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! TODO: check that ungriddedCount = glc_nec+1 ! Get land mesh - call fldbun_getmesh(is_local%wrap%FBImp(complnd,complnd), lmesh_l, rc) + call fldbun_getmesh(is_local%wrap%FBImp(complnd,complnd), mesh_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return 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_l, 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 @@ -276,46 +277,43 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! 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 - do ns = 1,max_icesheets - if (ice_sheet_toglc(ns)%is_active) then - ! get mesh on glc grid - call fldbun_getmesh(is_local%wrap%FBExp(compglc(ns)), ice_sheet_toglc(ns)%mesh_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! 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 - ! create accumulation field bundle on glc grid - ice_sheet_toglc(ns)%FBlndAccum_g = ESMF_FieldBundleCreate(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 + 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 - do nf = 1,size(fldnames_fr_lnd) - lfield = ESMF_FieldCreate(ice_sheet_toglc(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(ice_sheet_toglc(ns)%FBlndAccum_g, (/lfield/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - call fldbun_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + 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 - ! create land fraction field on glc mesh (this is just needed for normalization mapping) - ice_sheet_toglc(ns)%field_lfrac_g = ESMF_FieldCreate(ice_sheet_toglc(ns)%mesh_g, 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(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 + ! 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 @@ -349,61 +347,103 @@ subroutine med_phases_prep_glc_init(gcomp, rc) write(logunit,'(a,l4)') trim(subname)//' smb_renormalize is ',smb_renormalize end if - ! ------------------------------- - ! If smb will be renormalized then... - ! ------------------------------- if (smb_renormalize) then - - field_normdst_l = ESMF_FieldCreate(lmesh_l, 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 mask without elevation classes on lnd - field_icemask_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + field_icemask_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 lnd - field_frac_l = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + 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 lnd - NOTE that this includes bare land - field_frac_l_ec = ESMF_FieldCreate(lmesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + 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 ! Loop over ice sheets - do ns = 1,max_icesheets - ! Determine if ice sheets ns is active - if (ice_sheet_toglc(ns)%is_active) then - - ! ice mask without elevation classes on glc - ice_sheet_toglc(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_toglc(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 - ice_sheet_toglc(ns)%field_frac_g = ESMF_FieldCreate(ice_sheet_toglc(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 - ice_sheet_toglc(ns)%field_frac_g_ec = ESMF_FieldCreate(ice_sheet_toglc(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 + 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 + ! ------------------------------- + + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compocn,compglc(ns))) then + ocn2glc_coupling = .true. + exit end if + end do + 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 + 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 if (dbug_flag > 5) then @@ -414,13 +454,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 field to glc on the land grid - ! Mapping from the land to the glc grid is then done after the accumulated fields have been - ! time averaged + ! 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 @@ -430,15 +472,13 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield - type(ESMF_Alarm) :: alarm - 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) ' !--------------------------------------- call t_startf('MED:'//subname) - if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif @@ -451,20 +491,17 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) 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 - !--------------------------------------- - ! accumulator land input to glc on land grid - !--------------------------------------- - - ! Advance prepglc_clock - this will make the prepglc_clock in sync with the mediator clock - call ESMF_ClockAdvance(prepglc_clock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Accumulate fields + ! 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 @@ -474,10 +511,7 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) data2d_out(:,i) = data2d_out(:,i) + data2d_in(:,i) end do end do - - ! Increment accumulation counter 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 @@ -487,12 +521,84 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) 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_accum_ocn(gcomp, rc) + + !--------------------------------------- + ! 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 + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + 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) + endif + + rc = ESMF_SUCCESS + + 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) !--------------------------------------- + ! Create module clock (prepglc_clock) ! Prepare the GLC export Fields from the mediator !--------------------------------------- @@ -502,17 +608,21 @@ subroutine med_phases_prep_glc(gcomp, rc) ! 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 - type(ESMF_Field) :: lfield - integer :: i, n, ncnt, ns + integer :: i, n, ns real(r8), pointer :: data2d(:,:) => null() real(r8), pointer :: data2d_import(:,:) => null() - character(len=*) , parameter :: subname=' (med_phases_prep_glc_avg) ' + character(len=*) , parameter :: subname=' (med_phases_prep_glc) ' !--------------------------------------- call t_startf('MED:'//subname) @@ -533,40 +643,41 @@ subroutine med_phases_prep_glc(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Determine if avg alarm is ringing - and if not ringing then return - !--------------------------------------- - + ! 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 - 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 - - ! If the is ringing - turn it off and continue - otherwise reset field bundle to zero and return + ! 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 (ESMF_AlarmIsRinging(alarm, rc=rc)) then ! Turn off the alarm call ESMF_AlarmRingerOff( alarm, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! 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) - if (mastertask) then - write(logunit,'(a)') trim(subname)//"glc_avg alarm is ringing - averaging input from lnd to glc" - end if + ! 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 @@ -582,38 +693,59 @@ subroutine med_phases_prep_glc(gcomp, rc) end if end do + ! 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(FBlndAccum_l, string=trim(subname)//' FBlndAccum for after avg for field bundle ', rc=rc) + 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 - ! Initialize accumulated field bundle on the glc grid to zero before doing the mapping - do ns = 1,num_icesheets - call fldbun_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - ! 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 - - ! zero accumulator and accumulated field bundles on land grid FBlndAccumCnt = 0 - call fldbun_reset(FBlndAccum_l, value=0.0_r8, rc=rc) + call fldbun_reset(FBlndAccum_l, value=czero, 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 if (dbug_flag > 1) then - do ns = 1,max_icesheets + 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 - - else - - call ESMF_LogWrite(trim(subname)//": glc_avg alarm is not ringing - returning", ESMF_LOGMSG_INFO) - end if if (dbug_flag > 5) then @@ -650,18 +782,16 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) integer :: nfld, ec 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_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 @@ -671,6 +801,12 @@ subroutine med_phases_prep_glc_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 @@ -690,29 +826,25 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! TODO: is this needed? - do ns = 1,max_icesheets - if (ice_sheet_toglc(ns)%is_active) then - call fldbun_reset(ice_sheet_toglc(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if + 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 to each ice sheet (normalize by the land fraction in the mapping) - do ns = 1,max_icesheets - if (ice_sheet_toglc(ns)%is_active) then - call ESMF_FieldBundleGet(ice_sheet_toglc(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=ice_sheet_toglc(ns)%field_lfrac_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - end if + 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) @@ -723,12 +855,10 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return 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,max_icesheets - if (ice_sheet_toglc(ns)%is_active) then - call fldbun_diagnose(ice_sheet_toglc(ns)%FBlndAccum_g, string=trim(subname)//& - ' FBlndAccum_glc '//compname(compglc(ns)), rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if + 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 @@ -737,8 +867,7 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) ! ------------------------------------------------------------------------ ! Loop over ice sheets - do ns = 1,max_icesheets - + 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)), & @@ -758,7 +887,7 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) call glc_get_elevation_classes(ice_covered_g, topoglc_g, elevclass_g, logunit) ! Determine topo field in multiple elevation classes on the glc grid - call fldbun_getdata2d(ice_sheet_toglc(ns)%FBlndAccum_g, 'Sl_topo_elev', topolnd_g_ec, rc=rc) + call fldbun_getdata2d(toglc_frlnd(ns)%FBlndAccum_g, 'Sl_topo_elev', topolnd_g_ec, rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! ------------------------------------------------------------------------ @@ -776,7 +905,7 @@ subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) do nfld = 1, size(fldnames_to_glc) ! Get a pointer to the land data in multiple elevation classes on the glc grid - call fldbun_getdata2d(ice_sheet_toglc(ns)%FBlndAccum_g, fldnames_fr_lnd(nfld), dataptr2d, rc) + call fldbun_getdata2d(toglc_frlnd(ns)%FBlndAccum_g, fldnames_fr_lnd(nfld), dataptr2d, 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) @@ -979,13 +1108,13 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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(ice_sheet_toglc(ns)%field_icemask_g, icemask_g, rc=rc) + 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=ice_sheet_toglc(ns)%field_icemask_g, & + 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) @@ -1006,23 +1135,23 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! 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(ice_sheet_toglc(ns)%field_lfrac_g, frac_g, rc) ! module field + call field_getdata1d(toglc_frlnd(ns)%field_lfrac_g, frac_g, rc) ! module field frac_g(:) = dataptr1d(:) ! 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(ice_sheet_toglc(ns)%field_frac_g_ec, frac_g_ec, rc=rc) ! module field + 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) ! 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=ice_sheet_toglc(ns)%field_frac_g_ec, & + 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=ice_sheet_toglc(ns)%field_icemask_g, & + field_normsrc=toglc_frlnd(ns)%field_icemask_g, & field_normdst=field_normdst_l, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -1131,4 +1260,50 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) 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 + From 7cb568ead1a17018da0bcd534e30c4715a0ab5f4 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Wed, 16 Dec 2020 10:09:19 -0700 Subject: [PATCH 197/206] bug fixes --- mediator/med_phases_prep_glc_mod.F90 | 87 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 294148bd7..aca1eb8df 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -111,7 +111,7 @@ module med_phases_prep_glc_mod logical :: ocn_sends_depths = .false. logical :: lnd2glc_coupling = .false. - logical :: ocn2glc_coupling = .true. + logical :: ocn2glc_coupling = .false. logical :: init_prep_glc = .false. type(ESMF_Clock) :: prepglc_clock character(*), parameter :: u_FILE_u = & @@ -407,7 +407,6 @@ subroutine med_phases_prep_glc_init(gcomp, rc) end if end do 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 @@ -693,52 +692,56 @@ subroutine med_phases_prep_glc(gcomp, rc) end if end do - ! 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 (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 - data2d(:,:) = data2d_import(:,:) + 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 - end do - if (dbug_flag > 1) then - call fldbun_diagnose(FBocnAccum_o, string=trim(subname)//' FBocnAccum for after avg for field bundle ', rc=rc) + + ! 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 - ! 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 - - ! 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 (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 - 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 + FBlndAccumCnt = 0 + call fldbun_reset(FBlndAccum_l, value=czero, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if if (dbug_flag > 1) then do ns = 1,num_icesheets From 9c8b94f69e89d093229b157aed676b5cd6670e31 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Thu, 17 Dec 2020 20:15:24 +0000 Subject: [PATCH 198/206] fix error when scalar_id is 0 (triggered in new datm debug test) --- mediator/med_phases_prep_ice_mod.F90 | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index d96c57251..d55461b44 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -138,15 +138,17 @@ subroutine med_phases_prep_ice(gcomp, rc) 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) + if(is_local%wrap%flds_scalar_index_nextsw_cday .ne. 0) then + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr_scalar_atm(scalar_id,1) + end if + call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! set nextsw_cday on all ice export tasks + dataptr_scalar_ice(scalar_id,1) = tmp(1) + call t_stopf('MED:'//trim(subname)//' nextsw_cday') end if - call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! set nextsw_cday on all ice export tasks - dataptr_scalar_ice(scalar_id,1) = tmp(1) - call t_stopf('MED:'//trim(subname)//' nextsw_cday') end if if (dbug_flag > 1) then From 5e99e9153d514fe0f64b6aceeb9b661cdcf193aa Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sat, 19 Dec 2020 16:15:42 -0700 Subject: [PATCH 199/206] removed nems reference in buildnml --- cime_config/buildnml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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")) ############################################################################### From 0e35a1b9779f28d0a04a422f499342d3b67d9303 Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Sun, 20 Dec 2020 20:49:09 -0700 Subject: [PATCH 200/206] bug fixes for ocn2glc coupling --- cime_config/namelist_definition_drv.xml | 155 ++++++++++++++++++++++++ mediator/esmFlds.F90 | 1 + mediator/esmFldsExchange_cesm_mod.F90 | 3 +- mediator/med.F90 | 9 +- mediator/med_phases_prep_glc_mod.F90 | 9 +- 5 files changed, 166 insertions(+), 11 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 775904e2f..4bd5d7f05 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -851,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/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 8747cdaca..e41d4289f 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -32,6 +32,7 @@ module esmflds 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 diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 1b4ee913a..3d082892e 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -44,7 +44,6 @@ module esmFldsExchange_cesm_mod character(len=CX) :: atm2wav_smap='unset', ice2wav_smap='unset', ocn2wav_smap='unset' character(len=CX) :: wav2ocn_smap='unset' logical :: mapuv_with_cart3d - logical :: ocn2glc_coupling logical :: flds_i2o_per_cat logical :: flds_co2a logical :: flds_co2b @@ -70,7 +69,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) use esmFlds , only : addmrg => med_fldList_AddMrg use esmflds , only : compmed, compatm, complnd, compocn use esmflds , only : compice, comprof, compwav, ncomps - use esmflds , only : compglc, num_icesheets ! compglc is an array of integers + 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 diff --git a/mediator/med.F90 b/mediator/med.F90 index d26d5dbda..4c0366b97 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -33,7 +33,7 @@ module MED 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 ! compglc is an array + 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 @@ -1882,6 +1882,13 @@ subroutine DataInitialize(gcomp, rc) endif enddo + ! 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 diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index aca1eb8df..adff495d5 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -23,7 +23,7 @@ module med_phases_prep_glc_mod 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 + use esmFlds , only : max_icesheets, num_icesheets, compglc, ocn2glc_coupling use med_internalstate_mod , only : InternalState, mastertask, logunit 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 @@ -111,7 +111,6 @@ module med_phases_prep_glc_mod logical :: ocn_sends_depths = .false. logical :: lnd2glc_coupling = .false. - logical :: ocn2glc_coupling = .false. logical :: init_prep_glc = .false. type(ESMF_Clock) :: prepglc_clock character(*), parameter :: u_FILE_u = & @@ -400,12 +399,6 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! If ocn->glc couplng is active ! ------------------------------- - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compocn,compglc(ns))) then - ocn2glc_coupling = .true. - exit - end if - end do if (ocn2glc_coupling) then ! Get ocean mesh call fldbun_getmesh(is_local%wrap%FBImp(compocn,compocn), mesh_o, rc) From 0bdc342e88557faad49974e7d9a05d8f069b65ac Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Dec 2020 13:59:34 -0700 Subject: [PATCH 201/206] fixed phrasing --- cime_config/namelist_definition_drv.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 4bd5d7f05..00bec50fa 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -773,7 +773,7 @@ flds ALLCOMP_attributes - .true. if ocean is sends fields at multiple ocean levels to the land-ice component + .true. if ocean sends fields at multiple ocean levels to the land-ice component .false. From aac500478af3519028ea89b1872223a3e60f850d Mon Sep 17 00:00:00 2001 From: Mariana Vertenstein Date: Tue, 22 Dec 2020 14:04:27 -0700 Subject: [PATCH 202/206] more phrasing fixes --- cime_config/namelist_definition_drv.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 00bec50fa..d36e61c2b 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -785,7 +785,7 @@ flds ALLCOMP_attributes - if ocean is sends fields at multiple ocean levels to the + if the ocean component sends fields at multiple ocean levels to the land-ice component, these are the colon deliminted level indices From 56a5e44152139b3079b45c3efa34691f74a075dd Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Wed, 23 Dec 2020 10:49:29 -0500 Subject: [PATCH 203/206] fix mismatched subname/subroutines --- mediator/med_diag_mod.F90 | 4 ++-- mediator/med_map_mod.F90 | 6 +++--- mediator/med_merge_mod.F90 | 4 ++-- mediator/med_methods_mod.F90 | 4 ++-- mediator/med_phases_aofluxes_mod.F90 | 4 ++-- mediator/med_phases_ocnalb_mod.F90 | 2 +- mediator/med_phases_post_glc_mod.F90 | 4 ++-- mediator/med_phases_prep_ocn_mod.F90 | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 7c907adb4..c191b7121 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -1978,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 @@ -2126,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 diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 69e1947f4..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) @@ -403,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 @@ -613,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 5afbc4de1..3d0d6bbd4 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -237,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 @@ -445,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 fbfed3ffb..63eb4890c 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -1155,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 @@ -1220,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 diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index deaec2a28..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 @@ -205,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 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_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 index 6facc4433..5b7b23f13 100644 --- a/mediator/med_phases_post_glc_mod.F90 +++ b/mediator/med_phases_post_glc_mod.F90 @@ -154,7 +154,7 @@ subroutine med_phases_post_glc(gcomp, rc) end if !--------------------------------------- - ! glc->ocn mapping - + ! glc->ocn mapping - ! merging with rof->ocn fields is done in med_phases_prep_ocn !--------------------------------------- if (glc2ocn_coupling) then @@ -423,7 +423,7 @@ subroutine map_glc2lnd( gcomp, 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) + 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 diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index f6f309db8..e924058f8 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -53,7 +53,7 @@ subroutine med_phases_prep_ocn_accum(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,7 +131,7 @@ subroutine med_phases_prep_ocn_avg(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: ncnt - character(len=*),parameter :: subname='(med_phases_prep_ocn)' + character(len=*),parameter :: subname='(med_phases_prep_ocn_avg)' !--------------------------------------- rc = ESMF_SUCCESS From c5e942648c6b79749a108890b5dc46f3f96a0b6f Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Wed, 30 Dec 2020 07:53:32 -0500 Subject: [PATCH 204/206] restore files restore cmake subdir and CMakeLists.txt that were removed from emc/develop in case they conflicted w/ ufs-weather build; testing with these files shows they have no impact (all cpld * datm tests pass) --- CMakeLists.txt | 48 ++++++ cmake/FindESMF.cmake | 47 ++++++ cmake/FindPIO.cmake | 103 ++++++++++++ cmake/LibCheck.cmake | 104 ++++++++++++ cmake/LibFind.cmake | 333 +++++++++++++++++++++++++++++++++++++++ nems/util/CMakeLists.txt | 7 + 6 files changed, 642 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/FindESMF.cmake create mode 100644 cmake/FindPIO.cmake create mode 100644 cmake/LibCheck.cmake create mode 100644 cmake/LibFind.cmake create mode 100644 nems/util/CMakeLists.txt 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/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/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}) From 493e283bb9c4b22e061f47887c666c1e785e60b9 Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Thu, 7 Jan 2021 12:44:06 -0500 Subject: [PATCH 205/206] update med_io_mod for version currently in cmeps/master *this mod was supposed to have been replaced in previous update to emc/develop but was found to still be the "performance" version which has caused issues in cesm testing. skip-ci --- mediator/med_io_mod.F90 | 356 +++++++++++++++++++++++----------------- 1 file changed, 201 insertions(+), 155 deletions(-) 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 From 1f6757124acf51f01d8c665d7d1b0f58afc4f76e Mon Sep 17 00:00:00 2001 From: "denise.worthen" Date: Thu, 7 Jan 2021 13:11:58 -0700 Subject: [PATCH 206/206] alternate fix for scalar_id=0 case * the same issue found in prep_ice for the datm (scalar_id=0) was found in cesm using the gnu compiler. this commit implements an alternate fix suggested by escomp for the case when the netsw_cday is not obtained from the atm, yielding a scalar_id=0 *this commit also produces b4b results against the current baselines for both the cpld and datm --- mediator/med_phases_prep_ice_mod.F90 | 46 +++++++++------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index d55461b44..df4c08c4f 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -24,7 +24,7 @@ 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_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 @@ -118,37 +118,19 @@ subroutine med_phases_prep_ice(gcomp, rc) end if ! obtain nextsw_cday from atm if it is in the import state and send it to ice - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & - trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (itemType /= ESMF_STATEITEM_NOTFOUND) then - call t_startf('MED:'//trim(subname)//' nextsw_cday') - if (first_call) then - ! determine module pointer data for performance reasons - call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & - itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_atm, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_StateGet(is_local%wrap%NStateExp(compice), & - trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ice, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - ! obtain nextsw_cday from atm import on all tasks - if(is_local%wrap%flds_scalar_index_nextsw_cday .ne. 0) then - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday - if (mastertask) then - tmp(1) = dataptr_scalar_atm(scalar_id,1) - end if - call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! set nextsw_cday on all ice export tasks - dataptr_scalar_ice(scalar_id,1) = tmp(1) - call t_stopf('MED:'//trim(subname)//' nextsw_cday') - end if + 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 (dbug_flag > 1) then