From 4015a2d01414af15ccdbb10e5eeb820a54551f3d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 20 Aug 2025 15:18:31 -0500 Subject: [PATCH 1/9] Move MALI calving flux from Fogg_rofi to Figg_rofi This moves the calving flux from being passed to the ocean to being passed to sea ice. --- components/mpas-albany-landice/driver/glc_comp_mct.F | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/mpas-albany-landice/driver/glc_comp_mct.F b/components/mpas-albany-landice/driver/glc_comp_mct.F index 72f827960636..81c00c328488 100644 --- a/components/mpas-albany-landice/driver/glc_comp_mct.F +++ b/components/mpas-albany-landice/driver/glc_comp_mct.F @@ -1554,12 +1554,12 @@ subroutine glc_export_mct(g2x_g, errorCode) do i = 1, nCellsSolve n = n + 1 - ! Fogg_rofl + ! Fogg_rofl - liquid runoff to ocean g2x_g % rAttr(index_g2x_Fogg_rofl,n) = avgBareIceAblationApplied(i) - ! Figg_rofi - g2x_g % rAttr(index_g2x_Figg_rofi,n) = 0.0 ! placeholder - ! Fogg_rofi - g2x_g % rAttr(index_g2x_Fogg_rofi,n) = avgCalvingFlux(i) + ! Figg_rofi - solid runoff to sea ice + g2x_g % rAttr(index_g2x_Figg_rofi,n) = avgCalvingFlux(i) + ! Fogg_rofi - solid runoff to ocean + g2x_g % rAttr(index_g2x_Fogg_rofi,n) = 0.0 g2x_g % rAttr(index_g2x_Fogg_rofi,n) = g2x_g % rAttr(index_g2x_Fogg_rofi,n) + avgFaceMeltFlux(i) if (trim(config_basal_mass_bal_float) == 'ismip6') then ! if MALI is calculating ISMF, add that to rofi From 23bd1d375fe77c771d21aff2a0091c1e48176be6 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 27 Aug 2025 10:31:20 -0500 Subject: [PATCH 2/9] Attach Fixx_rofi to berg fluxes in MPAS-Seaice The Fixx_rofi solid runoff flux has existed in the coupler for some time, but it had not been attached to MPAS-Seaice. This commit adds the connection to MPAS-Seaice in the ice_comp_mct import routine. The Fixx_rofi flux is passed to bergFreshwaterFlux. bergLatentHeatFlux is then calculated using ice temperature specified by config_iceberg_temperature. This commit also changes ice_export_mct so that Fioi_bergw/h are always exported - they will now either come from the coupler or from data. --- components/mpas-seaice/driver/ice_comp_mct.F | 59 +++++++++++++++---- .../mpas-seaice/driver/mpassi_cpl_indices.F | 2 + 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 6aaf30708bc2..f6fc6afe57d5 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -2095,6 +2095,7 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ ! The following fields are sometimes received from the coupler, ! depending on model options: ! +! o rofi -- frozen water flux into sea ice ! o algae1 -- ! o algae2 -- ! o algae3 -- @@ -2125,6 +2126,10 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ ! !REVISION HISTORY: ! same as module + use seaice_constants, only: & + seaiceLatentHeatMelting, & ! latent heat of melting of fresh ice (J/kg) + seaiceFreshIceSpecificHeat ! specific heat of fresh ice (J/kg/K) + ! !INPUT/OUTPUT PARAMETERS: type(mct_aVect), intent(inout) :: x2i_i @@ -2161,6 +2166,7 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ aerosols, & atmosCoupling, & oceanCoupling, & + icebergFluxes, & biogeochemistry integer, pointer :: nCellsSolve @@ -2170,7 +2176,11 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ config_use_modal_aerosols, & config_use_zaerosols, & config_use_column_biogeochemistry, & - config_couple_biogeochemistry_fields + config_couple_biogeochemistry_fields, & + config_use_data_icebergs + + real(kind=RKIND), pointer :: & + bergTemperature ! iceberg temperature character(len=strKIND), pointer :: & config_column_physics_type, & @@ -2201,6 +2211,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ snowfallRateField, & uAirVelocityField, & vAirVelocityField, & + bergFreshwaterFluxField, & + bergLatentHeatFluxField, & oceanNitrateConcField, & oceanSilicateConcField, & oceanAmmoniumConcField, & @@ -2246,6 +2258,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ snowfallRate, & uAirVelocity, & vAirVelocity, & + bergFreshwaterFlux, & + bergLatentHeatFlux, & oceanNitrateConc, & oceanSilicateConc, & oceanAmmoniumConc, & @@ -2291,6 +2305,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_config(configs, "config_column_physics_type", config_column_physics_type) call mpas_pool_get_config(configs, "config_thermodynamics_type", config_thermodynamics_type) call mpas_pool_get_config(configs, "config_ocean_surface_type", config_ocean_surface_type) + call MPAS_pool_get_config(configs, "config_use_data_icebergs", config_use_data_icebergs) + call MPAS_pool_get_config(configs, "config_iceberg_temperature", bergTemperature) call mpas_pool_get_config(configs, "config_use_aerosols", config_use_aerosols) call mpas_pool_get_config(configs, "config_use_modal_aerosols", config_use_modal_aerosols) call mpas_pool_get_config(configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) @@ -2328,6 +2344,12 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_array(atmosCoupling, 'uAirVelocity', uAirVelocity) call mpas_pool_get_array(atmosCoupling, 'vAirVelocity', vAirVelocity) + if (.not. config_use_data_icebergs) then + call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) + call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) + endif + if (config_use_aerosols) then call mpas_pool_get_subpool(block_ptr % structs, 'aerosols', aerosols) @@ -2417,6 +2439,13 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ uAirVelocity(i) = x2i_i % rAttr(index_x2i_Sa_u, n) vAirVelocity(i) = x2i_i % rAttr(index_x2i_Sa_v, n) + ! if not using data icebergs, import icebergs here + if (.not. config_use_data_icebergs) then + bergFreshwaterFlux(i) = x2i_i % rAttr(index_x2i_Fixx_rofi, n) + bergLatentHeatFlux(i) = bergFreshwaterFlux(i) * & + (seaiceLatentHeatMelting - seaiceFreshIceSpecificHeat*bergTemperature) + endif + ! set aerosols, if configured if (config_use_aerosols) then if (config_use_modal_aerosols) then @@ -2641,6 +2670,14 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_dmpar_exch_halo_field(uAirVelocityField) call mpas_dmpar_exch_halo_field(vAirVelocityField) + if (.not. config_use_data_icebergs) then + call mpas_pool_get_subpool(domain % blocklist % structs, 'berg_fluxes', icebergFluxes) + call mpas_pool_get_field(icebergFluxes, 'bergFreshwaterFlux', bergFreshwaterFluxField) + call mpas_pool_get_field(icebergFluxes, 'bergLatentHeatFlux', bergLatentHeatFluxField) + call mpas_dmpar_exch_halo_field(bergFreshwaterFluxField) + call mpas_dmpar_exch_halo_field(bergLatentHeatFluxField) + endif + if (config_use_aerosols) then call mpas_dmpar_exch_halo_field(atmosAerosolFluxField) endif @@ -2742,8 +2779,7 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ config_use_column_biogeochemistry, & config_use_zaerosols, & config_couple_biogeochemistry_fields, & - config_use_column_shortwave, & - config_use_data_icebergs + config_use_column_shortwave real(kind=RKIND), pointer :: & sphere_radius @@ -2818,7 +2854,6 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ call MPAS_pool_get_config(configs, "config_use_column_biogeochemistry", config_use_column_biogeochemistry) call mpas_pool_get_config(configs, "config_couple_biogeochemistry_fields", config_couple_biogeochemistry_fields) call MPAS_pool_get_config(configs, "config_use_column_shortwave", config_use_column_shortwave) - call MPAS_pool_get_config(configs, "config_use_data_icebergs", config_use_data_icebergs) call MPAS_pool_get_subpool(block_ptr % structs, 'mesh', meshPool) call MPAS_pool_get_subpool(block_ptr % structs, "tracers_aggregate", tracersAggregate) @@ -2872,12 +2907,10 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ call MPAS_pool_get_array(oceanFluxes, 'oceanFreshWaterFlux', oceanFreshWaterFlux) call MPAS_pool_get_array(oceanFluxes, 'oceanSaltFlux', oceanSaltFlux) - if (config_use_data_icebergs) then - call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) + call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) - call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) - call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) - endif + call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) if (config_use_column_biogeochemistry .and. config_couple_biogeochemistry_fields) then call mpas_pool_get_subpool(block_ptr % structs, 'biogeochemistry', biogeochemistry) @@ -2956,10 +2989,10 @@ subroutine ice_export_mct(i2x_i, errorCode) !{{{ !-------states-------------------- i2x_i % rAttr(index_i2x_Si_ifrac ,n) = ailohi - if (config_use_data_icebergs) then - i2x_i % rAttr(index_i2x_Fioi_bergw,n) = bergFreshwaterFlux(i) - i2x_i % rAttr(index_i2x_Fioi_bergh,n) = bergLatentHeatFlux(i) - endif + ! Always export berg fluxes - they are either from coupler or from data + ! but either way have been assigned at this point + i2x_i % rAttr(index_i2x_Fioi_bergw,n) = bergFreshwaterFlux(i) + i2x_i % rAttr(index_i2x_Fioi_bergh,n) = bergLatentHeatFlux(i) if ( ailohi > 0.0_RKIND ) then diff --git a/components/mpas-seaice/driver/mpassi_cpl_indices.F b/components/mpas-seaice/driver/mpassi_cpl_indices.F index 8646233475bb..b32fae41c04b 100644 --- a/components/mpas-seaice/driver/mpassi_cpl_indices.F +++ b/components/mpas-seaice/driver/mpassi_cpl_indices.F @@ -87,6 +87,7 @@ module mpassi_cpl_indices integer :: index_x2i_Faxa_swnet ! sw: net integer :: index_x2i_Fioo_q ! ocn freezing melting potential integer :: index_x2i_Fioo_frazil ! ocn frazil ice formation + integer :: index_x2i_Fixx_rofi ! flux: frozen water flux into sea ice integer :: index_x2i_Faxa_bcphidry ! flux: Black Carbon hydrophilic dry deposition integer :: index_x2i_Faxa_bcphodry ! flux: Black Carbon hydrophobic dry deposition integer :: index_x2i_Faxa_bcphiwet ! flux: Black Carbon hydrophilic wet deposition @@ -214,6 +215,7 @@ subroutine mpassi_cpl_indices_set( ) index_x2i_Faxa_swvdf = mct_avect_indexra(x2i,'Faxa_swvdf') index_x2i_Fioo_q = mct_avect_indexra(x2i,'Fioo_q') index_x2i_Fioo_frazil = mct_avect_indexra(x2i,'Fioo_frazil') + index_x2i_Fixx_rofi = mct_avect_indexra(x2i,'Fixx_rofi') index_x2i_Faxa_bcphidry = mct_avect_indexra(x2i,'Faxa_bcphidry') index_x2i_Faxa_bcphodry = mct_avect_indexra(x2i,'Faxa_bcphodry') index_x2i_Faxa_bcphiwet = mct_avect_indexra(x2i,'Faxa_bcphiwet') From 847a790ade27aed665a59ff58a90041510e1fe2d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Wed, 27 Aug 2025 21:34:47 -0500 Subject: [PATCH 3/9] Remove berg package from berg variables With Fixx_rofi now being coupled to ice, the berg variables will be used all the time when running in E3SM, as opposed to just when data icebergs are active. Note that this is unlikely to be the most desirable solution; the berg variables would ideally be disabled for standalone MPAS-Seaice, but with this change they will always be allocated. I could not find an obvious way to make the package conditional on MPAS-Seaice being run within E3SM, which I think would be the preferred criterion. Also, if the solution of having the berg variables be always allocated is acceptable, then there is no longer a need for the berg package and it could be fully removed. So either way, this commit will need to be revisited. --- components/mpas-seaice/src/Registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index ed94bb094e88..fa2a2dae6fb6 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -4967,7 +4967,7 @@ - + Date: Wed, 27 Aug 2025 22:48:10 -0500 Subject: [PATCH 4/9] Enable coupler var iceberg_prognostic from seaice driver This coupler flag is what tells the coupler to send rofi fluxes from ROF and GLC to ICE. This will allow seaice to act as a pass-through for rofi fluxes to the ocean. When an iceberg model is eventually added to MPAS-Seaice, it can redistribute icebergs before they are passed on to the ocean. --- components/mpas-seaice/driver/ice_comp_mct.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index f6fc6afe57d5..a8a4b9bcd25f 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -874,7 +874,7 @@ end subroutine xml_stream_get_attributes call t_stopf ('mpassi_mct_init') - call seq_infodata_PutData( infodata, ice_prognostic=.true.) + call seq_infodata_PutData( infodata, ice_prognostic=.true., iceberg_prognostic=.true.) !----------------------------------------------------------------------- ! From 95613490937b358a0b5dd73fd0d420e518d0fca2 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 29 Aug 2025 13:59:15 -0500 Subject: [PATCH 5/9] Fix field list in prep_ice_calc_g2x_ix Fixx_rofi had been specified in this list when Fixx_rofi coupling was partially implemented (but not tested) years ago. However, that is the wrong variable at this point in the coupling chain - Figg_rofi is the field that needs to be remapped at this stage. Note that usually a previously defined list of variables is used at this stage, as opposed to hardcoding a variable name/list, but I am modifying the existing implementation and not changing that here. --- driver-mct/main/prep_ice_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-mct/main/prep_ice_mod.F90 b/driver-mct/main/prep_ice_mod.F90 index 36c478f6fc21..4e8a849c50c9 100644 --- a/driver-mct/main/prep_ice_mod.F90 +++ b/driver-mct/main/prep_ice_mod.F90 @@ -561,7 +561,7 @@ subroutine prep_ice_calc_g2x_ix(timer) do egi = 1,num_inst_glc g2x_gx => component_get_c2x_cx(glc(egi)) call seq_map_map(mapper_Rg2i, g2x_gx, g2x_ix(egi), & - fldlist='Fixx_rofi', norm=.true.) + fldlist='Figg_rofi', norm=.true.) enddo call t_drvstopf (trim(timer)) From 576a92d290bfb51cc09dc5c7a5d47781bd7daca1 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Thu, 28 Aug 2025 10:17:04 -0500 Subject: [PATCH 6/9] Add new ROF2ICE_RMAPTYPE xml variable --- driver-mct/cime_config/config_component.xml | 17 +++++++++++ .../cime_config/namelist_definition_drv.xml | 29 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/driver-mct/cime_config/config_component.xml b/driver-mct/cime_config/config_component.xml index b065cae41f40..b9df3738f8da 100644 --- a/driver-mct/cime_config/config_component.xml +++ b/driver-mct/cime_config/config_component.xml @@ -1738,6 +1738,23 @@ rof2ocn runoff mapping file decomp type + + char + idmap + run_domain + env_run.xml + rof2ice runoff mapping file + + + + char + X,Y + Y + run_domain + env_run.xml + rof2ice runoff 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 227d4619869c..228f237dcd0b 100644 --- a/driver-mct/cime_config/namelist_definition_drv.xml +++ b/driver-mct/cime_config/namelist_definition_drv.xml @@ -4748,6 +4748,35 @@ + + char + mapping + abs + seq_maps + + runoff to ice mapping file + + + $ROF2ICE_RMAPNAME + + + + + 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. + + + $ROF2ICE_RMAPTYPE + X + + char From c7c4fc8bec319d4369e19325e2233aa3ba078abd Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Thu, 28 Aug 2025 10:17:39 -0500 Subject: [PATCH 7/9] Add new mapping file specifications - follow up reqd This commit adds mapping file specifications needed to run a LR G-case. This commit should be followed up with a more complete addition for other grids. --- cime_config/config_grids.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml index 179d8af39739..70641cd1c660 100755 --- a/cime_config/config_grids.xml +++ b/cime_config/config_grids.xml @@ -5910,6 +5910,7 @@ cpl/cpl6/map_JRA025_to_IcoswISC30E3r5_cstmnn.r150e300.20231121.nc cpl/cpl6/map_JRA025_to_IcoswISC30E3r5_cstmnn.r150e300.20231121.nc + cpl/cpl6/map_JRA025_to_IcoswISC30E3r5_cstmnn.r150e300.20231121.nc @@ -6486,6 +6487,7 @@ 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_esmfbilin.20250403.nc + cpl/gridmaps/mpas.ais4to20km/map_ais4to20_to_IcoswISC30E3r5-nomask_esmfaave.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 7a711563c361848f703ba874227b8d365c9f4189 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Fri, 29 Aug 2025 23:10:53 -0500 Subject: [PATCH 8/9] Allow Fixx_rofi flux to scale DIB Replace config_scale_dib_by_removed_ice_runoff option with config_dib_scale_mode option that can take on 3 values: 'none', 'removed_ice_runoff','coupler_ice_runoff'. If it's set to coupler_ice_runoff, the get_data_iceberg_fluxes routine calculates a global sum of the bergFreshwaterFlux field and uses that to scale the bergFreshwaterFluxData field (i.e., DIB). There are some to-do items in this commit: * need to know how to throw an error in MPAS-Seaice for an invalid namelist option value * logic at 3 places where "if (.not. config_use_data_icebergs) then" was removed in ice_comp_mct.F needs to be added to not do things if the coupler flux is not actually needed (i.e. if DIB is being used) --- .../mpaso/scaled_dib_dismf/README | 4 +- .../mpaso/scaled_dib_dismf/user_nl_mpassi | 2 +- components/mpas-seaice/bld/build-namelist | 2 +- .../mpas-seaice/bld/build-namelist-section | 2 +- .../namelist_defaults_mpassi.xml | 2 +- .../namelist_definition_mpassi.xml | 6 +- components/mpas-seaice/driver/ice_comp_mct.F | 50 +++++++-------- components/mpas-seaice/src/Registry.xml | 6 +- .../mpas_seaice_core_interface.F | 13 ++-- .../src/shared/mpas_seaice_forcing.F | 62 ++++++++++++++++--- 10 files changed, 97 insertions(+), 52 deletions(-) diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/README b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/README index f9f97d27de15..cb260f0638e4 100644 --- a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/README +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/README @@ -2,7 +2,7 @@ This testdef is used to test a stealth feature in mpaso and mpassi introduced by PR #6696. It simply changes sets the following namelist option in mpaso to true config_scale_dismf_by_removed_ice_runoff -and the following namelist option in mpassi to true - config_scale_dib_by_removed_ice_runoff +and the following namelist option in mpassi + config_dib_scale_mode = 'removed_ice_runoff' These flags only makes sense to use in a B-case runs with data icebergs (DIB) and data ice-shelf melt fluxes (DISMF). diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/user_nl_mpassi b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/user_nl_mpassi index 8512001af932..25d3cc3c9c8c 100644 --- a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/user_nl_mpassi +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/scaled_dib_dismf/user_nl_mpassi @@ -1 +1 @@ - config_scale_dib_by_removed_ice_runoff = .true. + config_dib_scale_mode = 'removed_ice_runoff' diff --git a/components/mpas-seaice/bld/build-namelist b/components/mpas-seaice/bld/build-namelist index 462454f828d5..b150b80b00ac 100755 --- a/components/mpas-seaice/bld/build-namelist +++ b/components/mpas-seaice/bld/build-namelist @@ -940,7 +940,7 @@ if ($iceberg_mode eq 'data') { add_default($nl, 'config_use_data_icebergs', 'val'=>"false"); } add_default($nl, 'config_iceberg_temperature'); -add_default($nl, 'config_scale_dib_by_removed_ice_runoff'); +add_default($nl, 'config_dib_scale_mode'); add_default($nl, 'config_salt_flux_coupling_type'); add_default($nl, 'config_ice_ocean_drag_coefficient'); diff --git a/components/mpas-seaice/bld/build-namelist-section b/components/mpas-seaice/bld/build-namelist-section index 467e04c7908b..24c5739931e7 100644 --- a/components/mpas-seaice/bld/build-namelist-section +++ b/components/mpas-seaice/bld/build-namelist-section @@ -446,7 +446,7 @@ add_default($nl, 'config_sea_freezing_temperature_type'); add_default($nl, 'config_ocean_surface_type'); add_default($nl, 'config_use_data_icebergs'); add_default($nl, 'config_iceberg_temperature'); -add_default($nl, 'config_scale_dib_by_removed_ice_runoff'); +add_default($nl, 'config_dib_scale_mode'); add_default($nl, 'config_salt_flux_coupling_type'); add_default($nl, 'config_ice_ocean_drag_coefficient'); diff --git a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml index 336c67a42848..bce5fa9121db 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_defaults_mpassi.xml @@ -457,7 +457,7 @@ 'free' false -4.0 -false +'none' 'constant' 0.00536 diff --git a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml index 193fab7a5e04..27d59b97948b 100644 --- a/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml +++ b/components/mpas-seaice/bld/namelist_files/namelist_definition_mpassi.xml @@ -2662,11 +2662,11 @@ Valid values: Any real number. Default: Defined in namelist_defaults.xml - -Whether to scale data iceberg fluxes by the running mean of removed ice runoff +How to scale data iceberg fluxes: 'none'=no scaling, 'removed_ice_runoff'=running mean of removed ice runoff, 'coupler_ice_runoff'=sum of Fixx_rofi from coupler" -Valid values: true or false +Valid values: 'none', 'removed_ice_runoff','coupler_ice_runoff' Default: Defined in namelist_defaults.xml diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index a8a4b9bcd25f..001b0f8b405e 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -243,8 +243,8 @@ subroutine ice_init_mct( EClock, cdata_i, x2i_i, i2x_i, NLFilename )!{{{ #endif logical, pointer :: & - tempLogicalConfig, & - config_scale_dib_by_removed_ice_runoff + tempLogicalConfig + character(len=StrKIND), pointer :: config_dib_scale_mode character(len=StrKIND), pointer :: tempCharConfig real (kind=RKIND), pointer :: tempRealConfig @@ -504,8 +504,8 @@ end subroutine xml_stream_get_attributes end if - call MPAS_pool_get_config(domain % configs, "config_scale_dib_by_removed_ice_runoff", & - config_scale_dib_by_removed_ice_runoff) + call MPAS_pool_get_config(domain % configs, "config_dib_scale_mode", & + config_dib_scale_mode) ! Setup MPASSI simulation clock ierr = domain % core % setup_clock(domain % clock, domain % configs) @@ -638,7 +638,7 @@ end subroutine xml_stream_get_attributes ! Determine coupling type call seq_infodata_GetData(infodata, cpl_seq_option=cpl_seq_option) - if (config_scale_dib_by_removed_ice_runoff) then + if (trim(config_dib_scale_mode) == 'removed_ice_runoff') then ! independent of space so should be no need to loop over blocks block => domain % blocklist call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) @@ -1186,8 +1186,9 @@ subroutine ice_run_mct( EClock, cdata_i, x2i_i, i2x_i)!{{{ integer :: ierr, streamDirection, iam logical :: streamActive, debugOn logical, pointer :: & - config_write_output_on_startup, & - config_scale_dib_by_removed_ice_runoff + config_write_output_on_startup + character (len=StrKIND), pointer :: & + config_dib_scale_mode logical, save :: first=.true. character (len=StrKIND), pointer :: & config_restart_timestamp_name, & @@ -1218,8 +1219,8 @@ subroutine ice_run_mct( EClock, cdata_i, x2i_i, i2x_i)!{{{ call MPAS_pool_get_config(domain % configs, 'config_restart_timestamp_name', config_restart_timestamp_name) call MPAS_pool_get_config(domain % configs, "config_column_physics_type", config_column_physics_type) - call MPAS_pool_get_config(domain % configs, "config_scale_dib_by_removed_ice_runoff", & - config_scale_dib_by_removed_ice_runoff) + call MPAS_pool_get_config(domain % configs, "config_dib_scale_mode", & + config_dib_scale_mode) ! Setup log information. call shr_file_getLogUnit (shrlogunit) @@ -1255,7 +1256,7 @@ subroutine ice_run_mct( EClock, cdata_i, x2i_i, i2x_i)!{{{ ! Post coupling calls block => domain % blocklist - if (config_scale_dib_by_removed_ice_runoff) then + if (trim(config_dib_scale_mode) == 'removed_ice_runoff') then ! independent of space so should be no need to loop over blocks call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) call MPAS_pool_get_array(berg_forcing, "runningMeanRemovedIceRunoff", & @@ -2344,11 +2345,9 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_array(atmosCoupling, 'uAirVelocity', uAirVelocity) call mpas_pool_get_array(atmosCoupling, 'vAirVelocity', vAirVelocity) - if (.not. config_use_data_icebergs) then - call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) - call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) - call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) - endif + call MPAS_pool_get_subpool(block_ptr % structs, "berg_fluxes", icebergFluxes) + call MPAS_pool_get_array(icebergFluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call MPAS_pool_get_array(icebergFluxes, "bergLatentHeatFlux", bergLatentHeatFlux) if (config_use_aerosols) then call mpas_pool_get_subpool(block_ptr % structs, 'aerosols', aerosols) @@ -2439,12 +2438,9 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ uAirVelocity(i) = x2i_i % rAttr(index_x2i_Sa_u, n) vAirVelocity(i) = x2i_i % rAttr(index_x2i_Sa_v, n) - ! if not using data icebergs, import icebergs here - if (.not. config_use_data_icebergs) then - bergFreshwaterFlux(i) = x2i_i % rAttr(index_x2i_Fixx_rofi, n) - bergLatentHeatFlux(i) = bergFreshwaterFlux(i) * & - (seaiceLatentHeatMelting - seaiceFreshIceSpecificHeat*bergTemperature) - endif + bergFreshwaterFlux(i) = x2i_i % rAttr(index_x2i_Fixx_rofi, n) + bergLatentHeatFlux(i) = bergFreshwaterFlux(i) * & + (seaiceLatentHeatMelting - seaiceFreshIceSpecificHeat*bergTemperature) ! set aerosols, if configured if (config_use_aerosols) then @@ -2670,13 +2666,11 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_dmpar_exch_halo_field(uAirVelocityField) call mpas_dmpar_exch_halo_field(vAirVelocityField) - if (.not. config_use_data_icebergs) then - call mpas_pool_get_subpool(domain % blocklist % structs, 'berg_fluxes', icebergFluxes) - call mpas_pool_get_field(icebergFluxes, 'bergFreshwaterFlux', bergFreshwaterFluxField) - call mpas_pool_get_field(icebergFluxes, 'bergLatentHeatFlux', bergLatentHeatFluxField) - call mpas_dmpar_exch_halo_field(bergFreshwaterFluxField) - call mpas_dmpar_exch_halo_field(bergLatentHeatFluxField) - endif + call mpas_pool_get_subpool(domain % blocklist % structs, 'berg_fluxes', icebergFluxes) + call mpas_pool_get_field(icebergFluxes, 'bergFreshwaterFlux', bergFreshwaterFluxField) + call mpas_pool_get_field(icebergFluxes, 'bergLatentHeatFlux', bergLatentHeatFluxField) + call mpas_dmpar_exch_halo_field(bergFreshwaterFluxField) + call mpas_dmpar_exch_halo_field(bergLatentHeatFluxField) if (config_use_aerosols) then call mpas_dmpar_exch_halo_field(atmosAerosolFluxField) diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index fa2a2dae6fb6..7eac5b7166bd 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -1866,9 +1866,9 @@ description="Initial temperature of icebergs." possible_values="Any real number." /> - domain % blocklist call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) call mpas_pool_get_array(berg_forcing, 'runningMeanRemovedIceRunoff', runningMeanRemovedIceRunoff) call mpas_pool_get_array(berg_forcing, 'areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux', & areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux) scaling = runningMeanRemovedIceRunoff / areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux - else + + elseif (trim(config_dib_scale_mode) == 'coupler_ice_runoff') then + ! TODO: add check for both of these options + + ! global reudction of coupler ice runoff + globalBergFluxIn = 0.0_RKIND + globalBergFluxOut = 0.0_RKIND + block => domain % blocklist + do while (associated(block)) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "berg_fluxes", berg_fluxes) + call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_array(mesh, "areaCell", areaCell) + call MPAS_pool_get_array(mesh, "latCell", latCell) + + call MPAS_pool_get_array(berg_fluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call mpas_pool_get_array(berg_forcing, 'areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux', & + areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux) + + do iCell = 1, nCellsSolve + ! TODO: Generalize to both ice sheets, accounting for the possibility of rofi from + ! runoff model at low-mid latitudes + if ((latCell(iCell) < 0.0_RKIND) .and. (bergFreshwaterFlux(iCell) > 0.0_RKIND)) then + globalBergFluxIn = globalBergFluxIn + areaCell(iCell) * bergFreshwaterFlux(iCell) + endif + enddo + + block => block % next + enddo + + call mpas_dmpar_sum_real(domain % dminfo, globalBergFluxIn, globalBergFluxOut) + scaling = globalBergFluxOut / areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux + call mpas_log_write("globalBergIn=$r, globalBergOut=$r, iceberg flux scaling=$r", realArgs=(/globalBergFluxIn, globalBergFluxOut, scaling/)) + if (scaling == 0.0_RKIND) scaling = 1.0_RKIND ! coupler rofi flux may be 0 on first coupling interval + + elseif (trim(config_dib_scale_mode) == 'none') then scaling = 1.0_RKIND + else + call mpas_log_write('Unknown value for config_dib_scale_mode', MPAS_LOG_ERR) + ! TODO: how to throw an error? + return end if block => domain % blocklist From 15ae5b934550315d76826c660449a24b289bbb79 Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Sat, 30 Aug 2025 20:31:47 -0500 Subject: [PATCH 9/9] Move DIB spreading of coupler Fixx_rofi flux ice_import_mct plus fixups This commit does 2 things: * Most obviously, I moved the code that uses the global sum of the coupler iceberg flux to ice_comp_mct. I did this because the spreading was not occurring and I thought there might be a sequencing problem with it being called from mpas_seaice_forcing.F. By putting the scalign directly after the Fixx_rofi field is imported to bergFreshwaterFlux, it ensures there is not a lag in the scaling being applied. * Adds areaIntegAnnMeanDataIcebergFreshwaterFlux to the input stream reading DIB information. Without this, the areaIntegAnnMeanDataIcebergFreshwaterFlux field will default to 0, which could well be the explanation for why the previous commit didn't work right. So it is possible the scaling could move back to mpas_seaice_forcing.F, but I feel it is more appropriate to have it occur immediately after importing the field. However, this decision should be informed by input from other developers. This commit has some to-do items: * Currently the global sum of bergFreshwaterFlux is used for DIB scaling. This ignores the fact that bergFreshwaterFlux could exist for both ice sheets, as well as the fact that bergFreshwaterFlux is assigned value from Fixx_rofi, which as designed will include rofi from both GLC and ROF components (but ROF is not currently hooked up). It is unclear if we want the scaling/spreading to use rofi from ROF. Handling the other issue - treating AIS and GIS bergFreshwaterFlux separately - is likely to require a mask or latitude assumption combined with using multiple DIB files. Note that if we adopt the Schmidt and Mankoff DIB-by-region mappings, we could use the region masks to handle the separation between ice sheets - by appending the regions from the ice sheets, nothing about the implementation would need to know that a specific region applies to one ice sheet or the other. So it might be worth adding that to this PR and making region masks a requirement. * indentation needs cleanup --- components/mpas-seaice/cime_config/buildnml | 1 + components/mpas-seaice/driver/ice_comp_mct.F | 112 +++++++++++++++++- components/mpas-seaice/src/Registry.xml | 7 ++ .../mpas_seaice_core_interface.F | 3 +- .../src/shared/mpas_seaice_forcing.F | 36 +----- 5 files changed, 122 insertions(+), 37 deletions(-) diff --git a/components/mpas-seaice/cime_config/buildnml b/components/mpas-seaice/cime_config/buildnml index 68ba3075a44a..a1acddf6d9d7 100755 --- a/components/mpas-seaice/cime_config/buildnml +++ b/components/mpas-seaice/cime_config/buildnml @@ -680,6 +680,7 @@ def buildnml(case, caseroot, compname): lines.append(' input_interval="none" >') lines.append('') lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append('') diff --git a/components/mpas-seaice/driver/ice_comp_mct.F b/components/mpas-seaice/driver/ice_comp_mct.F index 001b0f8b405e..54e4f37b9675 100644 --- a/components/mpas-seaice/driver/ice_comp_mct.F +++ b/components/mpas-seaice/driver/ice_comp_mct.F @@ -2186,7 +2186,8 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ character(len=strKIND), pointer :: & config_column_physics_type, & config_thermodynamics_type, & - config_ocean_surface_type + config_ocean_surface_type, & + config_dib_scale_mode type (field1DReal), pointer :: & seaSurfaceTemperatureField, & @@ -2307,6 +2308,7 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_pool_get_config(configs, "config_thermodynamics_type", config_thermodynamics_type) call mpas_pool_get_config(configs, "config_ocean_surface_type", config_ocean_surface_type) call MPAS_pool_get_config(configs, "config_use_data_icebergs", config_use_data_icebergs) + call MPAS_pool_get_config(configs, "config_dib_scale_mode", config_dib_scale_mode) call MPAS_pool_get_config(configs, "config_iceberg_temperature", bergTemperature) call mpas_pool_get_config(configs, "config_use_aerosols", config_use_aerosols) call mpas_pool_get_config(configs, "config_use_modal_aerosols", config_use_modal_aerosols) @@ -2699,6 +2701,10 @@ subroutine ice_import_mct(x2i_i, errorCode)!{{{ call mpas_dmpar_exch_halo_field(oceanDissolvedIronConcField) endif + if (trim(config_dib_scale_mode) == 'coupler_ice_runoff') then + call scale_icebergs(domain) + endif + ! REVISION HISTORY: ! Revised Andrew Roberts May 2021 !----------------------------------------------------------------------- @@ -3275,6 +3281,110 @@ subroutine frazil_mass(freezingPotential, frazilMassFlux, seaSurfaceSalinity) end subroutine frazil_mass!}}} + + subroutine scale_icebergs(domain) + use seaice_constants, only: & + seaiceLatentHeatMelting, & ! latent heat of melting of fresh ice (J/kg) + seaiceFreshIceSpecificHeat ! specific heat of fresh ice (J/kg/K) + + type(domain_type), intent(inout) :: & + domain + + type(block_type), pointer :: & + block + + type(MPAS_pool_type), pointer :: & + mesh, & + berg_forcing, & + berg_fluxes + + integer, pointer :: & + nCellsSolve + + real(kind=RKIND), dimension(:), pointer :: & + bergFreshwaterFluxData, & ! iceberg freshwater flux read in from file (kg/m^2/s) + bergFreshwaterFlux, & ! iceberg freshwater flux for ocean (kg/m^2/s) + bergLatentHeatFlux, & ! iceberg latent heat flux for ocean (J/m^2/s) + areaCell, & + latCell + + real(kind=RKIND), pointer :: & + bergTemperature, & ! iceberg temperature + areaIntegAnnMeanDataIcebergFreshwaterFlux, & ! area integrated, annual mean freshwater flux from icebegs and ice shelves (kg/s) + runningMeanRemovedIceRunoff ! the area integrated, running mean of removed ice runoff (kg/s) + + integer :: & + iCell + + real(kind=RKIND) :: & + scaling, & + globalBergFluxIn, & + globalBergFluxOut + + call MPAS_pool_get_config(domain % configs, "config_iceberg_temperature", & + bergTemperature) + + + ! global reudction of coupler ice runoff + globalBergFluxIn = 0.0_RKIND + globalBergFluxOut = 0.0_RKIND + block => domain % blocklist + do while (associated(block)) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "berg_fluxes", berg_fluxes) + call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + call MPAS_pool_get_array(mesh, "areaCell", areaCell) + call MPAS_pool_get_array(mesh, "latCell", latCell) + + call MPAS_pool_get_array(berg_fluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call mpas_pool_get_array(berg_forcing, 'areaIntegAnnMeanDataIcebergFreshwaterFlux', & + areaIntegAnnMeanDataIcebergFreshwaterFlux) + + do iCell = 1, nCellsSolve + ! TODO: Generalize to both ice sheets, accounting for the possibility of rofi from + ! runoff model at low-mid latitudes + if ((latCell(iCell) < 0.0_RKIND) .and. (bergFreshwaterFlux(iCell) > 0.0_RKIND)) then + globalBergFluxIn = globalBergFluxIn + areaCell(iCell) * bergFreshwaterFlux(iCell) + endif + enddo + + block => block % next + enddo + + call mpas_dmpar_sum_real(domain % dminfo, globalBergFluxIn, globalBergFluxOut) + scaling = globalBergFluxOut / areaIntegAnnMeanDataIcebergFreshwaterFlux + call mpas_log_write("globalBergIn=$r, globalBergOut=$r, areaIntegAnnMeanDataIcebergFreshwaterFlux=$r, iceberg flux scaling=$r", realArgs=(/globalBergFluxIn, globalBergFluxOut, areaIntegAnnMeanDataIcebergFreshwaterFlux, scaling/)) + if (scaling == 0.0_RKIND) scaling = 1.0_RKIND ! coupler rofi flux may be 0 on first coupling interval + + block => domain % blocklist + do while (associated(block)) + + call MPAS_pool_get_subpool(block % structs, "mesh", mesh) + call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) + call MPAS_pool_get_subpool(block % structs, "berg_fluxes", berg_fluxes) + + call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) + + call MPAS_pool_get_array(berg_forcing, "bergFreshwaterFluxData", bergFreshwaterFluxData) + call MPAS_pool_get_array(berg_fluxes, "bergFreshwaterFlux", bergFreshwaterFlux) + call MPAS_pool_get_array(berg_fluxes, "bergLatentHeatFlux", bergLatentHeatFlux) + + do iCell = 1, nCellsSolve + + bergFreshwaterFlux(iCell) = scaling * bergFreshwaterFluxData(iCell) + bergLatentHeatFlux(iCell) = -scaling * bergFreshwaterFluxData(iCell) * & + (seaiceLatentHeatMelting - seaiceFreshIceSpecificHeat*bergTemperature) + enddo + + block => block % next + enddo + + end subroutine scale_icebergs + + !*********************************************************************** !BOP ! diff --git a/components/mpas-seaice/src/Registry.xml b/components/mpas-seaice/src/Registry.xml index 7eac5b7166bd..bd088130f598 100644 --- a/components/mpas-seaice/src/Registry.xml +++ b/components/mpas-seaice/src/Registry.xml @@ -4956,6 +4956,13 @@ units="kg s-1" packages="pkgScaledDIB" description="The area integrated, annually averaged freshwater flux into the ocean from both data icebergs and ice-shelf melting." + /> + domain % blocklist - do while (associated(block)) - - call MPAS_pool_get_subpool(block % structs, "mesh", mesh) - call MPAS_pool_get_subpool(block % structs, "berg_fluxes", berg_fluxes) - call MPAS_pool_get_subpool(block % structs, "berg_forcing", berg_forcing) - - call MPAS_pool_get_dimension(mesh, "nCellsSolve", nCellsSolve) - call MPAS_pool_get_array(mesh, "areaCell", areaCell) - call MPAS_pool_get_array(mesh, "latCell", latCell) - - call MPAS_pool_get_array(berg_fluxes, "bergFreshwaterFlux", bergFreshwaterFlux) - call mpas_pool_get_array(berg_forcing, 'areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux', & - areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux) - - do iCell = 1, nCellsSolve - ! TODO: Generalize to both ice sheets, accounting for the possibility of rofi from - ! runoff model at low-mid latitudes - if ((latCell(iCell) < 0.0_RKIND) .and. (bergFreshwaterFlux(iCell) > 0.0_RKIND)) then - globalBergFluxIn = globalBergFluxIn + areaCell(iCell) * bergFreshwaterFlux(iCell) - endif - enddo - - block => block % next - enddo - - call mpas_dmpar_sum_real(domain % dminfo, globalBergFluxIn, globalBergFluxOut) - scaling = globalBergFluxOut / areaIntegAnnMeanDataIcebergIceShelfFreshwaterFlux - call mpas_log_write("globalBergIn=$r, globalBergOut=$r, iceberg flux scaling=$r", realArgs=(/globalBergFluxIn, globalBergFluxOut, scaling/)) - if (scaling == 0.0_RKIND) scaling = 1.0_RKIND ! coupler rofi flux may be 0 on first coupling interval + return ! handled in ice_comp_mct.F elseif (trim(config_dib_scale_mode) == 'none') then scaling = 1.0_RKIND