From 4d02387fc25568d24d9aa98a778ee52836fc14b6 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 3 May 2019 10:53:38 -0600 Subject: [PATCH] Add seaice_melt and seaice_melt_heat This commit adds two new fluxes to the nuopc cap. The MOM (coupler) definition of these terms is seaice_melt (meltw) and seaice_melt_heat (melth). Currently, the alias name for these terms in the fd.yaml file is mean_fresh_water_to_ocean_rate and net_heat_flx_to_ocn. We need to change these to more meningful names and this will require changes in CICE. --- .../nuopc_driver/MOM_surface_forcing.F90 | 25 +++++++------ config_src/nuopc_driver/mom_cap.F90 | 10 ++++-- config_src/nuopc_driver/mom_cap_methods.F90 | 35 ++++++++++--------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/config_src/nuopc_driver/MOM_surface_forcing.F90 b/config_src/nuopc_driver/MOM_surface_forcing.F90 index 7bd705a07a..57da9d5a31 100644 --- a/config_src/nuopc_driver/MOM_surface_forcing.F90 +++ b/config_src/nuopc_driver/MOM_surface_forcing.F90 @@ -163,7 +163,7 @@ module MOM_surface_forcing real, pointer, dimension(:,:) :: q_flux =>NULL() !< specific humidity flux [kg/m2/s] real, pointer, dimension(:,:) :: salt_flux =>NULL() !< salt flux [kg/m2/s] real, pointer, dimension(:,:) :: seaice_melt_heat =>NULL() !< sea ice and snow melt heat flux [W/m2] - real, pointer, dimension(:,:) :: seaice_melt_water =>NULL() !< water flux due to sea ice and snow melting [kg/m2/s] + real, pointer, dimension(:,:) :: seaice_melt =>NULL() !< water flux due to sea ice and snow melting [kg/m2/s] real, pointer, dimension(:,:) :: lw_flux =>NULL() !< long wave radiation [W/m2] real, pointer, dimension(:,:) :: sw_flux_vis_dir =>NULL() !< direct visible sw radiation [W/m2] real, pointer, dimension(:,:) :: sw_flux_vis_dif =>NULL() !< diffuse visible sw radiation [W/m2] @@ -457,18 +457,18 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, G, US, CS, & fluxes%heat_content_frunoff(i,j) = IOB%calving_hflx(i-i0,j-j0) * G%mask2dT(i,j) if (associated(IOB%lw_flux)) & - fluxes%LW(i,j) = IOB%lw_flux(i-i0,j-j0) * G%mask2dT(i,j) + fluxes%LW(i,j) = IOB%lw_flux(i-i0,j-j0) * G%mask2dT(i,j) if (associated(IOB%t_flux)) & - fluxes%sens(i,j) = IOB%t_flux(i-i0,j-j0) * G%mask2dT(i,j) + fluxes%sens(i,j) = IOB%t_flux(i-i0,j-j0) * G%mask2dT(i,j) - ! ! sea ice and snow melt heat flux [W/m2] - ! if (associated(fluxes%seaice_melt_heat)) & - ! fluxes%seaice_melt_heat(i,j) = G%mask2dT(i,j) * IOB%seaice_melt_heat(i-i0,j-j0) + ! sea ice and snow melt heat flux [W/m2] + if (associated(IOB%seaice_melt_heat)) & + fluxes%seaice_melt_heat(i,j) = G%mask2dT(i,j) * IOB%seaice_melt_heat(i-i0,j-j0) - ! ! water flux due to sea ice and snow melt [kg/m2/s] - ! if (associated(fluxes%seaice_melt)) & - ! fluxes%seaice_melt(i,j) = G%mask2dT(i,j) * IOB%seaice_melt_water(i-i0,j-j0) + ! water flux due to sea ice and snow melt [kg/m2/s] + if (associated(IOB%seaice_melt)) & + fluxes%seaice_melt(i,j) = G%mask2dT(i,j) * IOB%seaice_melt(i-i0,j-j0) fluxes%latent(i,j) = 0.0 if (associated(IOB%fprec)) then @@ -540,10 +540,9 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, G, US, CS, & sign_for_net_FW_bug = 1. if (CS%use_net_FW_adjustment_sign_bug) sign_for_net_FW_bug = -1. do j=js,je ; do i=is,ie - net_FW(i,j) = (((fluxes%lprec(i,j) + fluxes%fprec(i,j)) + & + net_FW(i,j) = (((fluxes%lprec(i,j) + fluxes%fprec(i,j) + fluxes%seaice_melt(i,j)) + & (fluxes%lrunoff(i,j) + fluxes%frunoff(i,j))) + & (fluxes%evap(i,j) + fluxes%vprec(i,j)) ) * G%areaT(i,j) - ! net_FW(i,j) = netFW(i,j) + fluxes%seaice_melt(i,j) * G%areaT(i,j) ! The following contribution appears to be calculating the volume flux of sea-ice ! melt. This calculation is clearly WRONG if either sea-ice has variable @@ -1368,8 +1367,8 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt) write(outunit,100) 'iobt%t_flux ' , mpp_chksum( iobt%t_flux ) write(outunit,100) 'iobt%q_flux ' , mpp_chksum( iobt%q_flux ) write(outunit,100) 'iobt%salt_flux ' , mpp_chksum( iobt%salt_flux ) - !write(outunit,100) 'iobt%seaice_melt_heat' , mpp_chksum( iobt%seaice_melt_heat) - !write(outunit,100) 'iobt%seaice_melt_water' , mpp_chksum( iobt%seaice_melt_water) + write(outunit,100) 'iobt%seaice_melt_heat' , mpp_chksum( iobt%seaice_melt_heat) + write(outunit,100) 'iobt%seaice_melt ' , mpp_chksum( iobt%seaice_melt ) write(outunit,100) 'iobt%lw_flux ' , mpp_chksum( iobt%lw_flux ) write(outunit,100) 'iobt%sw_flux_vis_dir' , mpp_chksum( iobt%sw_flux_vis_dir) write(outunit,100) 'iobt%sw_flux_vis_dif' , mpp_chksum( iobt%sw_flux_vis_dif) diff --git a/config_src/nuopc_driver/mom_cap.F90 b/config_src/nuopc_driver/mom_cap.F90 index 9cf16c8a40..53e44fda7d 100644 --- a/config_src/nuopc_driver/mom_cap.F90 +++ b/config_src/nuopc_driver/mom_cap.F90 @@ -204,6 +204,8 @@ !! --------------------------|------------|-----------------|---------------------------------------|------------------- !! inst_pres_height_surface | Pa | p | pressure of overlying sea ice and atmosphere !! mass_of_overlying_sea_ice | kg | mi | mass of overlying sea ice | | +!! seaice_melt_heat | W m-2 | seaice_melt_heat| sea ice and snow melt heat flux | | +!! seaice_melt | kg m-2 s-1 | seaice_melt | water flux due to sea ice and snow melting | | !! mean_calving_heat_flx | W m-2 | calving_hflx | heat flux, relative to 0C, of frozen land water into ocean !! mean_calving_rate | kg m-2 s-1 | calving | mass flux of frozen runoff | | !! mean_evap_rate | kg m-2 s-1 | q_flux | specific humidity flux | @@ -961,6 +963,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) Ice_ocean_boundary% sw_flux_nir_dif (isc:iec,jsc:jec), & Ice_ocean_boundary% lprec (isc:iec,jsc:jec), & Ice_ocean_boundary% fprec (isc:iec,jsc:jec), & + Ice_ocean_boundary% seaice_melt_heat (isc:iec,jsc:jec),& + Ice_ocean_boundary% seaice_melt (isc:iec,jsc:jec), & Ice_ocean_boundary% mi (isc:iec,jsc:jec), & Ice_ocean_boundary% p (isc:iec,jsc:jec), & Ice_ocean_boundary% runoff (isc:iec,jsc:jec), & @@ -982,6 +986,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) Ice_ocean_boundary%sw_flux_nir_dif = 0.0 Ice_ocean_boundary%lprec = 0.0 Ice_ocean_boundary%fprec = 0.0 + Ice_ocean_boundary%seaice_melt = 0.0 + Ice_ocean_boundary%seaice_melt_heat= 0.0 Ice_ocean_boundary%mi = 0.0 Ice_ocean_boundary%p = 0.0 Ice_ocean_boundary%runoff = 0.0 @@ -1031,8 +1037,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call fld_list_add(fldsToOcn_num, fldsToOcn, "inst_pres_height_surface" , "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 - !call fld_list_add(fldsToOcn_num, fldsToOcn, "seaice_melt_water" , "will provide") - !call fld_list_add(fldsToOcn_num, fldsToOcn, "seaice_melt_heat" , "will provide") + call fld_list_add(fldsToOcn_num, fldsToOcn, "mean_fresh_water_to_ocean_rate", "will provide") + call fld_list_add(fldsToOcn_num, fldsToOcn, "net_heat_flx_to_ocn" , "will provide") !call fld_list_add(fldsToOcn_num, fldsToOcn, "mean_runoff_rate" , "will provide") !call fld_list_add(fldsToOcn_num, fldsToOcn, "mean_calving_rate" , "will provide") diff --git a/config_src/nuopc_driver/mom_cap_methods.F90 b/config_src/nuopc_driver/mom_cap_methods.F90 index d893685aec..e6bdbea307 100644 --- a/config_src/nuopc_driver/mom_cap_methods.F90 +++ b/config_src/nuopc_driver/mom_cap_methods.F90 @@ -294,6 +294,7 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary, !---- ! salt flux from ice !---- + ice_ocean_boundary%salt_flux(:,:) = 0._ESMF_KIND_R8 call state_getimport(importState, 'mean_salt_rate', & isc, iec, jsc, jec, ice_ocean_boundary%salt_flux,rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & @@ -304,22 +305,24 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary, ! !---- ! ! snow&ice melt heat flux (W/m^2) ! !---- - ! call state_getimport(importState, 'seaice_melt_heat', & - ! isc, iec, jsc, jec, ice_ocean_boundary%seaice_melt_heat,rc=rc) - ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - ! line=__LINE__, & - ! file=__FILE__)) & - ! return ! bail out + ice_ocean_boundary%seaice_melt_heat(:,:) = 0._ESMF_KIND_R8 + call state_getimport(importState, 'net_heat_flx_to_ocn', & + isc, iec, jsc, jec, ice_ocean_boundary%seaice_melt_heat,rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out - ! !---- - ! ! snow&ice melt water flux (W/m^2) - ! !---- - ! call state_getimport(importState, 'seaice_melt_water', & - ! isc, iec, jsc, jec, ice_ocean_boundary%seaice_melt_water,rc=rc) - ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & - ! line=__LINE__, & - ! file=__FILE__)) & - ! return ! bail out + ! !---- + ! ! snow&ice melt water flux (W/m^2) + ! !---- + ice_ocean_boundary%seaice_melt(:,:) = 0._ESMF_KIND_R8 + call state_getimport(importState, 'mean_fresh_water_to_ocean_rate', & + isc, iec, jsc, jec, ice_ocean_boundary%seaice_melt,rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out !---- ! mass of overlying ice @@ -373,7 +376,6 @@ subroutine mom_export(ocean_public, ocean_grid, ocean_state, exportState, clock, rc = ESMF_SUCCESS - ! Use Adcroft's rule of reciprocals; it does the right thing here. call ESMF_ClockGet( clock, timeStep=timeStep, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, & @@ -386,6 +388,7 @@ subroutine mom_export(ocean_public, ocean_grid, ocean_state, exportState, clock, file=__FILE__)) & return ! bail out + ! Use Adcroft's rule of reciprocals; it does the right thing here. if (real(dt_int) > 0.0) then inv_dt_int = 1.0 / real(dt_int) else