From f14d71a51425acd47dde73e7732eb76d7a4d0caa Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 22 Apr 2024 23:49:57 -0500 Subject: [PATCH 01/19] Create avgThermalForcing300m coupling field in MPAS-Ocean This commits adds a new field to MPAS-Ocean called avgThermalForcing300m. It is calculated as the thermal forcing (difference between ocean temperature local freezing temperature) at 300 m depth. It uses the temperature of the layer shallower than 300 m. This could be replaced with vertical interpolation to get the value exactly at 300 m. The TF at 300 m is time averaged over the ocean coupling interval. --- components/mpas-ocean/src/Registry.xml | 3 + .../shared/mpas_ocn_time_average_coupled.F | 57 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 2a21e22f40d2..fea5c17b9569 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -4010,6 +4010,9 @@ description="The time-averaged effective ocean density within ice shelves based on Archimedes' principle." packages="landIceCouplingPKG" /> + 300.0_RKIND) then + iLevel0300 = iLevel-1 + exit + end if + end do + !$omp parallel + !$omp do schedule(runtime) + ! calculate thermal forcing at identified level for each cell + do iCell = 1, nCells + ! ignore cells that are too shallow + if (iLevel0300 <= maxLevelCell(iCell)) then + ! this uses the level shallower than the reference level. could interpolate instead + ! note: assuming no LandIce cavity, but we may want to support that + freezingTemp = ocn_freezing_temperature(salinity=activeTracers(indexSalinity, iLevel0300, iCell), & + pressure=pressure(iLevel0300, iCell), inLandIceCavity=.false.) + avgThermalForcing300m(iCell) = ( avgThermalForcing300m(iCell) * nAccumulatedCoupled & + + activeTracers(indexTemperature, iLevel0300, iCell) - freezingTemp ) / ( nAccumulatedCoupled + 1) + end if + end do + !$omp end do + !$omp end parallel + ! accumulate BGC coupling fields if necessary if (config_use_ecosysTracers) then From 2abf17a24323f10358d079f5cc3d819f5264e30c Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 23 Apr 2024 00:02:17 -0500 Subject: [PATCH 02/19] Define coupler fields for TF at 300 m and connect to OCN and GLC This commit adds the So_tf300 coupler field for passing thermal forcing at 300m through the coupler. It also passes the avgThermalForcing300m added to MPAS-Ocean in the previous commit to this coupler field, and send it to the ismip6_2dThermalForcing field in MALI as the destination. Note that a new list of coupler fields called x2g_tf_states_from_ocn has been added to seq_flds_mod to differentiate this coupling field from the iceshelf OCN/GLC coupling, which is handled differently. --- .../mpas-albany-landice/driver/glc_comp_mct.F | 5 ++++- .../mpas-albany-landice/driver/glc_cpl_indices.F | 2 ++ components/mpas-ocean/driver/mpaso_cpl_indices.F | 2 ++ components/mpas-ocean/driver/ocn_comp_mct.F | 6 +++++- driver-mct/shr/seq_flds_mod.F90 | 14 ++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/components/mpas-albany-landice/driver/glc_comp_mct.F b/components/mpas-albany-landice/driver/glc_comp_mct.F index ac33d17b1f31..8bc9fc255d17 100644 --- a/components/mpas-albany-landice/driver/glc_comp_mct.F +++ b/components/mpas-albany-landice/driver/glc_comp_mct.F @@ -1383,7 +1383,8 @@ subroutine glc_import_mct(x2g_g, errorCode) floatingBasalMassBal,& surfaceTemperature,& basalOceanHeatflx,& - OceanDensity + OceanDensity, & + ismip6_2dThermalForcing errorCode = 0 @@ -1401,6 +1402,7 @@ subroutine glc_import_mct(x2g_g, errorCode) call mpas_pool_get_array(geometryPool, 'sfcMassBal', sfcMassBal) call mpas_pool_get_array(geometryPool, 'floatingBasalMassBal',floatingBasalMassBal) call mpas_pool_get_array(thermalPool, 'surfaceTemperature',surfaceTemperature) + call mpas_pool_get_array(geometryPool, 'ismip6_2dThermalForcing', ismip6_2dThermalForcing) ! call mpas_pool_get_array(thermalPool, 'basalOceanHeatflx',basalOceanHeatflx) !call mpas_pool_get_array(geometryPool, 'OceanDensity',OceanDensity) @@ -1408,6 +1410,7 @@ subroutine glc_import_mct(x2g_g, errorCode) n = n + 1 sfcMassBal(i) = x2g_g % rAttr(index_x2g_Flgl_qice, n) floatingBasalMassBal(i) = x2g_g % rAttr(index_x2g_Fogx_qiceli, n) + ismip6_2dThermalForcing(i) = x2g_g % rAttr(index_x2g_So_tf300, n) ! surfaceTemperature(i) = x2g_g % rAttr(index_x2g_Sl_tsrf, n) !JW basalOceanHeatflx(i) = x2g_g % rAttr(index_x2g_Fogo_qiceh, n) ! basalOceanHeatflx(i) = x2g_g % rAttr(index_x2g_Fogx_qicehi, n) diff --git a/components/mpas-albany-landice/driver/glc_cpl_indices.F b/components/mpas-albany-landice/driver/glc_cpl_indices.F index 123185225f82..e84ac9174b19 100644 --- a/components/mpas-albany-landice/driver/glc_cpl_indices.F +++ b/components/mpas-albany-landice/driver/glc_cpl_indices.F @@ -22,6 +22,7 @@ module glc_cpl_indices integer, public :: index_x2g_So_htv = 0 !Ice shelf ocean heat transfer velocity integer, public :: index_x2g_So_stv = 0 !Ice shelf ocean salinity transfer velocity integer, public :: index_x2g_So_rhoeff = 0 !Ocean effective pressure + integer, public :: index_x2g_So_tf300 = 0 !Ocean thermal forcing at 300m integer, public :: index_x2g_Fogx_qiceli = 0 !Subshelf mass flux integer, public :: index_x2g_Fogx_qicehi = 0 !Subshelf heat flux for the ice sheet @@ -70,6 +71,7 @@ subroutine glc_cpl_indices_set( ) index_x2g_Fogx_qiceli = mct_avect_indexra(x2g,'Fogx_qiceli',perrwith='quiet') index_x2g_Fogx_qicehi = mct_avect_indexra(x2g,'Fogx_qicehi',perrwith='quiet') index_x2g_So_rhoeff = mct_avect_indexra(x2g,'So_rhoeff',perrwith='quiet') + index_x2g_So_tf300 = mct_avect_indexra(x2g,'So_tf300',perrwith='quiet') !Following block of x2g/g2x vectors are used internally within coupler for subshelf melt flux !calculations (and so do not have directly-related export-side arrays) diff --git a/components/mpas-ocean/driver/mpaso_cpl_indices.F b/components/mpas-ocean/driver/mpaso_cpl_indices.F index f099cf8ea46a..c51aa68bf5b8 100644 --- a/components/mpas-ocean/driver/mpaso_cpl_indices.F +++ b/components/mpas-ocean/driver/mpaso_cpl_indices.F @@ -37,6 +37,7 @@ module mpaso_cpl_indices integer :: index_o2x_So_htv !ocean heat-transfer velocity integer :: index_o2x_So_stv !ocean salt-transfer velocity integer :: index_o2x_So_rhoeff !ocean effective density + integer :: index_o2x_So_tf300 !ocean thermal forcing at 300m ! ocn -> drv (BGC) @@ -208,6 +209,7 @@ subroutine mpaso_cpl_indices_set( ) index_o2x_So_htv = mct_avect_indexra(o2x,'So_htv') index_o2x_So_stv = mct_avect_indexra(o2x,'So_stv') index_o2x_So_rhoeff = mct_avect_indexra(o2x,'So_rhoeff') + index_o2x_So_tf300 = mct_avect_indexra(o2x,'So_tf300') index_o2x_So_algae1 = mct_avect_indexra(o2x,'So_algae1',perrWith='quiet') index_o2x_So_algae2 = mct_avect_indexra(o2x,'So_algae2',perrWith='quiet') diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index d1b140563bb7..3132847ecc8e 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -2689,7 +2689,8 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ avgRemovedRiverRunoffFlux, & avgRemovedIceRunoffFlux, & avgLandIceHeatFlux, & - avgRemovedIceRunoffHeatFlux + avgRemovedIceRunoffHeatFlux, & + avgThermalForcing300m real (kind=RKIND), dimension(:,:), pointer :: avgTracersSurfaceValue, avgSurfaceVelocity, & avgSSHGradient, avgOceanSurfacePhytoC, & @@ -2753,6 +2754,7 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ call mpas_pool_get_array(forcingPool, 'avgSurfaceVelocity', avgSurfaceVelocity) call mpas_pool_get_array(forcingPool, 'avgSSHGradient', avgSSHGradient) call mpas_pool_get_array(forcingPool, 'avgTotalFreshWaterTemperatureFlux', avgTotalFreshWaterTemperatureFlux) + call mpas_pool_get_array(forcingPool, 'avgThermalForcing300m', avgThermalForcing300m) if ( frazilIceActive ) then call mpas_pool_get_array(forcingPool, 'seaIceEnergy', seaIceEnergy) @@ -2933,6 +2935,8 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ o2x_o % rAttr(index_o2x_So_stv, n) = landIceTracerTransferVelocities(indexSaltTrans,i) o2x_o % rAttr(index_o2x_So_rhoeff, n) = 0.0_RKIND endif + o2x_o % rAttr(index_o2x_So_tf300, n) = avgThermalForcing300m(i) + !Fyke: test !write(stderrUnit,*) 'n=',n diff --git a/driver-mct/shr/seq_flds_mod.F90 b/driver-mct/shr/seq_flds_mod.F90 index dbfba0889d0c..6ecdd5598fc7 100644 --- a/driver-mct/shr/seq_flds_mod.F90 +++ b/driver-mct/shr/seq_flds_mod.F90 @@ -213,6 +213,7 @@ module seq_flds_mod character(CXX) :: seq_flds_x2g_states character(CXX) :: seq_flds_x2g_states_from_lnd character(CXX) :: seq_flds_x2g_states_from_ocn + character(CXX) :: seq_flds_x2g_tf_states_from_ocn character(CXX) :: seq_flds_x2g_fluxes character(CXX) :: seq_flds_x2g_fluxes_from_lnd @@ -348,6 +349,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) character(CXX) :: x2g_states = '' character(CXX) :: x2g_states_from_lnd = '' character(CXX) :: x2g_states_from_ocn = '' + character(CXX) :: x2g_tf_states_from_ocn = '' character(CXX) :: x2g_fluxes = '' character(CXX) :: x2g_fluxes_from_lnd = '' character(CXX) :: xao_albedo = '' @@ -2985,6 +2987,16 @@ subroutine seq_flds_set(nmlfile, ID, infodata) attname = 'So_rhoeff' call metadata_set(attname, longname, stdname, units) + name = 'So_tf300' + call seq_flds_add(o2x_states,trim(name)) + call seq_flds_add(x2g_states,trim(name)) + call seq_flds_add(x2g_tf_states_from_ocn,trim(name)) + longname = 'ocean thermal forcing at 300 m depth' + stdname = 'ocean_thermal_forcing_at_300m' + units = 'C' + attname = name + call metadata_set(attname, longname, stdname, units) + name = 'Fogx_qicelo' call seq_flds_add(g2x_fluxes,trim(name)) call seq_flds_add(x2o_fluxes,trim(name)) @@ -3937,6 +3949,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) seq_flds_x2g_states = trim(x2g_states) seq_flds_x2g_states_from_lnd = trim(x2g_states_from_lnd) seq_flds_x2g_states_from_ocn = trim(x2g_states_from_ocn) + seq_flds_x2g_tf_states_from_ocn = trim(x2g_tf_states_from_ocn) seq_flds_xao_states = trim(xao_states) seq_flds_xao_albedo = trim(xao_albedo) seq_flds_xao_diurnl = trim(xao_diurnl) @@ -4004,6 +4017,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) write(logunit,*) subname//': seq_flds_x2g_states_from_lnd= ',trim(seq_flds_x2g_states_from_lnd) write(logunit,*) subname//': seq_flds_l2x_states_to_glc= ',trim(seq_flds_l2x_states_to_glc) write(logunit,*) subname//': seq_flds_x2g_states_from_ocn= ',trim(seq_flds_x2g_states_from_ocn) + write(logunit,*) subname//': seq_flds_x2g_tf_states_from_ocn= ',trim(seq_flds_x2g_tf_states_from_ocn) write(logunit,*) subname//': seq_flds_x2g_fluxes= ',trim(seq_flds_x2g_fluxes) write(logunit,*) subname//': seq_flds_x2g_fluxes_from_lnd= ',trim(seq_flds_x2g_fluxes_from_lnd) write(logunit,*) subname//': seq_flds_l2x_fluxes_to_glc= ',trim(seq_flds_l2x_fluxes_to_glc) From 4c18c452806d37aaaf842c3e4cbdf0aa05bbf4b0 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 23 Apr 2024 00:10:46 -0500 Subject: [PATCH 03/19] Update MALI config to use new TF field This commit enables facemelting in MALI so that the new TF field will be used to calculate a melt rate. This is safe to enable in general, because for situations where thermal forcing is not calculated or not applicable, it will be zero and facemelting will in turn be zero. This commit also updates the MALI output stream to write out the TF and facemelting fields. Note that this commit also changes the MALI output stream interval to daily. While that might not be the ideal long-term production solution, it is likely the desired frequency for model development for the forseeable future. --- .../bld/namelist_files/namelist_defaults_mali.xml | 2 +- components/mpas-albany-landice/cime_config/buildnml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml index 0450eb44f116..1b0a9b19195b 100644 --- a/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml +++ b/components/mpas-albany-landice/bld/namelist_files/namelist_defaults_mali.xml @@ -98,7 +98,7 @@ 1.0 0.0 0.25 -'none' +'ismip6' .false. 1.18 0.0 diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 9489b6dfa8fd..8dcafdac1c7c 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -247,6 +247,9 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') From babbf3dd4bbccf3210fc3d5a74639a3712692987 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 23 Apr 2024 00:29:50 -0500 Subject: [PATCH 04/19] Define ocn2glc mapping for TF This commits defines the mapping for thermal forcing from ocean to glc. It defines a special mapper for thermal forcing state (ocn2glc_tf_smap) in CIME and MCT xml files. It also declares and allocates mapper_So2g_tf in prep_glc_mod but does not initialize or use it yet. The mapping file requires some special treatment: * it needs to use nearest neighbor mapping (which differs from most state remapping) * it needs to include grid_imask in the ocean scrip file to only consider ocean cells valid if they are deeper than 300m --- cime_config/config_grids.xml | 1 + driver-mct/cime_config/config_component.xml | 18 +++++++++++ .../cime_config/namelist_definition_drv.xml | 30 +++++++++++++++++++ driver-mct/main/prep_glc_mod.F90 | 2 ++ 4 files changed, 51 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index 0f1c3512ec8a..ee5931ee03bb 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -5569,6 +5569,7 @@ cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfaave.20240403.nc cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfbilin.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfneareststod.20240422.deeperThan300m.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_IcoswISC30E3r5_esmfaave.20240403.nc diff --git a/driver-mct/cime_config/config_component.xml b/driver-mct/cime_config/config_component.xml index 8cddad0abf89..666b2de17f26 100644 --- a/driver-mct/cime_config/config_component.xml +++ b/driver-mct/cime_config/config_component.xml @@ -1934,6 +1934,24 @@ ocn2glc state mapping file decomp type + + char + idmap_ignore + run_domain + env_run.xml + ocn2glc state mapping file for thermal forcing - the default value idmap_ignore, if set, will be ignored by buildnml and + will generate a runtime error if in fact a file is required for the given compset + + + + char + X,Y + Y + run_domain + env_run.xml + ocn2glc state mapping file decomp type + + char idmap diff --git a/driver-mct/cime_config/namelist_definition_drv.xml b/driver-mct/cime_config/namelist_definition_drv.xml index 7fbf83688c8a..5aabbe8bb98e 100644 --- a/driver-mct/cime_config/namelist_definition_drv.xml +++ b/driver-mct/cime_config/namelist_definition_drv.xml @@ -4590,6 +4590,36 @@ + + char + mapping + abs + seq_maps + + ocn to glc state mapping file for thermal forcing state fields + + + $OCN2GLC_TF_SMAPNAME + + + + + char + mapping + seq_maps + + The type of mapping desired, either "source" or "destination" mapping. + X is associated with rearrangement of the source grid to the + destination grid and then local mapping. Y is associated with mapping + on the source grid and then rearrangement and sum to the destination + grid. + + + $OCN2GLC_TF_SMAPTYPE + X + + + char mapping diff --git a/driver-mct/main/prep_glc_mod.F90 b/driver-mct/main/prep_glc_mod.F90 index 07aeb9890bda..4534319e53e2 100644 --- a/driver-mct/main/prep_glc_mod.F90 +++ b/driver-mct/main/prep_glc_mod.F90 @@ -77,6 +77,7 @@ module prep_glc_mod type(seq_map), pointer :: mapper_Sl2g type(seq_map), pointer :: mapper_Fl2g type(seq_map), pointer :: mapper_So2g + type(seq_map), pointer :: mapper_So2g_tf type(seq_map), pointer :: mapper_Fo2g type(seq_map), pointer :: mapper_Fg2l @@ -179,6 +180,7 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) allocate(mapper_Sl2g) allocate(mapper_Fl2g) allocate(mapper_So2g) + allocate(mapper_So2g_tf) allocate(mapper_Fo2g) allocate(mapper_Fg2l) From 8c10e45a5d1bf7c6aec482c4ac2b5d5574ca580a Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 23 Apr 2024 22:07:51 -0500 Subject: [PATCH 05/19] Implement new ocn2glc TF coupling 1. Differnetiate new ocn2glc TF coupling from existing ocn2glcshelf coupling Create ocn_c2_glc logical in cime_comp_mod. This controls the new ocn2glc TF (thermal forcing) coupling separately from the existing ocn2glcshelf coupling, which has its own ocn_c2_glcshelf flag already. The new TF coupling will be active whenever ocn is present and glc is prognostic. These flags are used to initialize different mappers independent of each other in prep_glc_init. Those flags are also now passed to prep_glc_calc_o2x_gx to control which mapping actually occurs. 2. Implement prep_glc_mrg_ocn The existing ocn2glcshelf coupling handled a number of operations in unusual ways because the fluxes themselves are calculated in the coupler, so it was missing some of the standard operations for simply passing fields between components. As such, adding the new TF coupling requires creating a prep_glc_mrg_ocn routine, which is responsible for transferring fields from o2x_g to x2g_g arrays. This routine was copied closely from the existing prep_glc_mrg_lnd routine. With this commit, the ocean TF field is successfully passed to MALI. --- driver-mct/main/cime_comp_mod.F90 | 25 +++- driver-mct/main/prep_glc_mod.F90 | 191 ++++++++++++++++++++++++++++-- 2 files changed, 201 insertions(+), 15 deletions(-) diff --git a/driver-mct/main/cime_comp_mod.F90 b/driver-mct/main/cime_comp_mod.F90 index 2131d0c86844..5b4d487aa0c7 100644 --- a/driver-mct/main/cime_comp_mod.F90 +++ b/driver-mct/main/cime_comp_mod.F90 @@ -433,6 +433,7 @@ module cime_comp_mod logical :: lnd_c2_rof ! .true. => lnd to rof coupling on logical :: lnd_c2_glc ! .true. => lnd to glc coupling on logical :: ocn_c2_atm ! .true. => ocn to atm coupling on + logical :: ocn_c2_glc ! .true. => ocn to glc coupling on logical :: ocn_c2_ice ! .true. => ocn to ice coupling on logical :: ocn_c2_glcshelf ! .true. => ocn to glc ice shelf coupling on logical :: ocn_c2_wav ! .true. => ocn to wav coupling on @@ -1731,6 +1732,7 @@ subroutine cime_init() lnd_c2_rof = .false. lnd_c2_glc = .false. ocn_c2_atm = .false. + ocn_c2_glc = .false. ocn_c2_ice = .false. ocn_c2_wav = .false. ocn_c2_rof = .false. @@ -1768,6 +1770,7 @@ subroutine cime_init() if (ocn_present) then if (atm_prognostic) ocn_c2_atm = .true. if (atm_present ) ocn_c2_atm = .true. ! needed for aoflux calc if aoflux=atm + if (glc_prognostic) ocn_c2_glc = .true. if (ice_prognostic) ocn_c2_ice = .true. if (wav_prognostic) ocn_c2_wav = .true. if (rofocn_prognostic) ocn_c2_rof = .true. @@ -1867,6 +1870,7 @@ subroutine cime_init() write(logunit,F0L)'lnd_c2_rof = ',lnd_c2_rof write(logunit,F0L)'lnd_c2_glc = ',lnd_c2_glc write(logunit,F0L)'ocn_c2_atm = ',ocn_c2_atm + write(logunit,F0L)'ocn_c2_glc = ',ocn_c2_glc write(logunit,F0L)'ocn_c2_ice = ',ocn_c2_ice write(logunit,F0L)'ocn_c2_glcshelf = ',ocn_c2_glcshelf write(logunit,F0L)'ocn_c2_wav = ',ocn_c2_wav @@ -1953,7 +1957,7 @@ subroutine cime_init() endif if ((ocn_c2_glcshelf .and. .not. glcshelf_c2_ocn) .or. (glcshelf_c2_ocn .and. .not. ocn_c2_glcshelf)) then ! Current logic will not allow this to be true, but future changes could make it so, which may be nonsensical - call shr_sys_abort(subname//' ERROR: if glc_c2_ocn must also have ocn_c2_glc and vice versa. '//& + call shr_sys_abort(subname//' ERROR: if glcshelf_c2_ocn must also have ocn_c2_glcshelf and vice versa. '//& 'Boundary layer fluxes calculated in coupler require input from both components.') endif if (rofice_present .and. .not.rof_present) then @@ -2022,7 +2026,7 @@ subroutine cime_init() call prep_rof_init(infodata, lnd_c2_rof, atm_c2_rof, ocn_c2_rof) - call prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) + call prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) call prep_wav_init(infodata, atm_c2_wav, ocn_c2_wav, ice_c2_wav) @@ -4210,12 +4214,16 @@ subroutine cime_run_ocnglc_coupling() if (glc_present) then + ! create o2x_gx for either ocn-glc coupling or ocn-glc shelf coupling + if (ocn_c2_glc .or. (ocn_c2_glcshelf .and. glcshelf_c2_ocn)) then + call prep_glc_calc_o2x_gx(ocn_c2_glc, ocn_c2_glcshelf, timer='CPL:glcprep_ocn2glc') !remap ocean fields to o2x_g at ocean couping interval + endif + + ! if ice-shelf coupling is on, now proceed to handle those calculations here in the coupler if (ocn_c2_glcshelf .and. glcshelf_c2_ocn) then ! the boundary flux calculations done in the coupler require inputs from both GLC and OCN, ! so they will only be valid if both OCN->GLC and GLC->OCN - call prep_glc_calc_o2x_gx(timer='CPL:glcprep_ocn2glc') !remap ocean fields to o2x_g at ocean couping interval - call prep_glc_calculate_subshelf_boundary_fluxes ! this is actual boundary layer flux calculation !this outputs !x2g_g/g2x_g, where latter is going @@ -4342,7 +4350,7 @@ subroutine cime_run_glc_setup_send(lnd2glc_averaged_now, prep_glc_accum_avg_call if (drv_threading) call seq_comm_setnthreads(nthreads_CPLID) ! NOTE - only create appropriate input to glc if the avg_alarm is on - if (lnd_c2_glc .or. ocn_c2_glcshelf) then + if (lnd_c2_glc .or. ocn_c2_glc .or. ocn_c2_glcshelf) then if (glcrun_avg_alarm) then call prep_glc_accum_avg(timer='CPL:glcprep_avg', & lnd2glc_averaged_now=lnd2glc_averaged_now) @@ -4355,6 +4363,13 @@ subroutine cime_run_glc_setup_send(lnd2glc_averaged_now, prep_glc_accum_avg_call call prep_glc_mrg_lnd(infodata, fractions_gx, timer_mrg='CPL:glcprep_mrgx2g') endif + if (ocn_c2_glc) then + ! note: o2x_gx is handled in prep_glc_calc_o2x_gx, which is called + ! from cime_run_ocnglc_coupling in this module + call prep_glc_mrg_ocn(infodata, fractions_gx, timer_mrg='CPL:glcprep_mrgocnx2g') + endif + + call component_diag(infodata, glc, flow='x2c', comment='send glc', & info_debug=info_debug, timer_diag='CPL:glcprep_diagav') diff --git a/driver-mct/main/prep_glc_mod.F90 b/driver-mct/main/prep_glc_mod.F90 index 4534319e53e2..5ed81f4c65e5 100644 --- a/driver-mct/main/prep_glc_mod.F90 +++ b/driver-mct/main/prep_glc_mod.F90 @@ -31,6 +31,7 @@ module prep_glc_mod public :: prep_glc_init public :: prep_glc_mrg_lnd + public :: prep_glc_mrg_ocn public :: prep_glc_accum_lnd public :: prep_glc_accum_ocn @@ -136,7 +137,7 @@ module prep_glc_mod !================================================================================================ - subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) + subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) !--------------------------------------------------------------- ! Description @@ -145,7 +146,8 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) ! Arguments type (seq_infodata_type) , intent(inout) :: infodata logical , intent(in) :: lnd_c2_glc ! .true. => lnd to glc coupling on - logical , intent(in) :: ocn_c2_glcshelf ! .true. => ocn to glc coupling on + logical , intent(in) :: ocn_c2_glc ! .true. => ocn to glc coupling on + logical , intent(in) :: ocn_c2_glcshelf ! .true. => ocn to glc shelf coupling on ! ! Local Variables integer :: eli, egi, eoi @@ -251,8 +253,8 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) end if - if (glc_present .and. ocn_c2_glcshelf) then - + ! setup needed for either kind of ocn2glc coupling + if (glc_present .and. (ocn_c2_glc .or. ocn_c2_glcshelf)) then call seq_comm_getData(CPLID, & mpicom=mpicom_CPLID, iamroot=iamroot_CPLID) @@ -277,6 +279,21 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) x2gacc_gx_cnt = 0 samegrid_go = .true. if (trim(ocn_gnam) /= trim(glc_gnam)) samegrid_go = .false. + end if + + ! setup needed for ocn2glc (TF) coupling + if (glc_present .and. ocn_c2_glc) then + if (iamroot_CPLID) then + write(logunit,*) ' ' + write(logunit,F00) 'Initializing mapper_So2g_tf' + end if + call seq_map_init_rcfile(mapper_So2g_tf, ocn(1), glc(1), & + 'seq_maps.rc','ocn2glc_tf_smapname:','ocn2glc_tf_smaptype:',samegrid_go, & + 'mapper_So2g_tf initialization',esmf_map_flag) + end if + + ! setup needed for ocn2glcshelf coupling + if (glc_present .and. ocn_c2_glcshelf) then if (iamroot_CPLID) then write(logunit,*) ' ' write(logunit,F00) 'Initializing mapper_So2g' @@ -291,7 +308,6 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) call seq_map_init_rcfile(mapper_Fo2g, ocn(1), glc(1), & 'seq_maps.rc','ocn2glc_fmapname:','ocn2glc_fmaptype:',samegrid_go, & 'mapper_Fo2g initialization',esmf_map_flag) - !Initialize module-level arrays associated with compute_melt_fluxes allocate(oceanTemperature(lsize_g)) allocate(oceanSalinity(lsize_g)) @@ -309,10 +325,9 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glcshelf) ! TODO: Can we allocate these only while used or are we worried about performance hit? ! TODO: add deallocates! - call shr_sys_flush(logunit) - end if + call shr_sys_flush(logunit) end subroutine prep_glc_init @@ -523,6 +538,154 @@ subroutine prep_glc_accum_avg(timer, lnd2glc_averaged_now) end subroutine prep_glc_accum_avg + !================================================================================================ + + subroutine prep_glc_mrg_ocn(infodata, fractions_gx, timer_mrg) + + !--------------------------------------------------------------- + ! Description + ! Merge glc inputs + ! + ! Arguments + type(seq_infodata_type) , intent(in) :: infodata + type(mct_aVect) , intent(in) :: fractions_gx(:) + character(len=*) , intent(in) :: timer_mrg + ! + ! Local Variables + integer :: egi, eoi, efi + type(mct_avect), pointer :: x2g_gx + character(*), parameter :: subname = '(prep_glc_mrg_ocn)' + !--------------------------------------------------------------- + + call t_drvstartf (trim(timer_mrg),barrier=mpicom_CPLID) + do egi = 1,num_inst_glc + ! Use fortran mod to address ensembles in merge + eoi = mod((egi-1),num_inst_ocn) + 1 + efi = mod((egi-1),num_inst_frc) + 1 + + x2g_gx => component_get_x2c_cx(glc(egi)) + call prep_glc_merge_ocn_forcing(o2x_gx(eoi), fractions_gx(efi), x2g_gx) + enddo + call t_drvstopf (trim(timer_mrg)) + + end subroutine prep_glc_mrg_ocn + + !================================================================================================ + + subroutine prep_glc_merge_ocn_forcing( o2x_g, fractions_g, x2g_g ) + + !----------------------------------------------------------------------- + ! Description + ! "Merge" ocean forcing for glc input. + ! + ! State fields are copied directly, meaning that averages are taken just over the + ! ocean-covered portion of the glc domain. + ! + ! Flux fields are downweighted by landfrac, which effectively sends a 0 flux from the + ! non-ocean-covered portion of the glc domain. + ! + ! Arguments + type(mct_aVect), intent(inout) :: o2x_g ! input + type(mct_aVect), intent(in) :: fractions_g + type(mct_aVect), intent(inout) :: x2g_g ! output + !----------------------------------------------------------------------- + + integer :: num_flux_fields + integer :: num_state_fields + integer :: nflds + integer :: i,n + integer :: mrgstr_index + integer :: index_o2x + integer :: index_x2g + integer :: index_ofrac + integer :: lsize + logical :: iamroot + logical, save :: first_time = .true. + character(CL),allocatable :: mrgstr(:) ! temporary string + character(CL) :: field ! string converted to char + character(*), parameter :: subname = '(prep_glc_merge_ocn_forcing) ' + + !----------------------------------------------------------------------- + + call seq_comm_getdata(CPLID, iamroot=iamroot) + lsize = mct_aVect_lsize(x2g_g) + + !num_flux_fields = shr_string_listGetNum(trim(seq_flds_x2g_fluxes_from_ocn)) + num_flux_fields = 0 + num_state_fields = shr_string_listGetNum(trim(seq_flds_x2g_tf_states_from_ocn)) + + if (first_time) then + nflds = num_flux_fields + num_state_fields + allocate(mrgstr(nflds)) + end if + + mrgstr_index = 1 + + do i = 1, num_state_fields + call seq_flds_getField(field, i, seq_flds_x2g_tf_states_from_ocn) + index_o2x = mct_aVect_indexRA(o2x_g, trim(field)) + index_x2g = mct_aVect_indexRA(x2g_g, trim(field)) + + if (first_time) then + mrgstr(mrgstr_index) = subname//'x2g%'//trim(field)//' =' // & + ' = o2x%'//trim(field) + end if + + do n = 1, lsize + x2g_g%rAttr(index_x2g,n) = o2x_g%rAttr(index_o2x,n) + end do + + mrgstr_index = mrgstr_index + 1 + enddo + + !index_lfrac = mct_aVect_indexRA(fractions_g,"lfrac") + !do i = 1, num_flux_fields + + ! call seq_flds_getField(field, i, seq_flds_x2g_fluxes_from_lnd) + ! index_l2x = mct_aVect_indexRA(l2x_g, trim(field)) + ! index_x2g = mct_aVect_indexRA(x2g_g, trim(field)) + + ! if (trim(field) == qice_fieldname) then + + ! if (first_time) then + ! mrgstr(mrgstr_index) = subname//'x2g%'//trim(field)//' =' // & + ! ' = l2x%'//trim(field) + ! end if + + ! ! treat qice as if it were a state variable, with a simple copy. + ! do n = 1, lsize + ! x2g_g%rAttr(index_x2g,n) = l2x_g%rAttr(index_l2x,n) + ! end do + + ! else + ! write(logunit,*) subname,' ERROR: Flux fields other than ', & + ! qice_fieldname, ' currently are not handled in lnd2glc remapping.' + ! write(logunit,*) '(Attempt to handle flux field <', trim(field), '>.)' + ! write(logunit,*) 'Substantial thought is needed to determine how to remap other fluxes' + ! write(logunit,*) 'in a smooth, conservative manner.' + ! call shr_sys_abort(subname//& + ! ' ERROR: Flux fields other than qice currently are not handled in lnd2glc remapping.') + ! endif ! qice_fieldname + + ! mrgstr_index = mrgstr_index + 1 + + !end do + + if (first_time) then + if (iamroot) then + write(logunit,'(A)') subname//' Summary:' + do i = 1,nflds + write(logunit,'(A)') trim(mrgstr(i)) + enddo + endif + deallocate(mrgstr) + endif + + first_time = .false. + + end subroutine prep_glc_merge_ocn_forcing + + !================================================================================================ subroutine prep_glc_mrg_lnd(infodata, fractions_gx, timer_mrg) @@ -606,7 +769,7 @@ subroutine prep_glc_merge_lnd_forcing( l2x_g, fractions_g, x2g_g ) mrgstr_index = 1 do i = 1, num_state_fields - call seq_flds_getField(field, i, seq_flds_x2g_states) + call seq_flds_getField(field, i, seq_flds_x2g_states_from_lnd) index_l2x = mct_aVect_indexRA(l2x_g, trim(field)) index_x2g = mct_aVect_indexRA(x2g_g, trim(field)) @@ -670,13 +833,15 @@ subroutine prep_glc_merge_lnd_forcing( l2x_g, fractions_g, x2g_g ) end subroutine prep_glc_merge_lnd_forcing - subroutine prep_glc_calc_o2x_gx(timer) + subroutine prep_glc_calc_o2x_gx(ocn_c2_glc, ocn_c2_glcshelf, timer) !--------------------------------------------------------------- ! Description ! Create o2x_gx ! Arguments character(len=*), intent(in) :: timer + logical, intent(in) :: ocn_c2_glc + logical, intent(in) :: ocn_c2_glcshelf character(*), parameter :: subname = '(prep_glc_calc_o2x_gx)' ! Local Variables @@ -686,8 +851,14 @@ subroutine prep_glc_calc_o2x_gx(timer) call t_drvstartf (trim(timer),barrier=mpicom_CPLID) do eoi = 1,num_inst_ocn o2x_ox => component_get_c2x_cx(ocn(eoi)) - call seq_map_map(mapper_So2g, o2x_ox, o2x_gx(eoi), & + if (ocn_c2_glc) then + call seq_map_map(mapper_So2g_tf, o2x_ox, o2x_gx(eoi), & + fldlist=seq_flds_x2g_tf_states_from_ocn,norm=.true.) + end if + if (ocn_c2_glcshelf) then + call seq_map_map(mapper_So2g, o2x_ox, o2x_gx(eoi), & fldlist=seq_flds_x2g_states_from_ocn,norm=.true.) + end if enddo call t_drvstopf (trim(timer)) From ffb207e2e8935f70bdf8089abc6bc5f142daf73a Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Sat, 11 May 2024 15:29:18 -0500 Subject: [PATCH 06/19] Make depth at which to calc TF namelist-configurable --- .../mpas-albany-landice/driver/glc_comp_mct.F | 2 +- .../driver/glc_cpl_indices.F | 4 +-- .../mpas-ocean/driver/mpaso_cpl_indices.F | 4 +-- components/mpas-ocean/driver/ocn_comp_mct.F | 6 ++-- components/mpas-ocean/src/Registry.xml | 8 +++-- .../shared/mpas_ocn_time_average_coupled.F | 32 ++++++++++--------- driver-mct/shr/seq_flds_mod.F90 | 6 ++-- 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/components/mpas-albany-landice/driver/glc_comp_mct.F b/components/mpas-albany-landice/driver/glc_comp_mct.F index 8bc9fc255d17..ba1043e52e7f 100644 --- a/components/mpas-albany-landice/driver/glc_comp_mct.F +++ b/components/mpas-albany-landice/driver/glc_comp_mct.F @@ -1410,7 +1410,7 @@ subroutine glc_import_mct(x2g_g, errorCode) n = n + 1 sfcMassBal(i) = x2g_g % rAttr(index_x2g_Flgl_qice, n) floatingBasalMassBal(i) = x2g_g % rAttr(index_x2g_Fogx_qiceli, n) - ismip6_2dThermalForcing(i) = x2g_g % rAttr(index_x2g_So_tf300, n) + ismip6_2dThermalForcing(i) = x2g_g % rAttr(index_x2g_So_tf2d, n) ! surfaceTemperature(i) = x2g_g % rAttr(index_x2g_Sl_tsrf, n) !JW basalOceanHeatflx(i) = x2g_g % rAttr(index_x2g_Fogo_qiceh, n) ! basalOceanHeatflx(i) = x2g_g % rAttr(index_x2g_Fogx_qicehi, n) diff --git a/components/mpas-albany-landice/driver/glc_cpl_indices.F b/components/mpas-albany-landice/driver/glc_cpl_indices.F index e84ac9174b19..459b534a7e07 100644 --- a/components/mpas-albany-landice/driver/glc_cpl_indices.F +++ b/components/mpas-albany-landice/driver/glc_cpl_indices.F @@ -22,7 +22,7 @@ module glc_cpl_indices integer, public :: index_x2g_So_htv = 0 !Ice shelf ocean heat transfer velocity integer, public :: index_x2g_So_stv = 0 !Ice shelf ocean salinity transfer velocity integer, public :: index_x2g_So_rhoeff = 0 !Ocean effective pressure - integer, public :: index_x2g_So_tf300 = 0 !Ocean thermal forcing at 300m + integer, public :: index_x2g_So_tf2d = 0 !Ocean thermal forcing at predefined critical depth integer, public :: index_x2g_Fogx_qiceli = 0 !Subshelf mass flux integer, public :: index_x2g_Fogx_qicehi = 0 !Subshelf heat flux for the ice sheet @@ -71,7 +71,7 @@ subroutine glc_cpl_indices_set( ) index_x2g_Fogx_qiceli = mct_avect_indexra(x2g,'Fogx_qiceli',perrwith='quiet') index_x2g_Fogx_qicehi = mct_avect_indexra(x2g,'Fogx_qicehi',perrwith='quiet') index_x2g_So_rhoeff = mct_avect_indexra(x2g,'So_rhoeff',perrwith='quiet') - index_x2g_So_tf300 = mct_avect_indexra(x2g,'So_tf300',perrwith='quiet') + index_x2g_So_tf2d = mct_avect_indexra(x2g,'So_tf2d',perrwith='quiet') !Following block of x2g/g2x vectors are used internally within coupler for subshelf melt flux !calculations (and so do not have directly-related export-side arrays) diff --git a/components/mpas-ocean/driver/mpaso_cpl_indices.F b/components/mpas-ocean/driver/mpaso_cpl_indices.F index c51aa68bf5b8..c5e84d2509d9 100644 --- a/components/mpas-ocean/driver/mpaso_cpl_indices.F +++ b/components/mpas-ocean/driver/mpaso_cpl_indices.F @@ -37,7 +37,7 @@ module mpaso_cpl_indices integer :: index_o2x_So_htv !ocean heat-transfer velocity integer :: index_o2x_So_stv !ocean salt-transfer velocity integer :: index_o2x_So_rhoeff !ocean effective density - integer :: index_o2x_So_tf300 !ocean thermal forcing at 300m + integer :: index_o2x_So_tf2d !ocean thermal forcing at predefined critical depth ! ocn -> drv (BGC) @@ -209,7 +209,7 @@ subroutine mpaso_cpl_indices_set( ) index_o2x_So_htv = mct_avect_indexra(o2x,'So_htv') index_o2x_So_stv = mct_avect_indexra(o2x,'So_stv') index_o2x_So_rhoeff = mct_avect_indexra(o2x,'So_rhoeff') - index_o2x_So_tf300 = mct_avect_indexra(o2x,'So_tf300') + index_o2x_So_tf2d = mct_avect_indexra(o2x,'So_tf2d') index_o2x_So_algae1 = mct_avect_indexra(o2x,'So_algae1',perrWith='quiet') index_o2x_So_algae2 = mct_avect_indexra(o2x,'So_algae2',perrWith='quiet') diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index 3132847ecc8e..d4f597db228e 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -2690,7 +2690,7 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ avgRemovedIceRunoffFlux, & avgLandIceHeatFlux, & avgRemovedIceRunoffHeatFlux, & - avgThermalForcing300m + avgThermalForcingAtCritDepth real (kind=RKIND), dimension(:,:), pointer :: avgTracersSurfaceValue, avgSurfaceVelocity, & avgSSHGradient, avgOceanSurfacePhytoC, & @@ -2754,7 +2754,7 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ call mpas_pool_get_array(forcingPool, 'avgSurfaceVelocity', avgSurfaceVelocity) call mpas_pool_get_array(forcingPool, 'avgSSHGradient', avgSSHGradient) call mpas_pool_get_array(forcingPool, 'avgTotalFreshWaterTemperatureFlux', avgTotalFreshWaterTemperatureFlux) - call mpas_pool_get_array(forcingPool, 'avgThermalForcing300m', avgThermalForcing300m) + call mpas_pool_get_array(forcingPool, 'avgThermalForcingAtCritDepth', avgThermalForcingAtCritDepth) if ( frazilIceActive ) then call mpas_pool_get_array(forcingPool, 'seaIceEnergy', seaIceEnergy) @@ -2935,7 +2935,7 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ o2x_o % rAttr(index_o2x_So_stv, n) = landIceTracerTransferVelocities(indexSaltTrans,i) o2x_o % rAttr(index_o2x_So_rhoeff, n) = 0.0_RKIND endif - o2x_o % rAttr(index_o2x_So_tf300, n) = avgThermalForcing300m(i) + o2x_o % rAttr(index_o2x_So_tf2d, n) = avgThermalForcingAtCritDepth(i) !Fyke: test diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index fea5c17b9569..83af31633793 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -807,6 +807,10 @@ description="If true, solid runoff from the Antarctic Ice Sheet (below 60S latitude) coming from the coupled is zeroed in the coupler import routines. To be used with data iceberg fluxes coming from the sea ice model." possible_values=".true. or .false." /> + - 300.0_RKIND) then - iLevel0300 = iLevel-1 + if(refBottomDepth(iLevel) > config_2d_thermal_forcing_depth) then + iLevelCritDepth = iLevel-1 exit end if end do @@ -457,13 +459,13 @@ subroutine ocn_time_average_coupled_accumulate(statePool, forcingPool, timeLevel ! calculate thermal forcing at identified level for each cell do iCell = 1, nCells ! ignore cells that are too shallow - if (iLevel0300 <= maxLevelCell(iCell)) then + if (iLevelCritDepth <= maxLevelCell(iCell)) then ! this uses the level shallower than the reference level. could interpolate instead ! note: assuming no LandIce cavity, but we may want to support that - freezingTemp = ocn_freezing_temperature(salinity=activeTracers(indexSalinity, iLevel0300, iCell), & - pressure=pressure(iLevel0300, iCell), inLandIceCavity=.false.) - avgThermalForcing300m(iCell) = ( avgThermalForcing300m(iCell) * nAccumulatedCoupled & - + activeTracers(indexTemperature, iLevel0300, iCell) - freezingTemp ) / ( nAccumulatedCoupled + 1) + freezingTemp = ocn_freezing_temperature(salinity=activeTracers(indexSalinity, iLevelCritDepth, iCell), & + pressure=pressure(iLevelCritDepth, iCell), inLandIceCavity=.false.) + avgThermalForcingAtCritDepth(iCell) = ( avgThermalForcingAtCritDepth(iCell) * nAccumulatedCoupled & + + activeTracers(indexTemperature, iLevelCritDepth, iCell) - freezingTemp ) / ( nAccumulatedCoupled + 1) end if end do !$omp end do diff --git a/driver-mct/shr/seq_flds_mod.F90 b/driver-mct/shr/seq_flds_mod.F90 index 6ecdd5598fc7..8d7404b8a854 100644 --- a/driver-mct/shr/seq_flds_mod.F90 +++ b/driver-mct/shr/seq_flds_mod.F90 @@ -2987,12 +2987,12 @@ subroutine seq_flds_set(nmlfile, ID, infodata) attname = 'So_rhoeff' call metadata_set(attname, longname, stdname, units) - name = 'So_tf300' + name = 'So_tf2d' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) call seq_flds_add(x2g_tf_states_from_ocn,trim(name)) - longname = 'ocean thermal forcing at 300 m depth' - stdname = 'ocean_thermal_forcing_at_300m' + longname = 'ocean thermal forcing at predefined critical depth' + stdname = 'ocean_thermal_forcing_at_critical_depth' units = 'C' attname = name call metadata_set(attname, longname, stdname, units) From 3257d65f4ed24d84140616e9e481573a86a14a69 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 13 May 2024 14:41:53 -0500 Subject: [PATCH 07/19] Better differentiate ocn->glc coupling for shelf and tf The entirety of existing ocn->glc coupling was for the ice-shelf coupling. To better differentiate the coupling in this branch based on thermal forcing, this commit ensures there is either a 'shelf' or 'tf' suffix on all ocn-glc coupling variables. --- cime_config/config_grids.xml | 48 ++++++------- driver-mct/cime_config/config_component.xml | 18 ++--- .../cime_config/namelist_definition_drv.xml | 20 +++--- driver-mct/main/cime_comp_mod.F90 | 19 +++--- driver-mct/main/prep_glc_mod.F90 | 68 +++++++++---------- driver-mct/shr/seq_flds_mod.F90 | 18 ++--- 6 files changed, 96 insertions(+), 95 deletions(-) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index ee5931ee03bb..58a2d7c7a8be 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -5503,15 +5503,15 @@ - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.aisgis20km_aave.190403.nc - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.aisgis20km_bilin.190403.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.aisgis20km_aave.190403.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.aisgis20km_bilin.190403.nc cpl/gridmaps/mpas.aisgis20km/map_mpas.aisgis20km_to_oEC60to30v3_aave.190403.nc cpl/gridmaps/mpas.aisgis20km/map_mpas.aisgis20km_to_oEC60to30v3_bilin.190403.nc - cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_to_mpas.aisgis20km_aave.190713.nc - cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_to_mpas.aisgis20km_bilin.190713.nc + cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_to_mpas.aisgis20km_aave.190713.nc + cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_to_mpas.aisgis20km_bilin.190713.nc cpl/gridmaps/mpas.aisgis20km/map_mpas.aisgis20km_to_oEC60to30v3wLI_aave.190713.nc cpl/gridmaps/mpas.aisgis20km/map_mpas.aisgis20km_to_oEC60to30v3wLI_bilin.190713.nc @@ -5528,8 +5528,8 @@ - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.gis20km_aave.181115.nc - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.gis20km_bilin.181115.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.gis20km_aave.181115.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_mpas.gis20km_bilin.181115.nc cpl/gridmaps/mpas.gis20km/map_mpas.gis20km_to_oEC60to30v3_aave.181115.nc cpl/gridmaps/mpas.gis20km/map_mpas.gis20km_to_oEC60to30v3_aave.181115.nc @@ -5556,8 +5556,8 @@ - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_aave.230510.nc - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_bilin.230510.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_aave.230510.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_bilin.230510.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_EC30to60E2r2_aave.230510.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_EC30to60E2r2_aave.230510.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_EC30to60E2r2_aave.230510.nc @@ -5567,8 +5567,8 @@ - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfaave.20240403.nc - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfbilin.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfaave.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfbilin.20240403.nc cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis20km_esmfneareststod.20240422.deeperThan300m.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis20km/map_gis20km_to_IcoswISC30E3r5_esmfaave.20240403.nc @@ -5604,8 +5604,8 @@ - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_gis1to10km_aave.200602.nc - cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_gis1to10km_bilin.200602.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_gis1to10km_aave.200602.nc + cpl/gridmaps/oEC60to30v3/map_oEC60to30v3_to_gis1to10km_bilin.200602.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_oEC60to30v3_aave.200602.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_oEC60to30v3_aave.200602.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_oEC60to30v3_aave.200602.nc @@ -5615,8 +5615,8 @@ - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10km_aave.210304.nc - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10km_bilin.210304.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10km_aave.210304.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10km_bilin.210304.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_EC30to60E2r2_aave.210304.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_EC30to60E2r2_aave.210304.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10km_to_EC30to60E2r2_aave.210304.nc @@ -5651,8 +5651,8 @@ - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10r02_aave.230725.nc - cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10r02_bilin.230725.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10r02_aave.230725.nc + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis1to10r02_bilin.230725.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10r02_to_EC30to60E2r2_aave.230725.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10r02_to_EC30to60E2r2_aave.230725.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10r02_to_EC30to60E2r2_aave.230725.nc @@ -5662,8 +5662,8 @@ - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfaave.20240403.nc - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfbilin.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfaave.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfbilin.20240403.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc @@ -5878,11 +5878,11 @@ cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240_aave.151209.nc - cpl/gridmaps/oQU240/map_oQU240_to_ais20km_aave.151209.nc + cpl/gridmaps/oQU240/map_oQU240_to_ais20km_aave.151209.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240_nearestdtos.151209.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240_nearestdtos.151209.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240_nearestdtos.151209.nc - cpl/gridmaps/oQU240/map_oQU240_to_ais20km_nearestdtos.151209.nc + cpl/gridmaps/oQU240/map_oQU240_to_ais20km_nearestdtos.151209.nc @@ -5892,8 +5892,8 @@ cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU120_nearestdtos.160331.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU120_nearestdtos.160331.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU120_nearestdtos.160331.nc - cpl/gridmaps/oQU120/map_oQU120_to_ais20km_aave.160331.nc - cpl/gridmaps/oQU120/map_oQU120_to_ais20km_neareststod.160331.nc + cpl/gridmaps/oQU120/map_oQU120_to_ais20km_aave.160331.nc + cpl/gridmaps/oQU120/map_oQU120_to_ais20km_neareststod.160331.nc @@ -5903,8 +5903,8 @@ cpl/gridmaps/mpas.ais20km/map_ais20km_to_oEC60to30v3wLI_nomask_nearestdtos.190207.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oEC60to30v3wLI_nomask_nearestdtos.190207.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oEC60to30v3wLI_nomask_nearestdtos.190207.nc - cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_nomask_to_ais20km_aave.190207.nc - cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_nomask_to_ais20km_neareststod.190207.nc + cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_nomask_to_ais20km_aave.190207.nc + cpl/gridmaps/oEC60to30v3wLI/map_oEC60to30v3wLI_nomask_to_ais20km_neareststod.190207.nc diff --git a/driver-mct/cime_config/config_component.xml b/driver-mct/cime_config/config_component.xml index 666b2de17f26..6fb75609e5a9 100644 --- a/driver-mct/cime_config/config_component.xml +++ b/driver-mct/cime_config/config_component.xml @@ -1898,40 +1898,40 @@ glc2ocn runoff mapping file decomp type for ice runoff - + char idmap_ignore run_domain env_run.xml - ocn2glc flux mapping file - the default value idmap_ignore, if set, will be ignored by buildnml and + ocn2glc shelf flux mapping file - the default value idmap_ignore, if set, will be ignored by buildnml and will generate a runtime error if in fact a file is required for the given compset - + char X,Y Y run_domain env_run.xml - ocn2glc flux mapping file decomp type + ocn2glc shelf flux mapping file decomp type - + char idmap_ignore run_domain env_run.xml - ocn2glc state mapping file - the default value idmap_ignore, if set, will be ignored by buildnml and + ocn2glc shelf state mapping file - the default value idmap_ignore, if set, will be ignored by buildnml and will generate a runtime error if in fact a file is required for the given compset - + char X,Y Y run_domain env_run.xml - ocn2glc state mapping file decomp type + ocn2glc shelf state mapping file decomp type @@ -1949,7 +1949,7 @@ Y run_domain env_run.xml - ocn2glc state mapping file decomp type + ocn2glc thermal forcing state mapping file decomp type diff --git a/driver-mct/cime_config/namelist_definition_drv.xml b/driver-mct/cime_config/namelist_definition_drv.xml index 5aabbe8bb98e..316f24a0f583 100644 --- a/driver-mct/cime_config/namelist_definition_drv.xml +++ b/driver-mct/cime_config/namelist_definition_drv.xml @@ -4530,20 +4530,20 @@ - + char mapping abs seq_maps - ocn to glc flux mapping file for fluxes + ocn to glc shelf mapping file for fluxes - $OCN2GLC_FMAPNAME + $OCN2GLC_SHELF_FMAPNAME - + char mapping seq_maps @@ -4555,25 +4555,25 @@ grid. - $OCN2GLC_FMAPTYPE + $OCN2GLC_SHELF_FMAPTYPE X - + char mapping abs seq_maps - ocn to glc state mapping file for states + ocn to glc shelf mapping file for states - $OCN2GLC_SMAPNAME + $OCN2GLC_SHELF_SMAPNAME - + char mapping seq_maps @@ -4585,7 +4585,7 @@ grid. - $OCN2GLC_SMAPTYPE + $OCN2GLC_SHELF_SMAPTYPE X diff --git a/driver-mct/main/cime_comp_mod.F90 b/driver-mct/main/cime_comp_mod.F90 index 5b4d487aa0c7..fc69cc4c2cb3 100644 --- a/driver-mct/main/cime_comp_mod.F90 +++ b/driver-mct/main/cime_comp_mod.F90 @@ -433,8 +433,8 @@ module cime_comp_mod logical :: lnd_c2_rof ! .true. => lnd to rof coupling on logical :: lnd_c2_glc ! .true. => lnd to glc coupling on logical :: ocn_c2_atm ! .true. => ocn to atm coupling on - logical :: ocn_c2_glc ! .true. => ocn to glc coupling on logical :: ocn_c2_ice ! .true. => ocn to ice coupling on + logical :: ocn_c2_glctf ! .true. => ocn to glc thermal forcing coupling on logical :: ocn_c2_glcshelf ! .true. => ocn to glc ice shelf coupling on logical :: ocn_c2_wav ! .true. => ocn to wav coupling on logical :: ocn_c2_rof ! .true. => ocn to rof coupling on @@ -1732,8 +1732,9 @@ subroutine cime_init() lnd_c2_rof = .false. lnd_c2_glc = .false. ocn_c2_atm = .false. - ocn_c2_glc = .false. ocn_c2_ice = .false. + ocn_c2_glctf = .false. + ocn_c2_glcshelf = .false. ocn_c2_wav = .false. ocn_c2_rof = .false. ice_c2_atm = .false. @@ -1770,7 +1771,7 @@ subroutine cime_init() if (ocn_present) then if (atm_prognostic) ocn_c2_atm = .true. if (atm_present ) ocn_c2_atm = .true. ! needed for aoflux calc if aoflux=atm - if (glc_prognostic) ocn_c2_glc = .true. + if (glc_prognostic) ocn_c2_glctf = .true. if (ice_prognostic) ocn_c2_ice = .true. if (wav_prognostic) ocn_c2_wav = .true. if (rofocn_prognostic) ocn_c2_rof = .true. @@ -1870,7 +1871,7 @@ subroutine cime_init() write(logunit,F0L)'lnd_c2_rof = ',lnd_c2_rof write(logunit,F0L)'lnd_c2_glc = ',lnd_c2_glc write(logunit,F0L)'ocn_c2_atm = ',ocn_c2_atm - write(logunit,F0L)'ocn_c2_glc = ',ocn_c2_glc + write(logunit,F0L)'ocn_c2_glctf = ',ocn_c2_glctf write(logunit,F0L)'ocn_c2_ice = ',ocn_c2_ice write(logunit,F0L)'ocn_c2_glcshelf = ',ocn_c2_glcshelf write(logunit,F0L)'ocn_c2_wav = ',ocn_c2_wav @@ -2026,7 +2027,7 @@ subroutine cime_init() call prep_rof_init(infodata, lnd_c2_rof, atm_c2_rof, ocn_c2_rof) - call prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) + call prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glctf, ocn_c2_glcshelf) call prep_wav_init(infodata, atm_c2_wav, ocn_c2_wav, ice_c2_wav) @@ -4215,8 +4216,8 @@ subroutine cime_run_ocnglc_coupling() if (glc_present) then ! create o2x_gx for either ocn-glc coupling or ocn-glc shelf coupling - if (ocn_c2_glc .or. (ocn_c2_glcshelf .and. glcshelf_c2_ocn)) then - call prep_glc_calc_o2x_gx(ocn_c2_glc, ocn_c2_glcshelf, timer='CPL:glcprep_ocn2glc') !remap ocean fields to o2x_g at ocean couping interval + if (ocn_c2_glctf .or. (ocn_c2_glcshelf .and. glcshelf_c2_ocn)) then + call prep_glc_calc_o2x_gx(ocn_c2_glctf, ocn_c2_glcshelf, timer='CPL:glcprep_ocn2glc') !remap ocean fields to o2x_g at ocean couping interval endif ! if ice-shelf coupling is on, now proceed to handle those calculations here in the coupler @@ -4350,7 +4351,7 @@ subroutine cime_run_glc_setup_send(lnd2glc_averaged_now, prep_glc_accum_avg_call if (drv_threading) call seq_comm_setnthreads(nthreads_CPLID) ! NOTE - only create appropriate input to glc if the avg_alarm is on - if (lnd_c2_glc .or. ocn_c2_glc .or. ocn_c2_glcshelf) then + if (lnd_c2_glc .or. ocn_c2_glctf .or. ocn_c2_glcshelf) then if (glcrun_avg_alarm) then call prep_glc_accum_avg(timer='CPL:glcprep_avg', & lnd2glc_averaged_now=lnd2glc_averaged_now) @@ -4363,7 +4364,7 @@ subroutine cime_run_glc_setup_send(lnd2glc_averaged_now, prep_glc_accum_avg_call call prep_glc_mrg_lnd(infodata, fractions_gx, timer_mrg='CPL:glcprep_mrgx2g') endif - if (ocn_c2_glc) then + if (ocn_c2_glctf) then ! note: o2x_gx is handled in prep_glc_calc_o2x_gx, which is called ! from cime_run_ocnglc_coupling in this module call prep_glc_mrg_ocn(infodata, fractions_gx, timer_mrg='CPL:glcprep_mrgocnx2g') diff --git a/driver-mct/main/prep_glc_mod.F90 b/driver-mct/main/prep_glc_mod.F90 index 5ed81f4c65e5..6ce136305d0d 100644 --- a/driver-mct/main/prep_glc_mod.F90 +++ b/driver-mct/main/prep_glc_mod.F90 @@ -54,8 +54,8 @@ module prep_glc_mod public :: prep_glc_get_mapper_Sl2g public :: prep_glc_get_mapper_Fl2g - public :: prep_glc_get_mapper_So2g - public :: prep_glc_get_mapper_Fo2g + public :: prep_glc_get_mapper_So2g_shelf + public :: prep_glc_get_mapper_Fo2g_shelf public :: prep_glc_calculate_subshelf_boundary_fluxes @@ -77,9 +77,9 @@ module prep_glc_mod ! mappers type(seq_map), pointer :: mapper_Sl2g type(seq_map), pointer :: mapper_Fl2g - type(seq_map), pointer :: mapper_So2g + type(seq_map), pointer :: mapper_So2g_shelf + type(seq_map), pointer :: mapper_Fo2g_shelf type(seq_map), pointer :: mapper_So2g_tf - type(seq_map), pointer :: mapper_Fo2g type(seq_map), pointer :: mapper_Fg2l ! attribute vectors @@ -137,7 +137,7 @@ module prep_glc_mod !================================================================================================ - subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) + subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glctf, ocn_c2_glcshelf) !--------------------------------------------------------------- ! Description @@ -146,7 +146,7 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) ! Arguments type (seq_infodata_type) , intent(inout) :: infodata logical , intent(in) :: lnd_c2_glc ! .true. => lnd to glc coupling on - logical , intent(in) :: ocn_c2_glc ! .true. => ocn to glc coupling on + logical , intent(in) :: ocn_c2_glctf ! .true. => ocn to glc thermal forcing coupling on logical , intent(in) :: ocn_c2_glcshelf ! .true. => ocn to glc shelf coupling on ! ! Local Variables @@ -181,9 +181,9 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) allocate(mapper_Sl2g) allocate(mapper_Fl2g) - allocate(mapper_So2g) + allocate(mapper_So2g_shelf) allocate(mapper_So2g_tf) - allocate(mapper_Fo2g) + allocate(mapper_Fo2g_shelf) allocate(mapper_Fg2l) smb_renormalize = prep_glc_do_renormalize_smb(infodata) @@ -254,7 +254,7 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) end if ! setup needed for either kind of ocn2glc coupling - if (glc_present .and. (ocn_c2_glc .or. ocn_c2_glcshelf)) then + if (glc_present .and. (ocn_c2_glctf .or. ocn_c2_glcshelf)) then call seq_comm_getData(CPLID, & mpicom=mpicom_CPLID, iamroot=iamroot_CPLID) @@ -281,8 +281,8 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) if (trim(ocn_gnam) /= trim(glc_gnam)) samegrid_go = .false. end if - ! setup needed for ocn2glc (TF) coupling - if (glc_present .and. ocn_c2_glc) then + ! setup needed for ocn2glc TF coupling + if (glc_present .and. ocn_c2_glctf) then if (iamroot_CPLID) then write(logunit,*) ' ' write(logunit,F00) 'Initializing mapper_So2g_tf' @@ -296,18 +296,18 @@ subroutine prep_glc_init(infodata, lnd_c2_glc, ocn_c2_glc, ocn_c2_glcshelf) if (glc_present .and. ocn_c2_glcshelf) then if (iamroot_CPLID) then write(logunit,*) ' ' - write(logunit,F00) 'Initializing mapper_So2g' + write(logunit,F00) 'Initializing mapper_So2g_shelf' end if - call seq_map_init_rcfile(mapper_So2g, ocn(1), glc(1), & - 'seq_maps.rc','ocn2glc_smapname:','ocn2glc_smaptype:',samegrid_go, & - 'mapper_So2g initialization',esmf_map_flag) + call seq_map_init_rcfile(mapper_So2g_shelf, ocn(1), glc(1), & + 'seq_maps.rc','ocn2glc_shelf_smapname:','ocn2glc_shelf_smaptype:',samegrid_go, & + 'mapper_So2g_shelf initialization',esmf_map_flag) if (iamroot_CPLID) then write(logunit,*) ' ' - write(logunit,F00) 'Initializing mapper_Fo2g' + write(logunit,F00) 'Initializing mapper_Fo2g_shelf' end if - call seq_map_init_rcfile(mapper_Fo2g, ocn(1), glc(1), & - 'seq_maps.rc','ocn2glc_fmapname:','ocn2glc_fmaptype:',samegrid_go, & - 'mapper_Fo2g initialization',esmf_map_flag) + call seq_map_init_rcfile(mapper_Fo2g_shelf, ocn(1), glc(1), & + 'seq_maps.rc','ocn2glc_shelf_fmapname:','ocn2glc_shelf_fmaptype:',samegrid_go, & + 'mapper_Fo2g_shelf initialization',esmf_map_flag) !Initialize module-level arrays associated with compute_melt_fluxes allocate(oceanTemperature(lsize_g)) allocate(oceanSalinity(lsize_g)) @@ -833,14 +833,14 @@ subroutine prep_glc_merge_lnd_forcing( l2x_g, fractions_g, x2g_g ) end subroutine prep_glc_merge_lnd_forcing - subroutine prep_glc_calc_o2x_gx(ocn_c2_glc, ocn_c2_glcshelf, timer) + subroutine prep_glc_calc_o2x_gx(ocn_c2_glctf, ocn_c2_glcshelf, timer) !--------------------------------------------------------------- ! Description ! Create o2x_gx ! Arguments character(len=*), intent(in) :: timer - logical, intent(in) :: ocn_c2_glc + logical, intent(in) :: ocn_c2_glctf logical, intent(in) :: ocn_c2_glcshelf character(*), parameter :: subname = '(prep_glc_calc_o2x_gx)' @@ -851,13 +851,13 @@ subroutine prep_glc_calc_o2x_gx(ocn_c2_glc, ocn_c2_glcshelf, timer) call t_drvstartf (trim(timer),barrier=mpicom_CPLID) do eoi = 1,num_inst_ocn o2x_ox => component_get_c2x_cx(ocn(eoi)) - if (ocn_c2_glc) then + if (ocn_c2_glctf) then call seq_map_map(mapper_So2g_tf, o2x_ox, o2x_gx(eoi), & fldlist=seq_flds_x2g_tf_states_from_ocn,norm=.true.) end if if (ocn_c2_glcshelf) then - call seq_map_map(mapper_So2g, o2x_ox, o2x_gx(eoi), & - fldlist=seq_flds_x2g_states_from_ocn,norm=.true.) + call seq_map_map(mapper_So2g_shelf, o2x_ox, o2x_gx(eoi), & + fldlist=seq_flds_x2g_shelf_states_from_ocn,norm=.true.) end if enddo @@ -1023,8 +1023,8 @@ subroutine prep_glc_calculate_subshelf_boundary_fluxes !Done here instead of in glc-frequency mapping so it happens within ocean coupling interval. ! Also could map o2x_ox->o2x_gx(1) but using x2g_gx as destination allows us to see ! these fields on the GLC grid of the coupler history file, which helps with debugging. - call seq_map_map(mapper_So2g, o2x_ox, x2g_gx, & - fldlist=seq_flds_x2g_states_from_ocn,norm=.true.) + call seq_map_map(mapper_So2g_shelf, o2x_ox, x2g_gx, & + fldlist=seq_flds_x2g_shelf_states_from_ocn,norm=.true.) ! inputs to melt flux calculation index_x2g_So_blt = mct_avect_indexra(x2g_gx,'So_blt',perrwith='quiet') @@ -1622,15 +1622,15 @@ function prep_glc_get_mapper_Fl2g() prep_glc_get_mapper_Fl2g => mapper_Fl2g end function prep_glc_get_mapper_Fl2g - function prep_glc_get_mapper_So2g() - type(seq_map), pointer :: prep_glc_get_mapper_So2g - prep_glc_get_mapper_So2g=> mapper_So2g - end function prep_glc_get_mapper_So2g + function prep_glc_get_mapper_So2g_shelf() + type(seq_map), pointer :: prep_glc_get_mapper_So2g_shelf + prep_glc_get_mapper_So2g_shelf=> mapper_So2g_shelf + end function prep_glc_get_mapper_So2g_shelf - function prep_glc_get_mapper_Fo2g() - type(seq_map), pointer :: prep_glc_get_mapper_Fo2g - prep_glc_get_mapper_Fo2g=> mapper_Fo2g - end function prep_glc_get_mapper_Fo2g + function prep_glc_get_mapper_Fo2g_shelf() + type(seq_map), pointer :: prep_glc_get_mapper_Fo2g_shelf + prep_glc_get_mapper_Fo2g_shelf=> mapper_Fo2g_shelf + end function prep_glc_get_mapper_Fo2g_shelf !*********************************************************************** ! diff --git a/driver-mct/shr/seq_flds_mod.F90 b/driver-mct/shr/seq_flds_mod.F90 index 8d7404b8a854..4fb616b9cec0 100644 --- a/driver-mct/shr/seq_flds_mod.F90 +++ b/driver-mct/shr/seq_flds_mod.F90 @@ -212,7 +212,7 @@ module seq_flds_mod character(CXX) :: seq_flds_g2o_ice_fluxes character(CXX) :: seq_flds_x2g_states character(CXX) :: seq_flds_x2g_states_from_lnd - character(CXX) :: seq_flds_x2g_states_from_ocn + character(CXX) :: seq_flds_x2g_shelf_states_from_ocn character(CXX) :: seq_flds_x2g_tf_states_from_ocn character(CXX) :: seq_flds_x2g_fluxes character(CXX) :: seq_flds_x2g_fluxes_from_lnd @@ -348,7 +348,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) character(CXX) :: g2o_ice_fluxes = '' character(CXX) :: x2g_states = '' character(CXX) :: x2g_states_from_lnd = '' - character(CXX) :: x2g_states_from_ocn = '' + character(CXX) :: x2g_shelf_states_from_ocn = '' character(CXX) :: x2g_tf_states_from_ocn = '' character(CXX) :: x2g_fluxes = '' character(CXX) :: x2g_fluxes_from_lnd = '' @@ -2940,7 +2940,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) name = 'So_blt' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) - call seq_flds_add(x2g_states_from_ocn,trim(name)) + call seq_flds_add(x2g_shelf_states_from_ocn,trim(name)) longname = 'Ice shelf boundary layer ocean temperature' stdname = 'Ice_shelf_boundary_layer_ocean_temperature' units = 'C' @@ -2950,7 +2950,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) name = 'So_bls' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) - call seq_flds_add(x2g_states_from_ocn,trim(name)) + call seq_flds_add(x2g_shelf_states_from_ocn,trim(name)) longname = 'Ice shelf boundary layer ocean salinity' stdname = 'Ice_shelf_boundary_layer_ocean_salinity' units = 'psu' @@ -2960,7 +2960,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) name = 'So_htv' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) - call seq_flds_add(x2g_states_from_ocn,trim(name)) + call seq_flds_add(x2g_shelf_states_from_ocn,trim(name)) longname = 'Ice shelf ocean heat transfer velocity' stdname = 'Ice_shelf_ocean_heat_transfer_velocity' units = 'm/s' @@ -2970,7 +2970,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) name = 'So_stv' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) - call seq_flds_add(x2g_states_from_ocn,trim(name)) + call seq_flds_add(x2g_shelf_states_from_ocn,trim(name)) longname = 'Ice shelf ocean salinity transfer velocity' stdname = 'Ice_shelf_ocean_salinity_transfer_velocity' units = 'm/s' @@ -2980,7 +2980,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) name = 'So_rhoeff' call seq_flds_add(o2x_states,trim(name)) call seq_flds_add(x2g_states,trim(name)) - call seq_flds_add(x2g_states_from_ocn,trim(name)) + call seq_flds_add(x2g_shelf_states_from_ocn,trim(name)) longname = 'Ocean effective pressure' stdname = 'Ocean_effective_pressure' units = 'Pa' @@ -3948,7 +3948,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) seq_flds_g2x_states_to_lnd = trim(g2x_states_to_lnd) seq_flds_x2g_states = trim(x2g_states) seq_flds_x2g_states_from_lnd = trim(x2g_states_from_lnd) - seq_flds_x2g_states_from_ocn = trim(x2g_states_from_ocn) + seq_flds_x2g_shelf_states_from_ocn = trim(x2g_shelf_states_from_ocn) seq_flds_x2g_tf_states_from_ocn = trim(x2g_tf_states_from_ocn) seq_flds_xao_states = trim(xao_states) seq_flds_xao_albedo = trim(xao_albedo) @@ -4016,7 +4016,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata) write(logunit,*) subname//': seq_flds_x2g_states= ',trim(seq_flds_x2g_states) write(logunit,*) subname//': seq_flds_x2g_states_from_lnd= ',trim(seq_flds_x2g_states_from_lnd) write(logunit,*) subname//': seq_flds_l2x_states_to_glc= ',trim(seq_flds_l2x_states_to_glc) - write(logunit,*) subname//': seq_flds_x2g_states_from_ocn= ',trim(seq_flds_x2g_states_from_ocn) + write(logunit,*) subname//': seq_flds_x2g_shelf_states_from_ocn= ',trim(seq_flds_x2g_shelf_states_from_ocn) write(logunit,*) subname//': seq_flds_x2g_tf_states_from_ocn= ',trim(seq_flds_x2g_tf_states_from_ocn) write(logunit,*) subname//': seq_flds_x2g_fluxes= ',trim(seq_flds_x2g_fluxes) write(logunit,*) subname//': seq_flds_x2g_fluxes_from_lnd= ',trim(seq_flds_x2g_fluxes_from_lnd) From ccc0416cfa1725487e176b91726387b3f9e4add7 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 13 May 2024 16:08:27 -0500 Subject: [PATCH 08/19] Add TL319_IcoswISC30E3r5_gis1to10kmR2 grid specification This allows testing with a MALI mesh where fjords are resolved. --- cime_config/config_grids.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index 58a2d7c7a8be..e1727e58ae3a 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -1909,6 +1909,16 @@ IcoswISC30E3r5 + + TL319 + TL319 + IcoswISC30E3r5 + JRA025 + mpas.gis1to10kmR2 + null + IcoswISC30E3r5 + + ne30np4.pg2 r05 @@ -5664,6 +5674,7 @@ cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfaave.20240403.nc cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfbilin.20240403.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_gis1to10kmR2_esmfneareststod.20240422.deeperThan300m.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc cpl/gridmaps/mpas.gis1to10km/map_gis1to10kmR2_to_IcoswISC30E3r5_esmfaave.20240403.nc From 90c1a1d386ba80b023aa24436379ac93f6563c5d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 13 May 2024 20:51:46 -0500 Subject: [PATCH 09/19] Update mpas.gis1to10kmR2 mesh to include subglacial runoff field The facemelting parameterization requires a subglacial runoff field as an input. Eventually, we may have this calculated prognostically in E3SM from MALI and/or ELM, but that is not planned for the near-term. Until then, a reasonable approximation is to use a constant historical climatological field. This commit updates the mpas.gis1to10kmR2 input file to include a ismip6Runoff field provided by ISMIP6. The field used is a 1995-2014 mean from the MIROC5 model, which was bias-corrected to match MAR over that period. See www.the-cryosphere.net/14/985/2020/ Fig. 2 and related text for details. --- components/mpas-albany-landice/cime_config/buildnml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-albany-landice/cime_config/buildnml b/components/mpas-albany-landice/cime_config/buildnml index 8dcafdac1c7c..4256df0f2830 100755 --- a/components/mpas-albany-landice/cime_config/buildnml +++ b/components/mpas-albany-landice/cime_config/buildnml @@ -88,7 +88,7 @@ def buildnml(case, caseroot, compname): decomp_date += '051920' decomp_prefix += 'mpasli.graph.info.' elif glc_grid == 'mpas.gis1to10kmR2': - grid_date += '20230202' + grid_date += '20240513' grid_prefix += 'gis_1to10km_r02' decomp_date += '020223' decomp_prefix += 'mpasli.graph.info.' From 5c03d4039c758adf7df139e87f475cd62574c7d4 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 19 Aug 2024 23:00:09 -0500 Subject: [PATCH 10/19] Correct indexing for critical depth This uses the layer that the desired depth is in, rather than the layer above it. Co-authored-by: Xylar Asay-Davis --- .../mpas-ocean/src/shared/mpas_ocn_time_average_coupled.F | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_time_average_coupled.F b/components/mpas-ocean/src/shared/mpas_ocn_time_average_coupled.F index 8a731990bb44..746784f74092 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_time_average_coupled.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_time_average_coupled.F @@ -447,10 +447,10 @@ subroutine ocn_time_average_coupled_accumulate(statePool, forcingPool, timeLevel ! find vertical level that is just above the critical depth reference level ! this does not account for depression due to ice shelf cavities or sea ice - iLevelCritDepth = 1 + iLevelCritDepth = nVertLevels ! default to deepest layer if we don't find the desired depth do iLevel = 1, nVertLevels if(refBottomDepth(iLevel) > config_2d_thermal_forcing_depth) then - iLevelCritDepth = iLevel-1 + iLevelCritDepth = iLevel exit end if end do From 3f2615d31b8901a9978e8bb53534a42cadddcc93 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Tue, 10 Sep 2024 16:12:26 -0500 Subject: [PATCH 11/19] Add config_2d_thermal_forcing_depth to namelist system --- components/mpas-ocean/bld/build-namelist | 1 + components/mpas-ocean/bld/build-namelist-section | 1 + .../bld/namelist_files/namelist_defaults_mpaso.xml | 1 + .../bld/namelist_files/namelist_definition_mpaso.xml | 8 ++++++++ 4 files changed, 11 insertions(+) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 460b9ecda428..011396d879f0 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -731,6 +731,7 @@ if (($OCN_ICEBERG eq 'true') && ($OCN_FORCING eq 'active_atm')) { } else { add_default($nl, 'config_remove_ais_ice_runoff', 'val'=>".false."); } +add_default($nl, 'config_2d_thermal_forcing_depth'); ###################################### # Namelist group: shortwaveRadiation # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index c5dad5d935a9..115bd09c96a6 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -239,6 +239,7 @@ add_default($nl, 'config_sgr_salinity_prescribed'); add_default($nl, 'config_remove_ais_river_runoff'); add_default($nl, 'config_remove_ais_ice_runoff'); +add_default($nl, 'config_2d_thermal_forcing_depth'); ###################################### # Namelist group: shortwaveRadiation # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index fd2785616655..12a97836035c 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -354,6 +354,7 @@ .false. .false. +300.0 'jerlov' diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index bea1e98d9de8..45e4caf798a5 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1271,6 +1271,14 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + +Depth at which to pass 2d thermal forcing to the coupler for use in the GLC component. Note that mapping files for this field must be created with a mask to exclude ocean grid cells shallower than this value and thus must be regenerated if this value is changed. + +Valid values: any non-negative value +Default: Defined in namelist_defaults.xml + + From b6e410046f468f8faff395295b1b3b93dbf7c1a0 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 11 Sep 2024 16:42:32 -0500 Subject: [PATCH 12/19] Add config_glc_thermal_forcing_coupling_mode option This commit adds an MPAS-Ocean namelist option for activating the OCN-GLC TF coupling. This option controls if E3SM should enable the OCN-GLC TF coupling and also makes the associated TF calculations conditional on the option being active. The option defaults to false and there currently are not any compsets that activate it, so it can only be enabled with a namelist usermod at present. --- components/mpas-ocean/driver/ocn_comp_mct.F | 22 ++++- components/mpas-ocean/src/Registry.xml | 4 + .../shared/mpas_ocn_time_average_coupled.F | 84 ++++++++++--------- driver-mct/main/cime_comp_mod.F90 | 1 - 4 files changed, 68 insertions(+), 43 deletions(-) diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index d4f597db228e..54cae42dab21 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -223,6 +223,7 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )!{{{ logical, pointer :: config_use_activeTracers_surface_restoring logical, pointer :: config_use_surface_salinity_monthly_restoring character (len=StrKIND), pointer :: config_land_ice_flux_mode + character (len=StrKIND), pointer :: config_glc_thermal_forcing_coupling_mode ! ssh coupling interval initialization integer, pointer :: index_avgZonalSSHGradient, index_avgMeridionalSSHGradient @@ -878,6 +879,16 @@ end subroutine xml_stream_get_attributes call mpas_log_write('ERROR: unknown land_ice_flux_mode: ' // trim(config_land_ice_flux_mode), MPAS_LOG_CRIT) end if + call mpas_pool_get_config(domain % configs, 'config_glc_thermal_forcing_coupling_mode', config_glc_thermal_forcing_coupling_mode) + if ( trim(config_glc_thermal_forcing_coupling_mode) == 'off' ) then + call seq_infodata_PutData(infodata, ocn_c2_glctf=.false.) + else if ( trim(config_glc_thermal_forcing_coupling_mode) == '2d' ) then + call seq_infodata_PutData(infodata, ocn_c2_glctf=.true.) + else + call mpas_log_write('ERROR: unknown config_glc_thermal_forcing_coupling_mode: ' // & + trim(config_glc_thermal_forcing_coupling_mode), MPAS_LOG_CRIT) + end if + !----------------------------------------------------------------------- ! ! get initial state from driver @@ -2709,6 +2720,7 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ config_use_MacroMoleculesTracers_sea_ice_coupling character (len=StrKIND), pointer :: config_land_ice_flux_mode + character (len=StrKIND), pointer :: config_glc_thermal_forcing_coupling_mode logical :: keepFrazil @@ -2719,6 +2731,8 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ call mpas_pool_get_config(domain % configs, 'config_land_ice_flux_mode', config_land_ice_flux_mode) call mpas_pool_get_config(domain % configs, 'config_remove_ais_river_runoff', config_remove_ais_river_runoff) call mpas_pool_get_config(domain % configs, 'config_remove_ais_ice_runoff', config_remove_ais_ice_runoff) + call mpas_pool_get_config(domain % configs, 'config_glc_thermal_forcing_coupling_mode', & + config_glc_thermal_forcing_coupling_mode) call mpas_pool_get_config(domain % configs, 'config_use_DMSTracers', config_use_DMSTracers) call mpas_pool_get_config(domain % configs, 'config_use_MacroMoleculesTracers', config_use_MacroMoleculesTracers) call mpas_pool_get_config(domain % configs, 'config_use_ecosysTracers_sea_ice_coupling', & @@ -2754,7 +2768,6 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ call mpas_pool_get_array(forcingPool, 'avgSurfaceVelocity', avgSurfaceVelocity) call mpas_pool_get_array(forcingPool, 'avgSSHGradient', avgSSHGradient) call mpas_pool_get_array(forcingPool, 'avgTotalFreshWaterTemperatureFlux', avgTotalFreshWaterTemperatureFlux) - call mpas_pool_get_array(forcingPool, 'avgThermalForcingAtCritDepth', avgThermalForcingAtCritDepth) if ( frazilIceActive ) then call mpas_pool_get_array(forcingPool, 'seaIceEnergy', seaIceEnergy) @@ -2774,6 +2787,9 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ call mpas_pool_get_array(forcingPool, 'avgRemovedIceRunoffFlux', avgRemovedIceRunoffFlux) call mpas_pool_get_array(forcingPool, 'avgRemovedIceRunoffHeatFlux', avgRemovedIceRunoffHeatFlux) endif + if (trim(config_glc_thermal_forcing_coupling_mode) == '2d') then + call mpas_pool_get_array(forcingPool, 'avgThermalForcingAtCritDepth', avgThermalForcingAtCritDepth) + endif ! BGC fields if (config_use_ecosysTracers) then @@ -2935,7 +2951,9 @@ subroutine ocn_export_mct(o2x_o, errorCode) !{{{ o2x_o % rAttr(index_o2x_So_stv, n) = landIceTracerTransferVelocities(indexSaltTrans,i) o2x_o % rAttr(index_o2x_So_rhoeff, n) = 0.0_RKIND endif - o2x_o % rAttr(index_o2x_So_tf2d, n) = avgThermalForcingAtCritDepth(i) + if (trim(config_glc_thermal_forcing_coupling_mode) == '2d') then + o2x_o % rAttr(index_o2x_So_tf2d, n) = avgThermalForcingAtCritDepth(i) + endif !Fyke: test diff --git a/components/mpas-ocean/src/Registry.xml b/components/mpas-ocean/src/Registry.xml index 83af31633793..d4cd8cbac5af 100644 --- a/components/mpas-ocean/src/Registry.xml +++ b/components/mpas-ocean/src/Registry.xml @@ -807,6 +807,10 @@ description="If true, solid runoff from the Antarctic Ice Sheet (below 60S latitude) coming from the coupled is zeroed in the coupler import routines. To be used with data iceberg fluxes coming from the sea ice model." possible_values=".true. or .false." /> + config_2d_thermal_forcing_depth) then - iLevelCritDepth = iLevel - exit - end if - end do - !$omp parallel - !$omp do schedule(runtime) - ! calculate thermal forcing at identified level for each cell - do iCell = 1, nCells - ! ignore cells that are too shallow - if (iLevelCritDepth <= maxLevelCell(iCell)) then - ! this uses the level shallower than the reference level. could interpolate instead - ! note: assuming no LandIce cavity, but we may want to support that - freezingTemp = ocn_freezing_temperature(salinity=activeTracers(indexSalinity, iLevelCritDepth, iCell), & - pressure=pressure(iLevelCritDepth, iCell), inLandIceCavity=.false.) - avgThermalForcingAtCritDepth(iCell) = ( avgThermalForcingAtCritDepth(iCell) * nAccumulatedCoupled & - + activeTracers(indexTemperature, iLevelCritDepth, iCell) - freezingTemp ) / ( nAccumulatedCoupled + 1) - end if - end do - !$omp end do - !$omp end parallel + if (trim(config_glc_thermal_forcing_coupling_mode) == '2d') then + call mpas_pool_get_array(forcingPool, 'avgThermalForcingAtCritDepth', avgThermalForcingAtCritDepth) + call mpas_pool_get_subpool(statePool, 'tracers', tracersPool) + call mpas_pool_get_array(tracersPool, 'activeTracers', activeTracers, 2) + call mpas_pool_get_dimension(tracersPool, 'index_temperature', indexTemperature) + call mpas_pool_get_dimension(tracersPool, 'index_salinity', indexSalinity) + + + ! find vertical level that is just above the critical depth reference level + ! this does not account for depression due to ice shelf cavities or sea ice + iLevelCritDepth = nVertLevels ! default to deepest layer if we don't find the desired depth + do iLevel = 1, nVertLevels + if(refBottomDepth(iLevel) > config_2d_thermal_forcing_depth) then + iLevelCritDepth = iLevel + exit + end if + end do + !$omp parallel + !$omp do schedule(runtime) + ! calculate thermal forcing at identified level for each cell + do iCell = 1, nCells + ! ignore cells that are too shallow + if (iLevelCritDepth <= maxLevelCell(iCell)) then + ! this uses the level shallower than the reference level. could interpolate instead + ! note: assuming no LandIce cavity, but we may want to support that + freezingTemp = ocn_freezing_temperature(salinity=activeTracers(indexSalinity, iLevelCritDepth, iCell), & + pressure=pressure(iLevelCritDepth, iCell), inLandIceCavity=.false.) + avgThermalForcingAtCritDepth(iCell) = ( avgThermalForcingAtCritDepth(iCell) * nAccumulatedCoupled & + + activeTracers(indexTemperature, iLevelCritDepth, iCell) - freezingTemp ) / ( nAccumulatedCoupled + 1) + end if + end do + !$omp end do + !$omp end parallel + endif ! accumulate BGC coupling fields if necessary if (config_use_ecosysTracers) then diff --git a/driver-mct/main/cime_comp_mod.F90 b/driver-mct/main/cime_comp_mod.F90 index fc69cc4c2cb3..f582f7bd5aa8 100644 --- a/driver-mct/main/cime_comp_mod.F90 +++ b/driver-mct/main/cime_comp_mod.F90 @@ -1771,7 +1771,6 @@ subroutine cime_init() if (ocn_present) then if (atm_prognostic) ocn_c2_atm = .true. if (atm_present ) ocn_c2_atm = .true. ! needed for aoflux calc if aoflux=atm - if (glc_prognostic) ocn_c2_glctf = .true. if (ice_prognostic) ocn_c2_ice = .true. if (wav_prognostic) ocn_c2_wav = .true. if (rofocn_prognostic) ocn_c2_rof = .true. From b8c3864a59e86c587ff404d295fb11a76c83173a Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 11 Sep 2024 22:11:42 -0500 Subject: [PATCH 13/19] add ocn_c2_glctf to seq_infodata_PutData_explicit and getData --- driver-mct/shr/seq_infodata_mod.F90 | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/driver-mct/shr/seq_infodata_mod.F90 b/driver-mct/shr/seq_infodata_mod.F90 index fcc6a21eef1f..01ff3c98880e 100644 --- a/driver-mct/shr/seq_infodata_mod.F90 +++ b/driver-mct/shr/seq_infodata_mod.F90 @@ -203,6 +203,7 @@ MODULE seq_infodata_mod logical :: ocn_prognostic ! does component model need input data from driver logical :: ocnrof_prognostic ! does component need rof data logical :: ocn_c2_glcshelf ! will ocn component send data for ice shelf fluxes in driver + logical :: ocn_c2_glctf ! will ocn component send data for thermal forcing in driver logical :: ice_present ! does component model exist logical :: ice_prognostic ! does component model need input data from driver logical :: iceberg_prognostic ! does the ice model support icebergs @@ -765,6 +766,7 @@ SUBROUTINE seq_infodata_Init( infodata, nmlfile, ID, pioid, cpl_tag) infodata%ocn_prognostic = .false. infodata%ocnrof_prognostic = .false. infodata%ocn_c2_glcshelf = .false. + infodata%ocn_c2_glctf = .false. infodata%ice_prognostic = .false. infodata%glc_prognostic = .false. ! It's safest to assume glc_coupled_fluxes = .true. if it's not set elsewhere, @@ -1004,7 +1006,8 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_ atm_present, atm_prognostic, & lnd_present, lnd_prognostic, & rof_present, rof_prognostic, rofocn_prognostic, & - ocn_present, ocn_prognostic, ocnrof_prognostic, ocn_c2_glcshelf, & + ocn_present, ocn_prognostic, ocnrof_prognostic, & + ocn_c2_glcshelf, ocn_c2_glctf, & ice_present, ice_prognostic, & glc_present, glc_prognostic, & iac_present, iac_prognostic, & @@ -1179,6 +1182,7 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_ logical, optional, intent(OUT) :: ocn_prognostic logical, optional, intent(OUT) :: ocnrof_prognostic logical, optional, intent(OUT) :: ocn_c2_glcshelf + logical, optional, intent(OUT) :: ocn_c2_glctf logical, optional, intent(OUT) :: ice_present logical, optional, intent(OUT) :: ice_prognostic logical, optional, intent(OUT) :: iceberg_prognostic @@ -1365,6 +1369,7 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_ if ( present(ocn_prognostic) ) ocn_prognostic = infodata%ocn_prognostic if ( present(ocnrof_prognostic) ) ocnrof_prognostic = infodata%ocnrof_prognostic if ( present(ocn_c2_glcshelf) ) ocn_c2_glcshelf = infodata%ocn_c2_glcshelf + if ( present(ocn_c2_glctf) ) ocn_c2_glctf = infodata%ocn_c2_glctf if ( present(ice_present) ) ice_present = infodata%ice_present if ( present(ice_prognostic) ) ice_prognostic = infodata%ice_prognostic if ( present(iceberg_prognostic)) iceberg_prognostic = infodata%iceberg_prognostic @@ -1557,7 +1562,8 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_ atm_present, atm_prognostic, & lnd_present, lnd_prognostic, & rof_present, rof_prognostic, rofocn_prognostic, & - ocn_present, ocn_prognostic, ocnrof_prognostic, ocn_c2_glcshelf, & + ocn_present, ocn_prognostic, ocnrof_prognostic, & + ocn_c2_glcshelf, ocn_c2_glctf, & ice_present, ice_prognostic, & glc_present, glc_prognostic, & glc_coupled_fluxes, & @@ -1732,6 +1738,7 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_ logical, optional, intent(IN) :: ocn_prognostic logical, optional, intent(IN) :: ocnrof_prognostic logical, optional, intent(IN) :: ocn_c2_glcshelf + logical, optional, intent(IN) :: ocn_c2_glctf logical, optional, intent(IN) :: ice_present logical, optional, intent(IN) :: ice_prognostic logical, optional, intent(IN) :: iceberg_prognostic @@ -1917,6 +1924,7 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_ if ( present(ocn_prognostic) ) infodata%ocn_prognostic = ocn_prognostic if ( present(ocnrof_prognostic)) infodata%ocnrof_prognostic = ocnrof_prognostic if ( present(ocn_c2_glcshelf)) infodata%ocn_c2_glcshelf = ocn_c2_glcshelf + if ( present(ocn_c2_glctf)) infodata%ocn_c2_glctf = ocn_c2_glctf if ( present(ice_present) ) infodata%ice_present = ice_present if ( present(ice_prognostic) ) infodata%ice_prognostic = ice_prognostic if ( present(iceberg_prognostic)) infodata%iceberg_prognostic = iceberg_prognostic @@ -2229,6 +2237,7 @@ subroutine seq_infodata_bcast(infodata,mpicom) call shr_mpi_bcast(infodata%ocn_prognostic, mpicom) call shr_mpi_bcast(infodata%ocnrof_prognostic, mpicom) call shr_mpi_bcast(infodata%ocn_c2_glcshelf, mpicom) + call shr_mpi_bcast(infodata%ocn_c2_glctf, mpicom) call shr_mpi_bcast(infodata%ice_present, mpicom) call shr_mpi_bcast(infodata%ice_prognostic, mpicom) call shr_mpi_bcast(infodata%iceberg_prognostic, mpicom) @@ -2515,6 +2524,7 @@ subroutine seq_infodata_Exchange(infodata,ID,type) call shr_mpi_bcast(infodata%ocn_prognostic, mpicom, pebcast=cmppe) call shr_mpi_bcast(infodata%ocnrof_prognostic, mpicom, pebcast=cmppe) call shr_mpi_bcast(infodata%ocn_c2_glcshelf, mpicom, pebcast=cmppe) + call shr_mpi_bcast(infodata%ocn_c2_glctf, mpicom, pebcast=cmppe) call shr_mpi_bcast(infodata%ocn_nx, mpicom, pebcast=cmppe) call shr_mpi_bcast(infodata%ocn_ny, mpicom, pebcast=cmppe) ! dead_comps is true if it's ever set to true @@ -2591,6 +2601,7 @@ subroutine seq_infodata_Exchange(infodata,ID,type) call shr_mpi_bcast(infodata%ocn_prognostic, mpicom, pebcast=cplpe) call shr_mpi_bcast(infodata%ocnrof_prognostic, mpicom, pebcast=cplpe) call shr_mpi_bcast(infodata%ocn_c2_glcshelf, mpicom, pebcast=cplpe) + call shr_mpi_bcast(infodata%ocn_c2_glctf, mpicom, pebcast=cplpe) call shr_mpi_bcast(infodata%ice_present, mpicom, pebcast=cplpe) call shr_mpi_bcast(infodata%ice_prognostic, mpicom, pebcast=cplpe) call shr_mpi_bcast(infodata%iceberg_prognostic, mpicom, pebcast=cplpe) @@ -2948,6 +2959,7 @@ SUBROUTINE seq_infodata_print( infodata ) write(logunit,F0L) subname,'ocn_prognostic = ', infodata%ocn_prognostic write(logunit,F0L) subname,'ocnrof_prognostic = ', infodata%ocnrof_prognostic write(logunit,F0L) subname,'ocn_c2_glcshelf = ', infodata%ocn_c2_glcshelf + write(logunit,F0L) subname,'ocn_c2_glctf = ', infodata%ocn_c2_glctf write(logunit,F0L) subname,'ice_present = ', infodata%ice_present write(logunit,F0L) subname,'ice_prognostic = ', infodata%ice_prognostic write(logunit,F0L) subname,'iceberg_prognostic = ', infodata%iceberg_prognostic From 114c89e0185b518d5f5e832ad02e07077a1d3282 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 11 Sep 2024 16:51:58 -0500 Subject: [PATCH 14/19] Add config_glc_thermal_forcing_coupling_mode to nl system Eventually, when we have compsets that require this mode, it should be controlled analogously to MPASO_ISMF. --- components/mpas-ocean/bld/build-namelist | 1 + components/mpas-ocean/bld/build-namelist-section | 1 + .../bld/namelist_files/namelist_defaults_mpaso.xml | 1 + .../bld/namelist_files/namelist_definition_mpaso.xml | 8 ++++++++ 4 files changed, 11 insertions(+) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 011396d879f0..e492acc89adf 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -731,6 +731,7 @@ if (($OCN_ICEBERG eq 'true') && ($OCN_FORCING eq 'active_atm')) { } else { add_default($nl, 'config_remove_ais_ice_runoff', 'val'=>".false."); } +add_default($nl, 'config_glc_thermal_forcing_coupling_mode'); add_default($nl, 'config_2d_thermal_forcing_depth'); ###################################### diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index 115bd09c96a6..88e81ab25099 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -239,6 +239,7 @@ add_default($nl, 'config_sgr_salinity_prescribed'); add_default($nl, 'config_remove_ais_river_runoff'); add_default($nl, 'config_remove_ais_ice_runoff'); +add_default($nl, 'config_glc_thermal_forcing_coupling_mode'); add_default($nl, 'config_2d_thermal_forcing_depth'); ###################################### diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index 12a97836035c..09965cb8ac85 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -354,6 +354,7 @@ .false. .false. +'off' 300.0 diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index 45e4caf798a5..e2498597aa32 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1271,6 +1271,14 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + +If and how MPAS-Ocean sends thermal forcing to GLC (MALI) in E3SM. This is used for ocean coupling with a melt parameterization for grounded marine ice-cliffs in MALI. This is primarily relevant to the Greenland Ice Sheet, but also relevant to the Antarctic Ice Sheet. 'none' means no coupling of thermal forcing. '2d' means thermal forcing at a prescribed depth is passed to GLC. That depth is controlled by 'config_2d_thermal_forcing_depth', and the resulting thermal forcing field is calculated in the field 'avgThermalForcingAtCritDepth'. + +Valid values: 'off' or '2d' +Default: Defined in namelist_defaults.xml + + Depth at which to pass 2d thermal forcing to the coupler for use in the GLC component. Note that mapping files for this field must be created with a mask to exclude ocean grid cells shallower than this value and thus must be regenerated if this value is changed. From 28a25ddffecc08781756c201fa56d765be5c8f53 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 11 Sep 2024 17:10:14 -0500 Subject: [PATCH 15/19] Create testmod and test for TF coupling feature --- cime_config/tests.py | 1 + .../testmods_dirs/mpaso/ocn_glc_tf_coupling/README | 12 ++++++++++++ .../mpaso/ocn_glc_tf_coupling/shell_commands | 4 ++++ .../mpaso/ocn_glc_tf_coupling/user_nl_mpaso | 1 + 4 files changed, 18 insertions(+) create mode 100644 components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/README create mode 100644 components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/shell_commands create mode 100644 components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/user_nl_mpaso diff --git a/cime_config/tests.py b/cime_config/tests.py index 1cbf28b83974..80f5f8140a7a 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -305,6 +305,7 @@ "ERS_Ld5.T62_oQU120.CMPASO-NYF", "ERS.f09_g16_g.MALISIA", "ERS_Ld5.TL319_oQU240wLI_ais8to30.MPAS_LISIO_JRA1p5.mpaso-ocn_glcshelf", + "ERS_Ld5.TL319_IcoswISC30E3r5_gis20.MPAS_LISIO_JRA1p5.mpaso-ocn_glc_tf_coupling", "SMS_P12x2.ne4pg2_oQU480.WCYCL1850NS.allactive-mach_mods", "ERS_Ln9.ne4pg2_ne4pg2.F2010-MMF1.eam-mmf_crmout", ) diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/README b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/README new file mode 100644 index 000000000000..bd801c44f8af --- /dev/null +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/README @@ -0,0 +1,12 @@ +This testdef is used to test a stealth feature that enables coupling between +OCN and GLC for Greenland, which passes ocean thermal forcing from OCN to GLC +and uses that in a parameterization for marine melting of grounded vertical +cliffs. + +It changes one mpaso namelist variable, + config_glc_thermal_forcing_coupling_mode +from its default value to '2d'. +This tests the ocn/glc TF coupling. + +It also specified that DATM forcing should be restricted to 1958. +This allows JRA1p5 forcing to be used without a large input data requirement. diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/shell_commands b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/shell_commands new file mode 100644 index 000000000000..1d43ad8c5baf --- /dev/null +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/shell_commands @@ -0,0 +1,4 @@ +./xmlchange DATM_CLMNCEP_YR_START=1958 +./xmlchange DATM_CLMNCEP_YR_END=1958 +./xmlchange DROF_STRM_YR_START=1958 +./xmlchange DROF_STRM_YR_END=1958 diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/user_nl_mpaso b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/user_nl_mpaso new file mode 100644 index 000000000000..0e1378620836 --- /dev/null +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/ocn_glc_tf_coupling/user_nl_mpaso @@ -0,0 +1 @@ +config_glc_thermal_forcing_coupling_mode = '2d' From 97b7fc0e3ea8a7a4c8cb617aa83907131d6a6459 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Fri, 20 Sep 2024 11:26:20 -0500 Subject: [PATCH 16/19] Add TL319_oQU240wLI_gis20 configuration --- cime_config/config_grids.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index e1727e58ae3a..6240d4e320b1 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -1899,6 +1899,16 @@ IcoswISC30E3r5 + + TL319 + TL319 + oQU240wLI + JRA025 + mpas.gis20km + null + oQU240wLI + + TL319 TL319 @@ -5565,6 +5575,18 @@ cpl/gridmaps/mpas.gis20km/map_gis20km_to_TL319_traave.20240404.nc + + cpl/gridmaps/oQU240wLI/map_oQU240wLI_to_gis20km_esmfaave.20240919.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI_to_gis20km_esmfbilin.20240919.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI_to_gis20km_esmfneareststod.20240919.deeperThan300m.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + cpl/gridmaps/mpas.gis20km/map_gis20km_to_oQU240wLI_esmfaave.20240919.nc + + cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_aave.230510.nc cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_gis20km_bilin.230510.nc From dccd2056009331446b501b7fd1643af2430d8041 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 20 Sep 2024 12:48:09 -0500 Subject: [PATCH 17/19] Update test to use oQU240wLI and move to e3sm_ocnice_stealth_features --- cime_config/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/tests.py b/cime_config/tests.py index 80f5f8140a7a..5205d226998b 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -266,6 +266,7 @@ "SMS_D_Ld1.T62_oQU240wLI.GMPAS-IAF-PISMF.mpaso-impl_top_drag", "SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-harmonic_mean_drag", "SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-upwind_advection", + "ERS_Ld5.TL319_oQU240wLI_gis20.MPAS_LISIO_JRA1p5.mpaso-ocn_glc_tf_coupling", ) }, @@ -305,7 +306,6 @@ "ERS_Ld5.T62_oQU120.CMPASO-NYF", "ERS.f09_g16_g.MALISIA", "ERS_Ld5.TL319_oQU240wLI_ais8to30.MPAS_LISIO_JRA1p5.mpaso-ocn_glcshelf", - "ERS_Ld5.TL319_IcoswISC30E3r5_gis20.MPAS_LISIO_JRA1p5.mpaso-ocn_glc_tf_coupling", "SMS_P12x2.ne4pg2_oQU480.WCYCL1850NS.allactive-mach_mods", "ERS_Ln9.ne4pg2_ne4pg2.F2010-MMF1.eam-mmf_crmout", ) From 43ef3b0bcd62c6361f9f84d1c599b179fba3cd9f Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 11 Oct 2024 22:45:46 -0500 Subject: [PATCH 18/19] Rename OCN2GLC_*MAPNAME to OCN2GLC_SHELF_*FMAPNAME for new grids Four new gridspecs were introduced recently that were brought in to this branch after a rebase and were missed in the original renaming of OCN2GLC_*MAPNAME to OCN2GLC_SHELF_*FMAPNAME. This commit makes the name change for those grids as well. --- cime_config/config_grids.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index 6240d4e320b1..fd9258051f75 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -5724,8 +5724,8 @@ - cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais20km_esmfaave.20240509.nc - cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais20km_esmfbilin.20240509.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais20km_esmfaave.20240509.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais20km_esmfbilin.20240509.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240wLI-nomask_esmfaave.20240509.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240wLI-nomask_esmfbilin.20240509.nc cpl/gridmaps/mpas.ais20km/map_ais20km_to_oQU240wLI-nomask_esmfaave.20240509.nc @@ -5753,8 +5753,8 @@ - cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfaave.20240701.nc - cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfbilin.20240701.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfaave.20240701.nc + cpl/gridmaps/oQU240wLI/map_oQU240wLI-nomask_to_ais8to30_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfaave.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_oQU240wLI-nomask_esmfaave.20240701.nc @@ -5764,8 +5764,8 @@ - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfaave.20240701.nc - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfbilin.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfaave.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais8to30_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais8to30km/map_ais8to30_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc @@ -5793,8 +5793,8 @@ - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfaave.20240701.nc - cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfbilin.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfaave.20240701.nc + cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5-nomask_to_ais4to20_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfbilin.20240701.nc cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfaave.20240701.nc From e18f825615fe5b309790fc1b03753168e3fa8d0b Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Tue, 5 Nov 2024 10:56:59 -0600 Subject: [PATCH 19/19] Minor cleanup from making bld files consistent with Registry --- .../bld/namelist_files/namelist_definition_mpaso.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index e2498597aa32..ce48de48d5eb 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -1272,15 +1272,15 @@ Default: Defined in namelist_defaults.xml + category="coupling" group="coupling"> If and how MPAS-Ocean sends thermal forcing to GLC (MALI) in E3SM. This is used for ocean coupling with a melt parameterization for grounded marine ice-cliffs in MALI. This is primarily relevant to the Greenland Ice Sheet, but also relevant to the Antarctic Ice Sheet. 'none' means no coupling of thermal forcing. '2d' means thermal forcing at a prescribed depth is passed to GLC. That depth is controlled by 'config_2d_thermal_forcing_depth', and the resulting thermal forcing field is calculated in the field 'avgThermalForcingAtCritDepth'. -Valid values: 'off' or '2d' +Valid values: 'off', '2d' Default: Defined in namelist_defaults.xml + category="coupling" group="coupling"> Depth at which to pass 2d thermal forcing to the coupler for use in the GLC component. Note that mapping files for this field must be created with a mask to exclude ocean grid cells shallower than this value and thus must be regenerated if this value is changed. Valid values: any non-negative value