Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
35 changes: 35 additions & 0 deletions mediator/med_phases_post_atm_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module med_phases_post_atm_mod

character(*), parameter :: u_FILE_u = &
__FILE__
logical :: first_time = .true.
character(len=9), parameter :: fields_to_spread_runoff(1) = &
['Faoa_rofi']

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

did rofi and rofl get seperated elsewhere ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In access-esm rofl only contains the river runoff, and rofi contains both the iceberg basal and calving melt fluxes. The spreading here simultaneously does your calving flux spreading + a coastal distribution for the basal melt. Is that what you meant?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Oh - ah, I think it's better to have seperate steps in the mediator for basal and iceberg right ?

basal fraction, gets remapped with a fixed remapping weights file to put it along coastlines

and iceberg gets spread like this change

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It would be great if what was done was as close as possible consistent with OM3.

So that would mean splitting the iceberg and basal proportions before they leave the mediator. And having separate rofi/rofl fields to correspond to the MOM fields. It's relatively clear in the MOM diagnostics that rofi should be for the iceberg fraction - e.g. https://github.com/ACCESS-NRI/access-om3-configs/blob/b14a2797812531d5b4728f04cd67dcee19bfe439/docs/available_diags.000000#L4548, although less clear about the liquid proportion (e.g. there are lrunoff_glc fields available which OM3 doesn't use). Having separate fields for rofi and rofl means the rofi spreading input file can be the same across the two models. It also supports future/ongoing work to figure out how to spread the basal melt fraction vertically

The proposal to put the basal melt component in rofi by having a single pattern with 50% of the volume at the coastline will continue to give issues with supercooled water & excess sea ice from the large latent heat flux at the coastlines.


!-----------------------------------------------------------------------------
contains
Expand All @@ -24,6 +27,7 @@ subroutine med_phases_post_atm(gcomp, rc)
!---------------------------------------

use NUOPC_Mediator , only : NUOPC_MediatorGet
use NUOPC , only : NUOPC_CompAttributeGet
use ESMF , only : ESMF_Clock, ESMF_ClockIsCreated
use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_FieldBundleGet
use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS
Expand All @@ -35,6 +39,8 @@ subroutine med_phases_post_atm(gcomp, rc)
use med_utils_mod , only : chkerr => med_utils_ChkErr
use med_internalstate_mod , only : compocn, compatm, compice, complnd, compwav, coupling_mode
use perf_mod , only : t_startf, t_stopf
use shr_log_mod , only : shr_log_error
use med_phases_post_rof_mod, only: med_phases_post_rof_init_rof_spread_rofi, med_phases_post_rof_spread_rofi

! input/output variables
type(ESMF_GridComp) :: gcomp
Expand All @@ -44,6 +50,9 @@ subroutine med_phases_post_atm(gcomp, rc)
type(InternalState) :: is_local
type(ESMF_Clock) :: dClock
character(len=*), parameter :: subname='(med_phases_post_atm)'
character(len=CL) :: atm2ocn_ice_spread
Comment thread
kieranricardo marked this conversation as resolved.
Outdated
logical :: isPresent, isSet
integer :: n
!-------------------------------------------------------------------------------

