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

Modify NUOPC cap to accept separate glc runoff fluxes #288

Merged
merged 7 commits into from
Aug 30, 2024
24 changes: 23 additions & 1 deletion config_src/drivers/nuopc_cap/mom_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,18 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
Ice_ocean_boundary% hrofl (isc:iec,jsc:jec), &
Ice_ocean_boundary% hrofi (isc:iec,jsc:jec), &
Ice_ocean_boundary% hevap (isc:iec,jsc:jec), &
Ice_ocean_boundary% hcond (isc:iec,jsc:jec))
Ice_ocean_boundary% hcond (isc:iec,jsc:jec), &
Ice_ocean_boundary% lrunoff_glc (isc:iec,jsc:jec), &
Ice_ocean_boundary% frunoff_glc (isc:iec,jsc:jec))

Ice_ocean_boundary%hrain = 0.0
Ice_ocean_boundary%hsnow = 0.0
Ice_ocean_boundary%hrofl = 0.0
Ice_ocean_boundary%hrofi = 0.0
Ice_ocean_boundary%hevap = 0.0
Ice_ocean_boundary%hcond = 0.0
Ice_ocean_boundary%lrunoff_glc = 0.0
Ice_ocean_boundary%frunoff_glc = 0.0
endif

call query_ocean_state(ocean_state, use_waves=use_waves, wave_method=wave_method)
Expand Down Expand Up @@ -764,6 +768,10 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sa_pslv" , "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "Foxx_rofl" , "will provide") !-> liquid runoff
call fld_list_add(fldsToOcn_num, fldsToOcn, "Foxx_rofi" , "will provide") !-> ice runoff
if (cesm_coupled) then
call fld_list_add(fldsToOcn_num, fldsToOcn, "Forr_rofl_glc" , "will provide") !-> liquid glc runoff
call fld_list_add(fldsToOcn_num, fldsToOcn, "Forr_rofi_glc" , "will provide") !-> frozen glc runoff
endif
call fld_list_add(fldsToOcn_num, fldsToOcn, "Si_ifrac" , "will provide") !-> ice fraction
call fld_list_add(fldsToOcn_num, fldsToOcn, "So_duu10n" , "will provide") !-> wind^2 at 10m
call fld_list_add(fldsToOcn_num, fldsToOcn, "Fioi_meltw" , "will provide")
Expand Down Expand Up @@ -2767,6 +2775,20 @@ end subroutine shr_log_setLogUnit
!! <td></td>
!! </tr>
!! <tr>
!! <td>Forr_rofl_glc</td>
!! <td>kg m-2 s-1</td>
!! <td>runoff</td>
!! <td>mass flux of liquid glc runoff</td>
!! <td></td>
!! </tr>
!! <tr>
!! <td>Forr_rofi_glc</td>
!! <td>kg m-2 s-1</td>
!! <td>runoff</td>
!! <td>mass flux of frozen glc runoff</td>
!! <td></td>
!! </tr>
!! <tr>
!! <td>Fioi_salt</td>
!! <td>kg m-2 s-1</td>
!! <td>salt_flux</td>
Expand Down
16 changes: 16 additions & 0 deletions config_src/drivers/nuopc_cap/mom_cap_methods.F90
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary,
isc, iec, jsc, jec, ice_ocean_boundary%frunoff, areacor=med2mod_areacor, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! liquid glc runoff
if ( associated(ice_ocean_boundary%lrunoff_glc) ) then
ice_ocean_boundary%lrunoff_glc (:,:) = 0._ESMF_KIND_R8
call state_getimport(importState, 'Forr_rofl_glc', &
isc, iec, jsc, jec, ice_ocean_boundary%lrunoff_glc, areacor=med2mod_areacor, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif

! frozen glc runoff
if ( associated(ice_ocean_boundary%frunoff_glc) ) then
ice_ocean_boundary%frunoff_glc (:,:) = 0._ESMF_KIND_R8
call state_getimport(importState, 'Forr_rofi_glc', &
isc, iec, jsc, jec, ice_ocean_boundary%frunoff_glc, areacor=med2mod_areacor, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif

!----
! Enthalpy terms
!----
Expand Down
21 changes: 21 additions & 0 deletions config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ module MOM_surface_forcing_nuopc
type, public :: ice_ocean_boundary_type
real, pointer, dimension(:,:) :: lrunoff =>NULL() !< liquid runoff [kg/m2/s]
real, pointer, dimension(:,:) :: frunoff =>NULL() !< ice runoff [kg/m2/s]
real, pointer, dimension(:,:) :: lrunoff_glc =>NULL() !< liquid glc runoff via rof [kg/m2/s]
real, pointer, dimension(:,:) :: frunoff_glc =>NULL() !< frozen glc runoff via rof [kg/m2/s]
real, pointer, dimension(:,:) :: u_flux =>NULL() !< i-direction wind stress [Pa]
real, pointer, dimension(:,:) :: v_flux =>NULL() !< j-direction wind stress [Pa]
real, pointer, dimension(:,:) :: t_flux =>NULL() !< sensible heat flux [W/m2]
Expand Down Expand Up @@ -472,6 +474,16 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
fluxes%frunoff(i,j) = kg_m2_s_conversion * IOB%frunoff(i-i0,j-j0) * G%mask2dT(i,j)
endif

! add liquid glc runoff flux via rof
if (associated(IOB%lrunoff_glc)) then
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should keep these new fields separate in fluxes and not under fluxes%lrunoff and fluxes%frunoff.

Suggestion:
fluxes%lrunoff_glc(i,j) = fluxes%lrunoff_glc(i,j) + kg_m2_s_conversion * IOB%lrunoff_glc(i-i0,j-j0) * G%mask2dT(i,j)

fluxes%frunoff_glc(i,j) = fluxes%frunoff_glc(i,j) + kg_m2_s_conversion * IOB%frunoff_glc(i-i0,j-j0) * G%mask2dT(i,j)

fluxes%lrunoff(i,j) = fluxes%lrunoff(i,j) + kg_m2_s_conversion * IOB%lrunoff_glc(i-i0,j-j0) * G%mask2dT(i,j)
endif

! ice glc runoff flux via rof
if (associated(IOB%frunoff_glc)) then
fluxes%frunoff(i,j) = fluxes%frunoff(i,j) + kg_m2_s_conversion * IOB%frunoff_glc(i-i0,j-j0) * G%mask2dT(i,j)
endif

if (associated(IOB%ustar_berg)) &
fluxes%ustar_berg(i,j) = US%m_to_Z*US%T_to_s * IOB%ustar_berg(i-i0,j-j0) * G%mask2dT(i,j)

Expand Down Expand Up @@ -509,6 +521,13 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
fluxes%latent_frunoff_diag(i,j) = - G%mask2dT(i,j) * &
IOB%frunoff(i-i0,j-j0) * US%W_m2_to_QRZ_T * CS%latent_heat_fusion
endif
! notice minus sign since frunoff_glc is positive into the ocean
if (associated(IOB%frunoff_glc)) then
fluxes%latent(i,j) = fluxes%latent(i,j) - &
IOB%frunoff_glc(i-i0,j-j0) * US%W_m2_to_QRZ_T * CS%latent_heat_fusion
fluxes%latent_frunoff_diag(i,j) = fluxes%latent_frunoff_diag(i,j) - G%mask2dT(i,j) * &
IOB%frunoff_glc(i-i0,j-j0) * US%W_m2_to_QRZ_T * CS%latent_heat_fusion
endif
if (associated(IOB%q_flux)) then
fluxes%latent(i,j) = fluxes%latent(i,j) + &
IOB%q_flux(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_vapor
Expand Down Expand Up @@ -1479,6 +1498,8 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt)
chks = field_chksum( iobt%fprec ) ; if (root) write(outunit,100) 'iobt%fprec ', chks
chks = field_chksum( iobt%lrunoff ) ; if (root) write(outunit,100) 'iobt%lrunoff ', chks
chks = field_chksum( iobt%frunoff ) ; if (root) write(outunit,100) 'iobt%frunoff ', chks
chks = field_chksum( iobt%lrunoff_glc ) ; if (root) write(outunit,100) 'iobt%lrunoff_glc ', chks
chks = field_chksum( iobt%frunoff_glc ) ; if (root) write(outunit,100) 'iobt%frunoff_glc ', chks
chks = field_chksum( iobt%p ) ; if (root) write(outunit,100) 'iobt%p ', chks
if (associated(iobt%ice_fraction)) then
chks = field_chksum( iobt%ice_fraction ) ; if (root) write(outunit,100) 'iobt%ice_fraction ', chks
Expand Down
15 changes: 14 additions & 1 deletion src/initialization/MOM_shared_initialization.F90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module MOM_shared_initialization
use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, is_root_pe
use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint
use MOM_file_parser, only : get_param, log_param, param_file_type, log_version
use MOM_io, only : create_MOM_file, file_exists, field_size
use MOM_io, only : create_MOM_file, file_exists, field_size, get_filename_appendix
use MOM_io, only : MOM_infra_file, MOM_field
use MOM_io, only : MOM_read_data, MOM_read_vector, read_variable, stdout
use MOM_io, only : open_file_to_read, close_file_to_read, SINGLE_FILE, MULTIPLE
Expand Down Expand Up @@ -1348,13 +1348,15 @@ subroutine write_ocean_geometry_file(G, param_file, directory, US, geom_file)
! Local variables.
character(len=240) :: filepath ! The full path to the file to write
character(len=40) :: mdl = "write_ocean_geometry_file"
character(len=32) :: filename_appendix = '' ! Appendix to geom filename for ensemble runs
type(vardesc), dimension(:), allocatable :: &
vars ! Types with metadata about the variables and their staggering
type(MOM_field), dimension(:), allocatable :: &
fields ! Opaque types used by MOM_io to store variable metadata information
type(MOM_infra_file) :: IO_handle ! The I/O handle of the fileset
integer :: nFlds ! The number of variables in this file
integer :: file_threading
integer :: geom_file_len ! geometry file name length
logical :: multiple_files

call callTree_enter('write_ocean_geometry_file()')
Expand Down Expand Up @@ -1408,6 +1410,17 @@ subroutine write_ocean_geometry_file(G, param_file, directory, US, geom_file)
filepath = trim(directory) // "ocean_geometry"
endif

! Append ensemble run number to filename if it is an ensemble run
call get_filename_appendix(filename_appendix)
if (len_trim(filename_appendix) > 0) then
geom_file_len = len_trim(filepath)
if (filepath(geom_file_len-2:geom_file_len) == ".nc") then
filepath = filepath(1:geom_file_len-3) // '.' // trim(filename_appendix) // ".nc"
else
filepath = filepath // '.' // trim(filename_appendix)
endif
endif

call get_param(param_file, mdl, "PARALLEL_RESTARTFILES", multiple_files, &
"If true, the IO layout is used to group processors that write to the same "//&
"restart file or each processor writes its own (numbered) restart file. "//&
Expand Down
Loading