Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add freshwater tracers #108

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions components/mpas-ocean/bld/build-namelist
Original file line number Diff line number Diff line change
Expand Up @@ -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 #
#############################################
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions components/mpas-ocean/bld/build-namelist-group-list
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions components/mpas-ocean/bld/build-namelist-section
Original file line number Diff line number Diff line change
Expand Up @@ -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 #
#############################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,16 @@
<config_ecosysTracers_diagnostic_fields_level4>.false.</config_ecosysTracers_diagnostic_fields_level4>
<config_ecosysTracers_diagnostic_fields_level5>.false.</config_ecosysTracers_diagnostic_fields_level5>

<!-- tracer_forcing_freshwaterTracers -->
<config_use_freshwaterTracers>.false.</config_use_freshwaterTracers>
<config_use_freshwaterTracers_surface_bulk_forcing>.true.</config_use_freshwaterTracers_surface_bulk_forcing>
<config_use_freshwaterTracers_surface_restoring>.false.</config_use_freshwaterTracers_surface_restoring>
<config_use_freshwaterTracers_interior_restoring>.false.</config_use_freshwaterTracers_interior_restoring>
<config_use_freshwaterTracers_exponential_decay>.false.</config_use_freshwaterTracers_exponential_decay>
<config_use_freshwaterTracers_idealAge_forcing>.false.</config_use_freshwaterTracers_idealAge_forcing>
<config_use_freshwaterTracers_ttd_forcing>.false.</config_use_freshwaterTracers_ttd_forcing>
<config_use_freshwaterTracers_surface_value>.false.</config_use_freshwaterTracers_surface_value>

<!-- tracer_forcing_DMSTracers -->
<config_use_DMSTracers>.false.</config_use_DMSTracers>
<config_use_DMSTracers_surface_bulk_forcing>.false.</config_use_DMSTracers_surface_bulk_forcing>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3155,6 +3155,69 @@ Valid values: .true. or .false.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers" type="logical"
category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers">
if true, the 'freshwaterTracers' category is enabled for the run

Valid Values: .true. or .false.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_surface_bulk_forcing" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_surface_restoring" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_interior_restoring" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_exponential_decay" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_idealAge_forcing" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_ttd_forcing" type="logical"
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.
Default: Defined in namelist_defaults.xml
</entry>

<entry id="config_use_freshwaterTracers_surface_value" type="logical"
category="tracer_forcing_freshwaterTracers" group="tracer_forcing_freshwaterTracers">
if true, surface value is computed for 'freshwaterTracers' category

Valid Values: .true. or .false.
Default: Defined in namelist_defaults.xml
</entry>

<!-- tracer_forcing_DMSTracers -->

Expand Down
215 changes: 215 additions & 0 deletions components/mpas-ocean/src/shared/mpas_ocn_surface_bulk_forcing.F
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down Expand Up @@ -184,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))

Expand Down Expand Up @@ -880,6 +886,215 @@ 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 )
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
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')
endif
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')
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')
endif
call mpas_log_write('end fw assign sflux')

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)!{{{
Comment on lines +1036 to +1037
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@irenavankova Here is the routine that implements the subglacial runoff freshwater tracer if you want to take a look.


!-----------------------------------------------------------------
!
! 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


Expand Down
Loading