From e495d0c00675446e822c45e15a8e6c63d051fb19 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Wed, 10 Oct 2018 15:22:55 -0600 Subject: [PATCH 01/15] Add heat flux term deu to melt/freeze of sea ice This term is passed via IOB%melth. The corresponding term in fluxes is fluxes%seaice_melt. This commit also fixes units description for rofl_* in the MCT IOB. --- config_src/mct_driver/MOM_surface_forcing.F90 | 18 ++- config_src/mct_driver/ocn_cap_methods.F90 | 4 + src/core/MOM_forcing_type.F90 | 110 ++++++++++++------ 3 files changed, 88 insertions(+), 44 deletions(-) diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 5c4a43bfc0..97f118a6f9 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -152,11 +152,12 @@ module MOM_surface_forcing ! MOM-based coupled models. type, public :: ice_ocean_boundary_type real, pointer, dimension(:,:) :: latent_flux =>NULL() !< latent flux (W/m2) - real, pointer, dimension(:,:) :: rofl_flux =>NULL() !< liquid runoff (W/m2) - real, pointer, dimension(:,:) :: rofi_flux =>NULL() !< ice runoff (W/m2) + real, pointer, dimension(:,:) :: rofl_flux =>NULL() !< liquid runoff (kg/m2/s) + real, pointer, dimension(:,:) :: rofi_flux =>NULL() !< ice runoff (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) + real, pointer, dimension(:,:) :: melth =>NULL() !< sea ice and snow melt heat flux (W/m2) 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(:,:) :: lw_flux =>NULL() !< long wave radiation (W/m2) @@ -166,7 +167,6 @@ module MOM_surface_forcing real, pointer, dimension(:,:) :: sw_flux_nir_dif =>NULL() !< diffuse Near InfraRed sw radiation (W/m2) real, pointer, dimension(:,:) :: lprec =>NULL() !< mass flux of liquid precip (kg/m2/s) real, pointer, dimension(:,:) :: fprec =>NULL() !< mass flux of frozen precip (kg/m2/s) - real, pointer, dimension(:,:) :: runoff =>NULL() !< mass flux of liquid runoff (kg/m2/s) real, pointer, dimension(:,:) :: calving =>NULL() !< mass flux of frozen runoff (kg/m2/s) real, pointer, dimension(:,:) :: ustar_berg =>NULL() !< frictional velocity beneath icebergs (m/s) real, pointer, dimension(:,:) :: area_berg =>NULL() !< area covered by icebergs(m2/m2) @@ -442,6 +442,10 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, Time, G, CS, & if (associated(fluxes%sens)) & fluxes%sens(i,j) = G%mask2dT(i,j) * IOB%t_flux(i-i0,j-j0) + ! sea ice and snow melt heat flux (W/m2) + if (associated(fluxes%melth)) & + fluxes%melth(i,j) = G%mask2dT(i,j) * IOB%melth(i-i0,j-j0) + ! latent heat flux (W/m^2) if (associated(fluxes%latent)) & fluxes%latent(i,j) = G%mask2dT(i,j) * IOB%latent_flux(i-i0,j-j0) @@ -771,6 +775,7 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB% u_flux (isc:iec,jsc:jec), & IOB% v_flux (isc:iec,jsc:jec), & IOB% t_flux (isc:iec,jsc:jec), & + IOB% melth (isc:iec,jsc:jec), & IOB% q_flux (isc:iec,jsc:jec), & IOB% salt_flux (isc:iec,jsc:jec), & IOB% lw_flux (isc:iec,jsc:jec), & @@ -780,7 +785,6 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB% sw_flux_nir_dif (isc:iec,jsc:jec), & IOB% lprec (isc:iec,jsc:jec), & IOB% fprec (isc:iec,jsc:jec), & - IOB% runoff (isc:iec,jsc:jec), & IOB% ustar_berg (isc:iec,jsc:jec), & IOB% area_berg (isc:iec,jsc:jec), & IOB% mass_berg (isc:iec,jsc:jec), & @@ -796,6 +800,7 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB%u_flux = 0.0 IOB%v_flux = 0.0 IOB%t_flux = 0.0 + IOB%melth = 0.0 IOB%q_flux = 0.0 IOB%salt_flux = 0.0 IOB%lw_flux = 0.0 @@ -805,7 +810,6 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB%sw_flux_nir_dif = 0.0 IOB%lprec = 0.0 IOB%fprec = 0.0 - IOB%runoff = 0.0 IOB%ustar_berg = 0.0 IOB%area_berg = 0.0 IOB%mass_berg = 0.0 @@ -1311,7 +1315,10 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt) write(outunit,100) 'iobt%u_flux ', mpp_chksum( iobt%u_flux ) write(outunit,100) 'iobt%v_flux ', mpp_chksum( iobt%v_flux ) write(outunit,100) 'iobt%t_flux ', mpp_chksum( iobt%t_flux ) + write(outunit,100) 'iobt%melth ', mpp_chksum( iobt%melth ) write(outunit,100) 'iobt%q_flux ', mpp_chksum( iobt%q_flux ) + write(outunit,100) 'iobt%rofl_flux ', mpp_chksum( iobt%rofl_flux ) + write(outunit,100) 'iobt%rofi_flux ', mpp_chksum( iobt%rofi_flux ) write(outunit,100) 'iobt%salt_flux ', mpp_chksum( iobt%salt_flux ) 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) @@ -1320,7 +1327,6 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt) write(outunit,100) 'iobt%sw_flux_nir_dif', mpp_chksum( iobt%sw_flux_nir_dif) write(outunit,100) 'iobt%lprec ', mpp_chksum( iobt%lprec ) write(outunit,100) 'iobt%fprec ', mpp_chksum( iobt%fprec ) - write(outunit,100) 'iobt%runoff ', mpp_chksum( iobt%runoff ) write(outunit,100) 'iobt%calving ', mpp_chksum( iobt%calving ) write(outunit,100) 'iobt%p ', mpp_chksum( iobt%p ) if (associated(iobt%ustar_berg)) & diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index 95fd084bdc..a9527f1660 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -73,6 +73,9 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, ! latent heat flux (W/m^2) ice_ocean_boundary%latent_flux(i,j) = x2o(ind%x2o_Foxx_lat,k) !???TODO: should this be a minus sign + ! snow&ice melt heat flux (W/m^2) + ice_ocean_boundary%melth(i,j) = x2o(ind%x2o_Fioi_melth,k) + ! liquid runoff ice_ocean_boundary%rofl_flux(i,j) = x2o(ind%x2o_Foxx_rofl,k) * GRID%mask2dT(ig,jg) @@ -116,6 +119,7 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, write(logunit,F01)'import: day, secs, j, i, lwrad = ',day,secs,j,i,ice_ocean_boundary%lw_flux(i,j) write(logunit,F01)'import: day, secs, j, i, q_flux = ',day,secs,j,i,ice_ocean_boundary%q_flux(i,j) write(logunit,F01)'import: day, secs, j, i, t_flux = ',day,secs,j,i,ice_ocean_boundary%t_flux(i,j) + write(logunit,F01)'import: day, secs, j, i, melth = ',day,secs,j,i,ice_ocean_boundary%melth(i,j) write(logunit,F01)'import: day, secs, j, i, latent_flux = ',& day,secs,j,i,ice_ocean_boundary%latent_flux(i,j) write(logunit,F01)'import: day, secs, j, i, runoff = ',& diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 9486967b40..b6a1f069c6 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -65,6 +65,7 @@ module MOM_forcing_type real, pointer, dimension(:,:) :: & latent => NULL(), & !< latent (W/m^2) (typically < 0) sens => NULL(), & !< sensible (W/m^2) (typically negative) + melth => NULL(), & !< sea ice and snow melt (W/m^2) (typically negative) heat_added => NULL() !< additional heat flux from SST restoring or flux adjustments (W/m^2) ! components of latent heat fluxes used for diagnostic purposes @@ -261,6 +262,7 @@ module MOM_forcing_type integer :: id_heat_content_vprec = -1, id_heat_content_massout = -1 integer :: id_heat_added = -1, id_heat_content_massin = -1 integer :: id_hfrainds = -1, id_hfrunoffds = -1 + integer :: id_melth = -1 ! global area integrated heat flux diagnostic handles integer :: id_total_net_heat_coupler = -1, id_total_net_heat_surface = -1 @@ -486,20 +488,22 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, endif ! net volume/mass of liquid and solid passing through surface boundary fluxes - netMassInOut(i) = dt * (scale * ((((( fluxes%lprec(i,j) & - + fluxes%fprec(i,j) ) & - + fluxes%evap(i,j) ) & - + fluxes%lrunoff(i,j) ) & - + fluxes%vprec(i,j) ) & - + fluxes%frunoff(i,j) ) ) + netMassInOut(i) = dt * (scale * (((((( fluxes%lprec(i,j) & + + fluxes%fprec(i,j) ) & + + fluxes%evap(i,j) ) & + + fluxes%lrunoff(i,j) ) & + + fluxes%vprec(i,j) ) & + + fluxes%seaice_melt(i,j)) & + + fluxes%frunoff(i,j) )) if (do_NMIOr) then ! Repeat the above code w/ dt=1s for legacy reasons - netMassInOut_rate(i) = (scale * ((((( fluxes%lprec(i,j) & - + fluxes%fprec(i,j) ) & - + fluxes%evap(i,j) ) & - + fluxes%lrunoff(i,j) ) & - + fluxes%vprec(i,j) ) & - + fluxes%frunoff(i,j) ) ) + netMassInOut_rate(i) = (scale * (((((( fluxes%lprec(i,j) & + + fluxes%fprec(i,j) ) & + + fluxes%evap(i,j) ) & + + fluxes%lrunoff(i,j) ) & + + fluxes%vprec(i,j) ) & + + fluxes%seaice_melt(i,j)) & + + fluxes%frunoff(i,j) )) endif ! smg: @@ -544,11 +548,24 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, ! surface heat fluxes from radiation and turbulent fluxes (K * H) ! (H=m for Bouss, H=kg/m2 for non-Bouss) - net_heat(i) = scale * dt * J_m2_to_H * & - ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) ) - !Repeats above code w/ dt=1. for legacy reason - if (do_NHR) net_heat_rate(i) = scale * J_m2_to_H * & - ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) ) + + ! CIME provides heat flux from snow&ice melt (melth), so this should be added here + if (associated(fluxes%melth)) then + net_heat(i) = scale * dt * J_m2_to_H * & + ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j) + & + fluxes%melth(i,j)) ) + !Repeats above code w/ dt=1. for legacy reason + if (do_NHR) net_heat_rate(i) = scale * J_m2_to_H * & + ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j) + & + fluxes%melth(i,j))) + else + net_heat(i) = scale * dt * J_m2_to_H * & + ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) ) + !Repeats above code w/ dt=1. for legacy reason + if (do_NHR) net_heat_rate(i) = scale * J_m2_to_H * & + ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) ) + endif + ! Add heat flux from surface damping (restoring) (K * H) or flux adjustments. if (associated(fluxes%heat_added)) then net_heat(i) = net_heat(i) + (scale * (dt * J_m2_to_H)) * fluxes%heat_added(i,j) @@ -1201,13 +1218,14 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use cmor_long_name='Water Evaporation Flux Where Ice Free Ocean over Sea') ! smg: seaice_melt field requires updates to the sea ice model - !handles%id_seaice_melt = register_diag_field('ocean_model', 'seaice_melt', & - ! diag%axesT1, Time, 'water flux to ocean from sea ice melt(> 0) or form(< 0)', & - ! 'kg m-2 s-1', & - ! standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics', & - ! cmor_field_name='fsitherm', & - ! cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics',& - ! cmor_long_name='water flux to ocean from sea ice melt(> 0) or form(< 0)') + ! gmm: MCT provides this field + handles%id_seaice_melt = register_diag_field('ocean_model', 'seaice_melt', & + diag%axesT1, Time, 'water flux to ocean from sea ice melt(> 0) or form(< 0)', & + 'kg m-2 s-1', & + standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics', & + cmor_field_name='fsitherm', & + cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics',& + cmor_long_name='water flux to ocean from sea ice melt(> 0) or form(< 0)') handles%id_precip = register_diag_field('ocean_model', 'precip', diag%axesT1, Time, & 'Liquid + frozen precipitation into ocean', 'kg m-2 s-1') @@ -1269,12 +1287,13 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use cmor_long_name='Evaporation Where Ice Free Ocean over Sea Area Integrated') ! seaice_melt field requires updates to the sea ice model - !handles%id_total_seaice_melt = register_scalar_field('ocean_model', 'total_seaice_melt', Time, diag, & - ! long_name='Area integrated sea ice melt (>0) or form (<0)', units='kg s-1', & - ! standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', & - ! cmor_field_name='total_fsitherm', & - ! cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', & - ! cmor_long_name='Water Melt/Form from Sea Ice Area Integrated') + ! gmm: MCT provides this field + handles%id_total_seaice_melt = register_scalar_field('ocean_model', 'total_seaice_melt', Time, diag, & + long_name='Area integrated sea ice melt (>0) or form (<0)', units='kg s-1', & + standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', & + cmor_field_name='total_fsitherm', & + cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', & + cmor_long_name='Water Melt/Form from Sea Ice Area Integrated') handles%id_total_precip = register_scalar_field('ocean_model', 'total_precip', Time, diag, & long_name='Area integrated liquid+frozen precip into ocean', units='kg s-1') @@ -1404,11 +1423,11 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use 'W m-2') handles%id_net_heat_coupler = register_diag_field('ocean_model', 'net_heat_coupler', & - diag%axesT1,Time,'Surface ocean heat flux from SW+LW+latent+sensible (via the coupler)',& + diag%axesT1,Time,'Surface ocean heat flux from SW+LW+latent+sensible+melth (via the coupler)',& 'W m-2') handles%id_net_heat_surface = register_diag_field('ocean_model', 'net_heat_surface',diag%axesT1, & - Time,'Surface ocean heat flux from SW+LW+lat+sens+mass transfer+frazil+restore or flux adjustments', 'W m-2',& + Time,'Surface ocean heat flux from SW+LW+lat+sens+mass transfer+frazil+restore+melth or flux adjustments', 'W m-2',& standard_name='surface_downward_heat_flux_in_sea_water', cmor_field_name='hfds', & cmor_standard_name='surface_downward_heat_flux_in_sea_water', & cmor_long_name='Surface ocean heat flux from SW+LW+latent+sensible+masstransfer+frazil') @@ -1464,6 +1483,13 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use cmor_standard_name='surface_downward_sensible_heat_flux', & cmor_long_name='Surface Downward Sensible Heat Flux') + handles%id_melth = register_diag_field('ocean_model', 'melth', diag%axesT1, Time,& + 'Heat flux into ocean from snow and sea ice melt', 'W m-2', & + standard_name='snow_ice_melt_heat_flux', & + !GMM? cmor_field_name='hfsso', & + cmor_standard_name='snow_ice_melt_heat_flux', & + cmor_long_name='Heat flux into ocean from snow and sea ice melt') + handles%id_heat_added = register_diag_field('ocean_model', 'heat_added', diag%axesT1, Time, & 'Flux Adjustment or restoring surface heat flux into ocean', 'W m-2') @@ -1534,7 +1560,7 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use handles%id_total_net_heat_coupler = register_scalar_field('ocean_model', & 'total_net_heat_coupler', Time, diag, & - long_name='Area integrated surface heat flux from SW+LW+latent+sensible (via the coupler)',& + long_name='Area integrated surface heat flux from SW+LW+latent+sensible+melth (via the coupler)',& units='W') handles%id_total_net_heat_surface = register_scalar_field('ocean_model', & @@ -1621,12 +1647,12 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use handles%id_net_heat_coupler_ga = register_scalar_field('ocean_model', & 'net_heat_coupler_ga', Time, diag, & - long_name='Area averaged surface heat flux from SW+LW+latent+sensible (via the coupler)',& + long_name='Area averaged surface heat flux from SW+LW+latent+sensible+melth (via the coupler)',& units='W m-2') handles%id_net_heat_surface_ga = register_scalar_field('ocean_model', & 'net_heat_surface_ga', Time, diag, & - long_name='Area averaged surface heat flux from SW+LW+lat+sens+mass+frazil+restore or flux adjustments', & + long_name='Area averaged surface heat flux from SW+LW+lat+sens+mass+frazil+restore+melth or flux adjustments', & units='W m-2', & cmor_field_name='ave_hfds', & cmor_standard_name='surface_downward_heat_flux_in_sea_water_area_averaged', & @@ -1790,8 +1816,7 @@ subroutine forcing_accumulate(flux_tmp, forces, fluxes, dt, G, wt2) fluxes%vprec(i,j) = wt1*fluxes%vprec(i,j) + wt2*flux_tmp%vprec(i,j) fluxes%lrunoff(i,j) = wt1*fluxes%lrunoff(i,j) + wt2*flux_tmp%lrunoff(i,j) fluxes%frunoff(i,j) = wt1*fluxes%frunoff(i,j) + wt2*flux_tmp%frunoff(i,j) - ! ### ADD LATER fluxes%seaice_melt(i,j) = wt1*fluxes%seaice_melt(i,j) + wt2*flux_tmp%seaice_melt(i,j) - + fluxes%seaice_melt(i,j) = wt1*fluxes%seaice_melt(i,j) + wt2*flux_tmp%seaice_melt(i,j) fluxes%sw(i,j) = wt1*fluxes%sw(i,j) + wt2*flux_tmp%sw(i,j) fluxes%sw_vis_dir(i,j) = wt1*fluxes%sw_vis_dir(i,j) + wt2*flux_tmp%sw_vis_dir(i,j) fluxes%sw_vis_dif(i,j) = wt1*fluxes%sw_vis_dif(i,j) + wt2*flux_tmp%sw_vis_dif(i,j) @@ -2269,6 +2294,7 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%latent)) res(i,j) = res(i,j) + fluxes%latent(i,j) if (associated(fluxes%sens)) res(i,j) = res(i,j) + fluxes%sens(i,j) if (associated(fluxes%SW)) res(i,j) = res(i,j) + fluxes%SW(i,j) + if (associated(fluxes%melth)) res(i,j) = res(i,j) + fluxes%melth(i,j) enddo ; enddo call post_data(handles%id_net_heat_coupler, res, diag) if (handles%id_total_net_heat_coupler > 0) then @@ -2289,6 +2315,7 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%latent)) res(i,j) = res(i,j) + fluxes%latent(i,j) if (associated(fluxes%sens)) res(i,j) = res(i,j) + fluxes%sens(i,j) if (associated(fluxes%SW)) res(i,j) = res(i,j) + fluxes%SW(i,j) + if (associated(fluxes%melth)) res(i,j) = res(i,j) + fluxes%melth(i,j) if (associated(sfc_state%frazil)) res(i,j) = res(i,j) + sfc_state%frazil(i,j) * I_dt ! if (associated(sfc_state%TempXpme)) then ! res(i,j) = res(i,j) + sfc_state%TempXpme(i,j) * fluxes%C_p * I_dt @@ -2455,6 +2482,11 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if ((handles%id_sens > 0) .and. associated(fluxes%sens)) then call post_data(handles%id_sens, fluxes%sens, diag) endif + + if ((handles%id_melth > 0) .and. associated(fluxes%melth)) then + call post_data(handles%id_melth, fluxes%melth, diag) + endif + if ((handles%id_total_sens > 0) .and. associated(fluxes%sens)) then total_transport = global_area_integral(fluxes%sens,G) call post_data(handles%id_total_sens, total_transport, diag) @@ -2562,6 +2594,7 @@ subroutine allocate_forcing_type(G, fluxes, water, heat, ustar, press, shelf, ic call myAlloc(fluxes%netMassIn,isd,ied,jsd,jed, water) call myAlloc(fluxes%netSalt,isd,ied,jsd,jed, water) + call myAlloc(fluxes%melth,isd,ied,jsd,jed, heat) call myAlloc(fluxes%sw,isd,ied,jsd,jed, heat) call myAlloc(fluxes%lw,isd,ied,jsd,jed, heat) call myAlloc(fluxes%latent,isd,ied,jsd,jed, heat) @@ -2656,6 +2689,7 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%ustar_gustless)) deallocate(fluxes%ustar_gustless) if (associated(fluxes%buoy)) deallocate(fluxes%buoy) if (associated(fluxes%sw)) deallocate(fluxes%sw) + if (associated(fluxes%melth)) deallocate(fluxes%melth) if (associated(fluxes%sw_vis_dir)) deallocate(fluxes%sw_vis_dir) if (associated(fluxes%sw_vis_dif)) deallocate(fluxes%sw_vis_dif) if (associated(fluxes%sw_nir_dir)) deallocate(fluxes%sw_nir_dir) @@ -2818,7 +2852,7 @@ end subroutine deallocate_mech_forcing !! * non-penetrative = non-downwelling shortwave; portion of SW !! totally absorbed in the k=1 cell. !! The non-penetrative SW is combined with -!! LW+LAT+SENS in net_heat inside routine +!! LW+LAT+SENS+MELTH in net_heat inside routine !! extractFluxes1d. Notably, for many cases, !! non-penetrative SW = 0. !! * penetrative = that portion of shortwave penetrating below From 70779e6b306ee6b30ea851235e51d8ef708d8d7c Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 12 Oct 2018 15:30:24 -0600 Subject: [PATCH 02/15] Deletes TODO comments. Signs are correct. --- config_src/mct_driver/ocn_cap_methods.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index a9527f1660..38ee3f6b2e 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -65,13 +65,13 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, ice_ocean_boundary%lw_flux(i,j) = (x2o(ind%x2o_Faxa_lwdn,k) + x2o(ind%x2o_Foxx_lwup,k)) ! specific humitidy flux - ice_ocean_boundary%q_flux(i,j) = x2o(ind%x2o_Foxx_evap,k) !???TODO: should this be a minus sign + ice_ocean_boundary%q_flux(i,j) = x2o(ind%x2o_Foxx_evap,k) ! sensible heat flux (W/m2) - ice_ocean_boundary%t_flux(i,j) = x2o(ind%x2o_Foxx_sen,k) !???TODO: should this be a minus sign + ice_ocean_boundary%t_flux(i,j) = x2o(ind%x2o_Foxx_sen,k) ! latent heat flux (W/m^2) - ice_ocean_boundary%latent_flux(i,j) = x2o(ind%x2o_Foxx_lat,k) !???TODO: should this be a minus sign + ice_ocean_boundary%latent_flux(i,j) = x2o(ind%x2o_Foxx_lat,k) ! snow&ice melt heat flux (W/m^2) ice_ocean_boundary%melth(i,j) = x2o(ind%x2o_Fioi_melth,k) From 67e70c5f16c6bfb2cc85e7fdf9e21851bf5efb4b Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 12 Oct 2018 15:44:27 -0600 Subject: [PATCH 03/15] Add more complete description of Fioi_meltw --- config_src/mct_driver/ocn_cpl_indices.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config_src/mct_driver/ocn_cpl_indices.F90 b/config_src/mct_driver/ocn_cpl_indices.F90 index 52f94f6106..32c0f4155f 100644 --- a/config_src/mct_driver/ocn_cpl_indices.F90 +++ b/config_src/mct_driver/ocn_cpl_indices.F90 @@ -41,7 +41,7 @@ module ocn_cpl_indices integer :: x2o_Faxa_swndr !< near-IR, direct shortwave (W/m2) integer :: x2o_Faxa_swndf !< near-IR, direct shortwave (W/m2) integer :: x2o_Fioi_melth !< Heat flux from snow & ice melt (W/m2) - integer :: x2o_Fioi_meltw !< Snow melt flux (kg/m2/s) + integer :: x2o_Fioi_meltw !< Water flux from sea ice and snow melt (kg/m2/s) integer :: x2o_Fioi_bcpho !< Black Carbon hydrophobic release from sea ice component integer :: x2o_Fioi_bcphi !< Black Carbon hydrophilic release from sea ice component integer :: x2o_Fioi_flxdst !< Dust release from sea ice component From 918f218efab526ea973f991ff3ad2031e18b8d5a Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 12 Oct 2018 15:49:40 -0600 Subject: [PATCH 04/15] Adds meltw (water flux from seaice and snow) The corresponding variable from CIME is *Fioi_meltw --- config_src/mct_driver/MOM_surface_forcing.F90 | 8 ++++++++ config_src/mct_driver/ocn_cap_methods.F90 | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 97f118a6f9..0d45409925 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -158,6 +158,7 @@ module MOM_surface_forcing real, pointer, dimension(:,:) :: v_flux =>NULL() !< j-direction wind stress (Pa) real, pointer, dimension(:,:) :: t_flux =>NULL() !< sensible heat flux (W/m2) real, pointer, dimension(:,:) :: melth =>NULL() !< sea ice and snow melt heat flux (W/m2) + real, pointer, dimension(:,:) :: meltw =>NULL() !< water flux due to sea ice and snow melting (kg/m2/s) 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(:,:) :: lw_flux =>NULL() !< long wave radiation (W/m2) @@ -446,6 +447,10 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, Time, G, CS, & if (associated(fluxes%melth)) & fluxes%melth(i,j) = G%mask2dT(i,j) * IOB%melth(i-i0,j-j0) + ! water flux due to sea ice and snow melt (kg/m2/s) + if (associated(fluxes%meltw)) & + fluxes%meltw(i,j) = G%mask2dT(i,j) * IOB%meltw(i-i0,j-j0) + ! latent heat flux (W/m^2) if (associated(fluxes%latent)) & fluxes%latent(i,j) = G%mask2dT(i,j) * IOB%latent_flux(i-i0,j-j0) @@ -776,6 +781,7 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB% v_flux (isc:iec,jsc:jec), & IOB% t_flux (isc:iec,jsc:jec), & IOB% melth (isc:iec,jsc:jec), & + IOB% meltw (isc:iec,jsc:jec), & IOB% q_flux (isc:iec,jsc:jec), & IOB% salt_flux (isc:iec,jsc:jec), & IOB% lw_flux (isc:iec,jsc:jec), & @@ -801,6 +807,7 @@ subroutine IOB_allocate(IOB, isc, iec, jsc, jec) IOB%v_flux = 0.0 IOB%t_flux = 0.0 IOB%melth = 0.0 + IOB%meltw = 0.0 IOB%q_flux = 0.0 IOB%salt_flux = 0.0 IOB%lw_flux = 0.0 @@ -1316,6 +1323,7 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt) write(outunit,100) 'iobt%v_flux ', mpp_chksum( iobt%v_flux ) write(outunit,100) 'iobt%t_flux ', mpp_chksum( iobt%t_flux ) write(outunit,100) 'iobt%melth ', mpp_chksum( iobt%melth ) + write(outunit,100) 'iobt%meltw ', mpp_chksum( iobt%meltw ) write(outunit,100) 'iobt%q_flux ', mpp_chksum( iobt%q_flux ) write(outunit,100) 'iobt%rofl_flux ', mpp_chksum( iobt%rofl_flux ) write(outunit,100) 'iobt%rofi_flux ', mpp_chksum( iobt%rofi_flux ) diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index 38ee3f6b2e..d58400b270 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -76,6 +76,9 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, ! snow&ice melt heat flux (W/m^2) ice_ocean_boundary%melth(i,j) = x2o(ind%x2o_Fioi_melth,k) + ! water flux from snow&ice melt (kg/m2/s) + ice_ocean_boundary%meltw(i,j) = x2o(ind%x2o_Fioi_meltw,k) + ! liquid runoff ice_ocean_boundary%rofl_flux(i,j) = x2o(ind%x2o_Foxx_rofl,k) * GRID%mask2dT(ig,jg) @@ -120,6 +123,7 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, write(logunit,F01)'import: day, secs, j, i, q_flux = ',day,secs,j,i,ice_ocean_boundary%q_flux(i,j) write(logunit,F01)'import: day, secs, j, i, t_flux = ',day,secs,j,i,ice_ocean_boundary%t_flux(i,j) write(logunit,F01)'import: day, secs, j, i, melth = ',day,secs,j,i,ice_ocean_boundary%melth(i,j) + write(logunit,F01)'import: day, secs, j, i, meltw = ',day,secs,j,i,ice_ocean_boundary%meltw(i,j) write(logunit,F01)'import: day, secs, j, i, latent_flux = ',& day,secs,j,i,ice_ocean_boundary%latent_flux(i,j) write(logunit,F01)'import: day, secs, j, i, runoff = ',& From d581094ca6d1ad68b6aeb9533717211103259d56 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 12 Oct 2018 15:51:28 -0600 Subject: [PATCH 05/15] Updates MCT doxygen after adding meltw and melth --- config_src/mct_driver/ocn_comp_mct.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/config_src/mct_driver/ocn_comp_mct.F90 b/config_src/mct_driver/ocn_comp_mct.F90 index 97692ccc65..442b44f67d 100644 --- a/config_src/mct_driver/ocn_comp_mct.F90 +++ b/config_src/mct_driver/ocn_comp_mct.F90 @@ -773,8 +773,6 @@ end subroutine ocean_model_init_sfc !! mi, mass of ice (kg/m2) !! !! Variables in the coupler that are **NOT** used in MOM6 (i.e., no corresponding field in fluxes): -!! x2o_Fioi_melth, heat flux from snow & ice melt (W/m2) -!! x2o_Fioi_meltw, snow melt flux (kg/m2/s) !! x2o_Si_ifrac, fractional ice wrt ocean !! x2o_So_duu10n, 10m wind speed squared (m^2/s^2) !! x2o_Sa_co2prog, bottom atm level prognostic CO2 From 9b0af26e82bcef1c9959368740cfdd7096ece64e Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Mon, 15 Oct 2018 08:44:51 -0600 Subject: [PATCH 06/15] Adds meltw and melth into fluxes --- src/core/MOM_forcing_type.F90 | 72 ++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index b6a1f069c6..0d708a0e36 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -82,7 +82,7 @@ module MOM_forcing_type vprec => NULL(), & !< virtual liquid precip associated w/ SSS restoring ( kg/(m^2 s) ) lrunoff => NULL(), & !< liquid river runoff entering ocean ( kg/(m^2 s) ) frunoff => NULL(), & !< frozen river runoff (calving) entering ocean ( kg/(m^2 s) ) - seaice_melt => NULL(), & !< seaice melt (positive) or formation (negative) ( kg/(m^2 s) ) + meltw => NULL(), & !< snow/seaice melt (positive) or formation (negative) ( kg/(m^2 s) ) netMassIn => NULL(), & !< Sum of water mass flux out of the ocean ( kg/(m^2 s) ) netMassOut => NULL(), & !< Net water mass flux into of the ocean ( kg/(m^2 s) ) netSalt => NULL() !< Net salt entering the ocean @@ -234,7 +234,7 @@ module MOM_forcing_type integer :: id_lrunoff = -1, id_frunoff = -1 integer :: id_net_massout = -1, id_net_massin = -1 integer :: id_massout_flux = -1, id_massin_flux = -1 - integer :: id_seaice_melt = -1 + integer :: id_meltw = -1 ! global area integrated mass flux diagnostic handles integer :: id_total_prcme = -1, id_total_evap = -1 @@ -242,7 +242,7 @@ module MOM_forcing_type integer :: id_total_lprec = -1, id_total_fprec = -1 integer :: id_total_lrunoff = -1, id_total_frunoff = -1 integer :: id_total_net_massout = -1, id_total_net_massin = -1 - integer :: id_total_seaice_melt = -1 + integer :: id_total_meltw = -1 ! global area averaged mass flux diagnostic handles integer :: id_prcme_ga = -1, id_evap_ga = -1 @@ -275,6 +275,7 @@ module MOM_forcing_type integer :: id_total_heat_content_cond = -1, id_total_heat_content_surfwater= -1 integer :: id_total_heat_content_vprec = -1, id_total_heat_content_massout = -1 integer :: id_total_heat_added = -1, id_total_heat_content_massin = -1 + integer :: id_total_melth = -1 ! global area averaged heat flux diagnostic handles integer :: id_net_heat_coupler_ga = -1, id_net_heat_surface_ga = -1 @@ -493,7 +494,7 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, + fluxes%evap(i,j) ) & + fluxes%lrunoff(i,j) ) & + fluxes%vprec(i,j) ) & - + fluxes%seaice_melt(i,j)) & + + fluxes%meltw(i,j) ) & + fluxes%frunoff(i,j) )) if (do_NMIOr) then ! Repeat the above code w/ dt=1s for legacy reasons @@ -502,7 +503,7 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, + fluxes%evap(i,j) ) & + fluxes%lrunoff(i,j) ) & + fluxes%vprec(i,j) ) & - + fluxes%seaice_melt(i,j)) & + + fluxes%meltw(i,j) ) & + fluxes%frunoff(i,j) )) endif @@ -534,6 +535,11 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, netMassOut(i) = netMassOut(i) + fluxes%lprec(i,j) endif + ! meltw < 0 means sea ice formation taking water from the ocean. + if (fluxes%meltw(i,j) < 0.0) then + netMassOut(i) = netMassOut(i) + fluxes%meltw(i,j) + endif + ! vprec < 0 means virtual evaporation arising from surface salinity restoring, ! in which case heat_content_vprec is computed in MOM_diabatic_driver.F90. if (fluxes%vprec(i,j) < 0.0) then @@ -549,7 +555,7 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, ! surface heat fluxes from radiation and turbulent fluxes (K * H) ! (H=m for Bouss, H=kg/m2 for non-Bouss) - ! CIME provides heat flux from snow&ice melt (melth), so this should be added here + ! CIME provides heat flux from snow&ice melt (melth), so this is added below if (associated(fluxes%melth)) then net_heat(i) = scale * dt * J_m2_to_H * & ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j) + & @@ -1005,8 +1011,10 @@ subroutine MOM_forcing_chksum(mesg, fluxes, G, haloshift) call hchksum(fluxes%fprec, mesg//" fluxes%fprec",G%HI,haloshift=hshift) if (associated(fluxes%vprec)) & call hchksum(fluxes%vprec, mesg//" fluxes%vprec",G%HI,haloshift=hshift) - if (associated(fluxes%seaice_melt)) & - call hchksum(fluxes%seaice_melt, mesg//" fluxes%seaice_melt",G%HI,haloshift=hshift) + if (associated(fluxes%meltw)) & + call hchksum(fluxes%meltw, mesg//" fluxes%meltw",G%HI,haloshift=hshift) + if (associated(fluxes%melth)) & + call hchksum(fluxes%melth, mesg//" fluxes%melth",G%HI,haloshift=hshift) if (associated(fluxes%p_surf)) & call hchksum(fluxes%p_surf, mesg//" fluxes%p_surf",G%HI,haloshift=hshift) if (associated(fluxes%salt_flux)) & @@ -1111,7 +1119,8 @@ subroutine forcing_SinglePointPrint(fluxes, G, i, j, mesg) call locMsg(fluxes%lprec,'lprec') call locMsg(fluxes%fprec,'fprec') call locMsg(fluxes%vprec,'vprec') - call locMsg(fluxes%seaice_melt,'seaice_melt') + call locMsg(fluxes%meltw,'meltw') + call locMsg(fluxes%melth,'melth') call locMsg(fluxes%p_surf,'p_surf') call locMsg(fluxes%salt_flux,'salt_flux') call locMsg(fluxes%TKE_tidal,'TKE_tidal') @@ -1219,8 +1228,9 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use ! smg: seaice_melt field requires updates to the sea ice model ! gmm: MCT provides this field - handles%id_seaice_melt = register_diag_field('ocean_model', 'seaice_melt', & - diag%axesT1, Time, 'water flux to ocean from sea ice melt(> 0) or form(< 0)', & + ! TODO: confirm cmor field name + handles%id_meltw = register_diag_field('ocean_model', 'meltw', & + diag%axesT1, Time, 'water flux to ocean from snow/sea ice melt(> 0) or form(< 0)', & 'kg m-2 s-1', & standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics', & cmor_field_name='fsitherm', & @@ -1288,7 +1298,8 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use ! seaice_melt field requires updates to the sea ice model ! gmm: MCT provides this field - handles%id_total_seaice_melt = register_scalar_field('ocean_model', 'total_seaice_melt', Time, diag, & + ! TODO: confirm cmor field name + handles%id_total_meltw = register_scalar_field('ocean_model', 'total_meltw', Time, diag, & long_name='Area integrated sea ice melt (>0) or form (<0)', units='kg s-1', & standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', & cmor_field_name='total_fsitherm', & @@ -1430,7 +1441,7 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use Time,'Surface ocean heat flux from SW+LW+lat+sens+mass transfer+frazil+restore+melth or flux adjustments', 'W m-2',& standard_name='surface_downward_heat_flux_in_sea_water', cmor_field_name='hfds', & cmor_standard_name='surface_downward_heat_flux_in_sea_water', & - cmor_long_name='Surface ocean heat flux from SW+LW+latent+sensible+masstransfer+frazil') + cmor_long_name='Surface ocean heat flux from SW+LW+latent+sensible+masstransfer+frazil+melth') handles%id_sw = register_diag_field('ocean_model', 'SW', diag%axesT1, Time, & 'Shortwave radiation flux into ocean', 'W m-2', & @@ -1486,7 +1497,7 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use handles%id_melth = register_diag_field('ocean_model', 'melth', diag%axesT1, Time,& 'Heat flux into ocean from snow and sea ice melt', 'W m-2', & standard_name='snow_ice_melt_heat_flux', & - !GMM? cmor_field_name='hfsso', & + !GMM TODO cmor_field_name='hfsso', & cmor_standard_name='snow_ice_melt_heat_flux', & cmor_long_name='Heat flux into ocean from snow and sea ice melt') @@ -1641,6 +1652,10 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use long_name='Area integrated surface heat flux from restoring and/or flux adjustment', & units='W') + handles%id_total_melth = register_scalar_field('ocean_model',& + 'total_melth', Time, diag, & + long_name='Area integrated surface heat flux from snow and sea ice melt', & + units='W') !=============================================================== ! area averaged surface heat fluxes @@ -1816,7 +1831,7 @@ subroutine forcing_accumulate(flux_tmp, forces, fluxes, dt, G, wt2) fluxes%vprec(i,j) = wt1*fluxes%vprec(i,j) + wt2*flux_tmp%vprec(i,j) fluxes%lrunoff(i,j) = wt1*fluxes%lrunoff(i,j) + wt2*flux_tmp%lrunoff(i,j) fluxes%frunoff(i,j) = wt1*fluxes%frunoff(i,j) + wt2*flux_tmp%frunoff(i,j) - fluxes%seaice_melt(i,j) = wt1*fluxes%seaice_melt(i,j) + wt2*flux_tmp%seaice_melt(i,j) + fluxes%meltw(i,j) = wt1*fluxes%meltw(i,j) + wt2*flux_tmp%meltw(i,j) fluxes%sw(i,j) = wt1*fluxes%sw(i,j) + wt2*flux_tmp%sw(i,j) fluxes%sw_vis_dir(i,j) = wt1*fluxes%sw_vis_dir(i,j) + wt2*flux_tmp%sw_vis_dir(i,j) fluxes%sw_vis_dif(i,j) = wt1*fluxes%sw_vis_dif(i,j) + wt2*flux_tmp%sw_vis_dif(i,j) @@ -1971,7 +1986,7 @@ subroutine set_derived_forcing_fields(forces, fluxes, G, Rho0) end subroutine set_derived_forcing_fields -!> This subroutine calculates determines the net mass source to th eocean from +!> This subroutine calculates determines the net mass source to th ocean from !! a (thermodynamic) forcing type and stores it in a mech_forcing type. subroutine set_net_mass_forcing(fluxes, forces, G) type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields @@ -2001,6 +2016,9 @@ subroutine set_net_mass_forcing(fluxes, forces, G) if (associated(fluxes%evap)) then ; do j=js,je ; do i=is,ie forces%net_mass_src(i,j) = forces%net_mass_src(i,j) + fluxes%evap(i,j) enddo ; enddo ; endif + if (associated(fluxes%meltw)) then ; do j=js,je ; do i=is,ie + forces%net_mass_src(i,j) = forces%net_mass_src(i,j) + fluxes%meltw(i,j) + enddo ; enddo ; endif endif end subroutine set_net_mass_forcing @@ -2105,6 +2123,8 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%lrunoff)) res(i,j) = res(i,j)+fluxes%lrunoff(i,j) if (associated(fluxes%frunoff)) res(i,j) = res(i,j)+fluxes%frunoff(i,j) if (associated(fluxes%vprec)) res(i,j) = res(i,j)+fluxes%vprec(i,j) + ! GMM, not sure if meltw is needed here. If so, the name prcme is misleading. + if (associated(fluxes%meltw)) res(i,j) = res(i,j)+fluxes%meltw(i,j) enddo ; enddo call post_data(handles%id_prcme, res, diag) if (handles%id_total_prcme > 0) then @@ -2123,6 +2143,7 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (fluxes%lprec(i,j) < 0.0) res(i,j) = res(i,j) + fluxes%lprec(i,j) if (fluxes%vprec(i,j) < 0.0) res(i,j) = res(i,j) + fluxes%vprec(i,j) if (fluxes%evap(i,j) < 0.0) res(i,j) = res(i,j) + fluxes%evap(i,j) + if (fluxes%meltw(i,j) < 0.0) res(i,j) = res(i,j) + fluxes%meltw(i,j) enddo ; enddo call post_data(handles%id_net_massout, res, diag) if (handles%id_total_net_massout > 0) then @@ -2140,6 +2161,7 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (fluxes%vprec(i,j) > 0.0) res(i,j) = res(i,j) + fluxes%vprec(i,j) ! fluxes%cond is not needed because it is derived from %evap > 0 if (fluxes%evap(i,j) > 0.0) res(i,j) = res(i,j) + fluxes%evap(i,j) + if (fluxes%meltw(i,j) > 0.0) res(i,j) = res(i,j) + fluxes%meltw(i,j) enddo ; enddo call post_data(handles%id_net_massin, res, diag) if (handles%id_total_net_massin > 0) then @@ -2228,6 +2250,14 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) endif endif + if (associated(fluxes%meltw)) then + if (handles%id_meltw > 0) call post_data(handles%id_meltw, fluxes%meltw, diag) + if (handles%id_total_meltw > 0) then + total_transport = global_area_integral(fluxes%meltw,G) + call post_data(handles%id_total_meltw, total_transport, diag) + endif + endif + ! post diagnostics for boundary heat fluxes ==================================== if ((handles%id_heat_content_lrunoff > 0) .and. associated(fluxes%heat_content_lrunoff)) & @@ -2487,6 +2517,11 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) call post_data(handles%id_melth, fluxes%melth, diag) endif + if ((handles%id_total_melth > 0) .and. associated(fluxes%melth)) then + total_transport = global_area_integral(fluxes%melth,G) + call post_data(handles%id_total_melth, total_transport, diag) + endif + if ((handles%id_total_sens > 0) .and. associated(fluxes%sens)) then total_transport = global_area_integral(fluxes%sens,G) call post_data(handles%id_total_sens, total_transport, diag) @@ -2589,11 +2624,10 @@ subroutine allocate_forcing_type(G, fluxes, water, heat, ustar, press, shelf, ic call myAlloc(fluxes%vprec,isd,ied,jsd,jed, water) call myAlloc(fluxes%lrunoff,isd,ied,jsd,jed, water) call myAlloc(fluxes%frunoff,isd,ied,jsd,jed, water) - call myAlloc(fluxes%seaice_melt,isd,ied,jsd,jed, water) + call myAlloc(fluxes%meltw,isd,ied,jsd,jed, water) call myAlloc(fluxes%netMassOut,isd,ied,jsd,jed, water) call myAlloc(fluxes%netMassIn,isd,ied,jsd,jed, water) call myAlloc(fluxes%netSalt,isd,ied,jsd,jed, water) - call myAlloc(fluxes%melth,isd,ied,jsd,jed, heat) call myAlloc(fluxes%sw,isd,ied,jsd,jed, heat) call myAlloc(fluxes%lw,isd,ied,jsd,jed, heat) @@ -2714,7 +2748,7 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%vprec)) deallocate(fluxes%vprec) if (associated(fluxes%lrunoff)) deallocate(fluxes%lrunoff) if (associated(fluxes%frunoff)) deallocate(fluxes%frunoff) - if (associated(fluxes%seaice_melt)) deallocate(fluxes%seaice_melt) + if (associated(fluxes%meltw)) deallocate(fluxes%meltw) if (associated(fluxes%salt_flux)) deallocate(fluxes%salt_flux) if (associated(fluxes%p_surf_full)) deallocate(fluxes%p_surf_full) if (associated(fluxes%p_surf)) deallocate(fluxes%p_surf) From 6acc499e689efcf9efdc078e1b0ec53bb3990721 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Mon, 15 Oct 2018 10:44:27 -0600 Subject: [PATCH 07/15] Ignores volume flux of sea ice via reverse engineering --- config_src/mct_driver/MOM_surface_forcing.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 0d45409925..509907dd41 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -489,9 +489,12 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, Time, G, CS, & ! Bob thinks this is trying ensure the net fresh-water of the ocean + sea-ice system ! is constant. ! To do this correctly we will need a sea-ice melt field added to IOB. -AJA - if (associated(fluxes%salt_flux) .and. (CS%ice_salt_concentration>0.0)) & - net_FW(i,j) = net_FW(i,j) + G%areaT(i,j) * & - (fluxes%salt_flux(i,j) / CS%ice_salt_concentration) + ! GMM: as stated above, the following is wrong. CIME deals with volume/mass and + ! heat from sea ice/snow via meltw and melth, respectively. + !!if (associated(fluxes%salt_flux) .and. (CS%ice_salt_concentration>0.0)) & + ! net_FW(i,j) = net_FW(i,j) + G%areaT(i,j) * & + ! (fluxes%salt_flux(i,j) / CS%ice_salt_concentration) + net_FW2(i,j) = net_FW(i,j)/G%areaT(i,j) enddo; enddo From 719459354ce74af0a4c9e26dd2dd54e8e09064dc Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Tue, 16 Oct 2018 08:04:57 -0600 Subject: [PATCH 08/15] Re-introduces salt_flux contribution into net_FW --- config_src/mct_driver/MOM_surface_forcing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 509907dd41..5bc8fdd97a 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -491,9 +491,9 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, Time, G, CS, & ! To do this correctly we will need a sea-ice melt field added to IOB. -AJA ! GMM: as stated above, the following is wrong. CIME deals with volume/mass and ! heat from sea ice/snow via meltw and melth, respectively. - !!if (associated(fluxes%salt_flux) .and. (CS%ice_salt_concentration>0.0)) & - ! net_FW(i,j) = net_FW(i,j) + G%areaT(i,j) * & - ! (fluxes%salt_flux(i,j) / CS%ice_salt_concentration) + if (associated(fluxes%salt_flux) .and. (CS%ice_salt_concentration>0.0)) & + net_FW(i,j) = net_FW(i,j) + G%areaT(i,j) * & + (fluxes%salt_flux(i,j) / CS%ice_salt_concentration) net_FW2(i,j) = net_FW(i,j)/G%areaT(i,j) enddo; enddo From cd2648d9a3b79219a1cd4676ae879b276ab2ae64 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 2 Nov 2018 13:16:21 -0600 Subject: [PATCH 09/15] Take meltw into account when adjust_net_fresh_water_to_zero=true --- config_src/mct_driver/MOM_surface_forcing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 5bc8fdd97a..1145ab346c 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -480,7 +480,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, Time, G, CS, & ! adjust the NET fresh-water flux to zero, if flagged if (CS%adjust_net_fresh_water_to_zero) then 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%meltw(i,j)) + & (fluxes%lrunoff(i,j) + fluxes%frunoff(i,j))) + & (fluxes%evap(i,j) + fluxes%vprec(i,j)) ) * G%areaT(i,j) ! The following contribution appears to be calculating the volume flux of sea-ice From 622d19ec8d9a06611da1b2a00a6de69a8f659c94 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 2 Nov 2018 13:17:58 -0600 Subject: [PATCH 10/15] Delete comment on whether meltw is needed in PRmE --- src/core/MOM_forcing_type.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 0d708a0e36..4755358d73 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -2123,7 +2123,6 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%lrunoff)) res(i,j) = res(i,j)+fluxes%lrunoff(i,j) if (associated(fluxes%frunoff)) res(i,j) = res(i,j)+fluxes%frunoff(i,j) if (associated(fluxes%vprec)) res(i,j) = res(i,j)+fluxes%vprec(i,j) - ! GMM, not sure if meltw is needed here. If so, the name prcme is misleading. if (associated(fluxes%meltw)) res(i,j) = res(i,j)+fluxes%meltw(i,j) enddo ; enddo call post_data(handles%id_prcme, res, diag) From 3cd18cac64c750826b7e3c2d5b15be0e93cb14ab Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Fri, 2 Nov 2018 13:19:01 -0600 Subject: [PATCH 11/15] Sets CS%ignore_fluxes_over_land = .false. when ePBL is not used --- src/parameterizations/vertical/MOM_diabatic_aux.F90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parameterizations/vertical/MOM_diabatic_aux.F90 b/src/parameterizations/vertical/MOM_diabatic_aux.F90 index f662eda365..ee412b358c 100644 --- a/src/parameterizations/vertical/MOM_diabatic_aux.F90 +++ b/src/parameterizations/vertical/MOM_diabatic_aux.F90 @@ -1337,7 +1337,10 @@ subroutine diabatic_aux_init(Time, G, GV, param_file, diag, CS, useALEalgorithm, call get_param(param_file, mod, "RIVERMIX_DEPTH", CS%rivermix_depth, & "The depth to which rivers are mixed if DO_RIVERMIX is \n"//& "defined.", units="m", default=0.0) - else ; CS%do_rivermix = .false. ; CS%rivermix_depth = 0.0 ; endif + else + CS%do_rivermix = .false. ; CS%rivermix_depth = 0.0 ; CS%ignore_fluxes_over_land = .false. + endif + if (GV%nkml == 0) then call get_param(param_file, mod, "USE_RIVER_HEAT_CONTENT", CS%use_river_heat_content, & "If true, use the fluxes%runoff_Hflx field to set the \n"//& From 24cdc5cddb8992145f71da1c1da83588bbd0c278 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Mon, 19 Nov 2018 10:13:37 -0700 Subject: [PATCH 12/15] Add heat_content_meltw --- src/core/MOM_forcing_type.F90 | 66 +++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 4755358d73..aebba42eaa 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -90,7 +90,8 @@ module MOM_forcing_type ! heat associated with water crossing ocean surface real, pointer, dimension(:,:) :: & heat_content_cond => NULL(), & !< heat content associated with condensating water (W/m^2) - heat_content_lprec => NULL(), & !< heat content associated with liquid >0 precip (W/m^2) (diagnostic) + heat_content_lprec => NULL(), & !< heat content associated with liquid >0 precip (W/m^2) (diagnostic) + heat_content_meltw => NULL(), & !< heat content associated with snow/seaice melt/freeze (W/m^2) heat_content_fprec => NULL(), & !< heat content associated with frozen precip (W/m^2) heat_content_vprec => NULL(), & !< heat content associated with virtual >0 precip (W/m^2) heat_content_lrunoff => NULL(), & !< heat content associated with liquid runoff (W/m^2) @@ -262,7 +263,7 @@ module MOM_forcing_type integer :: id_heat_content_vprec = -1, id_heat_content_massout = -1 integer :: id_heat_added = -1, id_heat_content_massin = -1 integer :: id_hfrainds = -1, id_hfrunoffds = -1 - integer :: id_melth = -1 + integer :: id_melth = -1, id_heat_content_meltw = -1 ! global area integrated heat flux diagnostic handles integer :: id_total_net_heat_coupler = -1, id_total_net_heat_surface = -1 @@ -275,7 +276,7 @@ module MOM_forcing_type integer :: id_total_heat_content_cond = -1, id_total_heat_content_surfwater= -1 integer :: id_total_heat_content_vprec = -1, id_total_heat_content_massout = -1 integer :: id_total_heat_added = -1, id_total_heat_content_massin = -1 - integer :: id_total_melth = -1 + integer :: id_total_melth = -1, id_total_heat_content_meltw = -1 ! global area averaged heat flux diagnostic handles integer :: id_net_heat_coupler_ga = -1, id_net_heat_surface_ga = -1 @@ -727,6 +728,15 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, endif endif + ! Following lprec and fprec, water flux due to sea ice melt (meltw) enters at SST - GMM + if (associated(fluxes%heat_content_meltw)) then + if (fluxes%meltw(i,j) > 0.0) then + fluxes%heat_content_meltw(i,j) = fluxes%C_p*fluxes%meltw(i,j)*T(i,1) + else + fluxes%heat_content_meltw(i,j) = 0.0 + endif + endif + ! virtual precip associated with salinity restoring ! vprec > 0 means add water to ocean, assumed to be at SST ! vprec < 0 means remove water from ocean; set heat_content_vprec in MOM_diabatic_driver.F90 @@ -1035,6 +1045,8 @@ subroutine MOM_forcing_chksum(mesg, fluxes, G, haloshift) call hchksum(fluxes%heat_content_lprec, mesg//" fluxes%heat_content_lprec",G%HI,haloshift=hshift) if (associated(fluxes%heat_content_fprec)) & call hchksum(fluxes%heat_content_fprec, mesg//" fluxes%heat_content_fprec",G%HI,haloshift=hshift) + if (associated(fluxes%heat_content_meltw)) & + call hchksum(fluxes%heat_content_meltw, mesg//" fluxes%heat_content_meltw",G%HI,haloshift=hshift) if (associated(fluxes%heat_content_cond)) & call hchksum(fluxes%heat_content_cond, mesg//" fluxes%heat_content_cond",G%HI,haloshift=hshift) if (associated(fluxes%heat_content_massout)) & @@ -1131,6 +1143,7 @@ subroutine forcing_SinglePointPrint(fluxes, G, i, j, mesg) call locMsg(fluxes%heat_content_frunoff,'heat_content_frunoff') call locMsg(fluxes%heat_content_lprec,'heat_content_lprec') call locMsg(fluxes%heat_content_fprec,'heat_content_fprec') + call locMsg(fluxes%heat_content_meltw,'heat_content_meltw') call locMsg(fluxes%heat_content_vprec,'heat_content_vprec') call locMsg(fluxes%heat_content_cond,'heat_content_cond') call locMsg(fluxes%heat_content_cond,'heat_content_massout') @@ -1404,6 +1417,10 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use diag%axesT1,Time,'Heat content (relative to 0degC) of frozen prec entering ocean',& 'W m-2') + handles%id_heat_content_meltw = register_diag_field('ocean_model', 'heat_content_meltw',& + diag%axesT1,Time,'Heat content (relative to 0degC) of water flux due to sea ice melting entering ocean',& + 'W m-2') + handles%id_heat_content_vprec = register_diag_field('ocean_model', 'heat_content_vprec', & diag%axesT1,Time,'Heat content (relative to 0degC) of virtual precip entering ocean',& 'W m-2') @@ -1540,6 +1557,11 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles, use long_name='Area integrated heat content (relative to 0C) of frozen precip',& units='W') + handles%id_total_heat_content_meltw = register_scalar_field('ocean_model', & + 'total_heat_content_meltw', Time, diag, & + long_name='Area integrated heat content (relative to 0C) of water flux due to melting',& + units='W') + handles%id_total_heat_content_vprec = register_scalar_field('ocean_model', & 'total_heat_content_vprec', Time, diag, & long_name='Area integrated heat content (relative to 0C) of virtual precip',& @@ -1864,6 +1886,11 @@ subroutine forcing_accumulate(flux_tmp, forces, fluxes, dt, G, wt2) fluxes%heat_content_fprec(i,j) = wt1*fluxes%heat_content_fprec(i,j) + wt2*flux_tmp%heat_content_fprec(i,j) enddo ; enddo endif + if (associated(fluxes%heat_content_meltw) .and. associated(flux_tmp%heat_content_meltw)) then + do j=js,je ; do i=is,ie + fluxes%heat_content_meltw(i,j) = wt1*fluxes%heat_content_meltw(i,j) + wt2*flux_tmp%heat_content_meltw(i,j) + enddo ; enddo + endif if (associated(fluxes%heat_content_vprec) .and. associated(flux_tmp%heat_content_vprec)) then do j=js,je ; do i=is,ie fluxes%heat_content_vprec(i,j) = wt1*fluxes%heat_content_vprec(i,j) + wt2*flux_tmp%heat_content_vprec(i,j) @@ -2287,6 +2314,13 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) call post_data(handles%id_total_heat_content_fprec, total_transport, diag) endif + if ((handles%id_heat_content_meltw > 0) .and. associated(fluxes%heat_content_meltw)) & + call post_data(handles%id_heat_content_meltw, fluxes%heat_content_meltw, diag) + if ((handles%id_total_heat_content_meltw > 0) .and. associated(fluxes%heat_content_meltw)) then + total_transport = global_area_integral(fluxes%heat_content_meltw,G) + call post_data(handles%id_total_heat_content_meltw, total_transport, diag) + endif + if ((handles%id_heat_content_vprec > 0) .and. associated(fluxes%heat_content_vprec)) & call post_data(handles%id_heat_content_vprec, fluxes%heat_content_vprec, diag) if ((handles%id_total_heat_content_vprec > 0) .and. associated(fluxes%heat_content_vprec)) then @@ -2346,17 +2380,18 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%SW)) res(i,j) = res(i,j) + fluxes%SW(i,j) if (associated(fluxes%melth)) res(i,j) = res(i,j) + fluxes%melth(i,j) if (associated(sfc_state%frazil)) res(i,j) = res(i,j) + sfc_state%frazil(i,j) * I_dt - ! if (associated(sfc_state%TempXpme)) then - ! res(i,j) = res(i,j) + sfc_state%TempXpme(i,j) * fluxes%C_p * I_dt - ! else - if (associated(fluxes%heat_content_lrunoff)) res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j) - if (associated(fluxes%heat_content_frunoff)) res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j) - if (associated(fluxes%heat_content_lprec)) res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j) - if (associated(fluxes%heat_content_fprec)) res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j) - if (associated(fluxes%heat_content_vprec)) res(i,j) = res(i,j) + fluxes%heat_content_vprec(i,j) - if (associated(fluxes%heat_content_cond)) res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j) - if (associated(fluxes%heat_content_massout)) res(i,j) = res(i,j) + fluxes%heat_content_massout(i,j) - ! endif + !if (associated(sfc_state%TempXpme)) then + ! res(i,j) = res(i,j) + sfc_state%TempXpme(i,j) * fluxes%C_p * I_dt + !else + if (associated(fluxes%heat_content_lrunoff)) res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j) + if (associated(fluxes%heat_content_frunoff)) res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j) + if (associated(fluxes%heat_content_lprec)) res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j) + if (associated(fluxes%heat_content_fprec)) res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j) + if (associated(fluxes%heat_content_meltw)) res(i,j) = res(i,j) + fluxes%heat_content_meltw(i,j) + if (associated(fluxes%heat_content_vprec)) res(i,j) = res(i,j) + fluxes%heat_content_vprec(i,j) + if (associated(fluxes%heat_content_cond)) res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j) + if (associated(fluxes%heat_content_massout)) res(i,j) = res(i,j) + fluxes%heat_content_massout(i,j) + !endif if (associated(fluxes%heat_added)) res(i,j) = res(i,j) + fluxes%heat_added(i,j) enddo ; enddo call post_data(handles%id_net_heat_surface, res, diag) @@ -2380,6 +2415,7 @@ subroutine forcing_diagnostics(fluxes, sfc_state, dt, G, diag, handles) if (associated(fluxes%heat_content_lrunoff)) res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j) if (associated(fluxes%heat_content_frunoff)) res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j) if (associated(fluxes%heat_content_lprec)) res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j) + if (associated(fluxes%heat_content_meltw)) res(i,j) = res(i,j) + fluxes%heat_content_meltw(i,j) if (associated(fluxes%heat_content_fprec)) res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j) if (associated(fluxes%heat_content_vprec)) res(i,j) = res(i,j) + fluxes%heat_content_vprec(i,j) if (associated(fluxes%heat_content_cond)) res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j) @@ -2640,6 +2676,7 @@ subroutine allocate_forcing_type(G, fluxes, water, heat, ustar, press, shelf, ic if (present(heat) .and. present(water)) then ; if (heat .and. water) then call myAlloc(fluxes%heat_content_cond,isd,ied,jsd,jed, .true.) + call myAlloc(fluxes%heat_content_meltw,isd,ied,jsd,jed, .true.) call myAlloc(fluxes%heat_content_lprec,isd,ied,jsd,jed, .true.) call myAlloc(fluxes%heat_content_fprec,isd,ied,jsd,jed, .true.) call myAlloc(fluxes%heat_content_vprec,isd,ied,jsd,jed, .true.) @@ -2736,6 +2773,7 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%heat_added)) deallocate(fluxes%heat_added) if (associated(fluxes%heat_content_lrunoff)) deallocate(fluxes%heat_content_lrunoff) if (associated(fluxes%heat_content_frunoff)) deallocate(fluxes%heat_content_frunoff) + if (associated(fluxes%heat_content_meltw)) deallocate(fluxes%heat_content_meltw) if (associated(fluxes%heat_content_lprec)) deallocate(fluxes%heat_content_lprec) if (associated(fluxes%heat_content_fprec)) deallocate(fluxes%heat_content_fprec) if (associated(fluxes%heat_content_cond)) deallocate(fluxes%heat_content_cond) From c284cdd5d7a5127fcb76244a119966dee4b83a60 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Mon, 3 Dec 2018 16:46:21 -0700 Subject: [PATCH 13/15] Adds meltw and melth into FW_in and heat_in, respectively --- src/diagnostics/MOM_sum_output.F90 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/diagnostics/MOM_sum_output.F90 b/src/diagnostics/MOM_sum_output.F90 index 91a4dd96ab..6640a864c2 100644 --- a/src/diagnostics/MOM_sum_output.F90 +++ b/src/diagnostics/MOM_sum_output.F90 @@ -952,6 +952,10 @@ subroutine accumulate_net_input(fluxes, sfc_state, dt, G, CS) endif endif + if (associated(fluxes%meltw)) then ; do j=js,je ; do i=is,ie + FW_in(i,j) = FW_in(i,j) + dt * G%areaT(i,j) * fluxes%meltw(i,j) + enddo ; enddo ; endif + salt_in(:,:) = 0.0 ; heat_in(:,:) = 0.0 if (CS%use_temperature) then @@ -960,6 +964,10 @@ subroutine accumulate_net_input(fluxes, sfc_state, dt, G, CS) (fluxes%lw(i,j) + (fluxes%latent(i,j) + fluxes%sens(i,j)))) enddo ; enddo ; endif + if (associated(fluxes%melth)) then ; do j=js,je ; do i=is,ie + heat_in(i,j) = heat_in(i,j) + dt*G%areaT(i,j) * fluxes%melth(i,j) + enddo ; enddo ; endif + ! smg: new code ! include heat content from water transport across ocean surface ! if (associated(fluxes%heat_content_lprec)) then ; do j=js,je ; do i=is,ie From a910cd00df0e15d1d0716d4e72b42959b986ca26 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Mon, 3 Dec 2018 16:47:50 -0700 Subject: [PATCH 14/15] Adds meltw into net_mass_src --- src/core/MOM_forcing_type.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index fc688f15c0..03a568b4f4 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -2103,7 +2103,7 @@ subroutine get_net_mass_forcing(fluxes, G, net_mass_src) net_mass_src(i,j) = net_mass_src(i,j) + fluxes%evap(i,j) enddo ; enddo ; endif if (associated(fluxes%meltw)) then ; do j=js,je ; do i=is,ie - forces%net_mass_src(i,j) = forces%net_mass_src(i,j) + fluxes%meltw(i,j) + net_mass_src(i,j) = net_mass_src(i,j) + fluxes%meltw(i,j) enddo ; enddo ; endif end subroutine get_net_mass_forcing From 4b815771d30107d6038a0fd9d4ed04d8ae055ba6 Mon Sep 17 00:00:00 2001 From: Gustavo Marques Date: Wed, 12 Dec 2018 11:33:40 -0700 Subject: [PATCH 15/15] Fix indices bug in ocn_import --- config_src/mct_driver/ocn_cap_methods.F90 | 28 +++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index 92fe04bbdf..063cc13e96 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -33,7 +33,7 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, real(kind=8), optional , intent(in) :: c1, c2, c3, c4 !< Coeffs. used in the shortwave decomposition ! Local variables - integer :: i, j, ig, jg, isc, iec, jsc, jec ! Grid indices + integer :: i, j, isc, iec, jsc, jec ! Grid indices integer :: k integer :: day, secs, rc type(ESMF_time) :: currTime @@ -44,9 +44,7 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, k = 0 do j = jsc, jec - jg = j + grid%jsc - jsc do i = isc, iec - ig = i + grid%jsc - isc k = k + 1 ! Increment position within gindex ! taux @@ -80,16 +78,16 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, ice_ocean_boundary%meltw(i,j) = x2o(ind%x2o_Fioi_meltw,k) ! liquid runoff - ice_ocean_boundary%rofl_flux(i,j) = x2o(ind%x2o_Foxx_rofl,k) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%rofl_flux(i,j) = x2o(ind%x2o_Foxx_rofl,k) * GRID%mask2dT(i,j) ! ice runoff - ice_ocean_boundary%rofi_flux(i,j) = x2o(ind%x2o_Foxx_rofi,k) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%rofi_flux(i,j) = x2o(ind%x2o_Foxx_rofi,k) * GRID%mask2dT(i,j) ! surface pressure - ice_ocean_boundary%p(i,j) = x2o(ind%x2o_Sa_pslv,k) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%p(i,j) = x2o(ind%x2o_Sa_pslv,k) * GRID%mask2dT(i,j) ! salt flux (minus sign needed here -GMM) - ice_ocean_boundary%salt_flux(i,j) = -x2o(ind%x2o_Fioi_salt,k) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%salt_flux(i,j) = -x2o(ind%x2o_Fioi_salt,k) * GRID%mask2dT(i,j) ! 1) visible, direct shortwave (W/m2) ! 2) visible, diffuse shortwave (W/m2) @@ -97,15 +95,15 @@ subroutine ocn_import(x2o, ind, grid, ice_ocean_boundary, ocean_public, logunit, ! 4) near-IR, diffuse shortwave (W/m2) if (present(c1) .and. present(c2) .and. present(c3) .and. present(c4)) then ! Use runtime coefficients to decompose net short-wave heat flux into 4 components - ice_ocean_boundary%sw_flux_vis_dir(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c1 * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_vis_dif(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c2 * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_nir_dir(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c3 * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_nir_dif(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c4 * GRID%mask2dT(ig,jg) + ice_ocean_boundary%sw_flux_vis_dir(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c1 * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_vis_dif(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c2 * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_nir_dir(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c3 * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_nir_dif(i,j) = x2o(ind%x2o_Foxx_swnet,k) * c4 * GRID%mask2dT(i,j) else - ice_ocean_boundary%sw_flux_vis_dir(i,j) = x2o(ind%x2o_Faxa_swvdr,k) * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_vis_dif(i,j) = x2o(ind%x2o_Faxa_swvdf,k) * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_nir_dir(i,j) = x2o(ind%x2o_Faxa_swndr,k) * GRID%mask2dT(ig,jg) - ice_ocean_boundary%sw_flux_nir_dif(i,j) = x2o(ind%x2o_Faxa_swndf,k) * GRID%mask2dT(ig,jg) + ice_ocean_boundary%sw_flux_vis_dir(i,j) = x2o(ind%x2o_Faxa_swvdr,k) * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_vis_dif(i,j) = x2o(ind%x2o_Faxa_swvdf,k) * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_nir_dir(i,j) = x2o(ind%x2o_Faxa_swndr,k) * GRID%mask2dT(i,j) + ice_ocean_boundary%sw_flux_nir_dif(i,j) = x2o(ind%x2o_Faxa_swndf,k) * GRID%mask2dT(i,j) endif enddo enddo