rc = ESMF_SUCCESS
Expand Down Expand Up @@ -125,6 +134,32 @@ subroutine med_phases_post_atm(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if

call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_ice_spread', value=atm2ocn_ice_spread, isPresent=isPresent, isSet=isSet, rc=rc)

if (isPresent .and. isSet) then

if (first_time) then
call med_phases_post_rof_init_rof_spread_rofi(gcomp, fields_to_spread_runoff, atm2ocn_ice_spread, compocn, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
first_time=.false.
end if

do n = 1, size(fields_to_spread_runoff)
call ESMF_FieldBundleGet(is_local%wrap%FBImp(compatm,compocn), fieldName=trim(fields_to_spread_runoff(n)), isPresent=isPresent, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) then
call shr_log_error(string=trim(subname)//" Error checking field: "//trim(fields_to_spread_runoff(n)), line=__LINE__,file=u_FILE_u, rc=rc)
return
end if
if (isPresent) then
call med_phases_post_rof_spread_rofi(gcomp, fields_to_spread_runoff(n), is_local%wrap%FBImp(compatm,compocn), compocn, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
call shr_log_error(string=trim(subname)//" Runoff field to spread: "//trim(fields_to_spread_runoff(n))//" does not exist", line=__LINE__,file=u_FILE_u, rc=rc)
return
end if
end do
end if

Comment thread
anton-seaice marked this conversation as resolved.
Outdated
if (dbug_flag > 20) then
call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO)
end if
Expand Down
130 changes: 59 additions & 71 deletions mediator/med_phases_post_rof_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module med_phases_post_rof_mod
implicit none
private

public :: med_phases_post_rof_init
public :: med_phases_post_rof_init, med_phases_post_rof_init_rof_spread_rofi, med_phases_post_rof_spread_rofi
public :: med_phases_post_rof
private :: med_phases_post_rof_create_rof_field_bundle
private :: med_phases_post_rof_remove_negative_runoff
Expand All @@ -49,6 +49,7 @@ module med_phases_post_rof_mod
logical :: remove_negative_runoff_lnd
logical :: remove_negative_runoff_glc
logical :: spread_rofi_nh, spread_rofi_sh
logical :: first_time = .true.
character(len=CL) :: rof2ocn_ice_spread

character(len=9), parameter :: fields_to_remove_negative_runoff_lnd(2) = &
Expand Down Expand Up @@ -144,7 +145,6 @@ subroutine med_phases_post_rof(gcomp, rc)
real(r8), pointer :: data_copy(:)
integer :: n
logical :: exists
logical :: first_time = .true.
character(len=*), parameter :: subname='(med_phases_post_rof)'
!---------------------------------------

Expand All @@ -157,7 +157,7 @@ subroutine med_phases_post_rof(gcomp, rc)

! unclear why this can't be in med_phases_post_rof_init, possibly pio not initialised
if ((spread_rofi_nh .or. spread_rofi_sh) .and. first_time) then
call med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
call med_phases_post_rof_init_rof_spread_rofi(gcomp, fields_to_spread_runoff, rof2ocn_ice_spread, comprof, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
first_time=.false.
endif
Expand Down Expand Up @@ -203,7 +203,7 @@ subroutine med_phases_post_rof(gcomp, rc)
return
end if
if (exists) then
call med_phases_post_rof_spread_rofi(gcomp, fields_to_spread_runoff(n), rc)
call med_phases_post_rof_spread_rofi(gcomp, fields_to_spread_runoff(n), FBrof_r, comprof, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
call shr_log_error(string=trim(subname)//" Runoff field to spread: "//trim(fields_to_spread_runoff(n))//" does not exist", line=__LINE__,file=u_FILE_u, rc=rc)
Expand Down Expand Up @@ -459,13 +459,16 @@ subroutine med_phases_post_rof_remove_negative_runoff(gcomp, field_name, rc)

end subroutine med_phases_post_rof_remove_negative_runoff

subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, fields_to_spread_runoff, rof2ocn_ice_spread, comp, rc)
!---------------------------------------------------------------
use med_io_mod , only : med_io_read
use shr_reprosum_mod , only : shr_reprosum_calc

! input/output variables
type(ESMF_GridComp) :: gcomp
character(len=*), intent(in) :: fields_to_spread_runoff(:)
character(len=CL) :: rof2ocn_ice_spread
integer, intent(in) :: comp
Comment thread
kieranricardo marked this conversation as resolved.
Outdated
integer, intent(out) :: rc


Expand All @@ -478,13 +481,12 @@ subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
real(r8), allocatable:: rof2ocn_a_weight(:,:)
real(r8) :: global_sum(2) ! Antarctic, Greenland (frozen) runoff
integer :: n, i, month, comm
logical :: error = .false.

integer, parameter :: dbug_threshold = 0 ! threshold for writing debug information in this subroutine
character(len=*), parameter :: subname='(med_phases_post_rof_mod: med_phases_post_rof_init_rof_spread_rofi)'
!---------------------------------------

! to do - make component configurable (could be comprof or compatm)

rc = ESMF_SUCCESS

call t_startf('MED:'//subname)
Expand All @@ -508,7 +510,7 @@ subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
! Create module fields on rof mesh
! -------------------------------

call fldbun_getmesh(is_local%wrap%FBImp(comprof,comprof), mesh_l, rc)
call fldbun_getmesh(is_local%wrap%FBImp(comp,comp), mesh_l, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return

FBrof_pattern = ESMF_FieldBundleCreate(name='FBrof_pattern', rc=rc)
Expand All @@ -533,8 +535,8 @@ subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
call med_io_read(rof2ocn_ice_spread, vm, FBrof_pattern, pre='pattern', ungridded_nc=.true., rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return

areas => is_local%wrap%mesh_info(comprof)%areas
lats => is_local%wrap%mesh_info(comprof)%lats
areas => is_local%wrap%mesh_info(comp)%areas
lats => is_local%wrap%mesh_info(comp)%lats

allocate(rof2ocn_a_weight(size(areas),2))

Expand Down Expand Up @@ -566,33 +568,29 @@ subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)
if (global_sum(1) < (100.0_r8 * tiny(1.0_r8))) then
if (maintask) write(logunit,*) trim(subname)//": In rof2ocn_spread file, "//&
"Southern hemisphere sum is zero, or negative. Month = ",month, 'global_sum = ',global_sum(1)
spread_rofi_sh = .false.
error = .true.
Comment thread
anton-seaice marked this conversation as resolved.
Outdated
endif
if (global_sum(2) < (100.0_r8 * tiny(1.0_r8))) then
if (maintask) write(logunit,*) trim(subname)//": In rof2ocn_spread file, "//&
"Northern hemisphere sum is zero, or negative. Month = ",month, 'global_sum = ',global_sum(2)
spread_rofi_nh = .false.
error = .true.
endif

! adjust correction so that it's sums to 1 in each hemisphere
if (spread_rofi_sh) then
do i = 1, size(areas)
if (lats(i) < 0.0_r8) then
rof2ocn_spread(i,month) = rof2ocn_spread(i,month) / global_sum(1)
end if
end do
end if
if (spread_rofi_nh) then
do i = 1, size(areas)
if (lats(i) >= 0.0_r8) then
rof2ocn_spread(i,month) = rof2ocn_spread(i,month) / global_sum(2)
end if
end do
end if
do i = 1, size(areas)
if (lats(i) < 0.0_r8) then
rof2ocn_spread(i,month) = rof2ocn_spread(i,month) / global_sum(1)
end if
end do
do i = 1, size(areas)
if (lats(i) >= 0.0_r8) then
rof2ocn_spread(i,month) = rof2ocn_spread(i,month) / global_sum(2)
end if
end do

enddo ! month

if ( .not. (spread_rofi_nh .or. spread_rofi_sh)) then
if (error) then
call shr_log_error(string=trim(subname)//": error in rof2ocn_spread file, "//&
"sum in each hemispheres is zero, or negative", line=__LINE__,file=u_FILE_u, rc=rc)
return
Expand All @@ -607,14 +605,16 @@ subroutine med_phases_post_rof_init_rof_spread_rofi(gcomp, rc)

end subroutine med_phases_post_rof_init_rof_spread_rofi

subroutine med_phases_post_rof_spread_rofi(gcomp, field_name, rc)
subroutine med_phases_post_rof_spread_rofi(gcomp, field_name, field_bundle, comp, rc)
!---------------------------------------------------------------
! For one runoff field, spread runoff according to the pattern prescribed in spread_rofi_weights.
use shr_reprosum_mod , only : shr_reprosum_calc

! input/output variables
type(ESMF_GridComp) :: gcomp
character(len=*), intent(in) :: field_name ! name of runoff flux field to process
type(ESMF_FieldBundle) :: field_bundle
Comment thread
anton-seaice marked this conversation as resolved.
integer, intent(in) :: comp
integer, intent(out) :: rc

! local variables
Expand Down Expand Up @@ -652,29 +652,25 @@ subroutine med_phases_post_rof_spread_rofi(gcomp, field_name, rc)
call ESMF_GridCompGetInternalState(gcomp, is_local, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

areas => is_local%wrap%mesh_info(comprof)%areas
lats => is_local%wrap%mesh_info(comprof)%lats
areas => is_local%wrap%mesh_info(comp)%areas
lats => is_local%wrap%mesh_info(comp)%lats

call fldbun_getdata1d(FBrof_r, trim(field_name), runoff_flux, rc=rc)
call fldbun_getdata1d(field_bundle, trim(field_name), runoff_flux, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

allocate(rof2ocn_a_weight(size(runoff_flux),2))

rof2ocn_a_weight = 0.0_r8
if (spread_rofi_sh) then
do n = 1, size(runoff_flux)
if (lats(n) < 0.0_r8) then
rof2ocn_a_weight(n,1) = areas(n) * runoff_flux(n)
end if
end do
end if
if (spread_rofi_nh) then
do n = 1, size(runoff_flux)
if (lats(n) >= 0.0_r8) then
rof2ocn_a_weight(n,2) = areas(n) * runoff_flux(n)
end if
end do
end if
do n = 1, size(runoff_flux)
if (lats(n) < 0.0_r8) then
rof2ocn_a_weight(n,1) = areas(n) * runoff_flux(n)
end if
end do
do n = 1, size(runoff_flux)
if (lats(n) >= 0.0_r8) then
rof2ocn_a_weight(n,2) = areas(n) * runoff_flux(n)
end if
end do

! Get the MPI communicator from the VM
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
Expand All @@ -697,41 +693,33 @@ subroutine med_phases_post_rof_spread_rofi(gcomp, field_name, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! spread runoff by the saved pattern for the model month
if (spread_rofi_sh) then
do n = 1, size(runoff_flux)
if (lats(n) < 0.0_r8) then
runoff_flux(n) = rof2ocn_spread(n,mm) * global_sum(1)
end if
end do

do n = 1, size(runoff_flux)
if (lats(n) >= 0.0_r8) then
runoff_flux(n) = rof2ocn_spread(n,mm) * global_sum(2)
end if
end do

if (dbug_flag > dbug_threshold) then

! calculate the new global sum (after correction), difference should be equal to 0
rof2ocn_a_weight = 0.0_r8
do n = 1, size(runoff_flux)
if (lats(n) < 0.0_r8) then
runoff_flux(n) = rof2ocn_spread(n,mm) * global_sum(1)
rof2ocn_a_weight(n,1) = areas(n) * runoff_flux(n)
end if
end do
end if

if (spread_rofi_nh) then
do n = 1, size(runoff_flux)
if (lats(n) >= 0.0_r8) then
runoff_flux(n) = rof2ocn_spread(n,mm) * global_sum(2)
rof2ocn_a_weight(n,2) = areas(n) * runoff_flux(n)
end if
end do
end if

if (dbug_flag > dbug_threshold) then

! calculate the new global sum (after correction), difference should be equal to 0
rof2ocn_a_weight = 0.0_r8
if (spread_rofi_sh) then
do n = 1, size(runoff_flux)
if (lats(n) < 0.0_r8) then
rof2ocn_a_weight(n,1) = areas(n) * runoff_flux(n)
end if
end do
end if

if (spread_rofi_nh) then
do n = 1, size(runoff_flux)
if (lats(n) >= 0.0_r8) then
rof2ocn_a_weight(n,2) = areas(n) * runoff_flux(n)
end if
end do
end if

call shr_reprosum_calc(rof2ocn_a_weight, global_sum, size(runoff_flux), size(runoff_flux), 2, &
commid=comm)
Expand Down