From d8720674fd5595747937a259bac1ef0e60fa0669 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Mon, 15 Apr 2024 15:36:13 -0500 Subject: [PATCH 1/9] Add freshwater tracer without full capability --- components/mpas-ocean/src/shared/Makefile | 5 +- .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 24 +++ .../src/shared/mpas_ocn_tracer_freshwater.F | 174 ++++++++++++++++++ .../Registry_freshwaterTracers.xml | 174 ++++++++++++++++++ .../src/tracer_groups/Registry_tracers.xml | 1 + 5 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F create mode 100644 components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml diff --git a/components/mpas-ocean/src/shared/Makefile b/components/mpas-ocean/src/shared/Makefile index 27c3db10fee1..398f4ed8e25a 100644 --- a/components/mpas-ocean/src/shared/Makefile +++ b/components/mpas-ocean/src/shared/Makefile @@ -51,6 +51,7 @@ OBJS = mpas_ocn_init_routines.o \ mpas_ocn_tracer_ideal_age.o \ mpas_ocn_tracer_TTD.o \ mpas_ocn_tracer_ecosys.o \ + mpas_ocn_tracer_freshwater.o \ mpas_ocn_tracer_DMS.o \ mpas_ocn_tracer_MacroMolecules.o \ mpas_ocn_tracer_CFC.o \ @@ -83,7 +84,7 @@ all: $(OBJS) mpas_ocn_init_routines.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_mesh.o mpas_ocn_diagnostics.o mpas_ocn_diagnostics_variables.o mpas_ocn_gm.o mpas_ocn_submesoscale_eddies.o mpas_ocn_forcing.o mpas_ocn_surface_land_ice_fluxes.o -mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_tracer_CFC.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_vel_self_attraction_loading.o mpas_ocn_vel_tidal_potential.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_thick_hadv.o mpas_ocn_thick_vadv.o mpas_ocn_vel_hadv_coriolis.o mpas_ocn_vel_pressure_grad.o mpas_ocn_vel_vadv.o mpas_ocn_vel_hmix.o mpas_ocn_vel_forcing.o mpas_ocn_manufactured_solution.o +mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_freshwater.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_tracer_CFC.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_vel_self_attraction_loading.o mpas_ocn_vel_tidal_potential.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_thick_hadv.o mpas_ocn_thick_vadv.o mpas_ocn_vel_hadv_coriolis.o mpas_ocn_vel_pressure_grad.o mpas_ocn_vel_vadv.o mpas_ocn_vel_hmix.o mpas_ocn_vel_forcing.o mpas_ocn_manufactured_solution.o mpas_ocn_diagnostics.o: mpas_ocn_thick_ale.o mpas_ocn_equation_of_state.o mpas_ocn_gm.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_vertical_advection.o mpas_ocn_submesoscale_eddies.o mpas_ocn_subgrid.o @@ -205,6 +206,8 @@ mpas_ocn_tracer_TTD.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_tracer_ecosys.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_framework_forcing.o mpas_ocn_diagnostics_variables.o +mpas_ocn_tracer_freshwater.o: mpas_ocn_constants.o mpas_ocn_config.o + mpas_ocn_tracer_DMS.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_tracer_MacroMolecules.o: mpas_ocn_constants.o mpas_ocn_config.o diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index 0d049d1eb422..e470a26533d5 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -46,6 +46,7 @@ module ocn_tendency use ocn_tracer_surface_restoring use ocn_tracer_interior_restoring use ocn_tracer_exponential_decay + use ocn_tracer_freshwater use ocn_tracer_ideal_age use ocn_tracer_TTD use ocn_tracer_surface_flux_to_tend @@ -804,6 +805,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & ! Get tracers from pool, determine number of tracers in group call mpas_pool_get_array(tracersPool, groupName, & tracerGroup, timeLevel) + !call mpas_pool_print_summary(tracersPool, MPAS_POOL_FIELD, .true.) nTracersGroup = size(tracerGroup, dim=1) ! Get Tendency array @@ -811,12 +813,18 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & call mpas_pool_get_array(tracersTendPool, & modifiedGroupName, & tracerGroupTend) + call mpas_pool_print_summary(tracersTendPool, MPAS_POOL_FIELD, .true.) ! Get surface flux array modifiedGroupName = groupName // "SurfaceFlux" call mpas_pool_get_array(tracersSurfaceFluxPool, & modifiedGroupName, & tracerGroupSurfaceFlux) + if (associated(tracerGroupSurfaceFlux)) then + call mpas_log_write(modifiedGroupName // " is associated") + else + call mpas_log_write(modifiedGroupName // " is not associated") + endif ! Get Array of total surface temp/salt flux ! (includes thickness tendencies) @@ -842,6 +850,12 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & tracerGroupSurfaceFluxSubglacialRunoff) end if + if (associated(tracerGroupSurfaceFluxRunoff)) then + call mpas_log_write(modifiedGroupName // " is associated") + else + call mpas_log_write(modifiedGroupName // " is not associated") + endif + call mpas_pool_print_summary(tracersSurfaceFluxPool, MPAS_POOL_FIELD, .true.) ! Get surface flux removed array to keep track of how much ! flux is ignored modifiedGroupName = groupName // "SurfaceFluxRemoved" @@ -1044,6 +1058,16 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & call ocn_surface_land_ice_fluxes_tracers(meshPool, groupName, & forcingPool, tracerGroupSurfaceFlux, err) + ! + ! compute freshwaterTracers surface fluxes, there are no interior sources/sinks + ! + if ( groupName == 'freshwaterTracers' ) then + + call ocn_tracer_freshwater_surface_flux_compute(tracersPool, forcingPool, & + nTracersGroup, nCellsOwned, & + tracerGroupSurfaceFlux, tracerGroupSurfaceFluxRunoff, err) + endif ! freshwater + ! ! other additions to tracerGroupSurfaceFlux should be added here ! diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F new file mode 100644 index 000000000000..8674e31c1876 --- /dev/null +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F @@ -0,0 +1,174 @@ +! Copyright (c) 2013, Los Alamos National Security, LLC (LANS) +! and the University Corporation for Atmospheric Research (UCAR). +! +! Unless noted otherwise source code is licensed under the BSD license. +! Additional copyright and license information can be found in the LICENSE file +! distributed with this code, or at http://mpas-dev.github.io/license.html +! +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! +! ocn_tracer_freshwater +! +!> \brief MPAS freshwater tracer routines +!> \author Mathew Maltrud +!> \date 08/19/2021 +!> \details +!> This module contains routines for computing the tracer tendency due to freshwater fluxes +! +!----------------------------------------------------------------------- + +module ocn_tracer_freshwater + + use mpas_kind_types + use mpas_derived_types + use mpas_pool_routines + use ocn_constants + use ocn_config + + implicit none + private + save + + !-------------------------------------------------------------------- + ! + ! Public parameters + ! + !-------------------------------------------------------------------- + + !-------------------------------------------------------------------- + ! + ! Public member functions + ! + !-------------------------------------------------------------------- + + public :: ocn_tracer_freshwater_surface_flux_compute, & + ocn_tracer_freshwater_init + + !-------------------------------------------------------------------- + ! + ! Private module variables + ! + !-------------------------------------------------------------------- + +!*********************************************************************** + +contains + +!*********************************************************************** +! +! routine ocn_tracer_freshwater_surface_flux_compute +! +!> \brief computes a tracer tendency due to CFC surface fluxes +!> \author Mathew Maltrud +!> \date 12/22/2016 +!> \details +!> This routine computes a tracer tendency due to CFC surface fluxes +! +!----------------------------------------------------------------------- + + subroutine ocn_tracer_freshwater_surface_flux_compute(tracersPool, forcingPool, nTracers, & + nCellsSolve, freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff, err)!{{{ + + + use ocn_config + + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + + ! scalars + integer, intent(in) :: nTracers, nCellsSolve + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + + type (mpas_pool_type), intent(inout) :: tracersPool, forcingPool + + ! two dimensional arrays + real (kind=RKIND), dimension(:,:), intent(inout) :: & + freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + real (kind=RKIND), dimension(:), pointer :: & + rainFlux, snowFlux, riverRunoffFlux, iceRunoffFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, landIceFreshwaterFlux + + integer :: iCell + integer, pointer :: indexRain, indexSnow, indexRiverRunoff, indexIceRunoff, indexSeaIceFreshWater, indexIcebergFreshWater, indexLandIceFreshwater + + err = 0 + + call mpas_pool_get_dimension(tracersPool, 'index_rainConcentration', indexRain) + call mpas_pool_get_dimension(tracersPool, 'index_snowConcentration', indexSnow) + call mpas_pool_get_dimension(tracersPool, 'index_riverRunoffConcentration', indexRiverRunoff) + call mpas_pool_get_dimension(tracersPool, 'index_iceRunoffConcentration', indexIceRunoff) + call mpas_pool_get_dimension(tracersPool, 'index_seaIceFreshWaterConcentration', indexSeaIceFreshWater) + call mpas_pool_get_dimension(tracersPool, 'index_icebergFreshWaterConcentration', indexIcebergFreshWater) + call mpas_pool_get_dimension(tracersPool, 'index_landIceFreshwaterConcentration', indexLandIceFreshwater) + + call mpas_pool_get_array(forcingPool, 'rainFlux', rainFlux) + call mpas_pool_get_array(forcingPool, 'snowFlux', snowFlux) + call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) + call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) + call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshWaterFlux) + call mpas_pool_get_array(forcingPool, 'icebergFreshWaterFlux', icebergFreshWaterFlux) + call mpas_pool_get_array(forcingPool, 'landIceFreshWaterFlux', landIceFreshwaterFlux) + + do iCell=1,nCellsSolve + freshwaterSurfaceFlux(indexRain, iCell) = rainFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexSnow, iCell) = snowFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexSeaIceFreshWater, iCell) = seaIceFreshWaterFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexIcebergFreshWater, iCell) = icebergFreshWaterFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexLandIceFreshwater, iCell) = landIceFreshwaterFlux(iCell) / rho_sw + freshwaterSurfaceFluxRunoff(indexRiverRunoff, iCell) = riverRunoffFlux(iCell) / rho_sw + enddo ! iCell + + end subroutine ocn_tracer_freshwater_surface_flux_compute!}}} + +!*********************************************************************** +! +! routine ocn_tracer_freshwater_init +! +!> \brief Initializes ocean ideal age +!> \author Mathew Maltrud +!> \date 08/19/2021 +!> \details +!> This routine initializes fields required for tracer ideal age +! +!----------------------------------------------------------------------- + + subroutine ocn_tracer_freshwater_init(domain,err)!{{{ + + type (domain_type), intent(inout) :: domain !< Input/Output: domain information + + integer, intent(out) :: err !< Output: error flag + + err = 0 + + if (.not. config_use_freshwaterTracers) return + + end subroutine ocn_tracer_freshwater_init!}}} + +!*********************************************************************** + +end module ocn_tracer_freshwater + +!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +! vim: foldmethod=marker diff --git a/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml new file mode 100644 index 000000000000..068c455943e7 --- /dev/null +++ b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/mpas-ocean/src/tracer_groups/Registry_tracers.xml b/components/mpas-ocean/src/tracer_groups/Registry_tracers.xml index b8f0d1f519f5..8dd20a59acac 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_tracers.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_tracers.xml @@ -1,6 +1,7 @@ #include "Registry_activeTracers.xml" #include "Registry_debugTracers.xml" #include "Registry_ecosys.xml" +#include "Registry_freshwaterTracers.xml" #include "Registry_DMS.xml" #include "Registry_MacroMolecules.xml" #include "Registry_idealAge.xml" From 264a082548aeabf4346a7a8931b85eca9b5d3752 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Fri, 26 Apr 2024 09:49:30 -0500 Subject: [PATCH 2/9] Move freshwater tracer surface fluxes to bulk forcing --- components/mpas-ocean/src/shared/Makefile | 5 +- .../shared/mpas_ocn_surface_bulk_forcing.F | 117 ++++++++++++ .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 35 ++-- .../src/shared/mpas_ocn_tracer_freshwater.F | 174 ------------------ .../Registry_freshwaterTracers.xml | 20 +- 5 files changed, 143 insertions(+), 208 deletions(-) delete mode 100644 components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F diff --git a/components/mpas-ocean/src/shared/Makefile b/components/mpas-ocean/src/shared/Makefile index 398f4ed8e25a..27c3db10fee1 100644 --- a/components/mpas-ocean/src/shared/Makefile +++ b/components/mpas-ocean/src/shared/Makefile @@ -51,7 +51,6 @@ OBJS = mpas_ocn_init_routines.o \ mpas_ocn_tracer_ideal_age.o \ mpas_ocn_tracer_TTD.o \ mpas_ocn_tracer_ecosys.o \ - mpas_ocn_tracer_freshwater.o \ mpas_ocn_tracer_DMS.o \ mpas_ocn_tracer_MacroMolecules.o \ mpas_ocn_tracer_CFC.o \ @@ -84,7 +83,7 @@ all: $(OBJS) mpas_ocn_init_routines.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_mesh.o mpas_ocn_diagnostics.o mpas_ocn_diagnostics_variables.o mpas_ocn_gm.o mpas_ocn_submesoscale_eddies.o mpas_ocn_forcing.o mpas_ocn_surface_land_ice_fluxes.o -mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_freshwater.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_tracer_CFC.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_vel_self_attraction_loading.o mpas_ocn_vel_tidal_potential.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_thick_hadv.o mpas_ocn_thick_vadv.o mpas_ocn_vel_hadv_coriolis.o mpas_ocn_vel_pressure_grad.o mpas_ocn_vel_vadv.o mpas_ocn_vel_hmix.o mpas_ocn_vel_forcing.o mpas_ocn_manufactured_solution.o +mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_tracer_CFC.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_vel_self_attraction_loading.o mpas_ocn_vel_tidal_potential.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_thick_hadv.o mpas_ocn_thick_vadv.o mpas_ocn_vel_hadv_coriolis.o mpas_ocn_vel_pressure_grad.o mpas_ocn_vel_vadv.o mpas_ocn_vel_hmix.o mpas_ocn_vel_forcing.o mpas_ocn_manufactured_solution.o mpas_ocn_diagnostics.o: mpas_ocn_thick_ale.o mpas_ocn_equation_of_state.o mpas_ocn_gm.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_mesh.o mpas_ocn_diagnostics_variables.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_vertical_advection.o mpas_ocn_submesoscale_eddies.o mpas_ocn_subgrid.o @@ -206,8 +205,6 @@ mpas_ocn_tracer_TTD.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_tracer_ecosys.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_framework_forcing.o mpas_ocn_diagnostics_variables.o -mpas_ocn_tracer_freshwater.o: mpas_ocn_constants.o mpas_ocn_config.o - mpas_ocn_tracer_DMS.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_tracer_MacroMolecules.o: mpas_ocn_constants.o mpas_ocn_config.o diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index d25e147c312b..d31ab07b41fa 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -127,6 +127,9 @@ subroutine ocn_surface_bulk_forcing_tracers(meshPool, groupName, forcingPool, tr if ( trim(groupName) == 'activeTracers' ) then call ocn_surface_bulk_forcing_active_tracers(meshPool, forcingPool, tracerGroup, & tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, layerThickness, dt, err) + elseif ( trim(groupName) == 'freshwaterTracers' ) then + call ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tracerGroup, & + tracersSurfaceFlux, tracersSurfaceFluxRunoff, tracersSurfaceFluxRemoved, err) end if call mpas_timer_stop("bulk_" // trim(groupName)) @@ -880,6 +883,120 @@ subroutine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff(meshPool, f end subroutine ocn_surface_bulk_forcing_active_tracers_subglacial_runoff!}}} +!*********************************************************************** +! +! routine ocn_surface_bulk_forcing_freshwater_tracers +! +!> \brief computes a tracer tendency due to freshwater surface fluxes +!> \author Carolyn Branecky Begeman +!> \date June 2024 +!> \details +!> This routine computes a tracer tendency due to freshwater surface fluxes +! +!----------------------------------------------------------------------- + + subroutine ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tracerGroup, & + freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff, freshwaterSurfaceFluxRemoved, err)!{{{ + + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(in) :: meshPool !< Input: mesh information + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + + type (mpas_pool_type), intent(inout) :: forcingPool + + ! two dimensional arrays + real (kind=RKIND), dimension(:,:), intent(inout) :: & + freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff, freshwaterSurfaceFluxRemoved + real (kind=RKIND), dimension(:,:,:), intent(inout) :: tracerGroup + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + + integer :: iCell, nCells + integer, dimension(:), pointer :: nCellsArray + + type(mpas_pool_type),pointer :: tracersSurfaceFluxPool + integer, pointer :: indexRain, indexSnow, indexRiverRunoff, indexIceRunoff, indexSeaIceFreshWater, & + indexIcebergFreshWater, indexLandIceFreshwater + real (kind=RKIND), dimension(:), pointer :: & + rainFlux, snowFlux, riverRunoffFlux, iceRunoffFlux, seaIceFreshWaterFlux, & + icebergFreshWaterFlux, landIceFreshwaterFlux + + err = 0 + + call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray) + + call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_rainSurfaceFlux', indexRain) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_snowSurfaceFlux', indexSnow) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_riverRunoffFreshWaterSurfaceFlux', indexRiverRunoff) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_iceRunoffFreshWaterSurfaceFlux', indexIceRunoff) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_seaIceFreshWaterSurfaceFlux', indexSeaIceFreshWater) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_icebergFreshWaterSurfaceFlux', indexIcebergFreshWater) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_landIceFreshwaterSurfaceFlux', indexLandIceFreshwater) + + call mpas_pool_get_array(forcingPool, 'rainFlux', rainFlux) + call mpas_pool_get_array(forcingPool, 'snowFlux', snowFlux) + call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) + call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) + call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshWaterFlux) + call mpas_pool_get_array(forcingPool, 'icebergFreshWaterFlux', icebergFreshWaterFlux) + call mpas_pool_get_array(forcingPool, 'landIceFreshwaterFlux', landIceFreshwaterFlux) + + nCells = nCellsArray( 3 ) + do iCell=1,nCells + freshwaterSurfaceFlux(indexRain, iCell) = rainFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexSnow, iCell) = snowFlux(iCell) / rho_sw + freshwaterSurfaceFlux(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw + freshwaterSurfaceFluxRunoff(indexRiverRunoff, iCell) = riverRunoffFlux(iCell) / rho_sw + enddo ! iCell + if (associated(indexSeaIceFreshWater)) then + do iCell=1,nCells + freshwaterSurfaceFlux(indexSeaIceFreshWater, iCell) = seaIceFreshWaterFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexSeaIceFreshWater is not associated') + freshwaterSurfaceFlux(indexSeaIceFreshWater, :) = 0.0_RKIND + endif + if (associated(indexIcebergFreshWater)) then + do iCell=1,nCells + freshwaterSurfaceFlux(indexIcebergFreshWater, iCell) = icebergFreshWaterFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexIcebergFreshWater is not associated') + freshwaterSurfaceFlux(indexIcebergFreshWater, :) = 0.0_RKIND + endif + if (associated(indexLandIceFreshwater) .and. associated(landIceFreshwaterFlux)) then + do iCell=1,nCells + freshwaterSurfaceFlux(indexLandIceFreshwater, iCell) = landIceFreshwaterFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexLandIceFreshwater or landIceFreshwaterFlux is not associated') + freshwaterSurfaceFlux(indexLandIceFreshwater, :) = 0.0_RKIND + endif + + end subroutine ocn_surface_bulk_forcing_freshwater_tracers!}}} + end module ocn_surface_bulk_forcing diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index e470a26533d5..e0d46a305515 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -46,7 +46,6 @@ module ocn_tendency use ocn_tracer_surface_restoring use ocn_tracer_interior_restoring use ocn_tracer_exponential_decay - use ocn_tracer_freshwater use ocn_tracer_ideal_age use ocn_tracer_TTD use ocn_tracer_surface_flux_to_tend @@ -801,11 +800,22 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & modifiedConfigName = configBase // '_ttd_forcing' call mpas_pool_get_config(ocnConfigs, modifiedConfigName, & config_use_tracerGroup_ttd_forcing) - + if ( groupName == 'freshwaterTracers' ) then + if (config_use_tracerGroup_surface_restoring) & + call mpas_log_write('surface restoring not supported for freshwaterTracers group') + if (config_use_tracerGroup_interior_restoring) & + call mpas_log_write('interior restoring not supported for freshwaterTracers group') + if (config_use_tracerGroup_exponential_decay) & + call mpas_log_write('exponential decay not supported for freshwaterTracers group') + if (config_use_tracerGroup_idealAge_forcing) & + ! TODO support this + call mpas_log_write('idealAge forcing not supported for freshwaterTracers group') + if (config_use_tracerGroup_ttd_forcing) & + call mpas_log_write('TTD forcing not supported for freshwaterTracers group') + endif ! Get tracers from pool, determine number of tracers in group call mpas_pool_get_array(tracersPool, groupName, & tracerGroup, timeLevel) - !call mpas_pool_print_summary(tracersPool, MPAS_POOL_FIELD, .true.) nTracersGroup = size(tracerGroup, dim=1) ! Get Tendency array @@ -813,18 +823,12 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & call mpas_pool_get_array(tracersTendPool, & modifiedGroupName, & tracerGroupTend) - call mpas_pool_print_summary(tracersTendPool, MPAS_POOL_FIELD, .true.) ! Get surface flux array modifiedGroupName = groupName // "SurfaceFlux" call mpas_pool_get_array(tracersSurfaceFluxPool, & modifiedGroupName, & tracerGroupSurfaceFlux) - if (associated(tracerGroupSurfaceFlux)) then - call mpas_log_write(modifiedGroupName // " is associated") - else - call mpas_log_write(modifiedGroupName // " is not associated") - endif ! Get Array of total surface temp/salt flux ! (includes thickness tendencies) @@ -855,6 +859,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & else call mpas_log_write(modifiedGroupName // " is not associated") endif + call mpas_pool_print_summary(tracersSurfaceFluxPool, MPAS_POOL_FIELD, .true.) ! Get surface flux removed array to keep track of how much ! flux is ignored @@ -904,7 +909,7 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & ! compute surface tracer flux from bulk forcing ! if (config_use_tracerGroup_surface_bulk_forcing) then - + ! This applies surface fluxes if groupName is activeTracers call ocn_surface_bulk_forcing_tracers(meshPool, groupName, & forcingPool, tracerGroup, & tracerGroupSurfaceFlux, & @@ -1058,16 +1063,6 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & call ocn_surface_land_ice_fluxes_tracers(meshPool, groupName, & forcingPool, tracerGroupSurfaceFlux, err) - ! - ! compute freshwaterTracers surface fluxes, there are no interior sources/sinks - ! - if ( groupName == 'freshwaterTracers' ) then - - call ocn_tracer_freshwater_surface_flux_compute(tracersPool, forcingPool, & - nTracersGroup, nCellsOwned, & - tracerGroupSurfaceFlux, tracerGroupSurfaceFluxRunoff, err) - endif ! freshwater - ! ! other additions to tracerGroupSurfaceFlux should be added here ! diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F deleted file mode 100644 index 8674e31c1876..000000000000 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_freshwater.F +++ /dev/null @@ -1,174 +0,0 @@ -! Copyright (c) 2013, Los Alamos National Security, LLC (LANS) -! and the University Corporation for Atmospheric Research (UCAR). -! -! Unless noted otherwise source code is licensed under the BSD license. -! Additional copyright and license information can be found in the LICENSE file -! distributed with this code, or at http://mpas-dev.github.io/license.html -! -!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -! -! ocn_tracer_freshwater -! -!> \brief MPAS freshwater tracer routines -!> \author Mathew Maltrud -!> \date 08/19/2021 -!> \details -!> This module contains routines for computing the tracer tendency due to freshwater fluxes -! -!----------------------------------------------------------------------- - -module ocn_tracer_freshwater - - use mpas_kind_types - use mpas_derived_types - use mpas_pool_routines - use ocn_constants - use ocn_config - - implicit none - private - save - - !-------------------------------------------------------------------- - ! - ! Public parameters - ! - !-------------------------------------------------------------------- - - !-------------------------------------------------------------------- - ! - ! Public member functions - ! - !-------------------------------------------------------------------- - - public :: ocn_tracer_freshwater_surface_flux_compute, & - ocn_tracer_freshwater_init - - !-------------------------------------------------------------------- - ! - ! Private module variables - ! - !-------------------------------------------------------------------- - -!*********************************************************************** - -contains - -!*********************************************************************** -! -! routine ocn_tracer_freshwater_surface_flux_compute -! -!> \brief computes a tracer tendency due to CFC surface fluxes -!> \author Mathew Maltrud -!> \date 12/22/2016 -!> \details -!> This routine computes a tracer tendency due to CFC surface fluxes -! -!----------------------------------------------------------------------- - - subroutine ocn_tracer_freshwater_surface_flux_compute(tracersPool, forcingPool, nTracers, & - nCellsSolve, freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff, err)!{{{ - - - use ocn_config - - !----------------------------------------------------------------- - ! - ! input variables - ! - !----------------------------------------------------------------- - - ! scalars - integer, intent(in) :: nTracers, nCellsSolve - - !----------------------------------------------------------------- - ! - ! input/output variables - ! - !----------------------------------------------------------------- - - type (mpas_pool_type), intent(inout) :: tracersPool, forcingPool - - ! two dimensional arrays - real (kind=RKIND), dimension(:,:), intent(inout) :: & - freshwaterSurfaceFlux, freshwaterSurfaceFluxRunoff - - !----------------------------------------------------------------- - ! - ! output variables - ! - !----------------------------------------------------------------- - - integer, intent(out) :: err !< Output: Error flag - - !----------------------------------------------------------------- - ! - ! local variables - ! - !----------------------------------------------------------------- - real (kind=RKIND), dimension(:), pointer :: & - rainFlux, snowFlux, riverRunoffFlux, iceRunoffFlux, seaIceFreshWaterFlux, icebergFreshWaterFlux, landIceFreshwaterFlux - - integer :: iCell - integer, pointer :: indexRain, indexSnow, indexRiverRunoff, indexIceRunoff, indexSeaIceFreshWater, indexIcebergFreshWater, indexLandIceFreshwater - - err = 0 - - call mpas_pool_get_dimension(tracersPool, 'index_rainConcentration', indexRain) - call mpas_pool_get_dimension(tracersPool, 'index_snowConcentration', indexSnow) - call mpas_pool_get_dimension(tracersPool, 'index_riverRunoffConcentration', indexRiverRunoff) - call mpas_pool_get_dimension(tracersPool, 'index_iceRunoffConcentration', indexIceRunoff) - call mpas_pool_get_dimension(tracersPool, 'index_seaIceFreshWaterConcentration', indexSeaIceFreshWater) - call mpas_pool_get_dimension(tracersPool, 'index_icebergFreshWaterConcentration', indexIcebergFreshWater) - call mpas_pool_get_dimension(tracersPool, 'index_landIceFreshwaterConcentration', indexLandIceFreshwater) - - call mpas_pool_get_array(forcingPool, 'rainFlux', rainFlux) - call mpas_pool_get_array(forcingPool, 'snowFlux', snowFlux) - call mpas_pool_get_array(forcingPool, 'riverRunoffFlux', riverRunoffFlux) - call mpas_pool_get_array(forcingPool, 'iceRunoffFlux', iceRunoffFlux) - call mpas_pool_get_array(forcingPool, 'seaIceFreshWaterFlux', seaIceFreshWaterFlux) - call mpas_pool_get_array(forcingPool, 'icebergFreshWaterFlux', icebergFreshWaterFlux) - call mpas_pool_get_array(forcingPool, 'landIceFreshWaterFlux', landIceFreshwaterFlux) - - do iCell=1,nCellsSolve - freshwaterSurfaceFlux(indexRain, iCell) = rainFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexSnow, iCell) = snowFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexSeaIceFreshWater, iCell) = seaIceFreshWaterFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexIcebergFreshWater, iCell) = icebergFreshWaterFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexLandIceFreshwater, iCell) = landIceFreshwaterFlux(iCell) / rho_sw - freshwaterSurfaceFluxRunoff(indexRiverRunoff, iCell) = riverRunoffFlux(iCell) / rho_sw - enddo ! iCell - - end subroutine ocn_tracer_freshwater_surface_flux_compute!}}} - -!*********************************************************************** -! -! routine ocn_tracer_freshwater_init -! -!> \brief Initializes ocean ideal age -!> \author Mathew Maltrud -!> \date 08/19/2021 -!> \details -!> This routine initializes fields required for tracer ideal age -! -!----------------------------------------------------------------------- - - subroutine ocn_tracer_freshwater_init(domain,err)!{{{ - - type (domain_type), intent(inout) :: domain !< Input/Output: domain information - - integer, intent(out) :: err !< Output: error flag - - err = 0 - - if (.not. config_use_freshwaterTracers) return - - end subroutine ocn_tracer_freshwater_init!}}} - -!*********************************************************************** - -end module ocn_tracer_freshwater - -!||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -! vim: foldmethod=marker diff --git a/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml index 068c455943e7..9c0dc63f2272 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml @@ -52,7 +52,7 @@ - - - - - - - - - - Date: Fri, 26 Apr 2024 10:22:37 -0500 Subject: [PATCH 3/9] Fixup ice runoff to runoff surface flux array --- .../mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index d31ab07b41fa..5da4975e4dc0 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -967,7 +967,7 @@ subroutine ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tr do iCell=1,nCells freshwaterSurfaceFlux(indexRain, iCell) = rainFlux(iCell) / rho_sw freshwaterSurfaceFlux(indexSnow, iCell) = snowFlux(iCell) / rho_sw - freshwaterSurfaceFlux(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw + freshwaterSurfaceFluxRunoff(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw freshwaterSurfaceFluxRunoff(indexRiverRunoff, iCell) = riverRunoffFlux(iCell) / rho_sw enddo ! iCell if (associated(indexSeaIceFreshWater)) then From b9ded791eb717d7c75a8a5a6cfdf8a09283ebab9 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Tue, 2 Jul 2024 18:18:03 -0500 Subject: [PATCH 4/9] Change namelist bld files --- components/mpas-ocean/bld/build-namelist | 14 ++++++++++++++ .../mpas-ocean/bld/build-namelist-group-list | 1 + components/mpas-ocean/bld/build-namelist-section | 13 +++++++++++++ 3 files changed, 28 insertions(+) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index e2acfc35fce7..4cc2361104b4 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -1186,6 +1186,19 @@ if ($ice_bgc eq 'ice_bgc' ) { } add_default($nl, 'config_use_ecosysTracers_river_inputs_from_coupler'); +#################################################### +# Namelist group: tracer_forcing_freshwaterTracers # +#################################################### + +add_default($nl, 'config_use_freshwaterTracers'); +add_default($nl, 'config_use_freshwaterTracers_surface_bulk_forcing'); +add_default($nl, 'config_use_freshwaterTracers_surface_restoring'); +add_default($nl, 'config_use_freshwaterTracers_interior_restoring'); +add_default($nl, 'config_use_freshwaterTracers_exponential_decay'); +add_default($nl, 'config_use_freshwaterTracers_idealAge_forcing'); +add_default($nl, 'config_use_freshwaterTracers_ttd_forcing'); +add_default($nl, 'config_use_freshwaterTracers_surface_value'); + ############################################# # Namelist group: tracer_forcing_DMSTracers # ############################################# @@ -1855,6 +1868,7 @@ my @groups = qw(run_modes tracer_forcing_dmstracers tracer_forcing_macromoleculestracers tracer_forcing_idealagetracers + tracer_forcing_freshwatertracers tracer_forcing_cfctracers am_globalstats am_surfaceareaweightedaverages diff --git a/components/mpas-ocean/bld/build-namelist-group-list b/components/mpas-ocean/bld/build-namelist-group-list index c109ba9990e3..2adb0b92288b 100644 --- a/components/mpas-ocean/bld/build-namelist-group-list +++ b/components/mpas-ocean/bld/build-namelist-group-list @@ -44,6 +44,7 @@ my @groups = qw(run_modes tracer_forcing_activetracers tracer_forcing_debugtracers tracer_forcing_ecosystracers + tracer_forcing_freshwatertracers tracer_forcing_dmstracers tracer_forcing_macromoleculestracers tracer_forcing_idealagetracers diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index ef17ac9bc3d5..faa4b12d7e57 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -605,6 +605,19 @@ add_default($nl, 'config_ecosysTracers_diagnostic_fields_level3'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level4'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level5'); +#################################################### +# Namelist group: tracer_forcing_freshwaterTracers # +#################################################### + +add_default($nl, 'config_use_freshwaterTracers'); +add_default($nl, 'config_use_freshwaterTracers_surface_bulk_forcing'); +add_default($nl, 'config_use_freshwaterTracers_surface_restoring'); +add_default($nl, 'config_use_freshwaterTracers_interior_restoring'); +add_default($nl, 'config_use_freshwaterTracers_exponential_decay'); +add_default($nl, 'config_use_freshwaterTracers_idealAge_forcing'); +add_default($nl, 'config_use_freshwaterTracers_ttd_forcing'); +add_default($nl, 'config_use_freshwaterTracers_surface_value'); + ############################################# # Namelist group: tracer_forcing_DMSTracers # ############################################# From dd670fc7084889fc0c50888d3af34aa265cb4225 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Thu, 11 Jul 2024 16:11:58 -0500 Subject: [PATCH 5/9] Update e3sm namelist files --- .../namelist_defaults_mpaso.xml | 10 +++ .../namelist_definition_mpaso.xml | 63 +++++++++++++++++++ 2 files changed, 73 insertions(+) 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 b21b012ba74a..57f43010610f 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -749,6 +749,16 @@ .false. .false. + +.false. +.true. +.false. +.false. +.false. +.false. +.false. +.false. + .false. .false. 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 53b30d5347a2..bfabf0aed9b1 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -3155,6 +3155,69 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + +if true, the 'freshwaterTracers' category is enabled for the run + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, surface bulk forcing from coupler is added to surfaceTracerFlux in 'freshwaterTracers' category. True by default because the main function of this tracer group is tracking freshwater fluxes + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, surface restoring source is applied to tracers in 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, interior restoring source is applied to tracers in 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, exponential decay source is applied to tracers in 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, idealAge forcing source is applied to tracers in 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, transit time distribution forcing source is applied to tracers in 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + + + +if true, surface value is computed for 'freshwaterTracers' category + +Valid Values: .true. or .false. +Default: Defined in namelist_defaults.xml + From 6d9357c48d5077f8b49b01c9bf624fd07be9965d Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Tue, 24 Sep 2024 16:32:01 -0500 Subject: [PATCH 6/9] Add subglacial runoff as a freshwater tracer --- .../shared/mpas_ocn_surface_bulk_forcing.F | 77 +++++++++++++++++++ .../mpas-ocean/src/shared/mpas_ocn_tendency.F | 9 +-- .../Registry_freshwaterTracers.xml | 41 ++++++++++ 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 5da4975e4dc0..2c71cdeb2ac1 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -187,6 +187,9 @@ subroutine ocn_surface_bulk_forcing_tracers_subglacial_runoff(meshPool, groupNam if ( trim(groupName) == 'activeTracers' ) then call ocn_surface_bulk_forcing_active_tracers_subglacial_runoff(meshPool, forcingPool, & tracersSurfaceFluxSubglacialRunoff, err) + elseif ( trim(groupName) == 'freshwaterTracers' ) then + call ocn_surface_bulk_forcing_freshwater_tracers_subglacial_runoff(meshPool, forcingPool, & + tracersSurfaceFluxSubglacialRunoff, err)!{{{ end if call mpas_timer_stop("bulk_" // trim(groupName)) @@ -997,6 +1000,80 @@ subroutine ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tr end subroutine ocn_surface_bulk_forcing_freshwater_tracers!}}} +!*********************************************************************** +! +! routine ocn_surface_bulk_forcing_freshwater_tracers_subglacial_runoff +! +!> \brief computes a tracer tendency due to CFC surface fluxes +!> \author Irena Vankova +!> \date July 2024 +!> \details +!> This routine computes a tracer tendency due to CFC surface fluxes +! +!----------------------------------------------------------------------- + + subroutine ocn_surface_bulk_forcing_freshwater_tracers_subglacial_runoff(meshPool, forcingPool, & + tracersSurfaceFluxSubglacialRunoff, err)!{{{ + + !----------------------------------------------------------------- + ! + ! input variables + ! + !----------------------------------------------------------------- + type (mpas_pool_type), intent(in) :: meshPool !< Input: mesh information + + !----------------------------------------------------------------- + ! + ! input/output variables + ! + !----------------------------------------------------------------- + + type (mpas_pool_type), intent(inout) :: forcingPool + + ! two dimensional arrays + real (kind=RKIND), dimension(:,:), intent(inout) :: tracersSurfaceFluxSubglacialRunoff + + !----------------------------------------------------------------- + ! + ! output variables + ! + !----------------------------------------------------------------- + + integer, intent(out) :: err !< Output: Error flag + + !----------------------------------------------------------------- + ! + ! local variables + ! + !----------------------------------------------------------------- + integer :: iCell, nCells + integer, dimension(:), pointer :: nCellsArray + + type(mpas_pool_type),pointer :: tracersSurfaceFluxPool + integer, pointer :: indexSubglacialRunoff + real (kind=RKIND), dimension(:), pointer :: subglacialRunoffFlux + + err = 0 + + call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray) + + call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux',tracersSurfaceFluxPool) + call mpas_pool_get_dimension(tracersSurfaceFluxPool, 'index_subglacialRunoffFreshWaterSurfaceFlux', indexSubglacialRunoff) + + call mpas_pool_get_array(forcingPool, 'subglacialRunoffFlux', subglacialRunoffFlux) + + nCells = nCellsArray( 3 ) + if (associated(indexSubglacialRunoff) .and. associated(subglacialRunoffFlux)) then + do iCell=1,nCells + tracersSurfaceFluxSubglacialRunoff(indexSubglacialRunoff, iCell) = subglacialRunoffFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexSubglacialRunoff or subglacialRunoffFlux is not associated') + tracersSurfaceFluxSubglacialRunoff(indexSubglacialRunoff, :) = 0.0_RKIND + endif + + end subroutine ocn_surface_bulk_forcing_freshwater_tracers_subglacial_runoff!}}} + end module ocn_surface_bulk_forcing diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F index e0d46a305515..4187db383dd6 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_tendency.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tendency.F @@ -846,21 +846,14 @@ subroutine ocn_tend_tracer(tendPool, statePool, forcingPool, & if (trim(config_subglacial_runoff_mode) == 'data') then ! Get surface flux due to subglacial runoff array - ! only active tracers have subglacial runoff flux for now, - ! but we still need to associate for ALL tracers modifiedGroupName = groupName // "SurfaceFluxSubglacialRunoff" call mpas_pool_get_array(tracersSurfaceFluxPool, & modifiedGroupName, & tracerGroupSurfaceFluxSubglacialRunoff) end if - if (associated(tracerGroupSurfaceFluxRunoff)) then - call mpas_log_write(modifiedGroupName // " is associated") - else - call mpas_log_write(modifiedGroupName // " is not associated") - endif + !call mpas_pool_print_summary(tracersSurfaceFluxPool, MPAS_POOL_FIELD, .true.) - call mpas_pool_print_summary(tracersSurfaceFluxPool, MPAS_POOL_FIELD, .true.) ! Get surface flux removed array to keep track of how much ! flux is ignored modifiedGroupName = groupName // "SurfaceFluxRemoved" diff --git a/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml index 9c0dc63f2272..657486133a75 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_freshwaterTracers.xml @@ -67,6 +67,9 @@ + @@ -95,6 +98,9 @@ + @@ -123,6 +129,9 @@ + + + + + + + + + + + + + From f938f022fd4ac7c939b9e05d0c58947164764e64 Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Wed, 25 Sep 2024 12:04:28 -0500 Subject: [PATCH 7/9] Check for association of all fw fluxes in bulk forcing --- .../shared/mpas_ocn_surface_bulk_forcing.F | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F index 2c71cdeb2ac1..89198f722130 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F @@ -967,27 +967,48 @@ subroutine ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tr call mpas_pool_get_array(forcingPool, 'landIceFreshwaterFlux', landIceFreshwaterFlux) nCells = nCellsArray( 3 ) - do iCell=1,nCells + if (associated(indexRain) .and. associated(rainFlux)) then + do iCell=1,nCells freshwaterSurfaceFlux(indexRain, iCell) = rainFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexRain is not associated') + endif + if (associated(indexSnow) .and. associated(snowFlux)) then + do iCell=1,nCells freshwaterSurfaceFlux(indexSnow, iCell) = snowFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexSnow is not associated') + endif + if (associated(indexIceRunoff) .and. associated(iceRunoffFlux)) then + do iCell=1,nCells freshwaterSurfaceFluxRunoff(indexIceRunoff, iCell) = iceRunoffFlux(iCell) / rho_sw + enddo ! iCell + else + call mpas_log_write('indexIceRunoff is not associated') + endif + if (associated(indexRiverRunoff) .and. associated(riverRunoffFlux)) then + do iCell=1,nCells freshwaterSurfaceFluxRunoff(indexRiverRunoff, iCell) = riverRunoffFlux(iCell) / rho_sw - enddo ! iCell - if (associated(indexSeaIceFreshWater)) then + enddo ! iCell + else + if (.not. associated(indexRiverRunoff)) call mpas_log_write('indexRiverRunoff is not associated') + if (.not. associated(riverRunoffFlux)) call mpas_log_write('riverRunoffFlux is not associated') + endif + if (associated(indexSeaIceFreshWater) .and. associated(seaIceFreshWaterFlux)) then do iCell=1,nCells freshwaterSurfaceFlux(indexSeaIceFreshWater, iCell) = seaIceFreshWaterFlux(iCell) / rho_sw enddo ! iCell else call mpas_log_write('indexSeaIceFreshWater is not associated') - freshwaterSurfaceFlux(indexSeaIceFreshWater, :) = 0.0_RKIND endif - if (associated(indexIcebergFreshWater)) then + if (associated(indexIcebergFreshWater) .and. associated(icebergFreshWaterFlux)) then do iCell=1,nCells freshwaterSurfaceFlux(indexIcebergFreshWater, iCell) = icebergFreshWaterFlux(iCell) / rho_sw enddo ! iCell else call mpas_log_write('indexIcebergFreshWater is not associated') - freshwaterSurfaceFlux(indexIcebergFreshWater, :) = 0.0_RKIND endif if (associated(indexLandIceFreshwater) .and. associated(landIceFreshwaterFlux)) then do iCell=1,nCells @@ -995,8 +1016,8 @@ subroutine ocn_surface_bulk_forcing_freshwater_tracers(meshPool, forcingPool, tr enddo ! iCell else call mpas_log_write('indexLandIceFreshwater or landIceFreshwaterFlux is not associated') - freshwaterSurfaceFlux(indexLandIceFreshwater, :) = 0.0_RKIND endif + call mpas_log_write('end fw assign sflux') end subroutine ocn_surface_bulk_forcing_freshwater_tracers!}}} From 2b8dee26e45b9cddf2d80cc645261375f3a3ae3c Mon Sep 17 00:00:00 2001 From: Carolyn Begeman Date: Tue, 11 Mar 2025 14:49:16 -0500 Subject: [PATCH 8/9] Add stealth test for freshwater tracers --- cime_config/tests.py | 1 + .../testdefs/testmods_dirs/mpaso/freshwater_tracers/README | 4 ++++ .../testmods_dirs/mpaso/freshwater_tracers/user_nl_mpaso | 1 + 3 files changed, 6 insertions(+) create mode 100644 components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/README create mode 100644 components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/user_nl_mpaso diff --git a/cime_config/tests.py b/cime_config/tests.py index 3f74472549a1..cca1b851c8f6 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -282,6 +282,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", + "SMS_D_Ld1.T62_oQU240.GMPAS-IAF.mpaso-freshwater_tracers", "ERS_Ld5_D.T62_oQU240.GMPAS-IAF.mpaso-conservation_check", "ERS_Ld5_PS.ne30pg2_r05_IcoswISC30E3r5.CRYO1850-DISMF.mpaso-scaled_dib_dismf", "ERS_Ld5.TL319_oQU240wLI_gis20.MPAS_LISIO_JRA1p5.mpaso-ocn_glc_tf_coupling", diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/README b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/README new file mode 100644 index 000000000000..7fbaf2c59a12 --- /dev/null +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/README @@ -0,0 +1,4 @@ +This testdef is used to test a stealth feature in mpaso introduced by +PR #7087. It simplies changes one mpaso namelist variable, + config_use_freshwaterTracers +from its default value of .false. to .true.. diff --git a/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/user_nl_mpaso b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/user_nl_mpaso new file mode 100644 index 000000000000..102c23fc97bd --- /dev/null +++ b/components/mpas-ocean/cime_config/testdefs/testmods_dirs/mpaso/freshwater_tracers/user_nl_mpaso @@ -0,0 +1 @@ +config_use_freshwaterTracers = .true. From 906380a395cf75d06af04f54457ed159c85cad95 Mon Sep 17 00:00:00 2001 From: Jon Wolfe Date: Tue, 11 Mar 2025 16:58:13 -0500 Subject: [PATCH 9/9] Make bld files consistent with Registry --- components/mpas-ocean/bld/build-namelist | 2 +- .../namelist_definition_mpaso.xml | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 4cc2361104b4..214a759b4518 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -1865,10 +1865,10 @@ my @groups = qw(run_modes tracer_forcing_activetracers tracer_forcing_debugtracers tracer_forcing_ecosystracers + tracer_forcing_freshwatertracers tracer_forcing_dmstracers tracer_forcing_macromoleculestracers tracer_forcing_idealagetracers - tracer_forcing_freshwatertracers tracer_forcing_cfctracers am_globalstats am_surfaceareaweightedaverages 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 bfabf0aed9b1..aa17e216f884 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -3155,11 +3155,14 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + + + if true, the 'freshwaterTracers' category is enabled for the run -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3167,7 +3170,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, surface bulk forcing from coupler is added to surfaceTracerFlux in 'freshwaterTracers' category. True by default because the main function of this tracer group is tracking freshwater fluxes -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3175,7 +3178,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, surface restoring source is applied to tracers in 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3183,7 +3186,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, interior restoring source is applied to tracers in 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3191,7 +3194,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, exponential decay source is applied to tracers in 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3199,7 +3202,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, idealAge forcing source is applied to tracers in 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3207,7 +3210,7 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, transit time distribution forcing source is applied to tracers in 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml @@ -3215,10 +3218,11 @@ Default: Defined in namelist_defaults.xml category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers"> if true, surface value is computed for 'freshwaterTracers' category -Valid Values: .true. or .false. +Valid values: .true. or .false. Default: Defined in namelist_defaults.xml +