From 713db5514e9676b4dc1b47f024f4f0c4a66d59eb Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Thu, 11 Aug 2016 16:21:12 -0400 Subject: [PATCH 01/14] Fix for a LOAR2 model crash - LOAR2 model crashed with the following traceback with a particular combination of paramter overrides THERMO_SPANS_COUPLING = True FATAL from PE 294: MPP_RESET_GROUP_UPDATE_FIELD_3D_: group%reset_index_s > group%nscalar Image PC Routine Line Source fms_LOAR2G_exec.x 0000000002F0F106 mpp_mod_mp_mpp_er 50 mpp_util_mpi.inc fms_LOAR2G_exec.x 0000000002CA7DE7 mpp_domains_mod_m 887 mpp_group_update.h fms_LOAR2G_exec.x 0000000002227039 mom_domains_mp_cr 711 MOM_domains.F90 fms_LOAR2G_exec.x 00000000022655DA mom_mp_step_mom_ 521 MOM.F90 fms_LOAR2G_exec.x 000000000216894E ocean_model_mod_m 426 ocean_model_MOM.F90 fms_LOAR2G_exec.x 0000000000401CE8 MAIN__ 916 coupler_main.F90 - Zhi found a mismatch between the logic for calling group_create and group_update that would cause this issue. He also made the fix. The model does not crash with the fix. --- src/core/MOM.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index f888599b6e..59dfa5d12c 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -517,8 +517,9 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%ustar(:,:), G%Domain) if (ASSOCIATED(fluxes%p_surf)) & call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%p_surf(:,:), G%Domain) - if (CS%thickness_diffuse .OR. CS%mixedlayer_restrat) & + if ((CS%thickness_diffuse .and. (.not.CS%thickness_diffuse_first .or. CS%dt_trans == 0) ) .OR. CS%mixedlayer_restrat) & call create_group_pass(CS%pass_h, h, G%Domain) + if (CS%diabatic_first) then if (associated(CS%visc%Ray_u) .and. associated(CS%visc%Ray_v)) & call create_group_pass(CS%pass_ray, CS%visc%Ray_u, CS%visc%Ray_v, G%Domain, & From 744886df588111da1a98a7771ada50a939efc35d Mon Sep 17 00:00:00 2001 From: Alon Stern Date: Fri, 23 Sep 2016 10:56:55 -0400 Subject: [PATCH 02/14] Fields ustar_berg, area_berg and mass_berg have been passed from the iceberg model to SIS2, through the coupler to the ocean model. The ocean model has been edited to allow these fields to be passed to it when the flag ICEBERGS_APPLY_RIGID_BOUNDARY=.True. The iceberg surface fields are added to the ice shelf fields (if the ice shelf is running). The combined ice shelf /iceberg fields can now affect the upper ocean boundary conditions. This is done by adding area_berg to frac_shelf_h, and adding ustar_berg to ustar_shelf. The mass is also used to calculate the shelf rigidity --- .../coupled_driver/MOM_surface_forcing.F90 | 23 +++++ config_src/coupled_driver/ocean_model_MOM.F90 | 95 ++++++++++++++++++- src/core/MOM_forcing_type.F90 | 52 +++++++++- 3 files changed, 163 insertions(+), 7 deletions(-) diff --git a/config_src/coupled_driver/MOM_surface_forcing.F90 b/config_src/coupled_driver/MOM_surface_forcing.F90 index 8be4c72bfe..ecf05f9956 100644 --- a/config_src/coupled_driver/MOM_surface_forcing.F90 +++ b/config_src/coupled_driver/MOM_surface_forcing.F90 @@ -194,6 +194,9 @@ module MOM_surface_forcing 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) + real, pointer, dimension(:,:) :: mass_berg =>NULL() ! mass of icebergs(kg/m2) real, pointer, dimension(:,:) :: runoff_hflx =>NULL() ! heat content of liquid runoff (W/m2) real, pointer, dimension(:,:) :: calving_hflx =>NULL() ! heat content of frozen runoff (W/m2) real, pointer, dimension(:,:) :: p =>NULL() ! pressure of overlying ice and atmosphere @@ -469,6 +472,20 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, G, CS, state, if (ASSOCIATED(IOB%calving)) & fluxes%frunoff(i,j) = IOB%calving(i-i0,j-j0) * G%mask2dT(i,j) + if (((ASSOCIATED(IOB%ustar_berg) .and. (.not. ASSOCIATED(fluxes%ustar_berg))) & + .or. (ASSOCIATED(IOB%area_berg) .and. (.not. ASSOCIATED(fluxes%area_berg)))) & + .or. (ASSOCIATED(IOB%mass_berg) .and. (.not. ASSOCIATED(fluxes%mass_berg)))) & + call allocate_forcing_type(G, fluxes, iceberg=.true.) + + if (ASSOCIATED(IOB%ustar_berg)) & + fluxes%ustar_berg(i,j) = IOB%ustar_berg(i-i0,j-j0) * G%mask2dT(i,j) + + if (ASSOCIATED(IOB%area_berg)) & + fluxes%area_berg(i,j) = IOB%area_berg(i-i0,j-j0) * G%mask2dT(i,j) + + if (ASSOCIATED(IOB%mass_berg)) & + fluxes%mass_berg(i,j) = IOB%mass_berg(i-i0,j-j0) * G%mask2dT(i,j) + if (ASSOCIATED(IOB%runoff_hflx)) & fluxes%heat_content_lrunoff(i,j) = IOB%runoff_hflx(i-i0,j-j0) * G%mask2dT(i,j) @@ -1197,6 +1214,12 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt) 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)) & + write(outunit,100) 'iobt%ustar_berg ', mpp_chksum( iobt%ustar_berg ) + if (ASSOCIATED(iobt%area_berg)) & + write(outunit,100) 'iobt%area_berg ', mpp_chksum( iobt%area_berg ) + if (ASSOCIATED(iobt%mass_berg)) & + write(outunit,100) 'iobt%mass_berg ', mpp_chksum( iobt%mass_berg ) 100 FORMAT(" CHECKSUM::",A20," = ",Z20) do n = 1, iobt%fluxes%num_bcs !{ diff --git a/config_src/coupled_driver/ocean_model_MOM.F90 b/config_src/coupled_driver/ocean_model_MOM.F90 index 3543b5d6c0..6cd379ea9c 100644 --- a/config_src/coupled_driver/ocean_model_MOM.F90 +++ b/config_src/coupled_driver/ocean_model_MOM.F90 @@ -67,8 +67,10 @@ module ocean_model_mod use mpp_domains_mod, only : domain2d, mpp_get_layout, mpp_get_global_domain use mpp_domains_mod, only : mpp_define_domains, mpp_get_compute_domain, mpp_get_data_domain use atmos_ocean_fluxes_mod, only : aof_set_coupler_flux +use MOM_forcing_type, only : allocate_forcing_type use fms_mod, only : stdout use mpp_mod, only : mpp_chksum +use MOM_domains, only : pass_var, pass_vector, TO_ALL, CGRID_NE, BGRID_NE #include @@ -153,6 +155,9 @@ module ocean_model_mod integer :: nstep = 0 ! The number of calls to update_ocean. logical :: use_ice_shelf ! If true, the ice shelf model is enabled. + logical :: icebergs_apply_rigid_boundary ! If true, the icebergs can change ocean bd condition. + real :: kv_iceberg ! The viscosity of the icebergs in m2/s (for ice rigidity) + real :: density_iceberg ! A typical density of icebergs in kg/m3 (for ice rigidity) type(ice_shelf_CS), pointer :: Ice_shelf_CSp => NULL() logical :: restore_salinity ! If true, the coupled MOM driver adds a term to ! restore salinity to a specified value. @@ -160,7 +165,7 @@ module ocean_model_mod ! restore sst to a specified value. real :: press_to_z ! A conversion factor between pressure and ocean ! depth in m, usually 1/(rho_0*g), in m Pa-1. - real :: C_p ! The heat capacity of seawater, in J K-1 kg-1. + real :: C_p ! The heat capacity of seawater, in J K-1 kg-1. type(directories) :: dirs ! A structure containing several relevant directory paths. type(forcing) :: fluxes ! A structure containing pointers to @@ -280,6 +285,16 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in) call get_param(param_file, mod, "ICE_SHELF", OS%use_ice_shelf, & "If true, enables the ice shelf model.", default=.false.) + call get_param(param_file, mod, "ICEBERGS_APPLY_RIGID_BOUNDARY", OS%icebergs_apply_rigid_boundary, & + "If true, allows icebergs to change boundary condition felt by ocean", default=.false.) + + if (OS%icebergs_apply_rigid_boundary) then + call get_param(param_file, mod, "KV_ICEBERG", OS%kv_iceberg, & + "The viscosity of the icebergs", units="m2 s-1",default=1.0e10) + call get_param(param_file, mod, "DENSITY_ICEBERGS", OS%density_iceberg, & + "A typical density of icebergs.", units="kg m-3", default=917.0) + endif + OS%press_to_z = 1.0/(Rho0*G_Earth) call surface_forcing_init(Time_in, OS%grid, param_file, OS%MOM_CSp%diag, & @@ -289,6 +304,11 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in) call initialize_ice_shelf(param_file, OS%grid, OS%Time, OS%ice_shelf_CSp, & OS%MOM_CSp%diag, OS%fluxes) endif + if (OS%icebergs_apply_rigid_boundary) then + !call allocate_forcing_type(OS%grid, OS%fluxes, iceberg=.true.) + !This assumes that the iceshelf and ocean are on the same grid. I hope this is true + if (.not. OS%use_ice_shelf) call allocate_forcing_type(OS%grid, OS%fluxes, ustar=.true., shelf=.true.) + endif call MOM_sum_output_init(OS%grid, param_file, OS%dirs%output_directory, & OS%MOM_CSp%ntrunc, Time_init, OS%sum_output_CSp) @@ -394,12 +414,14 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, & call MOM_generic_tracer_fluxes_accumulate(OS%fluxes, weight) !here weight=1, just saving the current fluxes #endif - ! Add ice shelf fluxes - + ! Add ice shelf fluxes if (OS%use_ice_shelf) then call shelf_calc_flux(OS%State, OS%fluxes, OS%Time, time_step, OS%Ice_shelf_CSp) endif - + if (OS%icebergs_apply_rigid_boundary) then + !This assumes that the iceshelf and ocean are on the same grid. I hope this is true + call add_berg_flux_to_shelf(OS%grid, OS%fluxes,OS%use_ice_shelf,OS%density_iceberg,OS%kv_iceberg) + endif ! Indicate that there are new unused fluxes. OS%fluxes%fluxes_used = .false. OS%fluxes%dt_buoy_accum = time_step @@ -407,10 +429,13 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, & OS%flux_tmp%C_p = OS%fluxes%C_p call convert_IOB_to_fluxes(Ice_ocean_boundary, OS%flux_tmp, index_bnds, OS%Time, & OS%grid, OS%forcing_CSp, OS%state, OS%restore_salinity,OS%restore_temp) - if (OS%use_ice_shelf) then call shelf_calc_flux(OS%State, OS%flux_tmp, OS%Time, time_step, OS%Ice_shelf_CSp) endif + if (OS%icebergs_apply_rigid_boundary) then + !This assumes that the iceshelf and ocean are on the same grid. I hope this is true + call add_berg_flux_to_shelf(OS%grid, OS%flux_tmp, OS%use_ice_shelf,OS%density_iceberg,OS%kv_iceberg) + endif call forcing_accumulate(OS%flux_tmp, OS%fluxes, time_step, OS%grid, weight) #ifdef _USE_GENERIC_TRACER @@ -477,6 +502,66 @@ end subroutine update_ocean_model ! the any restart file name as a prefix. ! ! + +subroutine add_berg_flux_to_shelf(G, fluxes, use_ice_shelf, density_ice, kv_ice) + type(ocean_grid_type), intent(inout) :: G + type(forcing), intent(inout) :: fluxes + logical, intent(in) :: use_ice_shelf + real, intent(in) :: kv_ice ! The viscosity of ice, in m2 s-1. + real, intent(in) :: density_ice ! A typical density of ice, in kg m-3. +! Arguments: +! (in) fluxes - A structure of surface fluxes that may be used. +! (in) G - The ocean's grid structure. + integer :: i, j, is, ie, js, je, isd, ied, jsd, jed + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + isd = G%isd ; jsd = G%jsd ; ied = G%ied ; jed = G%jed + !This routine adds iceberg data to the ice shelf data (if ice shelf is used) + !which can then be used to change the top of ocean boundary condition used in + !the ocean model. This routine is taken from the add_shelf_flux subroutine + !within the ice shelf model. + + if (.not. (((associated(fluxes%frac_shelf_h) .and. associated(fluxes%frac_shelf_u)) & + .and.(associated(fluxes%frac_shelf_v) .and. associated(fluxes%ustar_shelf)))& + .and.(associated(fluxes%rigidity_ice_u) .and. associated(fluxes%rigidity_ice_v)))) return + + if (.not. ((associated(fluxes%area_berg) .and. associated(fluxes%ustar_berg)) .and. associated(fluxes%mass_berg) ) ) return + + if (.not. use_ice_shelf) then + fluxes%frac_shelf_h(:,:)=0. + fluxes%frac_shelf_u(:,:)=0. + fluxes%frac_shelf_v(:,:)=0. + fluxes%ustar_shelf(:,:)=0. + fluxes%rigidity_ice_u(:,:)=0. + fluxes%rigidity_ice_v(:,:)=0. + endif + + do j=jsd,jed ; do i=isd,ied + if (G%areaT(i,j) > 0.0) & + fluxes%frac_shelf_h(i,j) = fluxes%frac_shelf_h(i,j) + fluxes%area_berg(i,j) + fluxes%ustar_shelf(i,j) = fluxes%ustar_shelf(i,j) + fluxes%ustar_berg(i,j) + enddo ; enddo + !do I=isd,ied-1 ; do j=isd,jed + do j=jsd,jed ; do i=isd,ied-1 ! ### changed stride order; i->ied-1? + fluxes%frac_shelf_u(I,j) = 0.0 + if ((G%areaT(i,j) + G%areaT(i+1,j) > 0.0)) & ! .and. (G%dxdy_u(I,j) > 0.0)) & + fluxes%frac_shelf_u(I,j) = fluxes%frac_shelf_u(I,j) + (((fluxes%area_berg(i,j)*G%areaT(i,j)) + (fluxes%area_berg(i+1,j)*G%areaT(i+1,j))) / & + (G%areaT(i,j) + G%areaT(i+1,j))) + fluxes%rigidity_ice_u(I,j) = fluxes%rigidity_ice_u(I,j) +((kv_ice / density_ice) * & + min(fluxes%mass_berg(i,j), fluxes%mass_berg(i+1,j))) + enddo ; enddo + do j=jsd,jed-1 ; do i=isd,ied ! ### change stride order; j->jed-1? + !do i=isd,ied ; do J=isd,jed-1 + fluxes%frac_shelf_v(i,J) = 0.0 + if ((G%areaT(i,j) + G%areaT(i,j+1) > 0.0)) & ! .and. (G%dxdy_v(i,J) > 0.0)) & + fluxes%frac_shelf_v(i,J) = fluxes%frac_shelf_v(i,J) + (((fluxes%area_berg(i,j)*G%areaT(i,j)) + (fluxes%area_berg(i,j+1)*G%areaT(i,j+1))) / & + (G%areaT(i,j) + G%areaT(i,j+1) )) + fluxes%rigidity_ice_v(i,J) = fluxes%rigidity_ice_v(i,J) +((kv_ice / density_ice) * & + max(fluxes%mass_berg(i,j), fluxes%mass_berg(i,j+1))) + enddo ; enddo + call pass_vector(fluxes%frac_shelf_u, fluxes%frac_shelf_v, G%domain, TO_ALL, CGRID_NE) + +end subroutine add_berg_flux_to_shelf + subroutine ocean_model_restart(OS, timestamp) type(ocean_state_type), pointer :: OS character(len=*), intent(in), optional :: timestamp diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 651eb3ee48..db3889ccd6 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -122,6 +122,12 @@ module MOM_forcing_type TKE_tidal => NULL(), & !< tidal energy source driving mixing in bottom boundary layer (W/m^2) ustar_tidal => NULL() !< tidal contribution to bottom ustar (m/s) + ! iceberg related inputs + real, pointer, dimension(:,:) :: & + ustar_berg => NULL(),& !< iceberg contribution to top ustar (m/s) + area_berg => NULL(),& !< area of ocean surface covered by icebergs (m2/m2) + mass_berg => NULL() !< mass of icebergs (kg/m2) + ! land ice-shelf related inputs real, pointer, dimension(:,:) :: & ustar_shelf => NULL(), & !< friction velocity under ice-shelves (m/s) @@ -244,6 +250,15 @@ module MOM_forcing_type ! clock id handle integer :: id_clock_forcing + ! iceberg id handle + integer :: id_ustar_berg + integer :: id_area_berg + integer :: id_mass_berg + + !Iceberg + Ice shelf + integer :: id_ustar_ice_cover + integer :: id_frac_ice_cover + end type forcing_diags contains @@ -951,6 +966,21 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles) handles%id_ustar = register_diag_field('ocean_model', 'ustar', diag%axesT1, Time, & 'Surface friction velocity = [(gustiness + tau_magnitude)/rho0]^(1/2)', 'meter second-1') + handles%id_ustar_berg = register_diag_field('ocean_model', 'ustar_berg', diag%axesT1, Time, & + 'Friction velocity below iceberg ', 'meter second-1') + + handles%id_area_berg = register_diag_field('ocean_model', 'area_berg', diag%axesT1, Time, & + 'Area of grid cell covered by iceberg ', 'm2/m2') + + handles%id_mass_berg = register_diag_field('ocean_model', 'mass_berg', diag%axesT1, Time, & + 'Mass of icebergs ', 'kg/m2') + + handles%id_ustar_ice_cover = register_diag_field('ocean_model', 'ustar_ice_cover', diag%axesT1, Time, & + 'Friction velocity below iceberg and ice shelf together', 'meter second-1') + + handles%id_frac_ice_cover = register_diag_field('ocean_model', 'frac_ice_cover', diag%axesT1, Time, & + 'Area of grid cell below iceberg and ice shelf together ', 'm2/m2') + handles%id_psurf = register_diag_field('ocean_model', 'p_surf', diag%axesT1, Time, & 'Pressure at ice-ocean or atmosphere-ocean interface', 'Pascal', cmor_field_name='pso',& cmor_long_name='Sea Water Pressure at Sea Water Surface', cmor_units='Pa', & @@ -1684,6 +1714,16 @@ subroutine mech_forcing_diags(fluxes, dt, G, diag, handles) call post_data(handles%id_tauy, fluxes%tauy, diag) if ((handles%id_ustar > 0) .and. ASSOCIATED(fluxes%ustar)) & call post_data(handles%id_ustar, fluxes%ustar, diag) + if ((handles%id_ustar_berg > 0) .and. ASSOCIATED(fluxes%ustar_berg)) & + call post_data(handles%id_ustar_berg, fluxes%ustar_berg, diag) + if ((handles%id_area_berg > 0) .and. ASSOCIATED(fluxes%area_berg)) & + call post_data(handles%id_area_berg, fluxes%area_berg, diag) + if ((handles%id_mass_berg > 0) .and. ASSOCIATED(fluxes%mass_berg)) & + call post_data(handles%id_mass_berg, fluxes%mass_berg, diag) + if ((handles%id_frac_ice_cover > 0) .and. ASSOCIATED(fluxes%frac_shelf_h)) & + call post_data(handles%id_frac_ice_cover, fluxes%frac_shelf_h, diag) + if ((handles%id_ustar_ice_cover > 0) .and. ASSOCIATED(fluxes%ustar_shelf)) & + call post_data(handles%id_ustar_ice_cover, fluxes%ustar_shelf, diag) endif @@ -2161,7 +2201,7 @@ end subroutine forcing_diagnostics !> Conditionally allocate fields within the forcing type -subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press) +subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press,iceberg) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(forcing), intent(inout) :: fluxes !< Forcing fields structure logical, optional, intent(in) :: stress !< If present and true, allocate taux, tauy @@ -2170,6 +2210,7 @@ subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, p logical, optional, intent(in) :: heat !< If present and true, allocate heat fluxes logical, optional, intent(in) :: shelf !< If present and true, allocate fluxes for ice-shelf logical, optional, intent(in) :: press !< If present and true, allocate p_surf + logical, optional, intent(in) :: iceberg !< If present and true, allocate fluxes for icebergs ! Local variables integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB @@ -2221,7 +2262,11 @@ subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, p call myAlloc(fluxes%rigidity_ice_v,isd,ied,JsdB,JedB, shelf) call myAlloc(fluxes%p_surf,isd,ied,jsd,jed, press) - + + !These fields should only on allocated when iceberg area is being passed through the coupler. + call myAlloc(fluxes%ustar_berg,isd,ied,jsd,jed, iceberg) + call myAlloc(fluxes%area_berg,isd,ied,jsd,jed, iceberg) + call myAlloc(fluxes%mass_berg,isd,ied,jsd,jed, iceberg) contains subroutine myAlloc(array, is, ie, js, je, flag) @@ -2289,6 +2334,9 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%rigidity_ice_u)) deallocate(fluxes%rigidity_ice_u) if (associated(fluxes%rigidity_ice_v)) deallocate(fluxes%rigidity_ice_v) if (associated(fluxes%tr_fluxes)) deallocate(fluxes%tr_fluxes) + if (associated(fluxes%ustar_berg)) deallocate(fluxes%ustar_berg) + if (associated(fluxes%area_berg)) deallocate(fluxes%area_berg) + if (associated(fluxes%mass_berg)) deallocate(fluxes%mass_berg) end subroutine deallocate_forcing_type From 92cfcb2d99c7ac29e3492219b9fcd1623840a6b0 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Tue, 27 Sep 2016 09:02:34 -0400 Subject: [PATCH 03/14] +Added N2 diagnostics for diapyc_energy_req Added diagnostics of the initial and final stratification and of the test diffusivity profiles to the diapyc_energy_req code. All answers are bitwise identical. --- .../vertical/MOM_diapyc_energy_req.F90 | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 index b4685674af..063688158f 100644 --- a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 +++ b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 @@ -34,7 +34,7 @@ module MOM_diapyc_energy_req use MOM_grid, only : ocean_grid_type use MOM_variables, only : thermo_var_ptrs use MOM_verticalGrid, only : verticalGrid_type -use MOM_EOS, only : calculate_specific_vol_derivs +use MOM_EOS, only : calculate_specific_vol_derivs, calculate_density implicit none ; private @@ -50,9 +50,9 @@ module MOM_diapyc_energy_req ! profile in place of any that might be passed ! in as an argument. type(diag_ctrl), pointer :: diag ! Structure used to regulate timing of diagnostic output - integer :: id_ERt=-1, id_ERb=-1, id_ERc=-1, id_ERh=-1, id_Kddt=-1 + integer :: id_ERt=-1, id_ERb=-1, id_ERc=-1, id_ERh=-1, id_Kddt=-1, id_Kd=-1 integer :: id_CHCt=-1, id_CHCb=-1, id_CHCc=-1, id_CHCh=-1 - integer :: id_T0=-1, id_Tf=-1, id_S0=-1, id_Sf=-1 + integer :: id_T0=-1, id_Tf=-1, id_S0=-1, id_Sf=-1, id_N2_0=-1, id_N2_f=-1 integer :: id_h=-1, id_zInt=-1 end type diapyc_energy_req_CS @@ -211,6 +211,7 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & real, dimension(GV%ke+1) :: & pres, & ! Interface pressures in Pa. z_Int, & ! Interface heights relative to the surface, in m. + N2, & ! An estimate of the buoyancy frequency in s-2. Kddt_h_a, & ! Kddt_h_b, & ! Kddt_h, & ! The diapycnal diffusivity times a timestep divided by the @@ -238,6 +239,7 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & ! converted to turbulent kinetic energy if the velocity in ! the layer below an interface were homogenized with all of ! the water above the interface, in J m-2 = kg s-2. + real :: rho_here ! The in-situ density, in kg m-3. real :: PE_change, ColHt_cor real :: htot real :: dT_k, dT_km1, dS_k, dS_km1 ! Temporary arrays @@ -930,6 +932,7 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & if (CS%id_ERc>0) call post_data_1d_k(CS%id_ERc, PE_chg_k(:,3), CS%diag) if (CS%id_ERh>0) call post_data_1d_k(CS%id_ERh, PE_chg_k(:,4), CS%diag) if (CS%id_Kddt>0) call post_data_1d_k(CS%id_Kddt, GV%H_to_m*Kddt_h, CS%diag) + if (CS%id_Kd>0) call post_data_1d_k(CS%id_Kd, Kd, CS%diag) if (CS%id_h>0) call post_data_1d_k(CS%id_h, GV%H_to_m*h_tr, CS%diag) if (CS%id_zInt>0) call post_data_1d_k(CS%id_zInt, Z_int, CS%diag) if (CS%id_CHCt>0) call post_data_1d_k(CS%id_CHCt, ColHt_cor_k(:,1), CS%diag) @@ -940,6 +943,28 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & if (CS%id_Tf>0) call post_data_1d_k(CS%id_Tf, Tf, CS%diag) if (CS%id_S0>0) call post_data_1d_k(CS%id_S0, S0, CS%diag) if (CS%id_Sf>0) call post_data_1d_k(CS%id_Sf, Sf, CS%diag) + if (CS%id_N2_0>0) then + N2(1) = 0.0 ; N2(nz+1) = 0.0 + do K=2,nz + call calculate_density(0.5*(T0(k-1) + T0(k)), 0.5*(S0(k-1) + S0(k)), & + pres(K), rho_here, tv%eqn_of_state) + N2(K) = (GV%g_Earth * rho_here / (0.5*GV%H_to_m*(h_tr(k-1) + h_tr(k)))) * & + ( 0.5*(dSV_dT(k-1) + dSV_dT(k)) * (T0(k-1) - T0(k)) + & + 0.5*(dSV_dS(k-1) + dSV_dS(k)) * (S0(k-1) - S0(k)) ) + enddo + call post_data_1d_k(CS%id_N2_0, N2, CS%diag) + endif + if (CS%id_N2_f>0) then + N2(1) = 0.0 ; N2(nz+1) = 0.0 + do K=2,nz + call calculate_density(0.5*(Tf(k-1) + Tf(k)), 0.5*(Sf(k-1) + Sf(k)), & + pres(K), rho_here, tv%eqn_of_state) + N2(K) = (GV%g_Earth * rho_here / (0.5*GV%H_to_m*(h_tr(k-1) + h_tr(k)))) * & + ( 0.5*(dSV_dT(k-1) + dSV_dT(k)) * (Tf(k-1) - Tf(k)) + & + 0.5*(dSV_dS(k-1) + dSV_dS(k)) * (Sf(k-1) - Sf(k)) ) + enddo + call post_data_1d_k(CS%id_N2_f, N2, CS%diag) + endif endif end subroutine diapyc_energy_req_calc @@ -1345,6 +1370,8 @@ subroutine diapyc_energy_req_init(Time, G, param_file, diag, CS) "Diffusivity Energy Requirements, halves", "J m-2") CS%id_Kddt = register_diag_field('ocean_model', 'EnReqTest_Kddt', diag%axesZi, Time, & "Implicit diffusive coupling coefficient", "m") + CS%id_Kd = register_diag_field('ocean_model', 'EnReqTest_Kd', diag%axesZi, Time, & + "Diffusivity in test", "m2 s-1") CS%id_h = register_diag_field('ocean_model', 'EnReqTest_h_lay', diag%axesZL, Time, & "Test column layer thicknesses", "m") CS%id_zInt = register_diag_field('ocean_model', 'EnReqTest_z_int', diag%axesZi, Time, & @@ -1365,6 +1392,10 @@ subroutine diapyc_energy_req_init(Time, G, param_file, diag, CS) "Salinity before mixing", "g kg-1") CS%id_Sf = register_diag_field('ocean_model', 'EnReqTest_Sf', diag%axesZL, Time, & "Salinity after mixing", "g kg-1") + CS%id_N2_0 = register_diag_field('ocean_model', 'EnReqTest_N2_0', diag%axesZi, Time, & + "Squared buoyancy frequency before mixing", "second-2") + CS%id_N2_f = register_diag_field('ocean_model', 'EnReqTest_N2_f', diag%axesZi, Time, & + "Squared buoyancy frequency after mixing", "second-2") end subroutine diapyc_energy_req_init From 203559229bf84c80eb55fc5b71eec32f4c17e889 Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Tue, 27 Sep 2016 09:37:31 -0400 Subject: [PATCH 04/14] Doxygenized MOM_grid and MOM_hor_index - Adds a .images/ directory - Adds src/framework/_Horizontal_indexing.dox for more extensive documentation on indexing --- .doxygen | 6 +- .images/Arakawa_C_grid.png | Bin 0 -> 10159 bytes .images/Grid_metrics.png | Bin 0 -> 61868 bytes .images/Horizontal_NE_indexing_nonsym.png | Bin 0 -> 45889 bytes .images/Horizontal_NE_indexing_sym.png | Bin 0 -> 49605 bytes src/core/MOM_grid.F90 | 257 +++++++++++++--------- src/framework/MOM_hor_index.F90 | 88 +++++--- src/framework/_Horizontal_indexing.dox | 94 ++++++++ 8 files changed, 302 insertions(+), 143 deletions(-) create mode 100644 .images/Arakawa_C_grid.png create mode 100644 .images/Grid_metrics.png create mode 100755 .images/Horizontal_NE_indexing_nonsym.png create mode 100755 .images/Horizontal_NE_indexing_sym.png create mode 100644 src/framework/_Horizontal_indexing.dox diff --git a/.doxygen b/.doxygen index fceb7fea9b..4faf9f1d07 100644 --- a/.doxygen +++ b/.doxygen @@ -107,7 +107,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = YES +REPEAT_BRIEF = NO # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -872,7 +872,7 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = config_src src # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -892,7 +892,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = .images config_src src # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/.images/Arakawa_C_grid.png b/.images/Arakawa_C_grid.png new file mode 100644 index 0000000000000000000000000000000000000000..a765bf9338af577f7989777e42934d90672a606e GIT binary patch literal 10159 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 UlIP+KPuwBbuc=~-ubKq>7xQv}FaQ7m literal 0 HcmV?d00001 diff --git a/.images/Grid_metrics.png b/.images/Grid_metrics.png new file mode 100644 index 0000000000000000000000000000000000000000..22b1f0d55fbe40e7383a8ea53b1b243feff1ee1d GIT binary patch literal 61868 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%0A@I_SwK1tIGclj9++lV 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 literal 0 HcmV?d00001 diff --git a/.images/Horizontal_NE_indexing_nonsym.png b/.images/Horizontal_NE_indexing_nonsym.png new file mode 100755 index 0000000000000000000000000000000000000000..446700174822cd3a86bbae3fdb459254abb0a737 GIT binary patch literal 45889 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%0D6eP(Y^^j+FsDM>%QH0mzu0wzhqOPlFI2Y z?rZa{&WzrqtbCc+YiD<*)C1RxYU1Ym6m&z3h$9W>xjugVsz)5b!3Nib+&3V;#$&1E zzAOEScs2*N%5DI9w6#egS!zv^xj8f17DcpRGwbHHnIL`5zwAe~*T-kdvk(19EyBQM zX~esdW63Ax_`uZFl_mH?Nsuw_&Ye5ZaX*M!WWdkyb;gU=uXjUI1j>z4k{s?{Ku@&Z zhbOOo5^H+h%a@FV_h2;@oCbzb`Zl1AG>Kk2K`j3s4{?IiXTb0|aW;Pb7(7FCessTm z{`4vP{{6L@O&g*}auIALz43LiR>-rzDOE}bHtGGRei{3~n>v(yK2UL@q1@q9Q{gurt477%4BFpf+|iO8m+B5ApinU?#~9 zsVC>l)`cl9_qpD>m9BM{gAo#^zrQnE*h-|y9%96iMSIzR7DqoP4^JJ+ejF{A zE`Gu)E~*rKhbVxT=VA58|Mn3Gx003 zE%I-0R3QwZ{}LC+42t5woq~}OmlwNoOH21n2~(1CEm0}rh=v5qo~C*l8IB&**B-yAo+d+od;{$6!+(eB+I)1`_h7@aF{_OD>)hIMZ z*kGp9@%0Hrq^Jn8H~<5ftSy?Gn@!C!mFpKhk+qW9z@HVEmnV83WFB-S=!Y_)HFav_ z^5NXvLs%y>HXcWhMrLIRN=Qc3S%@W(;)$rjTIbHqmHfC=jjKbyW@88S92`7w=#er} zKy^KII;A9V^GlEV1_7gICVTg4qOC$C*lZOiAXqk~dbb4jx5zU@bKZ7;-Ht4N$BrFh zPnK{9p@Y;{t`=6)a_8_M+8VdAv(H3FBb7tFrXT1vF<3+DxVrv^)L9xjz{c9zsF1}j z8|Ltv9eUs?ocm)JQ7SPZ-4)&s3tYkRgG8baxqP-_^1|`#)p5 Ba3TNz literal 0 HcmV?d00001 diff --git a/.images/Horizontal_NE_indexing_sym.png b/.images/Horizontal_NE_indexing_sym.png new file mode 100755 index 0000000000000000000000000000000000000000..96ff5aa7bcd3e58cd01f82033ed8839dd1ead84f GIT binary patch literal 49605 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 )%4D>y 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 T#)3iwfj=E>eXT+btMLB^_v#(# literal 0 HcmV?d00001 diff --git a/src/core/MOM_grid.F90 b/src/core/MOM_grid.F90 index cae09ffcbd..47d9d6f01a 100644 --- a/src/core/MOM_grid.F90 +++ b/src/core/MOM_grid.F90 @@ -1,24 +1,7 @@ +!> Provides the ocean grid type module MOM_grid -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** +! This file is part of MOM6. See LICENSE.md for the license. use MOM_hor_index, only : hor_index_type, hor_index_init use MOM_domains, only : MOM_domain_type, get_domain_extent, compute_block_extent @@ -32,124 +15,162 @@ module MOM_grid public MOM_grid_init, MOM_grid_end, set_derived_metrics, set_first_direction public isPointInCell, hor_index_type +!> Ocean grid type. See mom_grid for details. type, public :: ocean_grid_type - type(MOM_domain_type), pointer :: Domain => NULL() - type(MOM_domain_type), pointer :: Domain_aux => NULL() ! A non-symmetric auxiliary domain type. - type(hor_index_type) :: HI - integer :: isc, iec, jsc, jec ! The range of the computational domain indices - integer :: isd, ied, jsd, jed ! and data domain indices at tracer cell centers. - integer :: isg, ieg, jsg, jeg ! The range of the global domain tracer cell indices. - integer :: IscB, IecB, JscB, JecB ! The range of the computational domain indices - integer :: IsdB, IedB, JsdB, JedB ! and data domain indices at tracer cell vertices. - integer :: IsgB, IegB, JsgB, JegB ! The range of the global domain vertex indices. - integer :: isd_global ! The values of isd and jsd in the global - integer :: jsd_global ! (decomposition invariant) index space. - integer :: idg_offset ! The offset between the corresponding global - integer :: jdg_offset ! and local array indices; add to local to get global. - integer :: ke ! The number of layers in the vertical. - logical :: symmetric ! True if symmetric memory is used. - logical :: nonblocking_updates ! If true, non-blocking halo updates are - ! allowed. The default is .false. (for now). - integer :: first_direction ! An integer that indicates which direction is - ! to be updated first in directionally split - ! parts of the calculation. This can be altered - ! during the course of the run via calls to - ! set_first_direction. + type(MOM_domain_type), pointer :: Domain => NULL() !< Ocean model domain + type(MOM_domain_type), pointer :: Domain_aux => NULL() !< A non-symmetric auxiliary domain type. + type(hor_index_type) :: HI !< Horizontal index ranges + + integer :: isc !< The start i-index of cell centers within the computational domain + integer :: iec !< The end i-index of cell centers within the computational domain + integer :: jsc !< The start j-index of cell centers within the computational domain + integer :: jec !< The end j-index of cell centers within the computational domain + + integer :: isd !< The start i-index of cell centers within the data domain + integer :: ied !< The end i-index of cell centers within the data domain + integer :: jsd !< The start j-index of cell centers within the data domain + integer :: jed !< The end j-index of cell centers within the data domain + + integer :: isg !< The start i-index of cell centers within the global domain + integer :: ieg !< The end i-index of cell centers within the global domain + integer :: jsg !< The start j-index of cell centers within the global domain + integer :: jeg !< The end j-index of cell centers within the global domain + + integer :: IscB !< The start i-index of cell vertices within the computational domain + integer :: IecB !< The end i-index of cell vertices within the computational domain + integer :: JscB !< The start j-index of cell vertices within the computational domain + integer :: JecB !< The end j-index of cell vertices within the computational domain + + integer :: IsdB !< The start i-index of cell vertices within the data domain + integer :: IedB !< The end i-index of cell vertices within the data domain + integer :: JsdB !< The start j-index of cell vertices within the data domain + integer :: JedB !< The end j-index of cell vertices within the data domain + + integer :: IsgB !< The start i-index of cell vertices within the global domain + integer :: IegB !< The end i-index of cell vertices within the global domain + integer :: JsgB !< The start j-index of cell vertices within the global domain + integer :: JegB !< The end j-index of cell vertices within the global domain + + integer :: isd_global !< The value of isd in the global index space (decompoistion invariant). + integer :: jsd_global !< The value of isd in the global index space (decompoistion invariant). + integer :: idg_offset !< The offset between the corresponding global and local i-indices. + integer :: jdg_offset !< The offset between the corresponding global and local j-indices. + integer :: ke !< The number of layers in the vertical. + logical :: symmetric !< True if symmetric memory is used. + logical :: nonblocking_updates !< If true, non-blocking halo updates are + !! allowed. The default is .false. (for now). + integer :: first_direction !< An integer that indicates which direction is + !! to be updated first in directionally split + !! parts of the calculation. This can be altered + !! during the course of the run via calls to + !! set_first_direction. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - mask2dT, & ! 0 for land points and 1 for ocean points on the h-grid. Nd. - geoLatT, & ! The geographic latitude at q points in degrees of latitude or m. - geoLonT, & ! The geographic longitude at q points in degrees of longitude or m. - dxT, IdxT, & ! dxT is delta x at h points, in m, and IdxT is 1/dxT in m-1. - dyT, IdyT, & ! dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. - areaT, & ! areaT is the area of an h-cell, in m2. - IareaT, & ! IareaT = 1/areaT, in m-2. - sin_rot, & ! The sine and cosine of the angular rotation between the local - cos_rot ! model grid's northward and the true northward directions. + mask2dT, & !< 0 for land points and 1 for ocean points on the h-grid. Nd. + geoLatT, & !< The geographic latitude at q points in degrees of latitude or m. + geoLonT, & !< The geographic longitude at q points in degrees of longitude or m. + dxT, & !< dxT is delta x at h points, in m. + IdxT, & !< 1/dxT in m-1. + dyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. + IdyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. + areaT, & !< The area of an h-cell, in m2. + IareaT, & !< 1/areaT, in m-2. + sin_rot, & !< The sine of the angular rotation between the local model grid's northward + !! and the true northward directions. + cos_rot !< The cosine of the angular rotation between the local model grid's northward + !! and the true northward directions. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: & - mask2dCu, & ! 0 for boundary points and 1 for ocean points on the u grid. Nondim. - geoLatCu, & ! The geographic latitude at u points in degrees of latitude or m. - geoLonCu, & ! The geographic longitude at u points in degrees of longitude or m. - dxCu, IdxCu, & ! dxCu is delta x at u points, in m, and IdxCu is 1/dxCu in m-1. - dyCu, IdyCu, & ! dyCu is delta y at u points, in m, and IdyCu is 1/dyCu in m-1. - dy_Cu, & ! The unblocked lengths of the u-faces of the h-cell in m. - dy_Cu_obc, & ! The unblocked lengths of the u-faces of the h-cell in m for OBC. - IareaCu, & ! The masked inverse areas of u-grid cells in m2. - areaCu ! The areas of the u-grid cells in m2. + mask2dCu, & !< 0 for boundary points and 1 for ocean points on the u grid. Nondim. + geoLatCu, & !< The geographic latitude at u points in degrees of latitude or m. + geoLonCu, & !< The geographic longitude at u points in degrees of longitude or m. + dxCu, & !< dxCu is delta x at u points, in m. + IdxCu, & !< 1/dxCu in m-1. + dyCu, & !< dyCu is delta y at u points, in m. + IdyCu, & !< 1/dyCu in m-1. + dy_Cu, & !< The unblocked lengths of the u-faces of the h-cell in m. + dy_Cu_obc, & !< The unblocked lengths of the u-faces of the h-cell in m for OBC. + IareaCu, & !< The masked inverse areas of u-grid cells in m2. + areaCu !< The areas of the u-grid cells in m2. + !> \todo dy_Cu_obc is not used? real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: & - mask2dCv, & ! 0 for boundary points and 1 for ocean points on the v grid. Nondim. - geoLatCv, & ! The geographic latitude at v points in degrees of latitude or m. - geoLonCv, & ! The geographic longitude at v points in degrees of longitude or m. - dxCv, IdxCv, & ! dxCv is delta x at v points, in m, and IdxCv is 1/dxCv in m-1. - dyCv, IdyCv, & ! dyCv is delta y at v points, in m, and IdyCv is 1/dyCv in m-1. - dx_Cv, & ! The unblocked lengths of the v-faces of the h-cell in m. - dx_Cv_obc, & ! The unblocked lengths of the v-faces of the h-cell in m for OBC. - IareaCv, & ! The masked inverse areas of v-grid cells in m2. - areaCv ! The areas of the v-grid cells in m2. + mask2dCv, & !< 0 for boundary points and 1 for ocean points on the v grid. Nondim. + geoLatCv, & !< The geographic latitude at v points in degrees of latitude or m. + geoLonCv, & !< The geographic longitude at v points in degrees of longitude or m. + dxCv, & !< dxCv is delta x at v points, in m. + IdxCv, & !< 1/dxCv in m-1. + dyCv, & !< dyCv is delta y at v points, in m. + IdyCv, & !< 1/dyCv in m-1. + dx_Cv, & !< The unblocked lengths of the v-faces of the h-cell in m. + dx_Cv_obc, & !< The unblocked lengths of the v-faces of the h-cell in m for OBC. + IareaCv, & !< The masked inverse areas of v-grid cells in m2. + areaCv !< The areas of the v-grid cells in m2. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - mask2dBu, & ! 0 for boundary points and 1 for ocean points on the q grid. Nondim. - geoLatBu, & ! The geographic latitude at q points in degrees of latitude or m. - geoLonBu, & ! The geographic longitude at q points in degrees of longitude or m. - dxBu, IdxBu, & ! dxBu is delta x at q points, in m, and IdxBu is 1/dxBu in m-1. - dyBu, IdyBu, & ! dyBu is delta y at q points, in m, and IdyBu is 1/dyBu in m-1. - areaBu, & ! areaBu is the area of a q-cell, in m2 - IareaBu ! IareaBu = 1/areaBu in m-2. + mask2dBu, & !< 0 for boundary points and 1 for ocean points on the q grid. Nondim. + geoLatBu, & !< The geographic latitude at q points in degrees of latitude or m. + geoLonBu, & !< The geographic longitude at q points in degrees of longitude or m. + dxBu, & !< dxBu is delta x at q points, in m. + IdxBu, & !< 1/dxBu in m-1. + dyBu, & !< dyBu is delta y at q points, in m. + IdyBu, & !< 1/dyBu in m-1. + areaBu, & !< areaBu is the area of a q-cell, in m2 + IareaBu !< IareaBu = 1/areaBu in m-2. real, pointer, dimension(:) :: & - gridLatT => NULL(), gridLatB => NULL() ! The latitude of T or B points for - ! the purpose of labeling the output axes. - ! On many grids these are the same as geoLatT & geoLatBu. + gridLatT => NULL(), & !< The latitude of T points for the purpose of labeling the output axes. + !! On many grids this is the same as geoLatT. + gridLatB => NULL() !< The latitude of B points for the purpose of labeling the output axes. + !! On many grids this is the same as geoLatBu. real, pointer, dimension(:) :: & - gridLonT => NULL(), gridLonB => NULL() ! The longitude of T or B points for - ! the purpose of labeling the output axes. - ! On many grids these are the same as geoLonT & geoLonBu. + gridLonT => NULL(), & !< The longitude of T points for the purpose of labeling the output axes. + !! On many grids this is the same as geoLonT. + gridLonB => NULL() !< The longitude of B points for the purpose of labeling the output axes. + !! On many grids this is the same as geoLonBu. character(len=40) :: & - x_axis_units, & ! The units that are used in labeling the coordinate - y_axis_units ! axes. Except on a Cartesian grid, these are usually - ! some variant of "degrees". + x_axis_units, & !< The units that are used in labeling the x coordinate axes. + y_axis_units !< The units that are used in labeling the y coordinate axes. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - bathyT ! Ocean bottom depth at tracer points, in m. + bathyT !< Ocean bottom depth at tracer points, in m. - logical :: bathymetry_at_vel ! If true, there are separate values for the - ! basin depths at velocity points. Otherwise the effects of - ! of topography are entirely determined from thickness points. + logical :: bathymetry_at_vel !< If true, there are separate values for the + !! basin depths at velocity points. Otherwise the effects of + !! of topography are entirely determined from thickness points. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: & - Dblock_u, & ! Topographic depths at u-points at which the flow is blocked - Dopen_u ! (Dblock_u) and open at width dy_Cu (Dopen_u), both in m. + Dblock_u, & !< Topographic depths at u-points at which the flow is blocked, in m. + Dopen_u !< Topographic depths at u-points at which the flow is open at width dy_Cu, in m. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: & - Dblock_v, & ! Topographic depths at v-points at which the flow is blocked - Dopen_v ! (Dblock_v) and open at width dx_Cv (Dopen_v), both in m. + Dblock_v, & !< Topographic depths at v-points at which the flow is blocked, in m. + Dopen_v !< Topographic depths at v-points at which the flow is open at width dx_Cv, in m. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - CoriolisBu ! The Coriolis parameter at corner points, in s-1. + CoriolisBu !< The Coriolis parameter at corner points, in s-1. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - dF_dx, dF_dy ! Derivatives of f (Coriolis parameter) at h-points, in s-1 m-1. - real :: g_Earth ! The gravitational acceleration in m s-2. + dF_dx, !< Derivative d/dx f (Coriolis parameter) at h-points, in s-1 m-1. + dF_dy !< Derivative d/dy f (Coriolis parameter) at h-points, in s-1 m-1. + real :: g_Earth !< The gravitational acceleration in m s-2. ! These variables are global sums that are useful for 1-d diagnostics - real :: areaT_global ! Global sum of h-cell area in m2 - real :: IareaT_global ! Global sum of inverse h-cell area (1/areaT_global) - ! in m2 + real :: areaT_global !< Global sum of h-cell area in m2 + real :: IareaT_global !< Global sum of inverse h-cell area (1/areaT_global) in m2. + ! These variables are for block structures. - integer :: nblocks + integer :: nblocks type(hor_index_type), pointer :: Block(:) => NULL() ! store indices for each block ! These parameters are run-time parameters that are used during some ! initialization routines (but not all) - real :: south_lat ! The latitude (or y-coordinate) of the first v-line - real :: west_lon ! The longitude (or x-coordinate) of the first u-line - real :: len_lat = 0. ! The latitudinal (or y-coord) extent of physical domain - real :: len_lon = 0. ! The longitudinal (or x-coord) extent of physical domain - real :: Rad_Earth = 6.378e6 ! The radius of the planet in meters. - real :: max_depth ! The maximum depth of the ocean in meters. + real :: south_lat !< The latitude (or y-coordinate) of the first v-line + real :: west_lon !< The longitude (or x-coordinate) of the first u-line + real :: len_lat = 0. !< The latitudinal (or y-coord) extent of physical domain + real :: len_lon = 0. !< The longitudinal (or x-coord) extent of physical domain + real :: Rad_Earth = 6.378e6 !< The radius of the planet in meters. + real :: max_depth !< The maximum depth of the ocean in meters. end type ocean_grid_type contains -!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! !> MOM_grid_init initializes the ocean grid array sizes and grid memory. subroutine MOM_grid_init(G, param_file, HI, global_indexing, bathymetry_at_vel) type(ocean_grid_type), intent(inout) :: G !< The horizontal grid type @@ -419,7 +440,6 @@ subroutine set_first_direction(G, y_first) G%first_direction = y_first end subroutine set_first_direction -!--------------------------------------------------------------------- !> Allocate memory used by the ocean_grid_type and related structures. subroutine allocate_metrics(G) type(ocean_grid_type), intent(inout) :: G !< The horizontal grid type @@ -493,7 +513,6 @@ subroutine allocate_metrics(G) end subroutine allocate_metrics -!--------------------------------------------------------------------- !> Release memory used by the ocean_grid_type and related structures. subroutine MOM_grid_end(G) type(ocean_grid_type), intent(inout) :: G !< The horizontal grid type @@ -537,4 +556,26 @@ subroutine MOM_grid_end(G) end subroutine MOM_grid_end +!> \namespace mom_grid +!! +!! Grid metrics and their inverses are labelled according to their staggered location on a Arakawa C (or B) grid. +!! - Metrics centered on h- or T-points are labelled T, e.g. dxT is the distance across the cell in the x-direction. +!! - Metrics centered on u-points are labelled Cu (C-grid u location). e.g. dyCu is the y-distance between two corners of a T-cell. +!! - Metrics centered on v-points are labelled Cv (C-grid v location). e.g. dyCv is the y-distance between two -points. +!! - Metrics centered on q-points are labelled Bu (B-grid u,v location). e.g. areaBu is the area centered on a q-point. +!! +!! \image html Grid_metrics.png "The labelling of distances (grid metrics) at various staggered location on an T-cell and around a q-point. +!! +!! Areas centered at T-, u-, v- and q- points are `areaT`, `areaCu`, `areaCv` and `areaBu` respectively. +!! +!! The reciprocal of metrics are pre-calculated and also stored in the ocean_grid_type with a I prepended to the name. +!! For example, `1./areaT` is called `IareaT`, and `1./dyCv` is `IdyCv`. +!! +!! Geographic latitude and longitude (or model coordinates if not on a sphere) are stored in `geoLatT`, `geoLonT` for T-points. +!! u-, v- and q- point coordinates are follow same pattern of replacing T with Cu, Cv and Bu respectively. +!! +!! Each location also has a 2D mask indicating whether the entire column is land or ocean. +!! `mask2dT` is 1. is the column is wet or 0. is the T-cell is land. +!! `mask2dCu` is 1. if both neighboring column are ocean, and 0. if either is land. + end module MOM_grid diff --git a/src/framework/MOM_hor_index.F90 b/src/framework/MOM_hor_index.F90 index db22d8fc84..4326693957 100644 --- a/src/framework/MOM_hor_index.F90 +++ b/src/framework/MOM_hor_index.F90 @@ -1,24 +1,7 @@ +!> Defines the horizontal index type (hor_index_type) used for providing index ranges module MOM_hor_index -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** +! This file is part of MOM6. See LICENSE.md for the license. use MOM_domains, only : MOM_domain_type, get_domain_extent use MOM_error_handler, only : MOM_error, MOM_mesg, FATAL @@ -28,23 +11,48 @@ module MOM_hor_index public :: hor_index_init, assignment(=) +!> Container for horizontal index ranges for data, computational and global domains type, public :: hor_index_type - integer :: isc, iec, jsc, jec ! The range of the computational indices and - integer :: isd, ied, jsd, jed ! data indices at tracer cell centers. - integer :: isg, ieg, jsg, jeg ! The range of the global domain tracer cell indices. - integer :: IscB, IecB, JscB, JecB ! The range of the computational indices and - integer :: IsdB, IedB, JsdB, JedB ! data indices at tracer cell vertices. - integer :: IsgB, IegB, JsgB, JegB ! The range of the global domain vertex indices. - integer :: idg_offset ! The offset between the corresponding global - integer :: jdg_offset ! and local array indices. - logical :: symmetric ! True if symmetric memory is used. + integer :: isc !< The start i-index of cell centers within the computational domain + integer :: iec !< The end i-index of cell centers within the computational domain + integer :: jsc !< The start j-index of cell centers within the computational domain + integer :: jec !< The end j-index of cell centers within the computational domain + + integer :: isd !< The start i-index of cell centers within the data domain + integer :: ied !< The end i-index of cell centers within the data domain + integer :: jsd !< The start j-index of cell centers within the data domain + integer :: jed !< The end j-index of cell centers within the data domain + + integer :: isg !< The start i-index of cell centers within the global domain + integer :: ieg !< The end i-index of cell centers within the global domain + integer :: jsg !< The start j-index of cell centers within the global domain + integer :: jeg !< The end j-index of cell centers within the global domain + + integer :: IscB !< The start i-index of cell vertices within the computational domain + integer :: IecB !< The end i-index of cell vertices within the computational domain + integer :: JscB !< The start j-index of cell vertices within the computational domain + integer :: JecB !< The end j-index of cell vertices within the computational domain + + integer :: IsdB !< The start i-index of cell vertices within the data domain + integer :: IedB !< The end i-index of cell vertices within the data domain + integer :: JsdB !< The start j-index of cell vertices within the data domain + integer :: JedB !< The end j-index of cell vertices within the data domain + + integer :: IsgB !< The start i-index of cell vertices within the global domain + integer :: IegB !< The end i-index of cell vertices within the global domain + integer :: JsgB !< The start j-index of cell vertices within the global domain + integer :: JegB !< The end j-index of cell vertices within the global domain + + integer :: idg_offset !< The offset between the corresponding global and local i-indices. + integer :: jdg_offset !< The offset between the corresponding global and local j-indices. + logical :: symmetric !< True if symmetric memory is used. end type hor_index_type interface assignment(=); module procedure HIT_assign ; end interface contains -!> hor_index_init sets various index values in a hor_index_type. +!> Sets various index values in a hor_index_type. subroutine hor_index_init(Domain, HI, param_file, local_indexing, index_offset) type(MOM_domain_type), intent(in) :: Domain !< The MOM domain from which to extract information. type(hor_index_type), intent(inout) :: HI !< A horizontal index type to populate with data @@ -82,10 +90,10 @@ subroutine hor_index_init(Domain, HI, param_file, local_indexing, index_offset) end subroutine hor_index_init !> HIT_assign copies one hor_index_type into another. It is accessed via an -!! assignment (=) operator. +!! assignment (=) operator. subroutine HIT_assign(HI1, HI2) - type(hor_index_type), intent(out) :: HI1 - type(hor_index_type), intent(in) :: HI2 + type(hor_index_type), intent(out) :: HI1 !< Horizontal index type to copy to + type(hor_index_type), intent(in) :: HI2 !< Horizontal index type to copy from ! This subroutine copies all components of the horizontal array index type ! variable on the RHS (HI2) to the variable on the LHS (HI1). @@ -102,4 +110,20 @@ subroutine HIT_assign(HI1, HI2) end subroutine HIT_assign +!> \namespace mom_hor_index +!! +!! The hor_index_type provides the decalarations and loop ranges for almost all data with horizontal extent. +!! +!! Declarations and loop ranges should always be coded with the symmetric memory model in mind. +!! The non-symmetric memory mode will then also work, albeit with a different (less efficient) communication pattern. +!! +!! Using the hor_index_type HI: +!! - declaration of h-point data is of the form `h(HI%%isd:HI%%ied,HI%%jsd:HI%%jed)`; +!! - declaration of q-point data is of the form `q(HI%%IsdB:HI%%IedB,HI%%JsdB:HI%%JedB)`; +!! - declaration of u-point data is of the form `u(HI%%IsdB:HI%%IedB,HI%%jsd:HI%%jed)`; +!! - declaration of v-point data is of the form `v(HI%%isd:HI%%ied,HI%%JsdB:HI%%JedB)`. +!! +!! For more detail explanation of horizontal indexing see \ref Horizontal_indexing. + + end module MOM_hor_index diff --git a/src/framework/_Horizontal_indexing.dox b/src/framework/_Horizontal_indexing.dox new file mode 100644 index 0000000000..3aa8b208d3 --- /dev/null +++ b/src/framework/_Horizontal_indexing.dox @@ -0,0 +1,94 @@ +/*! \page Horizontal_indexing Horizontal indexing and memory + +MOM6 is written in Fortran90 and uses the `i,j,k` order of indexing. +`i` corresponds to the fastest index (stride-1 in memory) and thus should be the inner-most loop variable. +We often refer to the i-direction as the x- or zonal direction, and similarly to the j-direction as y- or meridional direction. +The model can use curvilinear grids/coordinates in the horizontal and so these labels have loose meanings but convenient. + +\section Staggering Loops and staggered variables + +Many variables are staggered horizontally with respect to each other. +The dynamics and tracer equations are discretized on an Arakawa C grid. +Staggered variables must still have integer indices and we use a north-east convention centered on the h-points. +These means a variable with indices `i,j` will be either collocated, to the east, to the north, or to the north-east of the h-point with the same indices. + +\image html Arakawa_C_grid.png MOM6 uses an Arakawa C grid staggering of variables with a North-East indexing convention. "Cells" refer to the control volumes around tracer- or h-point located variables unless labelled otherwise. + +\subsection Soft_convention Soft convention for loop variables + +To ease reading the code we use a "soft" convection (soft because there is no syntax checking) where an upper-case index variable can be interpreted as the lower-case index variable plus \f$\frac{1}{2}\f$. + +For example, when a loop is over h-points collocated variables +- the do-loop statements will be for lower-case `i,j` variables +- references to h-point variables will be `h(i,j)`, `D(i+1,j)`, etc. +- references to u-point variables will be `u(I,j)` (meaning \f$u_{i+\frac{1}{2},j}\f$), `u(I-1,j)` (meaning \f$u_{i-\frac{1}{2},j}\f$), etc. +- references to v-point variables will be `v(i,J)` (meaning \f$v_{i,j+\frac{1}{2}}\f$), `u(I-1,j)` (meaning \f$u_{i,j-\frac{1}{2}}\f$), etc. +- references to q-point variables will be `q(I,J)` (meaning \f$q_{i+\frac{1}{2},j+\frac{1}{2}}\f$), etc. + +In contrast, when a loop is over u-points collocated variables +- the do-loop statements will be for upper-case `I` and lower-case `j` variables +- the expression \f$ u_{i+\frac{1}{2},j} ( h_{i,j} + h_{i+1,j} ) \f$ is `u(I,j) * ( h(i,j) + h(i+1,j)`. + + +\section Memory Declaration of variables + +\image html Horizontal_NE_indexing_nonsym.png Non-symmetric mode: All arrays are declared with the same shape `(isd:ied,jsd:jed)`. + +\image html Horizontal_NE_indexing_sym.png Symmetric mode: Arrays have different shapes depending on their staggering location on the Arakawa C grid. + +A field is described by 2D or 3D arrays which are distributed across parallel processors. +Each processor only sees a small window of the global field. +The processor "owns" the computational domain (red in above figure) but arrays are extended horizontally with halos which are intermittently updated with the values from neighboring processors. +The halo regions (blue in above figure) may not always be up-to-date. +Data in halo regions (blue in above figure) will be overwritten my mpp_updates. + +MOM6 has two memory models, "symmetric" and "non-symmetric". +In non-symmetric mode all arrays are given the same shape. +The consequence of this is that there are fewer staggered variables to the south-west of the computational domain. +An operator applied at h-point locations involving u- or v- point data can not have as wide a stencil on the south-west side of the processor domain as it can on the north-east side. + +In symmetric mode, declarations are dependent on the variables staggered location on the Arakawa C grid. +This allows loops to be symmetric and stencils to be applied more uniformly. + +In the code, declarations are consistent with the symmetric memory model. +The non-symmetric mode is implemented by setting the start values of the staggered data domain to be the same as the non-staggered start value. + +The horizontal index type (mom_hor_index::hor_index_type) provides the data domain start values. +The values are also copied into the mom_grid::ocean_grid_type for convenience although we might deprecate this convenience in the future. + +Declarations of h-point data take the form: +- `real, dimension(HI%%isd:HI%%ied, HI%%jsd:HI%%jed) :: D !< Depth at h-points (m)` +- `real, dimension(HI%%isd:HI%%ied, HI%%jsd:HI%%jed, GV%%ke) :: h !< Layer thickness (H units)` + +Declarations of u-point data take the form: +- `real, dimension(HI%%IsdB:HI%%IedB, HI%%jsd:HI%%jed) :: Du !< Depth at u-points (m)` +- `real, dimension(HI%%IsdB:HI%%IedB, HI%%jsd:HI%%jed, GV%%ke) :: h !< Zonal flow (m/s)` + +Declarations of v-point data take the form: +- `real, dimension(HI%%isd:HI%%ied, HI%%JsdB:HI%%JedB) :: Dv !< Depth at v-points (m)` +- `real, dimension(HI%%isd:HI%%ied, HI%%JsdB:HI%%JedB, GV%%ke) :: h !< Zonal flow (m/s)` + +Declarations of q-point data take the form: +- `real, dimension(HI%%IsdB:HI%%IedB, HI%%JsdB:HI%%JedB) :: Dq !< Depth at q-points (m)` +- `real, dimension(HI%%IsdB:HI%%IedB, HI%%JsdB:HI%%JedB, GV%%ke) :: vort !< Vertical componentof vorticity (s-1)` + +The file MOM_memory_macros.h provides the macros `SZI_`, `SZJ_`, `SZIB_` and `SZJB_` that help make the above more concise: +- `real, dimension(SZI_(HI), SZJ_(HI)) :: D !< Depth at h-points (m)` +- `real, dimension(SZIB_(HI), SZJ_(HI)) :: Du !< Depth at u-points (m)` +- `real, dimension(SZI_(HI), SZJB_(HI)) :: Dv !< Depth at v-points (m)` +- `real, dimension(SZIB_(HI), SZJB_(HI)) :: Dq !< Depth at q-points (m)` + +\section Global_index Calculating a global index + +For the most part we MOM6 code should be independent of an equivalent absolute global index. +There are exceptions are when the equivalent global index of a cell `i,j` is needed is can be calculated as follows: + + `i_global = i + HI%%idg_offset`, or + +Before the mom_hor_index::hor_index_type was introduced, this conversion was done use variables in the mom_grid::ocean_grid_type: + + `i_gloval = (i-G%%isd) + G%%isd_global` + +which is no longer preferred. + +*/ From f2ab14702c4fd67c8da2dfbdb5d7a53c1a3470e3 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Tue, 27 Sep 2016 17:07:57 -0400 Subject: [PATCH 05/14] Corrected a compile-time error in MOM_grid.F90 Added a missing continuation character in MOM_grid.F90. This was a very recently introduced bug, requiring a single character correction; the model would not even compile with this bug. This incident serves as a small reminder of our need to verify that our changes are correct by testing them before they are committed, no matter how innocuous they may seem! --- src/core/MOM_grid.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/MOM_grid.F90 b/src/core/MOM_grid.F90 index 47d9d6f01a..87fae7327b 100644 --- a/src/core/MOM_grid.F90 +++ b/src/core/MOM_grid.F90 @@ -147,7 +147,7 @@ module MOM_grid real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & CoriolisBu !< The Coriolis parameter at corner points, in s-1. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - dF_dx, !< Derivative d/dx f (Coriolis parameter) at h-points, in s-1 m-1. + dF_dx, & !< Derivative d/dx f (Coriolis parameter) at h-points, in s-1 m-1. dF_dy !< Derivative d/dy f (Coriolis parameter) at h-points, in s-1 m-1. real :: g_Earth !< The gravitational acceleration in m s-2. From c67b28a2a6737c11eb463ee874f27987bc89adf9 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Tue, 27 Sep 2016 17:08:36 -0400 Subject: [PATCH 06/14] MOM_energetic_PBL code clean-up Fixed the code indenting in energetic_PBL and dOxyGenized the arguments to find_PE_chg in MOM_energetic_PBL.F90. Also, eliminated redundant comments in find_PE_chg_orig in MOM_diapyc_energy_req.F90, as the dOxygenized comments convey this same information more clearly. All answers are bitwise identical. --- .../vertical/MOM_diapyc_energy_req.F90 | 72 +- .../vertical/MOM_energetic_PBL.F90 | 1305 +++++++++-------- 2 files changed, 663 insertions(+), 714 deletions(-) diff --git a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 index 063688158f..135952c86b 100644 --- a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 +++ b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 @@ -1063,7 +1063,7 @@ subroutine find_PE_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, & ! The expression for the change in potential energy used here is derived ! from the expression for the final estimates of the changes in temperature ! and salinities, and then extensively manipulated to get it into its most - ! succint form. The derivation is not necessarily obvious, but it demonstably + ! succint form. The derivation is not necessarily obvious, but it demonstrably ! works by comparison with separate calculations of the energy changes after ! the tridiagonal solver for the final changes in temperature and salinity are ! applied. @@ -1117,11 +1117,14 @@ subroutine find_PE_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, & end subroutine find_PE_chg +!> This subroutine calculates the change in potential energy and or derivatives +!! for several changes in an interfaces's diapycnal diffusivity times a timestep +!! using the original form used in the first version of ePBL. subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & - dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, & - dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, & - dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, & - PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0) + dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, & + dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, & + dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, & + PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0) real, intent(in) :: Kddt_h !< The diffusivity at an interface times the time step and !! divided by the average of the thicknesses around the !! interface, in units of H (m or kg-2). @@ -1192,64 +1195,7 @@ subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & ! The comments describing these arguments are for a downward mixing pass, but ! this routine can also be used for an upward pass with the sense of direction ! reversed. -! -! Arguments: Kddt_h - The diffusivity at an interface times the time step and -! divided by the average of the thicknesses around the -! interface, in units of H (m or kg-2). -! (in) h_k - The thickness of the layer below the interface, in H. -! (in) b_den_1 - The first first term in the denominator of the pivot -! for the tridiagonal solver, given by h_k plus a term that -! is a fraction (determined from the tridiagonal solver) of -! Kddt_h for the interface above, in H. -! (in) dTe_term - A diffusivity-independent term related to the -! temperature change in the layer below the interface, in K H. -! (in) dSe_term - A diffusivity-independent term related to the -! salinity change in the layer below the interface, in ppt H. -! (in) dT_km1_t2 - A diffusivity-independent term related to the -! temperature change in the layer above the interface, in K. -! (in) dS_km1_t2 - A diffusivity-independent term related to the -! salinity change in the layer above the interface, in ppt. -! (in) dT_to_dPE_k - A factor (pres_lay*mass_lay*dSpec_vol/dT) relating -! a layer's temperature change to the change in column -! potential energy, in J m-2 K-1. -! (in) dS_to_dPE_k - A factor (pres_lay*mass_lay*dSpec_vol/dS) relating -! a layer's salinity change to the change in column -! potential energy, in J m-2 ppt-1. -! (in) dT_to_dPEa - A factor (pres_lay*mass_lay*dSpec_vol/dT) relating -! a layer's temperature change to the change in column -! potential energy, including all implicit diffusive changes -! in the temperatures of all the layers above, in J m-2 K-1. -! (in) dS_to_dPEa - A factor (pres_lay*mass_lay*dSpec_vol/dS) relating -! a layer's salinity change to the change in column -! potential energy, including all implicit diffusive changes -! in the salinities of all the layers above, in J m-2 ppt-1. -! (in) pres - The hydrostatic interface pressure, which is used to relate -! the changes in column thickness to the energy that is radiated -! as gravity waves and unavailable to drive mixing, in Pa. -! (in) dT_to_dColHt_k - A factor (mass_lay*dSColHtc_vol/dT) relating -! a layer's temperature change to the change in column -! height, in m K-1. -! (in) dS_to_dColHt_k - A factor (mass_lay*dSColHtc_vol/dS) relating -! a layer's salinity change to the change in column -! height, in m ppt-1. -! (in) dT_to_dColHta - A factor (mass_lay*dSColHtc_vol/dT) relating -! a layer's temperature change to the change in column -! height, including all implicit diffusive changes -! in the temperatures of all the layers above, in m K-1. -! (in) dS_to_dColHta - A factor (mass_lay*dSColHtc_vol/dS) relating -! a layer's salinity change to the change in column -! height, including all implicit diffusive changes -! in the salinities of all the layers above, in m ppt-1. -! (out,opt) PE_chg - The change in column potential energy from applying -! Kddt_h at the present interface, in J m-2. -! (out,opt) dPE_chg_dKd - The partial derivative of PE_chg with Kddt_h, -! in units of J m-2 H-1. -! (out,opt) PE_max - The maximum change in column potential energy that could -! be realizedd by applying a huge value of Kddt_h at the -! present interface, in J m-2. -! (out,opt) dPEc_dKc0 - The partial derivative of PE_chg with Kddt_h in the -! limit where Kddt_h = 0, in J m-2 H-1. - ! b_den_1 - The first term in the denominator of b1, in m or kg m-2. + real :: b1 ! b1 is used by the tridiagonal solver, in H-1. real :: b1Kd ! Temporary array (nondim.) real :: ColHt_chg ! The change in column thickness in m. diff --git a/src/parameterizations/vertical/MOM_energetic_PBL.F90 b/src/parameterizations/vertical/MOM_energetic_PBL.F90 index be1da1087b..737bea6ce4 100644 --- a/src/parameterizations/vertical/MOM_energetic_PBL.F90 +++ b/src/parameterizations/vertical/MOM_energetic_PBL.F90 @@ -116,7 +116,7 @@ module MOM_energetic_PBL ! diffusivity in the planetary boundary layer. type(time_type), pointer :: Time ! A pointer to the ocean model's clock. logical :: TKE_diagnostics = .false. - LOGICAL :: Use_MLD_ITERATION=.false.!False to use old ePBL method. + LOGICAL :: Use_MLD_ITERATION=.false.!False to use old ePBL method. logical :: Mixing_Diagnostics = .false. ! Will be true when outputing mixing ! length and velocity scale type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the @@ -125,7 +125,7 @@ module MOM_energetic_PBL ! These are terms in the mixed layer TKE budget, all in J m-2 = kg s-2. real, allocatable, dimension(:,:) :: & ML_depth, & ! The mixed layer depth in m. - ML_depth2, & ! The mixed layer depth in m. + ML_depth2, & ! The mixed layer depth in m. diag_TKE_wind, & ! The wind source of TKE. diag_TKE_MKE, & ! The resolved KE source of TKE. diag_TKE_conv, & ! The convective source of TKE. @@ -358,11 +358,11 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! is very quick (e.g. if MLD doesn't change ! over timestep). Otherwise it takes 5-10 ! passes, but has a high convergence rate. - ! Other iteration may be tried, but this + ! Other iteration may be tried, but this ! method seems to rarely fail and the added ! cost is likely not significant. Additionally, - ! when it fails it does so in a reasonable - ! manner giving a usable guess. When it + ! when it fails it does so in a reasonable + ! manner giving a usable guess. When it ! does fail, it is due to convection within ! the boundary. Likely, a new method e.g. ! surface_disconnect, can improve this. @@ -377,8 +377,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! best as an input parameter, but then may want ! to use allocatable arrays if storing ! guess/found (as diagnostic); skipping for now. - ! In reality, the maximum number of guesses - ! needed is set by: + ! In reality, the maximum number of guesses + ! needed is set by: ! DEPTH/2^M < DZ ! where M is the number of guesses ! e.g. M=12 for DEPTH=4000m and DZ=1m @@ -421,7 +421,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & h_neglect = GV%H_subroundoff - if(.not.CS%Use_MLD_Iteration) MAX_OBL_IT=1 + if(.not.CS%Use_MLD_Iteration) MAX_OBL_IT=1 C1_3 = 1.0 / 3.0 dt__diag = dt ; if (present(dt_diag)) dt__diag = dt_diag IdtdR0 = 1.0 / (dt__diag * GV%Rho0) @@ -448,9 +448,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & CS%diag_TKE_conv_decay(i,j) = 0.0 !; CS%diag_TKE_unbalanced_forcing(i,j) = 0.0 enddo ; enddo endif - IF (CS%Mixing_Diagnostics) then - CS%Mixing_Length(:,:,:)=0.0 - CS%Velocity_Scale(:,:,:)=0.0 + if (CS%Mixing_Diagnostics) then + CS%Mixing_Length(:,:,:) = 0.0 + CS%Velocity_Scale(:,:,:) = 0.0 endif !!OMP end parallel endif @@ -490,10 +490,10 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & T(i,k) = tv%T(i,j,k) ; S(i,k) = tv%S(i,j,k) Kd(i,K) = 0.0 enddo ; enddo - do i=is,ie - CS%ML_depth(i,j) = h(i,1)*GV%H_to_m ; - !CS%ML_depth2(i,j) = h(i,1)*GV%H_to_m ; - sfc_connected(i) = .true. ; + do i=is,ie + CS%ML_depth(i,j) = h(i,1)*GV%H_to_m + !CS%ML_depth2(i,j) = h(i,1)*GV%H_to_m + sfc_connected(i) = .true. enddo if (debug) then @@ -509,636 +509,638 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then !/The following lines are for the iteration over MLD !{ - OBL_CONVERGED=.false.!Initialize convergence state to 'false' - MAX_MLD = 0.0;!MAX_MLD will initialized as ocean bottom depth - do k=1,nz ; - MAX_MLD = MAX_MLD + h(i,k)*GV%H_to_m; + MAX_MLD = 0.0 ! MAX_MLD will initialized as ocean bottom depth + do k=1,nz + MAX_MLD = MAX_MLD + h(i,k)*GV%H_to_m enddo MIN_MLD = 0.0 !MIN_MLD will initialize as 0. !/BGR: Add MLD_GUESS based on stored previous value. ! note that this is different from ML_Depth already ! computed by EPBL, need to figure out why. - if (CS%ML_Depth2(i,j).gt.1.) then + if (CS%ML_Depth2(i,j) > 1.) then !If prev value is present use for guess. MLD_GUESS=CS%ML_Depth2(i,j) else !Otherwise guess middle of water column. MLD_GUESS = 0.5 * (MIN_MLD+MAX_MLD) - endif + endif !/BGR: May add user-input bounds for max/min MLD - DO OBL_IT=1,MAX_OBL_IT ! Iterate up to MAX_OBL_IT times - IF (.not. OBL_CONVERGED) THEN !Cycle through EPBL if not converged - CS%ML_depth(i,j) = h(i,1)*GV%H_to_m ; - !CS%ML_depth2(i,j) = h(i,1)*GV%H_to_m ; - sfc_connected(i) = .true. ; - ! Store in 1D arrays cleared out each iteration. Only write in - ! 3D arrays after convergence. - VSTAR_USED(:)=0.0 - MIXING_LENGTH_USED(:)=0.0 - IF (.not.CS%Use_MLD_Iteration) OBL_CONVERGED=.true. - !/This ends the new code for the iteration. - !} - U_Star = fluxes%ustar(i,j) - if (associated(fluxes%ustar_shelf) .and. associated(fluxes%frac_shelf_h)) then - if (fluxes%frac_shelf_h(i,j) > 0.0) & - U_Star = (1.0 - fluxes%frac_shelf_h(i,j)) * U_star + & - fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j) - endif - if (U_Star < CS%ustar_min) U_Star = CS%ustar_min + ! Iterate up to MAX_OBL_IT times to determine a converged EPBL depth. + OBL_CONVERGED = .false. + do OBL_IT=1,MAX_OBL_IT ; if (.not. OBL_CONVERGED) then + CS%ML_depth(i,j) = h(i,1)*GV%H_to_m + !CS%ML_depth2(i,j) = h(i,1)*GV%H_to_m + sfc_connected(i) = .true. - if (CS%omega_frac >= 1.0) then ; absf(i) = 2.0*CS%omega - else - absf(i) = 0.25*((abs(G%CoriolisBu(I,J)) + abs(G%CoriolisBu(I-1,J-1))) + & - (abs(G%CoriolisBu(I,J-1)) + abs(G%CoriolisBu(I-1,J)))) - if (CS%omega_frac > 0.0) & - absf = sqrt(CS%omega_frac*4.0*CS%omega**2 + (1.0-CS%omega_frac)*absf**2) - endif - - mech_TKE(i) = (dt*CS%mstar*GV%Rho0)*((U_Star**3)) - conv_PErel(i) = 0.0 + ! Store in 1D arrays cleared out each iteration. Only write in + ! 3D arrays after convergence. + do k=1,nz + Vstar_Used(k) = 0.0 ; Mixing_Length_Used(k) = 0.0 + enddo + if (.not.CS%Use_MLD_Iteration) OBL_CONVERGED = .true. + !/This ends the new code for the iteration. + !} + U_Star = fluxes%ustar(i,j) + if (associated(fluxes%ustar_shelf) .and. associated(fluxes%frac_shelf_h)) then + if (fluxes%frac_shelf_h(i,j) > 0.0) & + U_Star = (1.0 - fluxes%frac_shelf_h(i,j)) * U_star + & + fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j) + endif + if (U_Star < CS%ustar_min) U_Star = CS%ustar_min - if (CS%TKE_diagnostics) then - CS%diag_TKE_wind(i,j) = CS%diag_TKE_wind(i,j) + mech_TKE(i) * IdtdR0 - if (TKE_forced(i,j,1) <= 0.0) then - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + & - max(-mech_TKE(i), TKE_forced(i,j,1)) * IdtdR0 - ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & - ! min(0.0, TKE_forced(i,j,1) + mech_TKE(i)) * IdtdR0 + if (CS%omega_frac >= 1.0) then ; absf(i) = 2.0*CS%omega else - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,1) * IdtdR0 + absf(i) = 0.25*((abs(G%CoriolisBu(I,J)) + abs(G%CoriolisBu(I-1,J-1))) + & + (abs(G%CoriolisBu(I,J-1)) + abs(G%CoriolisBu(I-1,J)))) + if (CS%omega_frac > 0.0) & + absf = sqrt(CS%omega_frac*4.0*CS%omega**2 + (1.0-CS%omega_frac)*absf**2) endif - endif - - if (TKE_forced(i,j,1) <= 0.0) then - mech_TKE(i) = mech_TKE(i) + TKE_forced(i,j,1) - if (mech_TKE(i) < 0.0) mech_TKE(i) = 0.0 - else - conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,1) - endif - -! endif ; enddo - -! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then - if (debug) then - mech_TKE_k(i,1) = mech_TKE(i) ; conv_PErel_k(i,1) = conv_PErel(i) - nstar_k(:) = 0.0 ; nstar_k(1) = CS%nstar - endif - if (.not.CS%Use_MLD_Iteration) then - h_sum(i) = H_neglect - do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo - I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) + mech_TKE(i) = (dt*CS%mstar*GV%Rho0)*((U_Star**3)) + conv_PErel(i) = 0.0 - h_bot(i) = 0.0 ; hb_hs(i,nz+1) = 0.0 - do k=nz,1,-1 - h_bot(i) = h_bot(i) + h(i,k) - hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs) - enddo - else - !New method where mixing length is reduced based on MLD - I_hs=1.0/MLD_GUESS - h_sum(i) = 0.0 - h_bot(i) = 0.0 ; hb_hs(i,1:nz+1) = 0.0 - do k=2,nz - h_sum(i)=h_sum(i)+h(i,k) - h_bot(i) = max(0.0,MLD_GUESS - h_sum(i)) - hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs)**2!Notice the square - ! makes KPP-like. - enddo - endif -! endif ; enddo - - ! Note the outer i-loop and inner k-loop loop order!!! -! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then - do k=1,nz ; T0(k) = T(i,k) ; S0(k) = S(i,k) ; enddo - - num_itts(:) = -1 - - pres(i,1) = 0.0 - do k=1,nz - dMass = GV%H_to_kg_m2 * h(i,k) - dPres = GV%g_Earth * dMass - dT_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dT(i,j,k) - dS_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dS(i,j,k) - dT_to_dColHt(i,k) = dMass * dSV_dT(i,j,k) - dS_to_dColHt(i,k) = dMass * dSV_dS(i,j,k) - - pres(i,K+1) = pres(i,K) + dPres - enddo - - Kd(i,1) = 0.0 ; Kddt_h(1) = 0.0 - b_den_1(i) = h(i,1) - dT_to_dPE_a(i,1) = dT_to_dPE(i,1) - dS_to_dPE_a(i,1) = dS_to_dPE(i,1) - dT_to_dColHt_a(i,1) = dT_to_dColHt(i,1) - dS_to_dColHt_a(i,1) = dS_to_dColHt(i,1) - - htot(i) = h(i,1) - uhtot(i) = u(i,1)*h(i,1) - vhtot(i) = v(i,1)*h(i,1) - - do K=2,nz - ! Apply dissipation to the TKE, here applied as an exponential decay - ! due to 3-d turbulent energy being lost to inefficient rotational modes. - - ! There should be several different "flavors" of TKE that decay at - ! different rates. The following form is often used for mechanical - ! stirring from the surface, perhaps due to breaking surface gravity - ! waves and wind-driven turbulence. - Idecay_len_TKE(i) = (CS%TKE_decay * absf(i) / U_Star) * GV%H_to_m - exp_kh = 1.0 - if (Idecay_len_TKE(i) > 0.0) exp_kh = exp(-h(i,k-1)*Idecay_len_TKE(i)) - if (CS%TKE_diagnostics) CS%diag_TKE_mech_decay(i,j) = & - CS%diag_TKE_mech_decay(i,j) + (exp_kh-1.0) * mech_TKE(i) * IdtdR0 - mech_TKE(i) = mech_TKE(i) * exp_kh - - - ! Accumulate any convectively released potential energy to contribute - ! to wstar and to drive penetrating convection. - if (TKE_forced(i,j,k) > 0.0) then - conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,k) - if (CS%TKE_diagnostics) then - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,k) * IdtdR0 + if (CS%TKE_diagnostics) then + CS%diag_TKE_wind(i,j) = CS%diag_TKE_wind(i,j) + mech_TKE(i) * IdtdR0 + if (TKE_forced(i,j,1) <= 0.0) then + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + & + max(-mech_TKE(i), TKE_forced(i,j,1)) * IdtdR0 + ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & + ! min(0.0, TKE_forced(i,j,1) + mech_TKE(i)) * IdtdR0 + else + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,1) * IdtdR0 endif endif - if (debug) then - mech_TKE_k(i,K) = mech_TKE(i) ; conv_PErel_k(i,K) = conv_PErel(i) + if (TKE_forced(i,j,1) <= 0.0) then + mech_TKE(i) = mech_TKE(i) + TKE_forced(i,j,1) + if (mech_TKE(i) < 0.0) mech_TKE(i) = 0.0 + else + conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,1) endif - ! Determine the total energy - nstar_FC = CS%nstar - if (CS%nstar * conv_PErel(i) > 0.0) then - ! Here nstar is a function of the natural Rossby number 0.2/(1+0.2/Ro), based - ! on a curve fit from the data of Wang (GRL, 2003). - ! Note: Ro = 1.0 / sqrt(0.5 * dt * Rho0 * (absf*htot(i))**3 / conv_PErel(i)) - nstar_FC = CS%nstar * conv_PErel(i) / (conv_PErel(i) + 0.2 * & - sqrt(0.5 * dt * GV%Rho0 * (absf(i)*(htot(i)*GV%H_to_m))**3 * conv_PErel(i))) + ! endif ; enddo + + ! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then + if (debug) then + mech_TKE_k(i,1) = mech_TKE(i) ; conv_PErel_k(i,1) = conv_PErel(i) + nstar_k(:) = 0.0 ; nstar_k(1) = CS%nstar endif - if (debug) nstar_k(K) = nstar_FC - tot_TKE = mech_TKE(i) + nstar_FC * conv_PErel(i) + if (.not.CS%Use_MLD_Iteration) then + h_sum(i) = H_neglect + do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo + I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) + + h_bot(i) = 0.0 ; hb_hs(i,nz+1) = 0.0 + do k=nz,1,-1 + h_bot(i) = h_bot(i) + h(i,k) + hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs) + enddo + else + !New method where mixing length is reduced based on MLD + I_hs=1.0/MLD_GUESS + h_sum(i) = 0.0 + h_bot(i) = 0.0 ; hb_hs(i,1:nz+1) = 0.0 + do k=2,nz + h_sum(i) = h_sum(i)+h(i,k) + h_bot(i) = max(0.0,MLD_GUESS - h_sum(i)) + hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs)**2!Notice the square + ! makes KPP-like. + enddo + endif + ! endif ; enddo - ! For each interior interface, first discard the TKE to account for - ! mixing of shortwave radiation through the next denser cell. - if (TKE_forced(i,j,k) < 0.0) then - if (TKE_forced(i,j,k) + tot_TKE < 0.0) then - ! The shortwave requirements deplete all the energy in this layer. - if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) + tot_TKE * IdtdR0 - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) - tot_TKE * IdtdR0 - ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & - ! (TKE_forced(i,j,k) + tot_TKE) * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & - (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 - endif - tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 - else - ! Reduce the mechanical and convective TKE proportionately. - TKE_reduc = (tot_TKE + TKE_forced(i,j,k)) / tot_TKE + ! Note the outer i-loop and inner k-loop loop order!!! + ! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then + do k=1,nz ; T0(k) = T(i,k) ; S0(k) = S(i,k) ; enddo + + num_itts(:) = -1 + + pres(i,1) = 0.0 + do k=1,nz + dMass = GV%H_to_kg_m2 * h(i,k) + dPres = GV%g_Earth * dMass + dT_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dT(i,j,k) + dS_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dS(i,j,k) + dT_to_dColHt(i,k) = dMass * dSV_dT(i,j,k) + dS_to_dColHt(i,k) = dMass * dSV_dS(i,j,k) + + pres(i,K+1) = pres(i,K) + dPres + enddo + + Kd(i,1) = 0.0 ; Kddt_h(1) = 0.0 + b_den_1(i) = h(i,1) + dT_to_dPE_a(i,1) = dT_to_dPE(i,1) + dS_to_dPE_a(i,1) = dS_to_dPE(i,1) + dT_to_dColHt_a(i,1) = dT_to_dColHt(i,1) + dS_to_dColHt_a(i,1) = dS_to_dColHt(i,1) + + htot(i) = h(i,1) + uhtot(i) = u(i,1)*h(i,1) + vhtot(i) = v(i,1)*h(i,1) + + do K=2,nz + ! Apply dissipation to the TKE, here applied as an exponential decay + ! due to 3-d turbulent energy being lost to inefficient rotational modes. + + ! There should be several different "flavors" of TKE that decay at + ! different rates. The following form is often used for mechanical + ! stirring from the surface, perhaps due to breaking surface gravity + ! waves and wind-driven turbulence. + Idecay_len_TKE(i) = (CS%TKE_decay * absf(i) / U_Star) * GV%H_to_m + exp_kh = 1.0 + if (Idecay_len_TKE(i) > 0.0) exp_kh = exp(-h(i,k-1)*Idecay_len_TKE(i)) + if (CS%TKE_diagnostics) CS%diag_TKE_mech_decay(i,j) = & + CS%diag_TKE_mech_decay(i,j) + (exp_kh-1.0) * mech_TKE(i) * IdtdR0 + mech_TKE(i) = mech_TKE(i) * exp_kh + + + ! Accumulate any convectively released potential energy to contribute + ! to wstar and to drive penetrating convection. + if (TKE_forced(i,j,k) > 0.0) then + conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,k) if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - TKE_forced(i,j,k) * IdtdR0 - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + TKE_forced(i,j,k) * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & - (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,k) * IdtdR0 endif - tot_TKE = TKE_reduc*tot_TKE ! = tot_TKE + TKE_forced(i,j,k) - mech_TKE(i) = TKE_reduc*mech_TKE(i) - conv_PErel(i) = TKE_reduc*conv_PErel(i) endif - endif - ! Precalculate some temporary expressions that are independent of Kddt_h(K). - if (K==2) then - dTe_t2 = 0.0 ; dSe_t2 = 0.0 - else - dTe_t2 = Kddt_h(K-1) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) - dSe_t2 = Kddt_h(K-1) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) - endif - dt_h = (GV%m_to_H**2*dt) / max(0.5*(h(i,k-1)+h(i,k)), 1e-15*h_sum(i)) - - ! This tests whether the layers above and below this interface are in - ! a convetively stable configuration, without considering any effects of - ! mixing at higher interfaces. It is an approximation to the more - ! complete test dPEc_dKd_Kd0 >= 0.0, that would include the effects of - ! mixing across interface K-1. The dT_to_dColHt here are effectively - ! mass-weigted estimates of dSV_dT. - Convectively_stable = ( 0.0 <= & - ( (dT_to_dColHt(i,k) + dT_to_dColHt(i,k-1) ) * (T0(k-1)-T0(k)) + & - (dS_to_dColHt(i,k) + dS_to_dColHt(i,k-1) ) * (S0(k-1)-S0(k)) ) ) - - if ((mech_TKE(i) + conv_PErel(i)) <= 0.0 .and. Convectively_stable) then - ! Energy is already exhausted, so set Kd = 0 and cycle or exit? - tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 - Kd(i,K) = 0.0 ; Kddt_h(K) = 0.0 - sfc_disconnect = .true. - ! if (.not.debug) exit - - ! The estimated properties for layer k-1 can be calculated, using - ! greatly simplified expressions when Kddt_h = 0. This enables the - ! tridiagonal solver for the whole column to be completed for debugging - ! purposes, and also allows for something akin to convective adjustment - ! in unstable interior regions? - b1 = 1.0 / (b_den_1(i)) - c1(K) = 0.0 - dTe(k-1) = b1 * ( dTe_t2 ) - dSe(k-1) = b1 * ( dSe_t2 ) - - b_den_1(i) = h(i,k) - dT_to_dPE_a(i,k) = dT_to_dPE(i,k) - dS_to_dPE_a(i,k) = dS_to_dPE(i,k) - dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) - dS_to_dColHt_a(i,k) = dS_to_dColHt(i,k) + if (debug) then + mech_TKE_k(i,K) = mech_TKE(i) ; conv_PErel_k(i,K) = conv_PErel(i) + endif - else ! tot_TKE > 0.0 or this is a potentially convectively unstable profile. - sfc_disconnect = .false. + ! Determine the total energy + nstar_FC = CS%nstar + if (CS%nstar * conv_PErel(i) > 0.0) then + ! Here nstar is a function of the natural Rossby number 0.2/(1+0.2/Ro), based + ! on a curve fit from the data of Wang (GRL, 2003). + ! Note: Ro = 1.0 / sqrt(0.5 * dt * Rho0 * (absf*htot(i))**3 / conv_PErel(i)) + nstar_FC = CS%nstar * conv_PErel(i) / (conv_PErel(i) + 0.2 * & + sqrt(0.5 * dt * GV%Rho0 * (absf(i)*(htot(i)*GV%H_to_m))**3 * conv_PErel(i))) + endif + if (debug) nstar_k(K) = nstar_FC + + tot_TKE = mech_TKE(i) + nstar_FC * conv_PErel(i) + + ! For each interior interface, first discard the TKE to account for + ! mixing of shortwave radiation through the next denser cell. + if (TKE_forced(i,j,k) < 0.0) then + if (TKE_forced(i,j,k) + tot_TKE < 0.0) then + ! The shortwave requirements deplete all the energy in this layer. + if (CS%TKE_diagnostics) then + CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) + tot_TKE * IdtdR0 + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) - tot_TKE * IdtdR0 + ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & + ! (TKE_forced(i,j,k) + tot_TKE) * IdtdR0 + CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 + endif + tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 + else + ! Reduce the mechanical and convective TKE proportionately. + TKE_reduc = (tot_TKE + TKE_forced(i,j,k)) / tot_TKE + if (CS%TKE_diagnostics) then + CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - TKE_forced(i,j,k) * IdtdR0 + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + TKE_forced(i,j,k) * IdtdR0 + CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 + endif + tot_TKE = TKE_reduc*tot_TKE ! = tot_TKE + TKE_forced(i,j,k) + mech_TKE(i) = TKE_reduc*mech_TKE(i) + conv_PErel(i) = TKE_reduc*conv_PErel(i) + endif + endif - ! Precalculate some more temporary expressions that are independent of - ! Kddt_h(K). + ! Precalculate some temporary expressions that are independent of Kddt_h(K). if (K==2) then - dT_km1_t2 = (T0(k)-T0(k-1)) - dS_km1_t2 = (S0(k)-S0(k-1)) - else - dT_km1_t2 = (T0(k)-T0(k-1)) - & - (Kddt_h(K-1) / b_den_1(i)) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) - dS_km1_t2 = (S0(k)-S0(k-1)) - & - (Kddt_h(K-1) / b_den_1(i)) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) - endif - dTe_term = dTe_t2 + b_den_1(i) * (T0(k-1)-T0(k)) - dSe_term = dSe_t2 + b_den_1(i) * (S0(k-1)-S0(k)) - - ! Using Pr=1 and the diffusivity at the bottom interface (once it is - ! known), determine how much resolved mean kinetic energy (MKE) will be - ! extracted within a timestep and add a fraction CS%MKE_to_TKE_effic of - ! this to the mTKE budget available for mixing in the next layer. - - if ((CS%MKE_to_TKE_effic > 0.0) .and. (htot(i)*h(i,k) > 0.0)) then - ! This is the energy that would be available from homogenizing the - ! velocities between layer k and the layers above. - dMKE_max = (GV%H_to_kg_m2 * CS%MKE_to_TKE_effic) * 0.5 * & - (h(i,k) / ((htot(i) + h(i,k))*htot(i))) * & - ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2) - ! A fraction (1-exp(Kddt_h*MKE2_Hharm)) of this energy would be - ! extracted by mixing with a finite viscosity. - MKE2_Hharm = (htot(i) + h(i,k) + 2.0*h_neglect) / & - ((htot(i)+h_neglect) * (h(i,k)+h_neglect)) + dTe_t2 = 0.0 ; dSe_t2 = 0.0 else - dMKE_max = 0.0 ; MKE2_Hharm = 0.0 + dTe_t2 = Kddt_h(K-1) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) + dSe_t2 = Kddt_h(K-1) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) endif + dt_h = (GV%m_to_H**2*dt) / max(0.5*(h(i,k-1)+h(i,k)), 1e-15*h_sum(i)) + + ! This tests whether the layers above and below this interface are in + ! a convetively stable configuration, without considering any effects of + ! mixing at higher interfaces. It is an approximation to the more + ! complete test dPEc_dKd_Kd0 >= 0.0, that would include the effects of + ! mixing across interface K-1. The dT_to_dColHt here are effectively + ! mass-weigted estimates of dSV_dT. + Convectively_stable = ( 0.0 <= & + ( (dT_to_dColHt(i,k) + dT_to_dColHt(i,k-1) ) * (T0(k-1)-T0(k)) + & + (dS_to_dColHt(i,k) + dS_to_dColHt(i,k-1) ) * (S0(k-1)-S0(k)) ) ) + + if ((mech_TKE(i) + conv_PErel(i)) <= 0.0 .and. Convectively_stable) then + ! Energy is already exhausted, so set Kd = 0 and cycle or exit? + tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 + Kd(i,K) = 0.0 ; Kddt_h(K) = 0.0 + sfc_disconnect = .true. + ! if (.not.debug) exit + + ! The estimated properties for layer k-1 can be calculated, using + ! greatly simplified expressions when Kddt_h = 0. This enables the + ! tridiagonal solver for the whole column to be completed for debugging + ! purposes, and also allows for something akin to convective adjustment + ! in unstable interior regions? + b1 = 1.0 / (b_den_1(i)) + c1(K) = 0.0 + dTe(k-1) = b1 * ( dTe_t2 ) + dSe(k-1) = b1 * ( dSe_t2 ) + + b_den_1(i) = h(i,k) + dT_to_dPE_a(i,k) = dT_to_dPE(i,k) + dS_to_dPE_a(i,k) = dS_to_dPE(i,k) + dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) + dS_to_dColHt_a(i,k) = dS_to_dColHt(i,k) + + else ! tot_TKE > 0.0 or this is a potentially convectively unstable profile. + sfc_disconnect = .false. + + ! Precalculate some more temporary expressions that are independent of + ! Kddt_h(K). + if (K==2) then + dT_km1_t2 = (T0(k)-T0(k-1)) + dS_km1_t2 = (S0(k)-S0(k-1)) + else + dT_km1_t2 = (T0(k)-T0(k-1)) - & + (Kddt_h(K-1) / b_den_1(i)) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) + dS_km1_t2 = (S0(k)-S0(k-1)) - & + (Kddt_h(K-1) / b_den_1(i)) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) + endif + dTe_term = dTe_t2 + b_den_1(i) * (T0(k-1)-T0(k)) + dSe_term = dSe_t2 + b_den_1(i) * (S0(k-1)-S0(k)) + + ! Using Pr=1 and the diffusivity at the bottom interface (once it is + ! known), determine how much resolved mean kinetic energy (MKE) will be + ! extracted within a timestep and add a fraction CS%MKE_to_TKE_effic of + ! this to the mTKE budget available for mixing in the next layer. + + if ((CS%MKE_to_TKE_effic > 0.0) .and. (htot(i)*h(i,k) > 0.0)) then + ! This is the energy that would be available from homogenizing the + ! velocities between layer k and the layers above. + dMKE_max = (GV%H_to_kg_m2 * CS%MKE_to_TKE_effic) * 0.5 * & + (h(i,k) / ((htot(i) + h(i,k))*htot(i))) * & + ((uhtot(i)-u(i,k)*htot(i))**2 + (vhtot(i)-v(i,k)*htot(i))**2) + ! A fraction (1-exp(Kddt_h*MKE2_Hharm)) of this energy would be + ! extracted by mixing with a finite viscosity. + MKE2_Hharm = (htot(i) + h(i,k) + 2.0*h_neglect) / & + ((htot(i)+h_neglect) * (h(i,k)+h_neglect)) + else + dMKE_max = 0.0 ; MKE2_Hharm = 0.0 + endif - ! At this point, Kddt_h(K) will be unknown because its value may depend - ! on how much energy is available. mech_TKE might be negative due to - ! contributions from TKE_forced. - h_tt = htot(i) + h_tt_min - TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*conv_PErel(i) - if (TKE_here > 0.0) then - vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = MAX(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) - !Note setting Kd_guess0 to Mixing_Length_Used(K) here will - ! change the answers. Therefore, skipping that. - if (.not.CS%Use_MLD_Iteration) then - Kd_guess0 = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + ! At this point, Kddt_h(K) will be unknown because its value may depend + ! on how much energy is available. mech_TKE might be negative due to + ! contributions from TKE_forced. + h_tt = htot(i) + h_tt_min + TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*conv_PErel(i) + if (TKE_here > 0.0) then + vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 + Mixing_Length_Used(k) = MAX(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) + !Note setting Kd_guess0 to Mixing_Length_Used(K) here will + ! change the answers. Therefore, skipping that. + if (.not.CS%Use_MLD_Iteration) then + Kd_guess0 = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + else + Kd_guess0 = vstar * vonKar * Mixing_Length_Used(k) + endif else - Kd_guess0 = vstar * vonKar * Mixing_Length_Used(k) + vstar = 0.0 ; Kd_guess0 = 0.0 endif - else - vstar = 0.0 ; Kd_guess0 = 0.0 - endif - Vstar_Used(k) = vstar!Track vstar - Kddt_h_g0 = Kd_guess0*dt_h - - call find_PE_chg(Kddt_h_g0, h(i,k), b_den_1(i), dTe_term, dSe_term, & - dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & - dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & - pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & - dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & - PE_chg=PE_chg_g0, dPEc_dKd=dPEa_dKd_g0, dPE_max=PE_chg_max, & - dPEc_dKd_0=dPEc_dKd_Kd0 ) - - MKE_src = dMKE_max*(1.0 - exp(-Kddt_h_g0 * MKE2_Hharm)) - - if ((PE_chg_g0 < 0.0) .or. ((vstar == 0.0) .and. (dPEc_dKd_Kd0 < 0.0))) then - ! This column is convectively unstable. - if (PE_chg_max <= 0.0) then - ! Does MKE_src need to be included in the calculation of vstar here? - TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*(conv_PErel(i)-PE_chg_max) - if (TKE_here > 0.0) then - vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = max(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) - if (.not.CS%Use_MLD_Iteration) then - ! Note again (as prev) that using Mixing_Length_Used here - ! instead of redoing the computation will change answers... - Kd(i,k) = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + Vstar_Used(k) = vstar ! Track vstar + Kddt_h_g0 = Kd_guess0*dt_h + + call find_PE_chg(Kddt_h_g0, h(i,k), b_den_1(i), dTe_term, dSe_term, & + dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & + pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + PE_chg=PE_chg_g0, dPEc_dKd=dPEa_dKd_g0, dPE_max=PE_chg_max, & + dPEc_dKd_0=dPEc_dKd_Kd0 ) + + MKE_src = dMKE_max*(1.0 - exp(-Kddt_h_g0 * MKE2_Hharm)) + + if ((PE_chg_g0 < 0.0) .or. ((vstar == 0.0) .and. (dPEc_dKd_Kd0 < 0.0))) then + ! This column is convectively unstable. + if (PE_chg_max <= 0.0) then + ! Does MKE_src need to be included in the calculation of vstar here? + TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*(conv_PErel(i)-PE_chg_max) + if (TKE_here > 0.0) then + vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 + Mixing_Length_Used(k) = max(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) + if (.not.CS%Use_MLD_Iteration) then + ! Note again (as prev) that using Mixing_Length_Used here + ! instead of redoing the computation will change answers... + Kd(i,k) = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + else + Kd(i,k) = vstar * vonKar * Mixing_Length_Used(k) + endif else - Kd(i,k) = vstar * vonKar * Mixing_Length_Used(k) + vstar = 0.0 ; Kd(i,k) = 0.0 + endif + Vstar_Used(k) = vstar + + call find_PE_chg(Kd(i,k)*dt_h, h(i,k), b_den_1(i), dTe_term, dSe_term, & + dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & + pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + PE_chg=dPE_conv) + ! Should this be iterated to convergence for Kd? + if (dPE_conv > 0.0) then + Kd(i,k) = Kd_guess0 ; dPE_conv = PE_chg_g0 + else + MKE_src = dMKE_max*(1.0 - exp(-(Kd(i,k)*dt_h) * MKE2_Hharm)) endif else - vstar = 0.0 ; Kd(i,k) = 0.0 - endif - Vstar_Used(k) = vstar - - call find_PE_chg(Kd(i,k)*dt_h, h(i,k), b_den_1(i), dTe_term, dSe_term, & - dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & - dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & - pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & - dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & - PE_chg=dPE_conv) - ! Should this be iterated to convergence for Kd? - if (dPE_conv > 0.0) then + ! The energy change does not vary monotonically with Kddt_h. Find the maximum? Kd(i,k) = Kd_guess0 ; dPE_conv = PE_chg_g0 - else - MKE_src = dMKE_max*(1.0 - exp(-(Kd(i,k)*dt_h) * MKE2_Hharm)) endif - else - ! The energy change does not vary monotonically with Kddt_h. Find the maximum? - Kd(i,k) = Kd_guess0 ; dPE_conv = PE_chg_g0 - endif - conv_PErel(i) = conv_PErel(i) - dPE_conv - mech_TKE(i) = mech_TKE(i) + MKE_src - if (CS%TKE_diagnostics) then - CS%diag_TKE_conv(i,j) = CS%diag_TKE_conv(i,j) - CS%nstar*dPE_conv * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 - endif - if (sfc_connected(i)) then - CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) - !CS%ML_depth2(i,j) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) - endif - - Kddt_h(K) = Kd(i,k)*dt_h - elseif (tot_TKE + (MKE_src - PE_chg_g0) >= 0.0) then - ! There is energy to support the suggested mixing. Keep that estimate. - Kd(i,k) = Kd_guess0 - Kddt_h(K) = Kddt_h_g0 - - ! Reduce the mechanical and convective TKE proportionately. - tot_TKE = tot_TKE + MKE_src - TKE_reduc = 0.0 ! tot_TKE could be 0 if Convectively_stable is false. - if (tot_TKE > 0.0) TKE_reduc = (tot_TKE - PE_chg_g0) / tot_TKE + conv_PErel(i) = conv_PErel(i) - dPE_conv + mech_TKE(i) = mech_TKE(i) + MKE_src + if (CS%TKE_diagnostics) then + CS%diag_TKE_conv(i,j) = CS%diag_TKE_conv(i,j) - CS%nstar*dPE_conv * IdtdR0 + CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 + endif + if (sfc_connected(i)) then + CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) + !CS%ML_depth2(i,j) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) + endif - if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - PE_chg_g0 * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & - (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 - endif - tot_TKE = TKE_reduc*tot_TKE - mech_TKE(i) = TKE_reduc*(mech_TKE(i) + MKE_src) - conv_PErel(i) = TKE_reduc*conv_PErel(i) - if (sfc_connected(i)) then - CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) - !CS%ML_depth2(i,J) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) - endif - elseif (tot_TKE == 0.0) then - ! This can arise if nstar_FC = 0. - Kd(i,k) = 0.0 ; Kddt_h(K) = 0.0 - tot_TKE = 0.0 ; conv_PErel(i) = 0.0 ; mech_TKE(i) = 0.0 - sfc_disconnect = .true. - else - ! There is not enough energy to support the mixing, so reduce the - ! diffusivity to what can be supported. - Kddt_h_max = Kddt_h_g0 ; Kddt_h_min = 0.0 - TKE_left_max = tot_TKE + (MKE_src - PE_chg_g0) ; TKE_left_min = tot_TKE - - ! As a starting guess, take the minimum of a false position estimate - ! and a Newton's method estimate starting from Kddt_h = 0.0. - Kddt_h_guess = tot_TKE * Kddt_h_max / max( PE_chg_g0 - MKE_src, & - Kddt_h_max * (dPEc_dKd_Kd0 - dMKE_max * MKE2_Hharm) ) - ! The above expression is mathematically the same as the following - ! except it is not susceptible to division by zero when - ! dPEc_dKd_Kd0 = dMKE_max = 0 . - ! Kddt_h_guess = tot_TKE * min( Kddt_h_max / (PE_chg_g0 - MKE_src), & - ! 1.0 / (dPEc_dKd_Kd0 - dMKE_max * MKE2_Hharm) ) - if (debug) then - TKE_left_itt(:) = 0.0 ; dPEa_dKd_itt(:) = 0.0 ; PE_chg_itt(:) = 0.0 - MKE_src_itt(:) = 0.0 ; Kddt_h_itt(:) = 0.0 - endif - do itt=1,max_itt - call find_PE_chg(Kddt_h_guess, h(i,k), b_den_1(i), dTe_term, dSe_term, & - dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & - dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & - pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & - dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & - PE_chg=PE_chg, dPEc_dKd=dPEc_dKd ) - MKE_src = dMKE_max * (1.0 - exp(-MKE2_Hharm * Kddt_h_guess)) - dMKE_src_dK = dMKE_max * MKE2_Hharm * exp(-MKE2_Hharm * Kddt_h_guess) - - TKE_left = tot_TKE + (MKE_src - PE_chg) - if (debug) then - Kddt_h_itt(itt) = Kddt_h_guess ; MKE_src_itt(itt) = MKE_src - PE_chg_itt(itt) = PE_chg ; TKE_left_itt(itt) = TKE_left - dPEa_dKd_itt(itt) = dPEc_dKd + Kddt_h(K) = Kd(i,k)*dt_h + elseif (tot_TKE + (MKE_src - PE_chg_g0) >= 0.0) then + ! There is energy to support the suggested mixing. Keep that estimate. + Kd(i,k) = Kd_guess0 + Kddt_h(K) = Kddt_h_g0 + + ! Reduce the mechanical and convective TKE proportionately. + tot_TKE = tot_TKE + MKE_src + TKE_reduc = 0.0 ! tot_TKE could be 0 if Convectively_stable is false. + if (tot_TKE > 0.0) TKE_reduc = (tot_TKE - PE_chg_g0) / tot_TKE + + if (CS%TKE_diagnostics) then + CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - PE_chg_g0 * IdtdR0 + CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 + CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif - ! Store the new bounding values, bearing in mind that min and max - ! here refer to Kddt_h and dTKE_left/dKddt_h < 0: - if (TKE_left >= 0.0) then - Kddt_h_min = Kddt_h_guess ; TKE_left_min = TKE_left - else - Kddt_h_max = Kddt_h_guess ; TKE_left_max = TKE_left + tot_TKE = TKE_reduc*tot_TKE + mech_TKE(i) = TKE_reduc*(mech_TKE(i) + MKE_src) + conv_PErel(i) = TKE_reduc*conv_PErel(i) + if (sfc_connected(i)) then + CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) + !CS%ML_depth2(i,J) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) endif + elseif (tot_TKE == 0.0) then + ! This can arise if nstar_FC = 0. + Kd(i,k) = 0.0 ; Kddt_h(K) = 0.0 + tot_TKE = 0.0 ; conv_PErel(i) = 0.0 ; mech_TKE(i) = 0.0 + sfc_disconnect = .true. + else + ! There is not enough energy to support the mixing, so reduce the + ! diffusivity to what can be supported. + Kddt_h_max = Kddt_h_g0 ; Kddt_h_min = 0.0 + TKE_left_max = tot_TKE + (MKE_src - PE_chg_g0) ; TKE_left_min = tot_TKE + + ! As a starting guess, take the minimum of a false position estimate + ! and a Newton's method estimate starting from Kddt_h = 0.0. + Kddt_h_guess = tot_TKE * Kddt_h_max / max( PE_chg_g0 - MKE_src, & + Kddt_h_max * (dPEc_dKd_Kd0 - dMKE_max * MKE2_Hharm) ) + ! The above expression is mathematically the same as the following + ! except it is not susceptible to division by zero when + ! dPEc_dKd_Kd0 = dMKE_max = 0 . + ! Kddt_h_guess = tot_TKE * min( Kddt_h_max / (PE_chg_g0 - MKE_src), & + ! 1.0 / (dPEc_dKd_Kd0 - dMKE_max * MKE2_Hharm) ) + if (debug) then + TKE_left_itt(:) = 0.0 ; dPEa_dKd_itt(:) = 0.0 ; PE_chg_itt(:) = 0.0 + MKE_src_itt(:) = 0.0 ; Kddt_h_itt(:) = 0.0 + endif + do itt=1,max_itt + call find_PE_chg(Kddt_h_guess, h(i,k), b_den_1(i), dTe_term, dSe_term, & + dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & + pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + PE_chg=PE_chg, dPEc_dKd=dPEc_dKd ) + MKE_src = dMKE_max * (1.0 - exp(-MKE2_Hharm * Kddt_h_guess)) + dMKE_src_dK = dMKE_max * MKE2_Hharm * exp(-MKE2_Hharm * Kddt_h_guess) + + TKE_left = tot_TKE + (MKE_src - PE_chg) + if (debug) then + Kddt_h_itt(itt) = Kddt_h_guess ; MKE_src_itt(itt) = MKE_src + PE_chg_itt(itt) = PE_chg ; TKE_left_itt(itt) = TKE_left + dPEa_dKd_itt(itt) = dPEc_dKd + endif + ! Store the new bounding values, bearing in mind that min and max + ! here refer to Kddt_h and dTKE_left/dKddt_h < 0: + if (TKE_left >= 0.0) then + Kddt_h_min = Kddt_h_guess ; TKE_left_min = TKE_left + else + Kddt_h_max = Kddt_h_guess ; TKE_left_max = TKE_left + endif - ! Try to use Newton's method, but if it would go outside the bracketed - ! values use the false-position method instead. - use_Newt = .true. - if (dPEc_dKd - dMKE_src_dK <= 0.0) then - use_Newt = .false. - else - dKddt_h_Newt = TKE_left / (dPEc_dKd - dMKE_src_dK) - Kddt_h_Newt = Kddt_h_guess + dKddt_h_Newt - if ((Kddt_h_Newt > Kddt_h_max) .or. (Kddt_h_Newt < Kddt_h_min)) & + ! Try to use Newton's method, but if it would go outside the bracketed + ! values use the false-position method instead. + use_Newt = .true. + if (dPEc_dKd - dMKE_src_dK <= 0.0) then use_Newt = .false. - endif + else + dKddt_h_Newt = TKE_left / (dPEc_dKd - dMKE_src_dK) + Kddt_h_Newt = Kddt_h_guess + dKddt_h_Newt + if ((Kddt_h_Newt > Kddt_h_max) .or. (Kddt_h_Newt < Kddt_h_min)) & + use_Newt = .false. + endif - if (use_Newt) then - Kddt_h_next = Kddt_h_guess + dKddt_h_Newt - dKddt_h = dKddt_h_Newt - else - Kddt_h_next = (TKE_left_max * Kddt_h_min - Kddt_h_max * TKE_left_min) / & - (TKE_left_max - TKE_left_min) - dKddt_h = Kddt_h_next - Kddt_h_guess - endif + if (use_Newt) then + Kddt_h_next = Kddt_h_guess + dKddt_h_Newt + dKddt_h = dKddt_h_Newt + else + Kddt_h_next = (TKE_left_max * Kddt_h_min - Kddt_h_max * TKE_left_min) / & + (TKE_left_max - TKE_left_min) + dKddt_h = Kddt_h_next - Kddt_h_guess + endif - if ((abs(dKddt_h) < 1e-9*Kddt_h_guess) .or. (itt==max_itt)) then - ! Use the old value so that the energy calculation does not need to be repeated. - if (debug) num_itts(K) = itt - exit - else - Kddt_h_guess = Kddt_h_next + if ((abs(dKddt_h) < 1e-9*Kddt_h_guess) .or. (itt==max_itt)) then + ! Use the old value so that the energy calculation does not need to be repeated. + if (debug) num_itts(K) = itt + exit + else + Kddt_h_guess = Kddt_h_next + endif + enddo + Kd(i,K) = Kddt_h_guess / dt_h ; Kddt_h(K) = Kd(i,K)*dt_h + + ! All TKE should have been consumed. + if (CS%TKE_diagnostics) then + CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - (tot_TKE + MKE_src) * IdtdR0 + CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 + CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif - enddo - Kd(i,K) = Kddt_h_guess / dt_h ; Kddt_h(K) = Kd(i,K)*dt_h - ! All TKE should have been consumed. - if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - (tot_TKE + MKE_src) * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & - (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 + if (sfc_connected(i)) CS%ML_depth(i,J) = CS%ML_depth(i,J) + & + (PE_chg / PE_chg_g0) * GV%H_to_m * h(i,k) + tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 + sfc_disconnect = .true. endif - if (sfc_connected(i)) CS%ML_depth(i,J) = CS%ML_depth(i,J) + & - (PE_chg / PE_chg_g0) * GV%H_to_m * h(i,k) - tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 - sfc_disconnect = .true. + Kddt_h(K) = Kd(i,K)*dt_h + ! At this point, the final value of Kddt_h(K) is known, so the + ! estimated properties for layer k-1 can be calculated. + b1 = 1.0 / (b_den_1(i) + Kddt_h(K)) + c1(K) = Kddt_h(K) * b1 + dTe(k-1) = b1 * ( Kddt_h(K)*(T0(k)-T0(k-1)) + dTe_t2 ) + dSe(k-1) = b1 * ( Kddt_h(K)*(S0(k)-S0(k-1)) + dSe_t2 ) + + b_den_1(i) = h(i,k) + (b_den_1(i) * b1) * Kddt_h(K) + dT_to_dPE_a(i,k) = dT_to_dPE(i,k) + c1(K)*dT_to_dPE_a(i,k-1) + dS_to_dPE_a(i,k) = dS_to_dPE(i,k) + c1(K)*dS_to_dPE_a(i,k-1) + dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) + c1(K)*dT_to_dColHt_a(i,k-1) + dS_to_dColHt_a(i,k) = dS_to_dColHt(i,k) + c1(K)*dS_to_dColHt_a(i,k-1) + + endif ! tot_TKT > 0.0 branch. Kddt_h(K) has been set. + + ! Store integrated velocities and thicknesses for MKE conversion calculations. + if (sfc_disconnect) then + ! There is no turbulence at this interface, so zero out the running sums. + uhtot(i) = u(i,k)*h(i,k) + vhtot(i) = v(i,k)*h(i,k) + htot(i) = h(i,k) + sfc_connected(i) = .false. + else + uhtot(i) = uhtot(i) + u(i,k)*h(i,k) + vhtot(i) = vhtot(i) + v(i,k)*h(i,k) + htot(i) = htot(i) + h(i,k) endif - Kddt_h(K) = Kd(i,K)*dt_h - ! At this point, the final value of Kddt_h(K) is known, so the - ! estimated properties for layer k-1 can be calculated. - b1 = 1.0 / (b_den_1(i) + Kddt_h(K)) - c1(K) = Kddt_h(K) * b1 - dTe(k-1) = b1 * ( Kddt_h(K)*(T0(k)-T0(k-1)) + dTe_t2 ) - dSe(k-1) = b1 * ( Kddt_h(K)*(S0(k)-S0(k-1)) + dSe_t2 ) - - b_den_1(i) = h(i,k) + (b_den_1(i) * b1) * Kddt_h(K) - dT_to_dPE_a(i,k) = dT_to_dPE(i,k) + c1(K)*dT_to_dPE_a(i,k-1) - dS_to_dPE_a(i,k) = dS_to_dPE(i,k) + c1(K)*dS_to_dPE_a(i,k-1) - dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) + c1(K)*dT_to_dColHt_a(i,k-1) - dS_to_dColHt_a(i,k) = dS_to_dColHt(i,k) + c1(K)*dS_to_dColHt_a(i,k-1) - - endif ! tot_TKT > 0.0 branch. Kddt_h(K) has been set. - - ! Store integrated velocities and thicknesses for MKE conversion calculations. - if (sfc_disconnect) then - ! There is no turbulence at this interface, so zero out the running sums. - uhtot(i) = u(i,k)*h(i,k) - vhtot(i) = v(i,k)*h(i,k) - htot(i) = h(i,k) - sfc_connected(i) = .false. - else - uhtot(i) = uhtot(i) + u(i,k)*h(i,k) - vhtot(i) = vhtot(i) + v(i,k)*h(i,k) - htot(i) = htot(i) + h(i,k) - endif + if (debug) then + if (k==2) then + Te(1) = b1*(h(i,1)*T0(1)) + Se(1) = b1*(h(i,1)*S0(1)) + else + Te(k-1) = b1 * (h(i,k-1) * T0(k-1) + Kddt_h(K-1) * Te(k-2)) + Se(k-1) = b1 * (h(i,k-1) * S0(k-1) + Kddt_h(K-1) * Se(k-2)) + endif + endif + enddo + Kd(i,nz+1) = 0.0 if (debug) then - if (k==2) then - Te(1) = b1*(h(i,1)*T0(1)) - Se(1) = b1*(h(i,1)*S0(1)) - else - Te(k-1) = b1 * (h(i,k-1) * T0(k-1) + Kddt_h(K-1) * Te(k-2)) - Se(k-1) = b1 * (h(i,k-1) * S0(k-1) + Kddt_h(K-1) * Se(k-2)) - endif + ! Complete the tridiagonal solve for Te. + b1 = 1.0 / (b_den_1(i)) + Te(nz) = b1 * (h(i,nz) * T0(nz) + Kddt_h(nz) * Te(nz-1)) + Se(nz) = b1 * (h(i,nz) * S0(nz) + Kddt_h(nz) * Se(nz-1)) + do k=nz-1,1,-1 + Te(k) = Te(k) + c1(K+1)*Te(k+1) + Se(k) = Se(k) + c1(K+1)*Se(k+1) + enddo endif - enddo - Kd(i,nz+1) = 0.0 - - if (debug) then - ! Complete the tridiagonal solve for Te. - b1 = 1.0 / (b_den_1(i)) - Te(nz) = b1 * (h(i,nz) * T0(nz) + Kddt_h(nz) * Te(nz-1)) - Se(nz) = b1 * (h(i,nz) * S0(nz) + Kddt_h(nz) * Se(nz-1)) - do k=nz-1,1,-1 - Te(k) = Te(k) + c1(K+1)*Te(k+1) - Se(k) = Se(k) + c1(K+1)*Se(k+1) + if (present(dT_expected)) then + do k=1,nz ; dT_expected(i,j,k) = Te(k) - T0(k) ; enddo + endif + if (present(dS_expected)) then + do k=1,nz ; dS_expected(i,j,k) = Se(k) - S0(k) ; enddo + endif + if (debug) then + dPE_debug = 0.0 + do k=1,nz + dPE_debug = dPE_debug + (dT_to_dPE(i,k) * (Te(k) - T0(k)) + & + dS_to_dPE(i,k) * (Se(k) - S0(k))) + enddo + mixing_debug = dPE_debug * IdtdR0 + endif + k = nz ! This is here to allow a breakpoint to be set. + + !/BGR: The following lines are used for the iteration + ITmax(obl_it) = max_MLD ! Track max } + ITmin(obl_it) = min_MLD ! Track min } For debug purpose + ITguess(obl_it) = MLD_GUESS ! Track guess } + MLD_FOUND=0.0 ; FIRST_OBL=.true. + ! MLD_FOUND=CS%ML_depth2(i,J) + do k=2,nz + if (FIRST_OBL) then !Breaks when OBL found + if (Vstar_Used(k) > 1.e-10 .and. k < nz) then + !If within OBL, keep integrating to find OBL + !/ Add thickness of level above to OBL depth. + MLD_FOUND = MLD_FOUND+h(i,k-1)*GV%H_to_m + !1. Check if guess was too shallow + !Adding -1 m as cushion, will help avoid + ! non-convergence flag when nearly converged. + elseif (MLD_FOUND-1.0 > MLD_GUESS) then + !elseif (MLD_FOUND > MLD_GUESS) then + !/ Guess was too shallow, set new minimum guess + MIN_MLD = MLD_GUESS + FIRST_OBL = .false. !Break OBL loop + !2. Check if Guess minus found MLD + ! is less than thickness of level (=converged) + ! - We could try to add a more precise + ! value for found MLD, but seems difficult to + ! to contrain beyond within a level. + elseif ((MLD_GUESS-MLD_FOUND) < max(1.,h(i,k-1)*GV%H_to_m)) then + ! Converged. Exit iteration. + FIRST_OBL = .false.!Break OBL loop + OBL_CONVERGED = .true.!Break convergence loop + ! Testing Output, comment for use. + !print*,'Converged--------' + !print*,MLD_FOUND,MLD_GUESS + !/ + if (OBL_IT_STATS) then !Compute iteration statistics + MAXIT = max(MAXIT,obl_it) + MINIT = min(MINIT,obl_it) + SUMIT = SUMIT+obl_it + NUMIT = NUMIT+1 + print*,MAXIT,MINIT,SUMIT/NUMIT + endif + !BGR this can be where MLD is stored for next time... + CS%ML_Depth2(i,j) = MLD_GUESS + !/ + !2. If not, guess was too deep + else + !Guess was too deep, set new maximum guess + MAX_MLD = MLD_GUESS !We know this guess was too deep + FIRST_OBL = .false.!Break OBL loop + endif + endif enddo + ! For next pass, guess average of minimum and maximum values. + MLD_GUESS = MIN_MLD*0.5 + MAX_MLD*0.5 + ITresult(obl_it) = MLD_FOUND + endif ; enddo ! Iteration loop for converged boundary layer thickness. + + if (.not.OBL_CONVERGED) then + !/Temp output, warn that EPBL didn't converge + !/Print guess/found for every iteration step + !print*,'EPBL MLD DID NOT CONVERGE' + NOTCONVERGED=NOTCONVERGED+1 + !do obl_it=1,max_obl_it + ! print*,ITmin(obl_it),ITmax(obl_it) + ! print*,obl_it,ITguess(obl_it),ITresult(obl_it) + !enddo + !Activate to print out some output when not converged + !{ + !print*,'Min/Max: ',ITmin(50),ITmax(50) + !print*,'Guess/result: ',ITguess(50),ITresult(50) + !print*,'Stats on CPU: ',CONVERGED,NOTCONVERGED,& + ! real(NOTCONVERGED)/real(CONVERGED) + !} + !stop !Kill if not converged during testing. + else + CONVERGED=CONVERGED+1 endif - if (present(dT_expected)) then - do k=1,nz ; dT_expected(i,j,k) = Te(k) - T0(k) ; enddo - endif - if (present(dS_expected)) then - do k=1,nz ; dS_expected(i,j,k) = Se(k) - S0(k) ; enddo - endif - if (debug) then - dPE_debug = 0.0 + if (CS%Mixing_Diagnostics) then + !Write to 3-D for outputing Mixing length and + ! velocity scale. do k=1,nz - dPE_debug = dPE_debug + (dT_to_dPE(i,k) * (Te(k) - T0(k)) + & - dS_to_dPE(i,k) * (Se(k) - S0(k))) + CS%Mixing_Length(i,j,k) = Mixing_Length_Used(k) + CS%Velocity_Scale(i,j,k) = Vstar_Used(k) enddo - mixing_debug = dPE_debug * IdtdR0 endif - k = nz ! This is here to allow a breakpoint to be set. - - !/BGR: The following lines are used for the iteration - ITmax(obl_it)=max_MLD ! Track max } - ITmin(obl_it)=min_MLD ! Track min } For debug purpose - ITguess(obl_it) = MLD_GUESS ! Track guess } - MLD_FOUND=0.0;FIRST_OBL=.true.; - ! MLD_FOUND=CS%ML_depth2(i,J) - do k=2,nz - IF (FIRST_OBL) then !Breaks when OBL found - if (Vstar_Used(k).gt.1.e-10 .and. k.lt.nz) then - !If within OBL, keep integrating to find OBL - !/ Add thickness of level above to OBL depth. - MLD_FOUND = MLD_FOUND+h(i,k-1)*GV%H_to_m - !1. Check if guess was too shallow - !Adding -1 m as cushion, will help avoid - ! non-convergence flag when nearly converged. - elseif (MLD_FOUND-1.0.GT.MLD_GUESS) then - !elseif (MLD_FOUND.GT.MLD_GUESS) then - !/ Guess was too shallow, set new minimum guess - MIN_MLD=MLD_GUESS - FIRST_OBL=.false. !Break OBL loop - !2. Check if Guess minus found MLD - ! is less than thickness of level (=converged) - ! - We could try to add a more precise - ! value for found MLD, but seems difficult to - ! to contrain beyond within a level. - elseif ((MLD_GUESS-MLD_FOUND).lt.max(1.,h(i,k-1)*GV%H_to_m)) then - ! Converged. Exit iteration. - FIRST_OBL=.false.!Break OBL loop - OBL_CONVERGED=.true.!Break convergence loop - ! Testing Output, comment for use. - !print*,'Converged--------' - !print*,MLD_FOUND,MLD_GUESS - !/ - IF (OBL_IT_STATS) then !Compute iteration statistics - MAXIT=max(MAXIT,obl_it) - MINIT=min(MINIT,obl_it) - SUMIT=SUMIT+obl_it - NUMIT=NUMIT+1 - print*,MAXIT,MINIT,SUMIT/NUMIT - ENDIF - !BGR this can be where MLD is stored for next time... - CS%ML_Depth2(i,j)=MLD_GUESS - !/ - !2. If not, guess was too deep - else - !Guess was too deep, set new maximum guess - MAX_MLD=MLD_GUESS !We know this guess was too deep - FIRST_OBL=.false.!Break OBL loop - endif - endif - enddo - ! For next pass, guess average of minimum and maximum values. - MLD_GUESS = MIN_MLD*0.5 + MAX_MLD*0.5 - ITresult(obl_it)=MLD_FOUND - ENDIF!Check for convergence loop - ENDDO!Iteration loop - if (.not.OBL_CONVERGED) then - !/Temp output, warn that EPBL didn't converge - !/Print guess/found for every iteration step - !print*,'EPBL MLD DID NOT CONVERGE' - NOTCONVERGED=NOTCONVERGED+1 - !do obl_it=1,max_obl_it - ! print*,ITmin(obl_it),ITmax(obl_it) - ! print*,obl_it,ITguess(obl_it),ITresult(obl_it) - !enddo - !Activate to print out some output when not converged - !{ - !print*,'Min/Max: ',ITmin(50),ITmax(50) - !print*,'Guess/result: ',ITguess(50),ITresult(50) - !print*,'Stats on CPU: ',CONVERGED,NOTCONVERGED,& - ! real(NOTCONVERGED)/real(CONVERGED) - !} - !stop !Kill if not converged during testing. - else - CONVERGED=CONVERGED+1 - endif - if (cs%Mixing_Diagnostics) then - !Write to 3-D for outputing Mixing length and - ! velocity scale. - do k=1,nz - cs%Mixing_Length(i,j,k)=Mixing_Length_Used(k) - cs%Velocity_Scale(i,j,k)=Vstar_Used(k) - enddo - endif - + else ! For masked points, Kd_int must still be set (to 0) because it has intent(out). do K=1,nz+1 @@ -1192,16 +1194,75 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & end subroutine energetic_PBL +!> This subroutine calculates the change in potential energy and or derivatives +!! for several changes in an interfaces's diapycnal diffusivity times a timestep +!! using the original form used in the first version of ePBL. subroutine find_PE_chg(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, & dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, & dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, & PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0) - real, intent(in) :: Kddt_h, h_k, b_den_1, dTe_term, dSe_term - real, intent(in) :: dT_km1_t2, dS_km1_t2, pres - real, intent(in) :: dT_to_dPE_k, dS_to_dPE_k, dT_to_dPEa, dS_to_dPEa - real, intent(in) :: dT_to_dColHt_k, dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta - real, optional, intent(out) :: PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0 + real, intent(in) :: Kddt_h !< The diffusivity at an interface times the time step and + !! divided by the average of the thicknesses around the + !! interface, in units of H (m or kg-2). + real, intent(in) :: h_k !< The thickness of the layer below the interface, in H. + real, intent(in) :: b_den_1 !< The first term in the denominator of the pivot + !! for the tridiagonal solver, given by h_k plus a term that + !! is a fraction (determined from the tridiagonal solver) of + !! Kddt_h for the interface above, in H. + real, intent(in) :: dTe_term !< A diffusivity-independent term related to the + !! temperature change in the layer below the interface, in K H. + real, intent(in) :: dSe_term !< A diffusivity-independent term related to the + !! salinity change in the layer below the interface, in ppt H. + real, intent(in) :: dT_km1_t2 !< A diffusivity-independent term related to the + !! temperature change in the layer above the interface, in K. + real, intent(in) :: dS_km1_t2 !< A diffusivity-independent term related to the + !! salinity change in the layer above the interface, in ppt. + real, intent(in) :: pres !< The hydrostatic interface pressure, which is used to relate + !! the changes in column thickness to the energy that is radiated + !! as gravity waves and unavailable to drive mixing, in Pa. + real, intent(in) :: dT_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating + !! a layer's temperature change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the temperatures of all the layers below, in J m-2 K-1. + real, intent(in) :: dS_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating + !! a layer's salinity change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the salinities of all the layers below, in J m-2 ppt-1. + real, intent(in) :: dT_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating + !! a layer's temperature change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the temperatures of all the layers above, in J m-2 K-1. + real, intent(in) :: dS_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating + !! a layer's salinity change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the salinities of all the layers above, in J m-2 ppt-1. + real, intent(in) :: dT_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dT) relating + !! a layer's temperature change to the change in column + !! height, including all implicit diffusive changes + !! in the temperatures of all the layers below, in m K-1. + real, intent(in) :: dS_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dS) relating + !! a layer's salinity change to the change in column + !! height, including all implicit diffusive changes + !! in the salinities of all the layers below, in m ppt-1. + real, intent(in) :: dT_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dT) relating + !! a layer's temperature change to the change in column + !! height, including all implicit diffusive changes + !! in the temperatures of all the layers above, in m K-1. + real, intent(in) :: dS_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dS) relating + !! a layer's salinity change to the change in column + !! height, including all implicit diffusive changes + !! in the salinities of all the layers above, in m ppt-1. + + real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying + !! Kddt_h at the present interface, in J m-2. + real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, + !! in units of J m-2 H-1. + real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could + !! be realizedd by applying a huge value of Kddt_h at the + !! present interface, in J m-2. + real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the + !! limit where Kddt_h = 0, in J m-2 H-1. ! This subroutine determines the total potential energy change due to mixing ! at an interface, including all of the implicit effects of the prescribed @@ -1211,64 +1272,7 @@ subroutine find_PE_chg(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & ! The comments describing these arguments are for a downward mixing pass, but ! this routine can also be used for an upward pass with the sense of direction ! reversed. -! -! Arguments: Kddt_h - The diffusivity at an interface times the time step and -! divided by the average of the thicknesses around the -! interface, in units of H (m or kg-2). -! (in) h_k - The thickness of the layer below the interface, in H. -! (in) b_den_1 - The first first term in the denominator of the pivot -! for the tridiagonal solver, given by h_k plus a term that -! is a fraction (determined from the tridiagonal solver) of -! Kddt_h for the interface above, in H. -! (in) dTe_term - A diffusivity-independent term related to the -! temperature change in the layer below the interface, in K H. -! (in) dSe_term - A diffusivity-independent term related to the -! salinity change in the layer below the interface, in ppt H. -! (in) dT_km1_t2 - A diffusivity-independent term related to the -! temperature change in the layer above the interface, in K. -! (in) dS_km1_t2 - A diffusivity-independent term related to the -! salinity change in the layer above the interface, in ppt. -! (in) dT_to_dPE_k - A factor (pres_lay*mass_lay*dSpec_vol/dT) relating -! a layer's temperature change to the change in column -! potential energy, in J m-2 K-1. -! (in) dS_to_dPE_k - A factor (pres_lay*mass_lay*dSpec_vol/dS) relating -! a layer's salinity change to the change in column -! potential energy, in J m-2 ppt-1. -! (in) dT_to_dPEa - A factor (pres_lay*mass_lay*dSpec_vol/dT) relating -! a layer's temperature change to the change in column -! potential energy, including all implicit diffusive changes -! in the temperatures of all the layers above, in J m-2 K-1. -! (in) dS_to_dPEa - A factor (pres_lay*mass_lay*dSpec_vol/dS) relating -! a layer's salinity change to the change in column -! potential energy, including all implicit diffusive changes -! in the salinities of all the layers above, in J m-2 ppt-1. -! (in) pres - The hydrostatic interface pressure, which is used to relate -! the changes in column thickness to the energy that is radiated -! as gravity waves and unavailable to drive mixing, in Pa. -! (in) dT_to_dColHt_k - A factor (mass_lay*dSColHtc_vol/dT) relating -! a layer's temperature change to the change in column -! height, in m K-1. -! (in) dS_to_dColHt_k - A factor (mass_lay*dSColHtc_vol/dS) relating -! a layer's salinity change to the change in column -! height, in m ppt-1. -! (in) dT_to_dColHta - A factor (mass_lay*dSColHtc_vol/dT) relating -! a layer's temperature change to the change in column -! height, including all implicit diffusive changes -! in the temperatures of all the layers above, in m K-1. -! (in) dS_to_dColHta - A factor (mass_lay*dSColHtc_vol/dS) relating -! a layer's salinity change to the change in column -! height, including all implicit diffusive changes -! in the salinities of all the layers above, in m ppt-1. -! (out,opt) PE_chg - The change in column potential energy from applying -! Kddt_h at the present interface, in J m-2. -! (out,opt) dPE_chg_dKd - The partial derivative of PE_chg with Kddt_h, -! in units of J m-2 H-1. -! (out,opt) PE_max - The maximum change in column potential energy that could -! be realizedd by applying a huge value of Kddt_h at the -! present interface, in J m-2. -! (out,opt) dPEc_dKc0 - The partial derivative of PE_chg with Kddt_h in the -! limit where Kddt_h = 0, in J m-2 H-1. - ! b_den_1 - The first term in the denominator of b1, in m or kg m-2. + real :: b1 ! b1 is used by the tridiagonal solver, in H-1. real :: b1Kd ! Temporary array (nondim.) real :: ColHt_chg ! The change in column thickness in m. @@ -1495,17 +1499,16 @@ subroutine energetic_PBL_init(Time, G, GV, param_file, diag, CS) CS%TKE_diagnostics = .true. endif - if (max(CS%id_Mixing_Length,CS%id_Velocity_Scale)>0) then - call safe_alloc_alloc(CS%Velocity_Scale,isd,ied,jsd,jed,SZK_(GV)+1) - call safe_alloc_alloc(CS%Mixing_Length,isd,ied,jsd,jed,SZK_(GV)+1) - CS%Velocity_Scale(:,:,:)=0.0 - CS%Mixing_Length(:,:,:)=0.0 - CS%mixing_diagnostics=.true. + if ((CS%id_Mixing_Length>0) .or. (CS%id_Velocity_Scale>0)) then + call safe_alloc_alloc(CS%Velocity_Scale,isd,ied,jsd,jed,GV%ke+1) + call safe_alloc_alloc(CS%Mixing_Length,isd,ied,jsd,jed,GV%ke+1) + CS%Velocity_Scale(:,:,:) = 0.0 + CS%Mixing_Length(:,:,:) = 0.0 + CS%mixing_diagnostics = .true. endif call safe_alloc_alloc(CS%ML_depth, isd, ied, jsd, jed) call safe_alloc_alloc(CS%ML_depth2, isd, ied, jsd, jed) - end subroutine energetic_PBL_init subroutine energetic_PBL_end(CS) @@ -1514,7 +1517,7 @@ subroutine energetic_PBL_end(CS) if (.not.associated(CS)) return if (allocated(CS%ML_depth)) deallocate(CS%ML_depth) - if (allocated(CS%ML_depth2)) deallocate(CS%ML_depth2) + if (allocated(CS%ML_depth2)) deallocate(CS%ML_depth2) if (allocated(CS%diag_TKE_wind)) deallocate(CS%diag_TKE_wind) if (allocated(CS%diag_TKE_MKE)) deallocate(CS%diag_TKE_MKE) if (allocated(CS%diag_TKE_conv)) deallocate(CS%diag_TKE_conv) From 143184cdd28a5bf8d0c3e1dac7c3e78b478e45e0 Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Fri, 30 Sep 2016 08:44:51 -0400 Subject: [PATCH 07/14] Dox: fixed clipping of indexing images - @kshedstrom noted the images I generated were clipped Todo: - Commit scripts for generating images --- .images/Horizontal_NE_indexing_nonsym.png | Bin 45889 -> 47404 bytes .images/Horizontal_NE_indexing_sym.png | Bin 49605 -> 51285 bytes 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .images/Horizontal_NE_indexing_nonsym.png mode change 100755 => 100644 .images/Horizontal_NE_indexing_sym.png diff --git a/.images/Horizontal_NE_indexing_nonsym.png b/.images/Horizontal_NE_indexing_nonsym.png old mode 100755 new mode 100644 index 446700174822cd3a86bbae3fdb459254abb0a737..6316a64e7a4d9fd65d1ce6b63671d333c58d96d0 GIT binary patch literal 47404 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%0D6eP(Y^^j+FsDM>%QH0mzu0wzhqOPlFI2Y z?rZa{&WzrqtbCc+YiD<*)C1RxYU1Ym6m&z3h$9W>xjugVsz)5b!3Nib+&3V;#$&1E zzAOEScs2*N%5DI9w6#egS!zv^xj8f17DcpRGwbHHnIL`5zwAe~*T-kdvk(19EyBQM zX~esdW63Ax_`uZFl_mH?Nsuw_&Ye5ZaX*M!WWdkyb;gU=uXjUI1j>z4k{s?{Ku@&Z zhbOOo5^H+h%a@FV_h2;@oCbzb`Zl1AG>Kk2K`j3s4{?IiXTb0|aW;Pb7(7FCessTm z{`4vP{{6L@O&g*}auIALz43LiR>-rzDOE}bHtGGRei{3~n>v(yK2UL@q1@q9Q{gurt477%4BFpf+|iO8m+B5ApinU?#~9 zsVC>l)`cl9_qpD>m9BM{gAo#^zrQnE*h-|y9%96iMSIzR7DqoP4^JJ+ejF{A zE`Gu)E~*rKhbVxT=VA58|Mn3Gx003 zE%I-0R3QwZ{}LC+42t5woq~}OmlwNoOH21n2~(1CEm0}rh=v5qo~C*l8IB&**B-yAo+d+od;{$6!+(eB+I)1`_h7@aF{_OD>)hIMZ z*kGp9@%0Hrq^Jn8H~<5ftSy?Gn@!C!mFpKhk+qW9z@HVEmnV83WFB-S=!Y_)HFav_ z^5NXvLs%y>HXcWhMrLIRN=Qc3S%@W(;)$rjTIbHqmHfC=jjKbyW@88S92`7w=#er} zKy^KII;A9V^GlEV1_7gICVTg4qOC$C*lZOiAXqk~dbb4jx5zU@bKZ7;-Ht4N$BrFh zPnK{9p@Y;{t`=6)a_8_M+8VdAv(H3FBb7tFrXT1vF<3+DxVrv^)L9xjz{c9zsF1}j z8|Ltv9eUs?ocm)JQ7SPZ-4)&s3tYkRgG8baxqP-_^1|`#)p5 Ba3TNz diff --git a/.images/Horizontal_NE_indexing_sym.png b/.images/Horizontal_NE_indexing_sym.png old mode 100755 new mode 100644 index 96ff5aa7bcd3e58cd01f82033ed8839dd1ead84f..c2aaa742acf0063153352d5f179aad48b393051d GIT binary patch literal 51285 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 )%4D>y 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 T#)3iwfj=E>eXT+btMLB^_v#(# From e061e6802efd9c5d8b4d443123e130464f72dec0 Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Fri, 30 Sep 2016 08:27:33 -0400 Subject: [PATCH 08/14] Doxygenized more of src/core - Also fixed all errors reported in doxygen.log for files in src/core and src/ALE --- .DoxygenLayout.xml | 10 +- .doxygen | 4 +- src/ALE/MOM_regridding.F90 | 2 +- src/core/MOM.F90 | 6 +- src/core/MOM_CoriolisAdv.F90 | 400 +++++++++++-------------- src/core/MOM_continuity.F90 | 188 ++++-------- src/core/MOM_continuity_PPM.F90 | 348 +++++++++------------ src/core/MOM_forcing_type.F90 | 30 +- src/core/MOM_grid.F90 | 11 +- src/core/MOM_open_boundary.F90 | 12 +- src/diagnostics/MOM_wave_speed.F90 | 270 ++++++----------- src/framework/_Horizontal_indexing.dox | 10 +- 12 files changed, 519 insertions(+), 772 deletions(-) diff --git a/.DoxygenLayout.xml b/.DoxygenLayout.xml index cddccea7db..d51eb5f6f0 100644 --- a/.DoxygenLayout.xml +++ b/.DoxygenLayout.xml @@ -1,17 +1,17 @@ - + - + - - + + - + diff --git a/.doxygen b/.doxygen index 4faf9f1d07..8b1e2aafab 100644 --- a/.doxygen +++ b/.doxygen @@ -107,7 +107,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = NO +REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -2028,7 +2028,7 @@ SEARCH_INCLUDES = YES # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = src/framework # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the diff --git a/src/ALE/MOM_regridding.F90 b/src/ALE/MOM_regridding.F90 index 0e9fca8edf..3b39e753a6 100644 --- a/src/ALE/MOM_regridding.F90 +++ b/src/ALE/MOM_regridding.F90 @@ -2870,7 +2870,7 @@ end subroutine regridding_memory_deallocation !! Most calculations in this module start with the coordinate at the bottom !! of the column set to -depth, and use a increasing value of coordinate with !! decreasing k. This is consistent with the rest of MOM6 that uses position, -!! f$z\f$ which is a negative quantity for most of the ocean. +!! \f$z\f$ which is a negative quantity for most of the ocean. !! !! A change in grid is define through a change in position of the interfaces: !! \f[ diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 131552a8e2..8c023adbac 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -3614,9 +3614,9 @@ end subroutine MOM_end !! * FRAZIL_HEAT_TENDENCY generally has 3d structure, since MOM6 frazil calculation checks the !! full ocean column. !! -!! * FRAZIL_HEAT_TENDENCY[k=@sum] = HFSIFRAZIL = column integrated frazil heating. +!! * FRAZIL_HEAT_TENDENCY[k=\@sum] = HFSIFRAZIL = column integrated frazil heating. !! -!! * HFDS = FRAZIL_HEAT_TENDENCY[k=@sum] + BOUNDARY_FORCING_HEAT_TENDENCY[k=@sum] +!! * HFDS = FRAZIL_HEAT_TENDENCY[k=\@sum] + BOUNDARY_FORCING_HEAT_TENDENCY[k=\@sum] !! !! Here is an example 2d heat budget (depth summed) diagnostic for MOM. !! @@ -3642,7 +3642,7 @@ end subroutine MOM_end !! * BOUNDARY_FORCING_SALT_TENDENCY generally has 3d structure, with k > 1 contributions from !! the case when layers are tiny, in which case MOM6 partitions tendencies into k > 1 layers. !! -!! * SFDSI = BOUNDARY_FORCING_SALT_TENDENCY[k=@sum] +!! * SFDSI = BOUNDARY_FORCING_SALT_TENDENCY[k=\@sum] !! !! Here is an example 2d salt budget (depth summed) diagnostic for MOM. !! diff --git a/src/core/MOM_CoriolisAdv.F90 b/src/core/MOM_CoriolisAdv.F90 index d53d1c9728..a175eeed2f 100644 --- a/src/core/MOM_CoriolisAdv.F90 +++ b/src/core/MOM_CoriolisAdv.F90 @@ -1,66 +1,9 @@ +!> Accelerations due to the Coriolis force and momentum advection module MOM_CoriolisAdv -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** - -!********+*********+*********+*********+*********+*********+*********+** -!* * -!* By Robert Hallberg, April 1994 - June 2002 * -!* * -!* This file contains the subroutine that calculates the time * -!* derivatives of the velocities due to Coriolis acceleration and * -!* momentum advection. This subroutine uses either a vorticity * -!* advection scheme from Arakawa and Hsu, Mon. Wea. Rev. 1990, or * -!* Sadourny's (JAS 1975) energy conserving scheme. Both have been * -!* modified to use general orthogonal coordinates as described in * -!* Arakawa and Lamb, Mon. Wea. Rev. 1981. Both schemes are second * -!* order accurate, and allow for vanishingly small layer thicknesses. * -!* The Arakawa and Hsu scheme globally conserves both total energy * -!* and potential enstrophy in the limit of nondivergent flow. * -!* Sadourny's energy conserving scheme conserves energy if the flow * -!* is nondivergent or centered difference thickness fluxes are used. * -!* * -!* Two sets of boundary conditions have been coded in the * -!* definition of relative vorticity. These are written as: * -!* NOSLIP defined (in spherical coordinates): * -!* relvort = dv/dx (east & west), with v = 0. * -!* relvort = -sec(Q) * d(u cos(Q))/dy (north & south), with u = 0. * -!* NOSLIP not defined (free slip): * -!* relvort = 0 (all boundaries) * -!* with Q temporarily defined as latitude. The free slip boundary * -!* condition is much more natural on a C-grid. * -!* * -!* Macros written all in capital letters are defined in MOM_memory.h. * -!* * -!* A small fragment of the grid is shown below: * -!* * -!* j+1 x ^ x ^ x At x: q, CoriolisBu * -!* j+1 > o > o > At ^: v, CAv, vh * -!* j x ^ x ^ x At >: u, CAu, uh, a, b, c, d * -!* j > o > o > At o: h, KE * -!* j-1 x ^ x ^ x * -!* i-1 i i+1 At x & ^: * -!* i i+1 At > & o: * -!* * -!* The boundaries always run through q grid points (x). * -!* * -!********+*********+*********+*********+*********+*********+*********+** + +! This file is part of MOM6. See LICENSE.md for the license. + +!> \author Robert Hallberg, April 1994 - June 2002 use MOM_diag_mediator, only : post_data, query_averaging_enabled, diag_ctrl use MOM_diag_mediator, only : register_diag_field, safe_alloc_ptr, time_type @@ -78,60 +21,54 @@ module MOM_CoriolisAdv #include +!> Control structure for mom_coriolisadv type, public :: CoriolisAdv_CS ; private - integer :: Coriolis_Scheme ! CORIOLIS_SCHEME selects the discretization for - ! the Coriolis terms. Valid values are: - ! SADOURNY75_ENERGY - Sadourny, 1975 - ! ARAKAWA_HSU90 - Arakawa & Hsu, 1990 - ! Energy & non-div. Enstrophy - ! ROBUST_ENSTRO - Pseudo-enstrophy scheme - ! SADOURNY75_ENSTRO - Sadourny, JAS 1975 - ! Enstrophy - ! ARAKAWA_LAMB81 - Arakawa & Lamb, MWR 1981 - ! Energy & Enstrophy - ! ARAKAWA_LAMB_BLEND - A blend of Arakawa & Lamb - ! with Arakawa & Hsu and - ! Sadourny energy. - ! The default, SADOURNY75_ENERGY, is the safest - ! choice when the deformation radius is poorly - ! resolved. - integer :: KE_Scheme ! KE_SCHEME selects the discretization for - ! the kinetic energy. Valid values are: - ! KE_ARAKAWA, KE_SIMPLE_GUDONOV, KE_GUDONOV - integer :: PV_Adv_Scheme ! PV_ADV_SCHEME selects the discretization for - ! PV advection. Valid values are: - ! PV_ADV_CENTERED - centered (aka Sadourny, 75) - ! PV_ADV_UPWIND1 - upwind, first order - real :: F_eff_max_blend ! The factor by which the maximum effective Coriolis - ! acceleration from any point can be increased when - ! blending different discretizations with the - ! ARAKAWA_LAMB_BLEND Coriolis scheme. This must be - ! greater than 2.0, and is 4.0 by default. - real :: wt_lin_blend ! A weighting value beyond which the blending between - ! Sadourny and Arakawa & Hsu goes linearly to 0. - ! This must be between 1 and 1e-15, often 1/8. - logical :: no_slip ! If true, no slip boundary conditions are used. - ! Otherwise free slip boundary conditions are assumed. - ! The implementation of the free slip boundary - ! conditions on a C-grid is much cleaner than the - ! no slip boundary conditions. The use of free slip - ! b.c.s is strongly encouraged. The no slip b.c.s - ! are not implemented with the biharmonic viscosity. - logical :: bound_Coriolis ! If true, the Coriolis terms at u points are - ! bounded by the four estimates of (f+rv)v from the - ! four neighboring v points, and similarly at v - ! points. This option would have no effect on the - ! SADOURNY75_ENERGY scheme if it were possible to - ! use centered difference thickness fluxes. - logical :: Coriolis_En_Dis ! If CORIOLIS_EN_DIS is defined, two estimates of - ! the thickness fluxes are used to estimate the - ! Coriolis term, and the one that dissipates energy - ! relative to the other one is used. This is only - ! available at present if Coriolis scheme is - ! SADOURNY75_ENERGY. - type(time_type), pointer :: Time ! A pointer to the ocean model's clock. - type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the - ! timing of diagnostic output. + integer :: Coriolis_Scheme !< Selects the discretization for the Coriolis terms. + !! Valid values are: + !! - SADOURNY75_ENERGY - Sadourny, 1975 + !! - ARAKAWA_HSU90 - Arakawa & Hsu, 1990, Energy & non-div. Enstrophy + !! - ROBUST_ENSTRO - Pseudo-enstrophy scheme + !! - SADOURNY75_ENSTRO - Sadourny, JAS 1975, Enstrophy + !! - ARAKAWA_LAMB81 - Arakawa & Lamb, MWR 1981, Energy & Enstrophy + !! - ARAKAWA_LAMB_BLEND - A blend of Arakawa & Lamb with Arakawa & Hsu and Sadourny energy. + !! The default, SADOURNY75_ENERGY, is the safest choice then the + !! deformation radius is poorly resolved. + integer :: KE_Scheme !< KE_SCHEME selects the discretization for + !! the kinetic energy. Valid values are: + !! KE_ARAKAWA, KE_SIMPLE_GUDONOV, KE_GUDONOV + integer :: PV_Adv_Scheme !< PV_ADV_SCHEME selects the discretization for PV advection + !! Valid values are: + !! - PV_ADV_CENTERED - centered (aka Sadourny, 75) + !! - PV_ADV_UPWIND1 - upwind, first order + real :: F_eff_max_blend !< The factor by which the maximum effective Coriolis + !! acceleration from any point can be increased when + !! blending different discretizations with the + !! ARAKAWA_LAMB_BLEND Coriolis scheme. This must be + !! greater than 2.0, and is 4.0 by default. + real :: wt_lin_blend !< A weighting value beyond which the blending between + !! Sadourny and Arakawa & Hsu goes linearly to 0. + !! This must be between 1 and 1e-15, often 1/8. + logical :: no_slip !< If true, no slip boundary conditions are used. + !! Otherwise free slip boundary conditions are assumed. + !! The implementation of the free slip boundary + !! conditions on a C-grid is much cleaner than the + !! no slip boundary conditions. The use of free slip + !! b.c.s is strongly encouraged. The no slip b.c.s + !! are not implemented with the biharmonic viscosity. + logical :: bound_Coriolis !< If true, the Coriolis terms at u points are + !! bounded by the four estimates of (f+rv)v from the + !! four neighboring v points, and similarly at v + !! points. This option would have no effect on the + !! SADOURNY75_ENERGY scheme if it were possible to + !! use centered difference thickness fluxes. + logical :: Coriolis_En_Dis !< If CORIOLIS_EN_DIS is defined, two estimates of + !! the thickness fluxes are used to estimate the + !! Coriolis term, and the one that dissipates energy + !! relative to the other one is used. This is only + !! available at present if Coriolis scheme is + !! SADOURNY75_ENERGY. + type(time_type), pointer :: Time !< A pointer to the ocean model's clock. + type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the timing of diagnostic output. integer :: id_rv = -1, id_PV = -1, id_gKEu = -1, id_gKEv = -1 integer :: id_rvxu = -1, id_rvxv = -1 end type CoriolisAdv_CS @@ -164,46 +101,23 @@ module MOM_CoriolisAdv contains +!> Calculates the Coriolis and momentum advection contributions to the acceleration. subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) - type(ocean_grid_type), intent(in) :: G - type(verticalGrid_type), intent(in) :: GV - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: CAu - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: CAv - type(ocean_OBC_type), pointer :: OBC - type(accel_diag_ptrs), intent(inout) :: AD - type(CoriolisAdv_CS), pointer :: CS -! This subroutine calculates the Coriolis and momentum advection -! contributions to the acceleration. -! -! Arguments: u - Zonal velocity, in m s-1. -! (in) v - Meridional velocity, in m s-1. -! (in) h - Layer thickness, in m or kg m-2. -! (in) uh - Volume flux through zonal faces = u*h*dy, m3 s-1 or kg s-1. -! (in) vh - Volume flux through meridional faces = v*h*dx, in units of -! m3 s-1 or kg s-1. -! (out) CAu - Zonal acceleration due to Coriolis and momentum -! advection terms, in m s-2. -! (out) CAv - Meridional acceleration due to Coriolis and -! momentum advection terms, in m s-2. -! (in) AD - A structure pointing to the various accelerations in -! the momentum equations. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! CoriolisAdv_init. -! -! To work, the following fields must be set outside of the usual -! is to ie range before this subroutine is called: -! v[is-1,ie+1,ie+2], u[is-1,ie+1], vh[ie+1], uh[is-1], and -! h[is-1,ie+1,ie+2]. -! In the y-direction, the following fields must be set: -! v[js-1,je+1], u[js-1,je+1,je+2], vh[js-1], uh[je+1], and -! h[js-1,je+1,je+2]. + type(ocean_grid_type), intent(in) :: G !< Ocen grid structure + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity (m/s) + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity (m/s) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh !< Zonal transport u*h*dy (m3/s or kg/s) + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh !< Meridional transport v*h*dx (m3/s or kg/s) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: CAu !< Zonal acceleration due to Coriolis + !! and momentum advection, in m/s2. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: CAv !< Meridional acceleration due to Coriolis + !! and momentum advection, in m/s2. + type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure + type(accel_diag_ptrs), intent(inout) :: AD !< Storage for acceleration diagnostics + type(CoriolisAdv_CS), pointer :: CS !< Control structure for MOM_CoriolisAdv + ! Local variables real, dimension(SZIB_(G),SZJB_(G)) :: & q, & ! Layer potential vorticity, in m-1 s-1. @@ -283,6 +197,14 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) real :: QUHeff,QVHeff ! More temporary variables, in m3 s-2 or kg s-2. integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz +! To work, the following fields must be set outside of the usual +! is to ie range before this subroutine is called: +! v[is-1,ie+1,ie+2], u[is-1,ie+1], vh[ie+1], uh[is-1], and +! h[is-1,ie+1,ie+2]. +! In the y-direction, the following fields must be set: +! v[js-1,je+1], u[js-1,je+1,je+2], vh[js-1], uh[je+1], and +! h[js-1,je+1,je+2]. + if (.not.associated(CS)) call MOM_error(FATAL, & "MOM_CoriolisAdv: Module must be initialized before it is used.") is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -311,10 +233,10 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) !$OMP do do k=1,nz -! Here the second order accurate layer potential vorticities, q, -! are calculated. hq is second order accurate in space. Relative -! vorticity is second order accurate everywhere with free slip b.c.s, -! but only first order accurate at boundaries with no slip b.c.s. + ! Here the second order accurate layer potential vorticities, q, + ! are calculated. hq is second order accurate in space. Relative + ! vorticity is second order accurate everywhere with free slip b.c.s, + ! but only first order accurate at boundaries with no slip b.c.s. do J=Jsq-1,Jeq+1 ; do I=Isq-1,Ieq+1 if (CS%no_slip ) then relative_vorticity = (2.0-G%mask2dBu(I,J)) * & @@ -361,9 +283,9 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) q2(I,J) = relative_vorticity * Ih enddo ; enddo -! a, b, c, and d are combinations of neighboring potential -! vorticities which form the Arakawa and Hsu vorticity advection -! scheme. All are defined at u grid points. + ! a, b, c, and d are combinations of neighboring potential + ! vorticities which form the Arakawa and Hsu vorticity advection + ! scheme. All are defined at u grid points. if (CS%Coriolis_Scheme == ARAKAWA_HSU90) then do j=Jsq,Jeq+1 @@ -480,12 +402,12 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) enddo ; enddo endif -! Calculate KE and the gradient of KE + ! Calculate KE and the gradient of KE call gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) -! Calculate the tendencies of zonal velocity due to the Coriolis -! force and momentum advection. On a Cartesian grid, this is -! CAu = q * vh - d(KE)/dx. + ! Calculate the tendencies of zonal velocity due to the Coriolis + ! force and momentum advection. On a Cartesian grid, this is + ! CAu = q * vh - d(KE)/dx. if (CS%Coriolis_Scheme == SADOURNY75_ENERGY) then if (CS%Coriolis_En_Dis) then ! Energy dissipating biased scheme, Hallberg 200x @@ -592,9 +514,9 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) enddo ; enddo -! Calculate the tendencies of meridional velocity due to the Coriolis -! force and momentum advection. On a Cartesian grid, this is -! CAv = - q * uh - d(KE)/dy. + ! Calculate the tendencies of meridional velocity due to the Coriolis + ! force and momentum advection. On a Cartesian grid, this is + ! CAv = - q * uh - d(KE)/dy. if (CS%Coriolis_Scheme == SADOURNY75_ENERGY) then if (CS%Coriolis_En_Dis) then ! Energy dissipating biased scheme, Hallberg 200x @@ -698,7 +620,7 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) enddo ; enddo if (ASSOCIATED(AD%rv_x_u) .or. ASSOCIATED(AD%rv_x_v)) then -! Calculate the Coriolis-like acceleration due to relative vorticity. + ! Calculate the Coriolis-like acceleration due to relative vorticity. if (CS%Coriolis_Scheme == SADOURNY75_ENERGY) then if (ASSOCIATED(AD%rv_x_u)) then do J=Jsq,Jeq ; do i=is,ie @@ -741,8 +663,7 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) enddo ! k-loop. !$OMP end parallel -! Here the various Coriolis-related derived quantities are offered -! for averaging. + ! Here the various Coriolis-related derived quantities are offered for averaging. if (query_averaging_enabled(CS%diag)) then if (CS%id_rv > 0) call post_data(CS%id_rv, RV, CS%diag) if (CS%id_PV > 0) call post_data(CS%id_PV, PV, CS%diag) @@ -754,38 +675,24 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) end subroutine CorAdCalc -! ========================================================================================= +!> Calculates the acceleration due to the gradient of kinetic energy. subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) - type(ocean_grid_type), intent(in) :: G - real, dimension(SZIB_(G),SZJ_(G) ,SZK_(G)), intent(in) :: u - real, dimension(SZI_(G) ,SZJB_(G),SZK_(G)), intent(in) :: v - real, dimension(SZI_(G) ,SZJ_(G) ,SZK_(G)), intent(in) :: h - real, dimension(SZIB_(G),SZJ_(G) ,SZK_(G)), intent(in) :: uh - real, dimension(SZI_(G),SZJB_(G) ,SZK_(G)), intent(in) :: vh - real, dimension(SZI_(G) ,SZJ_(G) ), intent(out) :: KE - real, dimension(SZIB_(G),SZJ_(G) ), intent(out) :: KEx - real, dimension(SZI_(G) ,SZJB_(G)), intent(out) :: KEy - integer, intent(in) :: k - type(ocean_OBC_type), pointer :: OBC - type(CoriolisAdv_CS), pointer :: CS -! This subroutine calculates the acceleration due to the gradient of kinetic energy. -! -! Arguments: u - Zonal velocity, in m s-1. -! (in) v - Meridional velocity, in m s-1. -! (in) h - Layer thickness, in m. -! (in) uh - Volume flux through zonal faces = u*h*dy, m3 s-1. -! (in) vh - Volume flux through meridional faces = v*h*dx, in m3 s-1. -! (out) KE - Kinetic energy used by s/r, in m2 s-2. -! (out) KEx - Zonal acceleration due to Coriolis and momentum -! advection terms, in m s-2. -! (out) KEy - Meridional acceleration due to Coriolis and -! momentum advection terms, in m s-2. -! (in) k - layer number -! (in) G - The ocean's grid structure. -! (in) CS - The control structure returned by a previous call to -! CoriolisAdv_init. - + type(ocean_grid_type), intent(in) :: G !< Ocen grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity (m/s) + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity (m/s) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh !< Zonal transport u*h*dy (m3/s or kg/s) + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh !< Meridional transport v*h*dx (m3/s or kg/s) + real, dimension(SZI_(G) ,SZJ_(G) ), intent(out) :: KE !< Kinetic energy (m2/s2) + real, dimension(SZIB_(G),SZJ_(G) ), intent(out) :: KEx !< Zonal acceleration due to kinetic + !! energy gradient (m/s2) + real, dimension(SZI_(G) ,SZJB_(G)), intent(out) :: KEy !< Meridional acceleration due to kinetic + !! energy gradient (m/s2) + integer, intent(in) :: k !< Layer number to calculate for + type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure + type(CoriolisAdv_CS), pointer :: CS !< Control structure for MOM_CoriolisAdv + ! Local variables real :: um, up, vm, vp ! Temporary variables with units of m s-1. real :: um2, up2, vm2, vp2 ! Temporary variables with units of m2 s-2. real :: um2a, up2a, vm2a, vp2a ! Temporary variables with units of m4 s-2. @@ -795,11 +702,11 @@ subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB -! Calculate KE (Kinetic energy for use in the -grad(KE) acceleration term). + ! Calculate KE (Kinetic energy for use in the -grad(KE) acceleration term). if (CS%KE_Scheme.eq.KE_ARAKAWA) then -! The following calculation of Kinetic energy includes the metric terms -! identified in Arakawa & Lamb 1982 as important for KE conservation. It -! also includes the possibility of partially-blocked tracer cell faces. + ! The following calculation of Kinetic energy includes the metric terms + ! identified in Arakawa & Lamb 1982 as important for KE conservation. It + ! also includes the possibility of partially-blocked tracer cell faces. do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 KE(i,j) = ( ( G%areaCu( I ,j)*(u( I ,j,k)*u( I ,j,k)) & +G%areaCu(I-1,j)*(u(I-1,j,k)*u(I-1,j,k)) ) & @@ -808,8 +715,8 @@ subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) )*0.25*G%IareaT(i,j) enddo ; enddo elseif (CS%KE_Scheme.eq.KE_SIMPLE_GUDONOV) then -! The following discretization of KE is based on the one-dimensinal Gudonov -! scheme which does not take into account any geometric factors + ! The following discretization of KE is based on the one-dimensinal Gudonov + ! scheme which does not take into account any geometric factors do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 up = 0.5*( u(I-1,j,k) + ABS( u(I-1,j,k) ) ) ; up2 = up*up um = 0.5*( u( I ,j,k) - ABS( u( I ,j,k) ) ) ; um2 = um*um @@ -818,8 +725,8 @@ subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) KE(i,j) = ( max(up2,um2) + max(vp2,vm2) ) *0.5 enddo ; enddo elseif (CS%KE_Scheme.eq.KE_GUDONOV) then -! The following discretization of KE is based on the one-dimensinal Gudonov -! scheme but has been adapted to take horizontal grid factors into account + ! The following discretization of KE is based on the one-dimensinal Gudonov + ! scheme but has been adapted to take horizontal grid factors into account do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 up = 0.5*( u(I-1,j,k) + ABS( u(I-1,j,k) ) ) ; up2a = up*up*G%areaCu(I-1,j) um = 0.5*( u( I ,j,k) - ABS( u( I ,j,k) ) ) ; um2a = um*um*G%areaCu( I ,j) @@ -829,12 +736,12 @@ subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) enddo ; enddo endif -! Term - d(KE)/dx. + ! Term - d(KE)/dx. do j=js,je ; do I=Isq,Ieq KEx(I,j) = (KE(i+1,j) - KE(i,j)) * G%IdxCu(i,j) enddo ; enddo -! Term - d(KE)/dy. + ! Term - d(KE)/dy. do J=Jsq,Jeq ; do i=is,ie KEy(i,J) = (KE(i,j+1) - KE(i,j)) * G%IdyCv(i,J) enddo ; enddo @@ -850,31 +757,22 @@ subroutine gradKE(u, v, h, uh, vh, KE, KEx, KEy, k, OBC, G, CS) end subroutine gradKE -! ========================================================================================= - +!> Initializes the control structure for coriolisadv_cs subroutine CoriolisAdv_init(Time, G, param_file, diag, AD, CS) - type(time_type), target, intent(in) :: Time - type(ocean_grid_type), intent(in) :: G - type(param_file_type), intent(in) :: param_file - type(diag_ctrl), target, intent(inout) :: diag - type(accel_diag_ptrs), target, intent(inout) :: AD - type(CoriolisAdv_CS), pointer :: CS -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (inout) AD - A structure pointing to the various accelerations in -! the momentum equations. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module - + type(time_type), target, intent(in) :: Time !< Current model time + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(param_file_type), intent(in) :: param_file !< Runtime parameter handles + type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure + type(accel_diag_ptrs), target, intent(inout) :: AD !< Strorage for acceleration diagnostics + type(CoriolisAdv_CS), pointer :: CS !< Control structure fro MOM_CoriolisAdv + ! Local variables ! This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mod = "MOM_CoriolisAdv" ! This module's name. character(len=20) :: tmpstr character(len=400) :: mesg integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, nz + isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed ; nz = G%ke IsdB = G%IsdB ; IedB = G%IedB ; JsdB = G%JsdB ; JedB = G%JedB @@ -1029,9 +927,51 @@ subroutine CoriolisAdv_init(Time, G, param_file, diag, AD, CS) end subroutine CoriolisAdv_init +!> Destructor for coriolisadv_cs subroutine CoriolisAdv_end(CS) - type(CoriolisAdv_CS), pointer :: CS + type(CoriolisAdv_CS), pointer :: CS !< Control structure fro MOM_CoriolisAdv deallocate(CS) end subroutine CoriolisAdv_end +!> \namespace mom_coriolisadv +!! +!! This file contains the subroutine that calculates the time +!! derivatives of the velocities due to Coriolis acceleration and +!! momentum advection. This subroutine uses either a vorticity +!! advection scheme from Arakawa and Hsu, Mon. Wea. Rev. 1990, or +!! Sadourny's (JAS 1975) energy conserving scheme. Both have been +!! modified to use general orthogonal coordinates as described in +!! Arakawa and Lamb, Mon. Wea. Rev. 1981. Both schemes are second +!! order accurate, and allow for vanishingly small layer thicknesses. +!! The Arakawa and Hsu scheme globally conserves both total energy +!! and potential enstrophy in the limit of nondivergent flow. +!! Sadourny's energy conserving scheme conserves energy if the flow +!! is nondivergent or centered difference thickness fluxes are used. +!! +!! Two sets of boundary conditions have been coded in the +!! definition of relative vorticity. These are written as: +!! NOSLIP defined (in spherical coordinates): +!! relvort = dv/dx (east & west), with v = 0. +!! relvort = -sec(Q) * d(u cos(Q))/dy (north & south), with u = 0. +!! +!! NOSLIP not defined (free slip): +!! relvort = 0 (all boundaries) +!! +!! with Q temporarily defined as latitude. The free slip boundary +!! condition is much more natural on a C-grid. +!! +!! A small fragment of the grid is shown below: +!! \verbatim +!! +!! j+1 x ^ x ^ x At x: q, CoriolisBu +!! j+1 > o > o > At ^: v, CAv, vh +!! j x ^ x ^ x At >: u, CAu, uh, a, b, c, d +!! j > o > o > At o: h, KE +!! j-1 x ^ x ^ x +!! i-1 i i+1 At x & ^: +!! i i+1 At > & o: +!! \endverbatim +!! +!! The boundaries always run through q grid points (x). + end module MOM_CoriolisAdv diff --git a/src/core/MOM_continuity.F90 b/src/core/MOM_continuity.F90 index 912dde87a7..0f068da864 100644 --- a/src/core/MOM_continuity.F90 +++ b/src/core/MOM_continuity.F90 @@ -1,44 +1,7 @@ +!> Solve the layer continuity equation. module MOM_continuity -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** - -!********+*********+*********+*********+*********+*********+*********+** -!* * -!* By Robert Hallberg and Alistair Adcroft, September 2006. * -!* * -!* This file contains the driver routine which selects which * -!* continuity solver will be called, based on run-time input. * -!* * -!* A small fragment of the grid is shown below: * -!* * -!* j+1 x ^ x ^ x At x: q * -!* j+1 > o > o > At ^: v, vh * -!* j x ^ x ^ x At >: u, uh * -!* j > o > o > At o: h, hin * -!* j-1 x ^ x ^ x * -!* i-1 i i+1 At x & ^: * -!* i i+1 At > & o: * -!* * -!* The boundaries always run through q grid points (x). * -!* * -!********+*********+*********+*********+*********+*********+*********+** + +! This file is part of MOM6. See LICENSE.md for the license. use MOM_continuity_PPM, only : continuity_PPM, continuity_PPM_init use MOM_continuity_PPM, only : continuity_PPM_end, continuity_PPM_CS @@ -57,85 +20,66 @@ module MOM_continuity public continuity, continuity_init, continuity_end -integer :: id_clock_pass, id_clock_vertvisc - +!> Control structure for mom_continuity type, public :: continuity_CS ; private - integer :: continuity_scheme ! CONTINUITY_SCHEME selects the discretization - ! for the continuity solver. Valid values are: - ! PPM - A directionally split peicewise - ! parabolic reconstruction solver. - ! The default, PPM, seems most appropriate for - ! use with our current time-splitting strategies. - type(continuity_PPM_CS), pointer :: PPM_CSp => NULL() + integer :: continuity_scheme !< Selects the discretization for the continuity solver. + !! Valid values are: + !! - PPM - A directionally split piecewise parabolic reconstruction solver. + !! The default, PPM, seems most appropriate for use with our current + !! time-splitting strategies. + type(continuity_PPM_CS), pointer :: PPM_CSp => NULL() !< Control structure for mom_continuity_ppm end type continuity_CS -integer, parameter :: PPM_SCHEME = 1 -character(len=20), parameter :: PPM_STRING = "PPM" +integer, parameter :: PPM_SCHEME = 1 !< Enumerated constant to select PPM +character(len=20), parameter :: PPM_STRING = "PPM" !< String to select PPM contains +!> Time steps the layer thicknesses, using a monotonically limited, directionally split PPM scheme, +!! based on Lin (1994). subroutine continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & visc_rem_u, visc_rem_v, u_cor, v_cor, & uhbt_aux, vhbt_aux, u_cor_aux, v_cor_aux, BT_cont) - type(ocean_grid_type), intent(inout) :: G - type(verticalGrid_type), intent(in) :: GV - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: hin - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: uh - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: vh - real, intent(in) :: dt - type(continuity_CS), pointer :: CS - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt - real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt - type(ocean_OBC_type), pointer, optional :: OBC - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in), optional :: visc_rem_u - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in), optional :: visc_rem_v - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux - real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt_aux - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout), optional :: u_cor_aux - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout), optional :: v_cor_aux - type(BT_cont_type), pointer, optional :: BT_cont -! This subroutine time steps the layer thicknesses, using a monotonically -! limit, directionally split PPM scheme, based on Lin (1994). - -! Arguments: u - Zonal velocity, in m s-1. -! (in) v - Meridional velocity, in m s-1. -! (in) hin - Initial layer thickness, in m. -! (out) h - Final layer thickness, in m. -! (out) uh - Volume flux through zonal faces = u*h*dy, m3 s-1. -! (out) vh - Volume flux through meridional faces = v*h*dx, -! in m3 s-1. -! (in) dt - Time increment in s. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! continuity_init. -! (in, opt) uhbt - The summed volume flux through zonal faces, m3 s-1. -! (in, opt) vhbt - The summed volume flux through meridional faces, m3 s-1. -! (in, opt) OBC - This open boundary condition type specifies whether, where, -! and what open boundary conditions are used. -! (in, opt) visc_rem_u - Both the fraction of the momentum originally in a -! (in, opt) visc_rem_v - layer that remains after a time-step of viscosity, -! and the fraction of a time-step's worth of a -! barotropic acceleration that a layer experiences -! after viscosity is applied, in the zonal (_u) and -! meridional (_v) directions. Nondimensional between -! 0 (at the bottom) and 1 (far above the bottom). -! (out, opt) u_cor - The zonal velocities that give uhbt as the depth- -! integrated transport, in m s-1. -! (out, opt) v_cor - The meridional velocities that give vhbt as the -! depth-integrated transport, in m s-1. -! (in, opt) uhbt_aux - A second set of summed volume fluxes through zonal -! (in, opt) vhbt_aux - and meridional faces, both in m3 s-1. -! (out, opt) u_cor_aux - The zonal and meridional velocities that give uhbt_aux -! (out, opt) v_cor_aux - and vhbt_aux as the depth-integrated transports, -! both in m s-1. -! (out, opt) BT_cont - A structure with elements that describe the effective -! open face areas as a function of barotropic flow. + type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure. + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< Zonal velocity, in m/s. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< Meridional velocity, in m/s. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: hin !< Initial layer thickness, in m or kg/m2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Final layer thickness, in m or kg/m2. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: uh !< Volume flux through zonal faces = + !! u*h*dy, in m3/s. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: vh !< Volume flux through meridional faces = + !! v*h*dx, in m3/s. + real, intent(in) :: dt !< Time increment, in s. + type(continuity_CS), pointer :: CS !< Control structure for mom_continuity. + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt !< The vertically summed volume + !! flux through zonal faces, in m3/s. + real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt !< The vertically summed volume + !! flux through meridional faces, in m3/s. + type(ocean_OBC_type), pointer, optional :: OBC !< Open boundaries control structure. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in), optional :: visc_rem_u !< Both the fraction of + !! zonal momentum that remains after a time-step of viscosity, and the fraction of a time-step's + !! worth of a barotropic acceleration that a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in), optional :: visc_rem_v !< Both the fraction of + !! meridional momentum that remains after a time-step of viscosity, and the fraction of a time-step's + !! worth of a barotropic acceleration that a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor !< The zonal velocities that + !! give uhbt as the depth-integrated transport, in m/s. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor !< The meridional velocities that + !! give vhbt as the depth-integrated transport, in m/s. + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux !< A second summed zonal + !! volume flux in m3/s. + real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt_aux !< A second summed meridional + !! volume flux in m3/s. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout), optional :: u_cor_aux !< The zonal velocities + !! that give uhbt_aux as the depth-integrated transport, in m/s. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout), optional :: v_cor_aux !< The meridional velocities + !! that give vhbt_aux as the depth-integrated transport, in m/s. + type(BT_cont_type), pointer, optional :: BT_cont !< A structure with elements + !! that describe the effective open face areas as a function of barotropic flow. + if (present(visc_rem_u) .neqv. present(visc_rem_v)) call MOM_error(FATAL, & "MOM_continuity: Either both visc_rem_u and visc_rem_v or neither"// & " one must be present in call to continuity.") @@ -163,21 +107,14 @@ subroutine continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & end subroutine continuity +!> Initializes continuity_cs subroutine continuity_init(Time, G, GV, param_file, diag, CS) - type(time_type), target, intent(in) :: Time - type(ocean_grid_type), intent(in) :: G - type(verticalGrid_type), intent(in) :: GV - type(param_file_type), intent(in) :: param_file - type(diag_ctrl), target, intent(inout) :: diag - type(continuity_CS), pointer :: CS -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module + type(time_type), target, intent(in) :: Time !< Current model time. + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. + type(param_file_type), intent(in) :: param_file !< Parameter file handles. + type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure. + type(continuity_CS), pointer :: CS !< Control structure for mom_continuity. ! This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mod = "MOM_continuity" ! This module's name. @@ -215,8 +152,9 @@ subroutine continuity_init(Time, G, GV, param_file, diag, CS) end subroutine continuity_init +!> Destructor for continuity_cs. subroutine continuity_end(CS) - type(continuity_CS), pointer :: CS + type(continuity_CS), pointer :: CS !< Control structure for mom_continuity. if (CS%continuity_scheme == PPM_SCHEME) then call continuity_PPM_end(CS%PPM_CSp) diff --git a/src/core/MOM_continuity_PPM.F90 b/src/core/MOM_continuity_PPM.F90 index a0097250cb..46820a7889 100644 --- a/src/core/MOM_continuity_PPM.F90 +++ b/src/core/MOM_continuity_PPM.F90 @@ -1,23 +1,7 @@ +!> Solve the layer continuity equation using the PPM method for layer fluxes. module MOM_continuity_PPM -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** + +! This file is part of MOM6. See LICENSE.md for the license. use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end, CLOCK_ROUTINE use MOM_diag_mediator, only : time_type, diag_ctrl @@ -37,56 +21,60 @@ module MOM_continuity_PPM integer :: id_clock_update, id_clock_correct +!> Control structure for mom_continuity_ppm type, public :: continuity_PPM_CS ; private - type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the - ! timing of diagnostic output. - logical :: upwind_1st ! If true, use a first-order upwind scheme. - logical :: monotonic ! If true, use the Colella & Woodward monotonic - ! limiter; otherwise use a simple positive - ! definite limiter. - logical :: simple_2nd ! If true, use a simple second order (arithmetic - ! mean) interpolation of the edge values instead - ! of the higher order interpolation. - real :: tol_eta ! The tolerance for free-surface height - ! discrepancies between the barotropic solution and - ! the sum of the layer thicknesses, in m. - real :: tol_vel ! The tolerance for barotropic velocity - ! discrepancies between the barotropic solution and - ! the sum of the layer thicknesses, in m s-1. - real :: tol_eta_aux ! The tolerance for free-surface height - ! discrepancies between the barotropic solution and - ! the sum of the layer thicknesses when calculating - ! the auxiliary corrected velocities, in m. - real :: CFL_limit_adjust ! The maximum CFL of the adjusted velocities, ND. - logical :: aggress_adjust ! If true, allow the adjusted velocities to have a - ! relative CFL change up to 0.5. False by default. - logical :: vol_CFL ! If true, use the ratio of the open face lengths - ! to the tracer cell areas when estimating CFL - ! numbers. Without aggress_adjust, the default is - ! false; it is always true with. - logical :: better_iter ! If true, stop corrective iterations using a - ! velocity-based criterion and only stop if the - ! iteration is better than all predecessors. - logical :: use_visc_rem_max ! If true, use more appropriate limiting bounds - ! for corrections in strongly viscous columns. - logical :: marginal_faces ! If true, use the marginal face areas from the - ! continuity solver for use as the weights in the - ! barotropic solver. Otherwise use the transport - ! averaged areas. + type(diag_ctrl), pointer :: diag !< Diagnostics control structure. + logical :: upwind_1st !< If true, use a first-order upwind scheme. + logical :: monotonic !< If true, use the Colella & Woodward monotonic + !! limiter; otherwise use a simple positive + !! definite limiter. + logical :: simple_2nd !< If true, use a simple second order (arithmetic + !! mean) interpolation of the edge values instead + !! of the higher order interpolation. + real :: tol_eta !< The tolerance for free-surface height + !! discrepancies between the barotropic solution and + !! the sum of the layer thicknesses, in m. + real :: tol_vel !< The tolerance for barotropic velocity + !! discrepancies between the barotropic solution and + !! the sum of the layer thicknesses, in m s-1. + real :: tol_eta_aux !< The tolerance for free-surface height + !! discrepancies between the barotropic solution and + !! the sum of the layer thicknesses when calculating + !! the auxiliary corrected velocities, in m. + real :: CFL_limit_adjust !< The maximum CFL of the adjusted velocities, ND. + logical :: aggress_adjust !< If true, allow the adjusted velocities to have a + !! relative CFL change up to 0.5. False by default. + logical :: vol_CFL !< If true, use the ratio of the open face lengths + !! to the tracer cell areas when estimating CFL + !! numbers. Without aggress_adjust, the default is + !! false; it is always true with. + logical :: better_iter !< If true, stop corrective iterations using a + !! velocity-based criterion and only stop if the + !! iteration is better than all predecessors. + logical :: use_visc_rem_max !< If true, use more appropriate limiting bounds + !! for corrections in strongly viscous columns. + logical :: marginal_faces !< If true, use the marginal face areas from the + !! continuity solver for use as the weights in the + !! barotropic solver. Otherwise use the transport + !! averaged areas. end type continuity_PPM_CS +!> A container for loop bounds type :: loop_bounds_type ; private + !>@{ + !! Loop bounds integer :: ish, ieh, jsh, jeh + !>@} end type loop_bounds_type contains -!> This subroutine time steps the layer thicknesses, using a monotonically -!! limit, directionally split PPM scheme, based on Lin (1994). In the following -!! documentation, H is used for the units of thickness (usually m or kg m-2.) +!> Time steps the layer thicknesses, using a monotonically limit, directionally split PPM scheme, +!! based on Lin (1994). subroutine continuity_PPM(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & visc_rem_u, visc_rem_v, u_cor, v_cor, & uhbt_aux, vhbt_aux, u_cor_aux, v_cor_aux, BT_cont) + ! In the following documentation, H is used for the units of thickness (usually m or kg m-2.) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(continuity_PPM_CS), pointer :: CS !< Module's control structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< Zonal velocity, in m s-1. @@ -99,42 +87,37 @@ subroutine continuity_PPM(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, !! v*h*dx, H m2 s-1. real, intent(in) :: dt !< Time increment in s. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt !< - !! The summed volume flux through zonal faces, H m2 s-1. - real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt !< - !! The summed volume flux through meridional faces, H m2 s-1. - type(ocean_OBC_type), pointer, optional :: OBC !< - !! This open boundary condition type specifies whether, where, - !! and what open boundary conditions are used. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in), optional :: visc_rem_u !< - !! Both the fraction of the momentum originally in a layer that remains after a time-step - !! of viscosity, and the fraction of a time-step's worth of a barotropic acceleration that - !! a layer experiences after viscosity is applied, in the zonal (_u) - !! direction. Nondimensional between 0 (at the bottom) and 1 (far above the bottom). - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in), optional :: visc_rem_v !< - !! Same as above for meridional direction. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor !< - !! The zonal velocities that give uhbt as the depth- - !! integrated transport, in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor !< - !! The meridional velocities that give vhbt as the - !! depth-integrated transport, in m s-1. - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux !< - !! A second set of summed volume fluxes through zonal faces, in H m2 s-1. - real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt_aux !< - !! A second set of summed volume fluxes through meridional faces, in H m2 s-1. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor_aux !< - !! The zonal velocities that give uhbt_aux as the - !! depth-integrated transports, in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor_aux !< - !! The meridional velocities that give vhbt_aux as the - !! depth-integrated transports, in m s-1. - type(BT_cont_type), pointer, optional :: BT_cont !< - !! A structure with elements that describe the effective - !! open face areas as a function of barotropic flow. - - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - h_input ! Left and right face thicknesses, in H. + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt + !< The summed volume flux through zonal faces, H m2 s-1. + real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt + !< The summed volume flux through meridional faces, H m2 s-1. + type(ocean_OBC_type), pointer, optional :: OBC !< Open boundaries control structure. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in), optional :: visc_rem_u + !< The fraction of zonal momentum originally in a layer that remains after a time-step + !! of viscosity, and the fraction of a time-step's worth of a barotropic acceleration that + !! a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in), optional :: visc_rem_v + !< The fraction of meridional momentum originally in a layer that remains after a time-step + !! of viscosity, and the fraction of a time-step's worth of a barotropic acceleration that + !! a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor + !< The zonal velocities that give uhbt as the depth-integrated transport, in m s-1. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor + !< The meridional velocities that give vhbt as the depth-integrated transport, in m s-1. + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux + !< A second set of summed volume fluxes through zonal faces, in H m2 s-1. + real, dimension(SZI_(G),SZJB_(G)), intent(in), optional :: vhbt_aux + !< A second set of summed volume fluxes through meridional faces, in H m2 s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor_aux + !< The zonal velocities that give uhbt_aux as the depth-integrated transports, in m s-1. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out), optional :: v_cor_aux + !< The meridional velocities that give vhbt_aux as the depth-integrated transports, in m s-1. + type(BT_cont_type), pointer, optional :: BT_cont !< A structure with + !! elements that describe the effective open face areas as a function of barotropic flow. + ! Local variables + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_input ! Left and right face thicknesses, in H. real :: h_min type(loop_bounds_type) :: LB integer :: is, ie, js, je, nz, stencil @@ -321,8 +304,7 @@ subroutine continuity_PPM(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, end subroutine continuity_PPM -!> This subroutine calculates the mass or volume fluxes through the zonal -!! faces, and other related quantities. +!> Calculates the mass or volume fluxes through the zonal faces, and other related quantities. subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & visc_rem_u, u_cor, uhbt_aux, u_cor_aux, BT_cont) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. @@ -335,35 +317,28 @@ subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & real, intent(in) :: dt !< Time increment in s. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. type(loop_bounds_type), intent(in) :: LB !< Loop bounds structure. - type(ocean_OBC_type), pointer, optional :: OBC !< - !! This open boundary condition type specifies whether, where, - !! and what open boundary conditions are used. + type(ocean_OBC_type), pointer, optional :: OBC !< Open boundaries control structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in), optional :: visc_rem_u !< - !! Both the fraction of the momentum originally in a - !! layer that remains after a time-step of viscosity, - !! and the fraction of a time-step's worth of a - !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between - !! 0 (at the bottom) and 1 (far above the bottom). - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt !< - !! The summed volume flux through zonal faces, H m2 s-1. - real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux !< - !! A second set of summed volume fluxes through zonal - !! faces, in H m2 s-1. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor !< - !! The zonal velocitiess (u with a barotropic correction) + !< The fraction of zonal momentum originally in a layer that remains after a time-step + !! of viscosity, and the fraction of a time-step's worth of a barotropic acceleration that + !! a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt + !< The summed volume flux through zonal faces, H m2 s-1. + real, dimension(SZIB_(G),SZJ_(G)), intent(in), optional :: uhbt_aux + !< A second set of summed volume fluxes through zonal faces, in H m2 s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor + !< The zonal velocitiess (u with a barotropic correction) !! that give uhbt as the depth-integrated transport, m s-1. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor_aux !< - !! The zonal velocities (u with a barotropic correction) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out), optional :: u_cor_aux + !< The zonal velocities (u with a barotropic correction) !! that give uhbt_aux as the depth-integrated transports, in m s-1. type(BT_cont_type), pointer, optional :: BT_cont !< - !! A structure with elements that describe the effective + !< A structure with elements that describe the effective !! open face areas as a function of barotropic flow. - - real, dimension(SZIB_(G),SZK_(G)) :: & - duhdu ! Partial derivative of uh with u, in H m. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - h_L, h_R ! Left and right face thicknesses, in H. + ! Local variables + real, dimension(SZIB_(G),SZK_(G)) :: duhdu ! Partial derivative of uh with u, in H m. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_L, h_R ! Left and right face thicknesses, in H. real, dimension(SZIB_(G)) :: & du, & ! Corrective barotropic change in the velocity, in m s-1. du_min_CFL, & ! Min/max limits on du correction @@ -611,16 +586,16 @@ subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & end subroutine zonal_mass_flux -!> This subroutines evaluates the zonal mass or volume fluxes in a layer. +!> Evaluates the zonal mass or volume fluxes in a layer. subroutine zonal_flux_layer(u, h, h_L, h_R, uh, duhdu, visc_rem, dt, G, j, & ish, ieh, do_I, vol_CFL) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. real, dimension(SZIB_(G)), intent(in) :: u !< Zonal velocity, in m s-1. real, dimension(SZIB_(G)), intent(in) :: visc_rem !< Both the fraction of the - !! momentum originally in a layer that remains after a time-step - !! of viscosity, and the fraction of a time-step's worth of a barotropic - !! acceleration that a layer experiences after viscosity is applied. - !! Nondimensional between 0 (at the bottom) and 1 (far above the bottom). + !! momentum originally in a layer that remains after a time-step + !! of viscosity, and the fraction of a time-step's worth of a barotropic + !! acceleration that a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G)), intent(in) :: h !< Layer thickness, in H. real, dimension(SZI_(G)), intent(in) :: h_L !< Left thickness, in H. real, dimension(SZI_(G)), intent(in) :: h_R !< Right thickness, in H. @@ -634,8 +609,8 @@ subroutine zonal_flux_layer(u, h, h_L, h_R, uh, duhdu, visc_rem, dt, G, j, & integer, intent(in) :: ieh !< End of index range. logical, dimension(SZIB_(G)), intent(in) :: do_I !< Which i values to work on. logical, intent(in) :: vol_CFL !< If true, rescale the - !! ratio of face areas to the cell areas when estimating the CFL number. - + !! ratio of face areas to the cell areas when estimating the CFL number. + ! Local variables real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. @@ -667,8 +642,7 @@ subroutine zonal_flux_layer(u, h, h_L, h_R, uh, duhdu, visc_rem, dt, G, j, & end subroutine zonal_flux_layer -!> This subroutines sets the effective interface thickness at each zonal -!! velocity point. +!> Sets the effective interface thickness at each zonal velocity point. subroutine zonal_face_thickness(u, h, h_L, h_R, h_u, dt, G, LB, vol_CFL, & marginal, visc_rem_u) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. @@ -694,9 +668,9 @@ subroutine zonal_face_thickness(u, h, h_L, h_R, h_u, dt, G, LB, vol_CFL, & !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). - + ! Local variables real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. @@ -745,7 +719,7 @@ subroutine zonal_face_thickness(u, h, h_L, h_R, h_u, dt, G, LB, vol_CFL, & end subroutine zonal_face_thickness -!> This subroutine returns the barotropic velocity adjustment that gives the +!> Returns the barotropic velocity adjustment that gives the !! desired barotropic (layer-summed) transport. subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & du, du_max_CFL, du_min_CFL, dt, G, CS, visc_rem, & @@ -763,7 +737,7 @@ subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G)), intent(in), optional :: uhbt !< !! The summed volume flux through zonal faces, H m2 s-1. @@ -783,13 +757,13 @@ subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. logical, dimension(SZIB_(G)), intent(in) :: do_I_in !< - !! A logical flag indiciating which I values to work on. + !! A logical flag indicating which I values to work on. logical, intent(in), optional :: full_precision !< !! A flag indicating how carefully to iterate. The !! default is .true. (more accurate). real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout), optional :: uh_3d !< !! Volume flux through zonal faces = u*h*dy, H m2 s-1. - + ! Local variables real, dimension(SZIB_(G),SZK_(G)) :: & uh_aux, & ! An auxiliary zonal volume flux, in H m s-1. duhdu ! Partial derivative of uh with u, in H m. @@ -908,9 +882,8 @@ subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & end subroutine zonal_flux_adjust -!> This subroutine sets of a structure that describes the zonal barotropic -!! volume or mass fluxes as a function of barotropic flow to agree closely with -!! the sum of the layer's transports. +!> Sets a structure that describes the zonal barotropic volume or mass fluxes as a +!! function of barotropic flow to agree closely with the sum of the layer's transports. subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, & du_max_CFL, du_min_CFL, dt, G, CS, visc_rem, & visc_rem_max, j, ish, ieh, do_I) @@ -940,15 +913,15 @@ subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G)), intent(in) :: visc_rem_max !< Maximum allowable visc_rem. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. logical, dimension(SZIB_(G)), intent(in) :: do_I !< - !! A logical flag indiciating which I values to work on. - + !! A logical flag indicating which I values to work on. + ! Local variables real, dimension(SZIB_(G)) :: & du0, & ! The barotropic velocity increment that gives 0 transport, m s-1. duL, duR, & ! The barotropic velocity increments that give the westerly @@ -1080,8 +1053,7 @@ subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, end subroutine set_zonal_BT_cont -!> This subroutine calculates the mass or volume fluxes through the meridional -!! faces, and other related quantities. +!> Calculates the mass or volume fluxes through the meridional faces, and other related quantities. subroutine meridional_mass_flux(v, h_in, vh, dt, G, GV, CS, LB, vhbt, OBC, & visc_rem_v, v_cor, vhbt_aux, v_cor_aux, BT_cont) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. @@ -1117,7 +1089,7 @@ subroutine meridional_mass_flux(v, h_in, vh, dt, G, GV, CS, LB, vhbt, OBC, & !! that give vhbt_aux as the depth-integrated transports, in m s-1. type(BT_cont_type), pointer, optional :: BT_cont !< !! A structure with elements that describe the effective - + ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & dvhdv ! Partial derivative of vh with v, in m2. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & @@ -1366,16 +1338,16 @@ subroutine meridional_mass_flux(v, h_in, vh, dt, G, GV, CS, LB, vhbt, OBC, & end subroutine meridional_mass_flux -!> This subroutines evaluates the meridional mass or volume fluxes in a layer. +!> Evaluates the meridional mass or volume fluxes in a layer. subroutine merid_flux_layer(v, h, h_L, h_R, vh, dvhdv, visc_rem, dt, G, J, & ish, ieh, do_I, vol_CFL) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. real, dimension(SZI_(G)), intent(in) :: v !< Meridional velocity, in m s-1. real, dimension(SZI_(G)), intent(in) :: visc_rem !< Both the fraction of the - !! momentum originally in a layer that remains after a time-step - !! of viscosity, and the fraction of a time-step's worth of a barotropic - !! acceleration that a layer experiences after viscosity is applied. - !! Nondimensional between 0 (at the bottom) and 1 (far above the bottom). + !! momentum originally in a layer that remains after a time-step + !! of viscosity, and the fraction of a time-step's worth of a barotropic + !! acceleration that a layer experiences after viscosity is applied. + !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h !< Layer thickness used to !! calculate fluxes, in H. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_L !< Left thickness in the @@ -1392,8 +1364,8 @@ subroutine merid_flux_layer(v, h, h_L, h_R, vh, dvhdv, visc_rem, dt, G, J, & integer, intent(in) :: ieh !< End of index range. logical, dimension(SZI_(G)), intent(in) :: do_I !< Which i values to work on. logical, intent(in) :: vol_CFL !< If true, rescale the - !! ratio of face areas to the cell areas when estimating the CFL number. - + !! ratio of face areas to the cell areas when estimating the CFL number. + ! Local variables real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. @@ -1426,8 +1398,7 @@ subroutine merid_flux_layer(v, h, h_L, h_R, vh, dvhdv, visc_rem, dt, G, J, & end subroutine merid_flux_layer -!> This subroutines sets the effective interface thickness at each meridional -!! velocity point. +!> Sets the effective interface thickness at each meridional velocity point. subroutine merid_face_thickness(v, h, h_L, h_R, h_v, dt, G, LB, vol_CFL, & marginal, visc_rem_v) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. @@ -1453,9 +1424,9 @@ subroutine merid_face_thickness(v, h, h_L, h_R, h_v, dt, G, LB, vol_CFL, & !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). - + ! Local variables real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. @@ -1506,8 +1477,7 @@ subroutine merid_face_thickness(v, h, h_L, h_R, h_v, dt, G, LB, vol_CFL, & end subroutine merid_face_thickness -!> This subroutine returns the barotropic velocity adjustment that gives the -!! desired barotropic (layer-summed) transport. +!> Returns the barotropic velocity adjustment that gives the desired barotropic (layer-summed) transport. subroutine meridional_flux_adjust(v, h_in, h_L, h_R, vhbt, vh_tot_0, dvhdv_tot_0, & dv, dv_max_CFL, dv_min_CFL, dt, G, CS, visc_rem, & j, ish, ieh, do_I_in, full_precision, vh_3d) @@ -1524,7 +1494,7 @@ subroutine meridional_flux_adjust(v, h_in, h_L, h_R, vhbt, vh_tot_0, dvhdv_tot_0 !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G)), intent(in), optional :: vhbt !< !! The summed volume flux through meridional faces, H m2 s-1. @@ -1544,15 +1514,15 @@ subroutine meridional_flux_adjust(v, h_in, h_L, h_R, vhbt, vh_tot_0, dvhdv_tot_0 integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. logical, dimension(SZI_(G)), intent(in) :: do_I_in !< - !! A logical flag indiciating which I values to work on. + !! A logical flag indicating which I values to work on. logical, intent(in), optional :: full_precision !< !! full_precision - A flag indicating how carefully to iterate. The !! default is .true. (more accurate). real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout), optional :: vh_3d !< !! Volume flux through meridional faces = v*h*dx, H m2 s-1. - + ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & - vh_aux, & ! An auxiliary meridonal volume flux, in H m s-1. + vh_aux, & ! An auxiliary meridional volume flux, in H m s-1. dvhdv ! Partial derivative of vh with v, in H m. real, dimension(SZI_(G)) :: & vh_err, & ! Difference between vhbt and the summed vh, in H m2 s-1. @@ -1669,9 +1639,8 @@ subroutine meridional_flux_adjust(v, h_in, h_L, h_R, vhbt, vh_tot_0, dvhdv_tot_0 end subroutine meridional_flux_adjust -!> This subroutine sets of a structure that describes the meridional -!! barotropic volume or mass fluxes as a function of barotropic flow to agree -!! closely with the sum of the layer's transports. +!> Sets of a structure that describes the meridional barotropic volume or mass fluxes as a +!! function of barotropic flow to agree closely with the sum of the layer's transports. subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, & dv_max_CFL, dv_min_CFL, dt, G, CS, visc_rem, & visc_rem_max, j, ish, ieh, do_I) @@ -1701,15 +1670,15 @@ subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, !! layer that remains after a time-step of viscosity, !! and the fraction of a time-step's worth of a !! barotropic acceleration that a layer experiences - !! after viscosity is applied. Nondimensional between + !! after viscosity is applied. Non-dimensional between !! 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G)), intent(in) :: visc_rem_max !< Maximum allowable visc_rem. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. logical, dimension(SZI_(G)), intent(in) :: do_I !< - !! A logical flag indiciating which I values to work on. - + !! A logical flag indicating which I values to work on. + ! Local variables real, dimension(SZI_(G)) :: & dv0, & ! The barotropic velocity increment that gives 0 transport, m s-1. dvL, dvR, & ! The barotropic velocity increments that give the southerly @@ -1838,7 +1807,7 @@ subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, end subroutine set_merid_BT_cont -!> This subroutine calculates left/right edge values for PPM reconstruction. +!> Calculates left/right edge values for PPM reconstruction. subroutine PPM_reconstruction_x(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_2nd) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. @@ -1856,7 +1825,7 @@ subroutine PPM_reconstruction_x(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_ !! arithmetic mean thicknesses as the default edge values !! for a simple 2nd order scheme. -! Local variables with useful mnemonic names. + ! Local variables with useful mnemonic names. real, dimension(SZI_(G),SZJ_(G)) :: slp ! The slopes. real, parameter :: oneSixth = 1./6. real :: h_ip1, h_im1 @@ -1929,7 +1898,7 @@ subroutine PPM_reconstruction_x(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_ return end subroutine PPM_reconstruction_x -!> This subroutine calculates left/right edge valus for PPM reconstruction. +!> Calculates left/right edge values for PPM reconstruction. subroutine PPM_reconstruction_y(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_2nd) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. @@ -1947,7 +1916,7 @@ subroutine PPM_reconstruction_y(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_ !! arithmetic mean thicknesses as the default edge values !! for a simple 2nd order scheme. -! Local variables with useful mnemonic names. + ! Local variables with useful mnemonic names. real, dimension(SZI_(G),SZJ_(G)) :: slp ! The slopes. real, parameter :: oneSixth = 1./6. real :: h_jp1, h_jm1 @@ -2077,7 +2046,7 @@ subroutine PPM_limit_CW84(h_in, h_L, h_R, G, iis, iie, jis, jie) integer, intent(in) :: jis !< Start of j index range. integer, intent(in) :: jie !< End of j index range. -! Local variables + ! Local variables real :: h_i, RLdiff, RLdiff2, RLmean, FunFac character(len=256) :: mesg integer :: i,j @@ -2101,7 +2070,7 @@ subroutine PPM_limit_CW84(h_in, h_L, h_R, G, iis, iie, jis, jie) return end subroutine PPM_limit_CW84 -!> Return the maxiumum ratio of a/b or maxrat. +!> Return the maximum ratio of a/b or maxrat. function ratio_max(a, b, maxrat) result(ratio) real, intent(in) :: a !< Numerator real, intent(in) :: b !< Denominator @@ -2115,7 +2084,7 @@ function ratio_max(a, b, maxrat) result(ratio) endif end function ratio_max -!> This include declares and sets the variable "version". +!> Initializes continuity_ppm_cs subroutine continuity_PPM_init(Time, G, GV, param_file, diag, CS) type(time_type), target, intent(in) :: Time !< Time increment in s. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. @@ -2125,7 +2094,7 @@ subroutine continuity_PPM_init(Time, G, GV, param_file, diag, CS) type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to !! regulate diagnostic output. type(continuity_PPM_CS), pointer :: CS !< Module's control structure. - +!> This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mod = "MOM_continuity_PPM" ! This module's name. @@ -2210,35 +2179,16 @@ subroutine continuity_PPM_init(Time, G, GV, param_file, diag, CS) end subroutine continuity_PPM_init -!> Deconstructor for CS object. +!> Destructor for continuity_ppm_cs subroutine continuity_PPM_end(CS) type(continuity_PPM_CS), pointer :: CS !< Module's control structure. deallocate(CS) end subroutine continuity_PPM_end -!> \class MOM_continuity_PPM -!!*******+*********+*********+*********+*********+*********+*********+** -!! * -!! By Robert Hallberg and Alistair Adcroft, September 2006 - . * -!! * -!! This program contains the subroutine that advects layer * -!! thickness. The scheme here uses a Piecewise-Parabolic method with * -!! a positive definite limiter. * -!! * -!! Macros written all in capital letters are defined in MOM_memory.h. * -!! * -!! A small fragment of the grid is shown below: * -!! * -!! j+1 x ^ x ^ x At x: q * -!! j+1 > o > o > At ^: v, vh * -!! j x ^ x ^ x At >: u, uh * -!! j > o > o > At o: h, hin * -!! j-1 x ^ x ^ x * -!! i-1 i i+1 At x & ^: * -!! i i+1 At > & o: * -!! * -!! The boundaries always run through q grid points (x). * -!! * -!!*******+*********+*********+*********+*********+*********+*********+** +!> \namespace mom_continuity_ppm +!! +!! This module contains the subroutines that advect layer +!! thickness. The scheme here uses a Piecewise-Parabolic method with +!! a positive definite limiter. end module MOM_continuity_PPM diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index 651eb3ee48..6356fb3965 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -628,7 +628,7 @@ subroutine extractFluxes2d(G, GV, fluxes, optics, nsw, dt, !! Units of net_heat are (K * H). real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_salt !< surface salt flux into the ocean accumulated !! over a time step (ppt * H) - real, dimension(:,:,:), intent(out) :: pen_SW_bnd !! penetrating shortwave flux, split into bands. + real, dimension(:,:,:), intent(out) :: pen_SW_bnd !< penetrating shortwave flux, split into bands. !! Units (deg K * H) & array size nsw x SZI_(G), !! where nsw=number of SW bands in pen_SW_bnd. !! This heat flux is not in net_heat. @@ -863,14 +863,13 @@ subroutine MOM_forcing_chksum(mesg, fluxes, G, haloshift) end subroutine MOM_forcing_chksum -!> Write out values of the fluxes arrays at the i,j location +!> Write out values of the fluxes arrays at the i,j location. This is a debugging tool. subroutine forcing_SinglePointPrint(fluxes, G, i, j, mesg) - - type(forcing), intent(in) :: fluxes !< fluxes type - type(ocean_grid_type), intent(in) :: G !< grid type - character(len=*), intent(in) :: mesg !< message - integer, intent(in) :: i, j !< horizontal indices - + type(forcing), intent(in) :: fluxes !< Fluxes type + type(ocean_grid_type), intent(in) :: G !< Grid type + character(len=*), intent(in) :: mesg !< Message + integer, intent(in) :: i !< i-index + integer, intent(in) :: j !< j-index write(0,'(2a)') 'MOM_forcing_type, forcing_SinglePointPrint: Called from ',mesg write(0,'(a,2es15.3)') 'MOM_forcing_type, forcing_SinglePointPrint: lon,lat = ',G%geoLonT(i,j),G%geoLatT(i,j) @@ -909,9 +908,10 @@ subroutine forcing_SinglePointPrint(fluxes, G, i, j, mesg) call locMsg(fluxes%heat_content_cond,'heat_content_massout') contains + !> Format and write a message depending on associated state of array subroutine locMsg(array,aname) - real, dimension(:,:), pointer :: array - character(len=*) :: aname + real, dimension(:,:), pointer :: array !< Array to write element from + character(len=*) :: aname !< Name of array if (associated(array)) then write(0,'(3a,es15.3)') 'MOM_forcing_type, forcing_SinglePointPrint: ',trim(aname),' = ',array(i,j) @@ -2142,7 +2142,7 @@ subroutine forcing_diagnostics(fluxes, state, dt, G, diag, handles) call post_data(handles%id_netFWGlobalScl, fluxes%netFWGlobalScl, diag) - ! remamining boundary terms ================================================== + ! remaining boundary terms ================================================== if ((handles%id_psurf > 0) .and. ASSOCIATED(fluxes%p_surf)) & call post_data(handles%id_psurf, fluxes%p_surf, diag) @@ -2224,9 +2224,13 @@ subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, p contains + !> Allocates and zeroes-out array. subroutine myAlloc(array, is, ie, js, je, flag) - real, dimension(:,:), pointer :: array - integer, intent(in) :: is, ie, js, je !< Bounds + real, dimension(:,:), pointer :: array !< Array to be allocated + integer, intent(in) :: is !< Start i-index + integer, intent(in) :: ie !< End i-index + integer, intent(in) :: js !< Start j-index + integer, intent(in) :: je !< End j-index logical, optional, intent(in) :: flag !< Flag to indicate to allocate if (present(flag)) then diff --git a/src/core/MOM_grid.F90 b/src/core/MOM_grid.F90 index 87fae7327b..57293a65fa 100644 --- a/src/core/MOM_grid.F90 +++ b/src/core/MOM_grid.F90 @@ -403,10 +403,12 @@ end function Adcroft_reciprocal !> Returns true if the coordinates (x,y) are within the h-cell (i,j) logical function isPointInCell(G, i, j, x, y) - type(ocean_grid_type), intent(in) :: G !< Grid type - integer, intent(in) :: i, j !< i,j indices of cell to test - real, intent(in) :: x, y !< x,y coordinates of point -! This is a crude calculation that assume a geographic coordinate system + type(ocean_grid_type), intent(in) :: G !< Grid type + integer, intent(in) :: i !< i index of cell to test + integer, intent(in) :: j !< j index of cell to test + real, intent(in) :: x !< x coordinate of point + real, intent(in) :: y !< y coordinate of point + ! Local variables real :: xNE, xNW, xSE, xSW, yNE, yNW, ySE, ySW real :: p0, p1, p2, p3, l0, l1, l2, l3 isPointInCell = .false. @@ -414,6 +416,7 @@ logical function isPointInCell(G, i, j, x, y) xNW = G%geoLonBu(i-1,j ) ; yNW = G%geoLatBu(i-1,j ) xSE = G%geoLonBu(i ,j-1) ; ySE = G%geoLatBu(i ,j-1) xSW = G%geoLonBu(i-1,j-1) ; ySW = G%geoLatBu(i-1,j-1) + ! This is a crude calculation that assume a geographic coordinate system if (xmax(xNE,xNW,xSE,xSW) .or. & ymax(yNE,yNW,ySE,ySW) ) then return ! Avoid the more complicated calculation diff --git a/src/core/MOM_open_boundary.F90 b/src/core/MOM_open_boundary.F90 index 9557b82509..76f6805d54 100644 --- a/src/core/MOM_open_boundary.F90 +++ b/src/core/MOM_open_boundary.F90 @@ -720,12 +720,12 @@ subroutine Radiation_Open_Bdry_Conds(OBC, u_new, u_old, v_new, v_old, & h_new, h_old, G) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_new - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u_old - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_new - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v_old - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_new - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_old + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_new !< New u values on open boundaries + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u_old !< Original unadjusted u + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_new !< New v values on open boundaries + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v_old !< Original unadjusted v + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_new !< New h values on open boundaries + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_old !< Original h values ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: grad real :: dhdt, dhdx, dhdy, gamma_u, gamma_h, gamma_v diff --git a/src/diagnostics/MOM_wave_speed.F90 b/src/diagnostics/MOM_wave_speed.F90 index b84ec40432..264500066d 100644 --- a/src/diagnostics/MOM_wave_speed.F90 +++ b/src/diagnostics/MOM_wave_speed.F90 @@ -1,46 +1,7 @@ +!> Routines for calculating baroclinic wave speeds module MOM_wave_speed -!*********************************************************************** -!* GNU General Public License * -!* This file is a part of MOM. * -!* * -!* MOM is free software; you can redistribute it and/or modify it and * -!* are expected to follow the terms of the GNU General Public License * -!* as published by the Free Software Foundation; either version 2 of * -!* the License, or (at your option) any later version. * -!* * -!* MOM is distributed in the hope that it will be useful, but WITHOUT * -!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * -!* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * -!* License for more details. * -!* * -!* For the full text of the GNU General Public License, * -!* write to: Free Software Foundation, Inc., * -!* 675 Mass Ave, Cambridge, MA 02139, USA. * -!* or see: http://www.gnu.org/licenses/gpl.html * -!*********************************************************************** -! -!********+*********+*********+*********+*********+*********+*********+** -!* * -!* By Robert Hallberg and Ben Mater, May 2008 - December 2015 * -!* * -!* The subroutines in this module calculates the first baroclinic * -!* mode internal wave speed, or a set of N wave speeds. * -!* * -!* Macros written all in capital letters are defined in MOM_memory.h. * -!* * -!* A small fragment of the grid is shown below: * -!* * -!* j+1 x ^ x ^ x At x: q * -!* j+1 > o > o > At ^: v, vh, vav * -!* j x ^ x ^ x At >: u, uh, uav * -!* j > o > o > At o: h * -!* j-1 x ^ x ^ x * -!* i-1 i i+1 At x & ^: * -!* i i+1 At > & o: * -!* * -!* The boundaries always run through q grid points (x). * -!* * -!********+*********+*********+*********+*********+*********+*********+** + +! This file is part of MOM6. See LICENSE.md for the license. use MOM_diag_mediator, only : post_data, query_averaging_enabled, diag_ctrl use MOM_diag_mediator, only : register_diag_field, safe_alloc_ptr, time_type @@ -57,64 +18,24 @@ module MOM_wave_speed public wave_speed, wave_speeds, wave_speed_init +!> Control structure for MOM_wave_speed type, public :: wave_speed_CS ; private - type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the - ! timing of diagnostic output. + type(diag_ctrl), pointer :: diag ! Diagnostics control structure end type wave_speed_CS contains +!> Calculates the wave speed of the first baroclinic mode. subroutine wave_speed(h, tv, G, GV, cg1, CS, full_halos) - type(ocean_grid_type), intent(in) :: G - type(verticalGrid_type), intent(in) :: GV - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h - type(thermo_var_ptrs), intent(in) :: tv - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: cg1 - type(wave_speed_CS), optional, pointer :: CS - logical, optional, intent(in) :: full_halos -! This subroutine determines the first mode internal wave speed. -! Arguments: h - Layer thickness, in m or kg m-2. -! (in) tv - A structure containing the thermobaric variables. -! (out) cg1 - The first mode internal gravity wave speed, in m s-1. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! wave_speed_init. -! (in,opt) full_halos - If true, do the calculation over the entire -! computational domain. - -! This subroutine solves for the first baroclinic mode wave speed. (It could -! solve for all the wave speeds, but the iterative approach taken here means -! that this is not particularly efficient.) - -! If e(k) is the perturbation interface height, this means solving for the -! smallest eigenvalue (lam = 1/c^2) of the system -! -! -Igu(k)*e(k-1) + (Igu(k)+Igl(k)-lam)*e(k) - Igl(k)*e(k+1) = 0.0 -! -! with rigid lid boundary conditions e(1) = e(nz+1) = 0.0 giving -! -! (Igu(2)+Igl(2)-lam)*e(2) - Igl(2)*e(3) = 0.0 -! -Igu(nz)*e(nz-1) + (Igu(nz)+Igl(nz)-lam)*e(nz) = 0.0 -! -! Here -! Igl(k) = 1.0/(gprime(k)*H(k)) ; Igu(k) = 1.0/(gprime(k)*H(k-1)) -! -! Alternately, these same eigenvalues can be found from the second smallest -! eigenvalue of the Montgomery potential (M(k)) calculation: -! -! -Igl(k)*M(k-1) + (Igl(k)+Igu(k+1)-lam)*M(k) - Igu(k+1)*M(k+1) = 0.0 -! -! with rigid lid and flat bottom boundary conditions -! -! (Igu(2)-lam)*M(1) - Igu(2)*M(2) = 0.0 -! -Igl(nz)*M(nz-1) + (Igl(nz)-lam)*M(nz) = 0.0 -! -! Note that the barotropic mode has been eliminated from the rigid lid -! interface height equations, hence the matrix is one row smaller. Without -! the rigid lid, the top boundary condition is simpler to implement with -! the M equations. - + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: cg1 !< First mode internal wave speed (m/s) + type(wave_speed_CS), optional, pointer :: CS !< Control structure for MOM_wave_speed + logical, optional, intent(in) :: full_halos !< If true, do the calculation + !! over the entire computational domain. + ! Local variables real, dimension(SZK_(G)+1) :: & dRho_dT, dRho_dS, & pres, T_int, S_int, & @@ -388,57 +309,18 @@ subroutine wave_speed(h, tv, G, GV, cg1, CS, full_halos) end subroutine wave_speed +!> Calculates the wave speeds for the first few barolinic modes. subroutine wave_speeds(h, tv, G, GV, nmodes, cn, CS, full_halos) - type(ocean_grid_type), intent(in) :: G - type(verticalGrid_type), intent(in) :: GV - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h - type(thermo_var_ptrs), intent(in) :: tv - integer, intent(in) :: nmodes - real, dimension(G%isd:G%ied,G%jsd:G%jed,nmodes), intent(out) :: cn - type(wave_speed_CS), optional, pointer :: CS - logical, optional, intent(in) :: full_halos -! This subroutine determines the first mode internal wave speed. -! Arguments: h - Layer thickness, in m or kg m-2. -! (in) tv - A structure containing the thermobaric variables. -! (out) cn - The internal gravity wave mode speeds, in m s-1. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! wave_speed_init. -! (in,opt) full_halos - If true, do the calculation over the entire -! computational domain. -! -! This subroutine solves for the baroclinic mode wave speed for the first -! few modes. (It is an iterative approach so is not particularly efficient.) - -! If e(k) is the perturbation interface height, this means solving for the -! eigenvalues (lam = 1/c^2) of the system -! -! -Igu(k)*e(k-1) + (Igu(k)+Igl(k)-lam)*e(k) - Igl(k)*e(k+1) = 0.0 -! -! with rigid lid boundary conditions e(1) = e(nz+1) = 0.0 giving -! -! (Igu(2)+Igl(2)-lam)*e(2) - Igl(2)*e(3) = 0.0 -! -Igu(nz)*e(nz-1) + (Igu(nz)+Igl(nz)-lam)*e(nz) = 0.0 -! -! Here -! Igl(k) = 1.0/(gprime(k)*H(k)) ; Igu(k) = 1.0/(gprime(k)*H(k-1)) -! -! Alternately, these same eigenvalues can be found from the second smallest -! eigenvalue of the Montgomery potential (M(k)) calculation: -! -! -Igl(k)*M(k-1) + (Igl(k)+Igu(k+1)-lam)*M(k) - Igu(k+1)*M(k+1) = 0.0 -! -! with rigid lid and flat bottom boundary conditions -! -! (Igu(2)-lam)*M(1) - Igu(2)*M(2) = 0.0 -! -Igl(nz)*M(nz-1) + (Igl(nz)-lam)*M(nz) = 0.0 -! -! Note that the barotropic mode has been eliminated from the rigid lid -! interface height equations, hence the matrix is one row smaller. Without -! the rigid lid, the top boundary condition is simpler to implement with -! the M equations. - + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables + integer, intent(in) :: nmodes !< Number of modes + real, dimension(G%isd:G%ied,G%jsd:G%jed,nmodes), intent(out) :: cn !< Waves speeds (m/s) + type(wave_speed_CS), optional, pointer :: CS !< Control structure for MOM_wave_speed + logical, optional, intent(in) :: full_halos !< If true, do the calculation + !! over the entire computational domain. + ! Local variables real, dimension(SZK_(G)+1) :: & dRho_dT, dRho_dS, & pres, T_int, S_int, & @@ -969,31 +851,21 @@ subroutine wave_speeds(h, tv, G, GV, nmodes, cn, CS, full_halos) end subroutine wave_speeds +!> Calculate the determinant of a tridiagonal matrix with diagonals a,b-lam,c where lam is constant across rows. subroutine tridiag_det(a,b,c,nrows,lam,det_out,ddet_out) - real, dimension(:), intent(in) :: a - real, dimension(:), intent(in) :: b - real, dimension(:), intent(in) :: c - integer, intent(in) :: nrows - real, intent(in) :: lam - real, intent(out):: det_out - real, intent(out):: ddet_out - ! Arguments: - ! (in) a - lower diagonal with first entry equal to zero - ! (in) b - middle diagonal - ! (in) c - upper diagonal with last entry equal to zero - ! (in) nrows - number of rows - ! (in) lam - value to subtract from middle diagonal - ! (out) det_out - determinate evaluated for given lam value - ! (out) ddet_out - derivative of determinate with respect to lam - ! evaluated for given lam value - real, dimension(nrows) :: & - det ! value of recursion function - real, dimension(nrows) :: & - ddet ! value of recursion function for derivative - real, parameter:: & - rescale = 1024.0**4 ! max value of determinant allowed before rescaling - real :: I_rescale ! inverse of rescale - integer :: n ! row (layer interface) index + real, dimension(:), intent(in) :: a !< Lower diagonal of matrix (first entry = 0) + real, dimension(:), intent(in) :: b !< Leading diagonal of matrix (excluding lam) + real, dimension(:), intent(in) :: c !< Upper diagonal of matrix (last entry = 0) + integer, intent(in) :: nrows !< Size of matrix + real, intent(in) :: lam !< Value subtracted from b + real, intent(out):: det_out !< Determinant + real, intent(out):: ddet_out !< Derivative of determinant w.r.t. lam + ! Local variables + real, dimension(nrows) :: det ! value of recursion function + real, dimension(nrows) :: ddet ! value of recursion function for derivative + real, parameter:: rescale = 1024.0**4 ! max value of determinant allowed before rescaling + real :: I_rescale ! inverse of rescale + integer :: n ! row (layer interface) index if (size(b) .ne. nrows) call MOM_error(WARNING, "Diagonal b must be same length as nrows.") if (size(a) .ne. nrows) call MOM_error(WARNING, "Diagonal a must be same length as nrows.") @@ -1017,19 +889,13 @@ subroutine tridiag_det(a,b,c,nrows,lam,det_out,ddet_out) end subroutine tridiag_det +!> Initialize control structure for MOM_wave_speed subroutine wave_speed_init(Time, G, param_file, diag, CS) - type(time_type), intent(in) :: Time - type(ocean_grid_type), intent(in) :: G - type(param_file_type), intent(in) :: param_file - type(diag_ctrl), target, intent(inout) :: diag - type(wave_speed_CS), pointer :: CS -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module + type(time_type), intent(in) :: Time !< Current model time + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(param_file_type), intent(in) :: param_file !< Parameter file handles + type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure + type(wave_speed_CS), pointer :: CS !< Control structure for MOM_wave_speed ! This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mod = "MOM_wave_speed" ! This module's name. @@ -1047,4 +913,48 @@ subroutine wave_speed_init(Time, G, param_file, diag, CS) end subroutine wave_speed_init +!> \namespace mom_wave_speed +!! +!! Subroutine wave_speed() solves for the first baroclinic mode wave speed. (It could +!! solve for all the wave speeds, but the iterative approach taken here means +!! that this is not particularly efficient.) +!! +!! If `e(k)` is the perturbation interface height, this means solving for the +!! smallest eigenvalue (`lam` = 1/c^2) of the system +!! +!! \verbatim +!! -Igu(k)*e(k-1) + (Igu(k)+Igl(k)-lam)*e(k) - Igl(k)*e(k+1) = 0.0 +!! \endverbatim +!! +!! with rigid lid boundary conditions e(1) = e(nz+1) = 0.0 giving +!! +!! \verbatim +!! (Igu(2)+Igl(2)-lam)*e(2) - Igl(2)*e(3) = 0.0 +!! -Igu(nz)*e(nz-1) + (Igu(nz)+Igl(nz)-lam)*e(nz) = 0.0 +!! \endverbatim +!! +!! Here +!! \verbatim +!! Igl(k) = 1.0/(gprime(k)*h(k)) ; Igu(k) = 1.0/(gprime(k)*h(k-1)) +!! \endverbatim +!! +!! Alternately, these same eigenvalues can be found from the second smallest +!! eigenvalue of the Montgomery potential (M(k)) calculation: +!! +!! \verbatim +!! -Igl(k)*M(k-1) + (Igl(k)+Igu(k+1)-lam)*M(k) - Igu(k+1)*M(k+1) = 0.0 +!! \endverbatim +!! +!! with rigid lid and flat bottom boundary conditions +!! +!! \verbatim +!! (Igu(2)-lam)*M(1) - Igu(2)*M(2) = 0.0 +!! -Igl(nz)*M(nz-1) + (Igl(nz)-lam)*M(nz) = 0.0 +!! \endverbatim +!! +!! Note that the barotropic mode has been eliminated from the rigid lid +!! interface height equations, hence the matrix is one row smaller. Without +!! the rigid lid, the top boundary condition is simpler to implement with +!! the M equations. + end module MOM_wave_speed diff --git a/src/framework/_Horizontal_indexing.dox b/src/framework/_Horizontal_indexing.dox index 3aa8b208d3..9eea1e9698 100644 --- a/src/framework/_Horizontal_indexing.dox +++ b/src/framework/_Horizontal_indexing.dox @@ -80,15 +80,17 @@ The file MOM_memory_macros.h provides the macros `SZI_`, `SZJ_`, `SZIB_` and `SZ \section Global_index Calculating a global index -For the most part we MOM6 code should be independent of an equivalent absolute global index. -There are exceptions are when the equivalent global index of a cell `i,j` is needed is can be calculated as follows: +For the most part MOM6 code should be independent of an equivalent absolute global index. +There are exceptions and when the global index of a cell `i,j` is needed is can be calculated as follows: - `i_global = i + HI%%idg_offset`, or + `i_global = i + HI%%idg_offset` Before the mom_hor_index::hor_index_type was introduced, this conversion was done use variables in the mom_grid::ocean_grid_type: - `i_gloval = (i-G%%isd) + G%%isd_global` + `i_global = (i-G%%isd) + G%%isd_global` which is no longer preferred. +Note that a global index only makes sense for a rectangular global domain. If the domain is a Mosaic of connected tiles (e.g. size tiles of a cube) the global indices (i,j) become meaningless. + */ From 489f00c82ee146e0cf99b58b8277c51cc13e51d4 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Fri, 30 Sep 2016 17:21:45 -0400 Subject: [PATCH 09/14] +Added run-time parameters for MOM_energetic_PBL Added a copy of the new two-way potential energy calculation to MOM_energetic_PBL.F90. Added 3 new run time parameters (EPBL_MLD_TOLERANCE, EPBL_MIN_MIX_LEN, and EPBL_ORIGINAL_PE_CALC) that control some of the behavior of the EPBL code, and corrected the units on 3 others. Also renamed some internal variables more sensibly. All answers are bitwise identical, but several of the MOM_parameter_doc files have changes. --- .../vertical/MOM_energetic_PBL.F90 | 404 ++++++++++++++---- 1 file changed, 316 insertions(+), 88 deletions(-) diff --git a/src/parameterizations/vertical/MOM_energetic_PBL.F90 b/src/parameterizations/vertical/MOM_energetic_PBL.F90 index 737bea6ce4..68cbbab491 100644 --- a/src/parameterizations/vertical/MOM_energetic_PBL.F90 +++ b/src/parameterizations/vertical/MOM_energetic_PBL.F90 @@ -114,9 +114,15 @@ module MOM_energetic_PBL ! the inhibition of the diffusive length scale by ! rotation. Making this larger decreases the ! diffusivity in the planetary boundary layer. + real :: MLD_tol ! A tolerance for determining the boundary layer + ! thickness when Use_MLD_iteration is true, in m. + real :: min_mix_len ! The minimum mixing length scale that will be + ! used by ePBL, in m. The default (0) does not + ! set a minimum. type(time_type), pointer :: Time ! A pointer to the ocean model's clock. logical :: TKE_diagnostics = .false. - LOGICAL :: Use_MLD_ITERATION=.false.!False to use old ePBL method. + logical :: orig_PE_calc = .true. + logical :: Use_MLD_iteration=.false. ! False to use old ePBL method. logical :: Mixing_Diagnostics = .false. ! Will be true when outputing mixing ! length and velocity scale type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the @@ -259,8 +265,19 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & Te, Se, & ! Estimated final values of T and S in the column, in K and ppt. c1, & ! c1 is used by the tridiagonal solver, ND. dTe, dSe ! Running (1-way) estimates of temperature and salinity change. + real, dimension(SZK_(GV)) :: & + Th_a, & ! An effective temperature times a thickness in the layer above, + ! including implicit mixing effects with other yet higher layers, in K H. + Sh_a, & ! An effective salinity times a thickness in the layer above, + ! including implicit mixing effects with other yet higher layers, in K H. + Th_b, & ! An effective temperature times a thickness in the layer below, + ! including implicit mixing effects with other yet lower layers, in K H. + Sh_b ! An effective salinity times a thickness in the layer below, + ! including implicit mixing effects with other yet lower layers, in K H. real, dimension(SZI_(G)) :: & - b_den_1 ! The first term in the denominator of b1, in H. + hp_a ! An effective pivot thickness of the layer including the effects + ! of coupling with layers above, in H. This is the first term + ! in the denominator of b1 in a downward-oriented tridiagonal solver. real, dimension(SZK_(GV)+1) :: & Kddt_h ! The diapycnal diffusivity times a timestep divided by the ! average thicknesses around a layer, in H (m or kg m-2). @@ -279,7 +296,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & real :: dt_h ! The timestep divided by the averages of the thicknesses around ! a layer, times a thickness conversion factor, in H s m-2. - real :: I_hs ! The inverse of h_sum. + real :: I_hs ! The inverse of h_sum, in H-1. + real :: I_mld ! The inverse of the current value of MLD, in H-1. real :: h_tt ! The distance from the surface or up to the next interface ! that did not exhibit turbulent mixing from this scheme plus ! a surface mixing roughness length given by h_tt_min, in H. @@ -345,8 +363,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !---------------------------------------------------------------------- !/BGR added Aug24,2016 for adding iteration to get boundary layer depth ! - needed to compute new mixing length. - real :: MLD_GUESS, MLD_FOUND ! Mixing Layer depth guessed/found for iteration - real :: MAX_MLD, MIN_MLD ! Iteration bounds which are adjusted at each step + real :: MLD_guess, MLD_found ! Mixing Layer depth guessed/found for iteration, in m. + real :: max_MLD, min_MLD ! Iteration bounds, in m, which are adjusted at each step ! - These are initialized based on surface/bottom ! 1. The iteration guesses a value (possibly from ! prev step or neighbor). @@ -368,12 +386,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! surface_disconnect, can improve this. logical :: FIRST_OBL ! Flag for computing "found" Mixing layer depth logical :: OBL_CONVERGED ! Flag for convergence of MLD - INTEGER :: OBL_IT ! Iteration counter - REAL :: MinMixLen=1.0 ! Minimum value for mixing length (must be non-zero - ! for iteration to converge when OBL shoals). - ! At present, this is the value used for convection - ! in the ocean interior. - INTEGER :: MAX_OBL_IT=20 ! Set maximum number of iterations. Probably + integer :: OBL_IT ! Iteration counter +!### These need to be made into run-time parameters. + integer :: MAX_OBL_IT=20 ! Set maximum number of iterations. Probably ! best as an input parameter, but then may want ! to use allocatable arrays if storing ! guess/found (as diagnostic); skipping for now. @@ -384,18 +399,20 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! e.g. M=12 for DEPTH=4000m and DZ=1m real, dimension(SZK_(GV)+1) :: Vstar_Used, & ! 1D arrays used to store Mixing_Length_Used ! Vstar and Mixing_Length + !/BGR - remaining variables are related to tracking iteration statistics. logical :: OBL_IT_STATS=.false. ! Flag for computing OBL iteration statistics REAL :: ITguess(20), ITresult(20),ITmax(20),ITmin(20) ! Flag for storing guess/result ! should have dim=MAX_OBL_IT integer, save :: MAXIT=0 ! Stores maximum number of iterations - integer, save :: MINIT=1e8 ! Stokes minimum number of iterations + integer, save :: MINIT=1e8 ! Stores minimum number of iterations integer, save :: SUMIT=0 ! Stores total iterations (summed over all) integer, save :: NUMIT=0 ! Stores number of times iterated !e.g. Average iterations = SUMIT/NUMIT integer, save :: CONVERGED! integer, save :: NOTCONVERGED! !-End BGR iteration parameters----------------------------------------- + logical :: debug=.false. ! Change this hard-coded value for debugging. ! The following arrays are used only for debugging purposes. real :: dPE_debug, mixing_debug @@ -465,9 +482,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !!OMP U_Star,absf,mech_TKE,conv_PErel,nstar_k, & !!OMP h_sum,I_hs,h_bot,hb_hs,T0,S0,num_itts, & !!OMP pres,dMass,dPres,dT_to_dPE,dS_to_dPE, & -!!OMP dT_to_dColHt,dS_to_dColHt,Kddt_h, & -!!OMP b_den_1,dT_to_dPE_a,dT_to_dColHt_a, & -!!OMP dS_to_dColHt_a,htot,uhtot,vhtot, & +!!OMP dT_to_dColHt,dS_to_dColHt,Kddt_h,hp_a, & +!!OMP Th_a,Sh_a,Th_b,Sh_b,dT_to_dPE_a,htot, & +!!OMP dT_to_dColHt_a,dS_to_dColHt_a,uhtot,vhtot, & !!OMP Idecay_len_TKE,exp_kh,nstar_FC,tot_TKE, & !!OMP TKE_reduc,dTe_t2,dSe_t2,dTe,dSe,dt_h, & !!OMP Convectively_stable,sfc_disconnect,b1, & @@ -509,21 +526,21 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then !/The following lines are for the iteration over MLD !{ - MAX_MLD = 0.0 ! MAX_MLD will initialized as ocean bottom depth + max_MLD = 0.0 ! max_MLD will initialized as ocean bottom depth do k=1,nz - MAX_MLD = MAX_MLD + h(i,k)*GV%H_to_m + max_MLD = max_MLD + h(i,k)*GV%H_to_m enddo - MIN_MLD = 0.0 !MIN_MLD will initialize as 0. + min_MLD = 0.0 !min_MLD will initialize as 0. - !/BGR: Add MLD_GUESS based on stored previous value. + !/BGR: Add MLD_guess based on stored previous value. ! note that this is different from ML_Depth already ! computed by EPBL, need to figure out why. if (CS%ML_Depth2(i,j) > 1.) then !If prev value is present use for guess. - MLD_GUESS=CS%ML_Depth2(i,j) + MLD_guess=CS%ML_Depth2(i,j) else !Otherwise guess middle of water column. - MLD_GUESS = 0.5 * (MIN_MLD+MAX_MLD) + MLD_guess = 0.5 * (min_MLD+max_MLD) endif !/BGR: May add user-input bounds for max/min MLD @@ -598,18 +615,20 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & h_bot(i) = h_bot(i) + h(i,k) hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs) enddo - else - !New method where mixing length is reduced based on MLD - I_hs=1.0/MLD_GUESS - h_sum(i) = 0.0 - h_bot(i) = 0.0 ; hb_hs(i,1:nz+1) = 0.0 - do k=2,nz - h_sum(i) = h_sum(i)+h(i,k) - h_bot(i) = max(0.0,MLD_GUESS - h_sum(i)) - hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs)**2!Notice the square - ! makes KPP-like. - enddo - endif + else + ! Reduce the mixing length based on MLD, with a quadratic + ! expression that follows KPP. + I_MLD=1.0/MLD_guess + h_sum(i) = 0.0 + h_bot(i) = 0.0 ; hb_hs(i,1:nz+1) = 0.0 + do k=2,nz + h_sum(i) = h_sum(i)+h(i,k) + h_bot(i) = max(0.0,MLD_guess - h_sum(i)) + ! ### USE A DIFFERENT ARRAY HERE.... + hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs)**2!Notice the square + ! makes KPP-like. + enddo + endif ! endif ; enddo ! Note the outer i-loop and inner k-loop loop order!!! @@ -631,7 +650,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & enddo Kd(i,1) = 0.0 ; Kddt_h(1) = 0.0 - b_den_1(i) = h(i,1) + hp_a(i) = h(i,1) dT_to_dPE_a(i,1) = dT_to_dPE(i,1) dS_to_dPE_a(i,1) = dS_to_dPE(i,1) dT_to_dColHt_a(i,1) = dT_to_dColHt(i,1) @@ -713,11 +732,13 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & endif ! Precalculate some temporary expressions that are independent of Kddt_h(K). - if (K==2) then - dTe_t2 = 0.0 ; dSe_t2 = 0.0 - else - dTe_t2 = Kddt_h(K-1) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) - dSe_t2 = Kddt_h(K-1) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) + if (CS%orig_PE_calc) then + if (K==2) then + dTe_t2 = 0.0 ; dSe_t2 = 0.0 + else + dTe_t2 = Kddt_h(K-1) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) + dSe_t2 = Kddt_h(K-1) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) + endif endif dt_h = (GV%m_to_H**2*dt) / max(0.5*(h(i,k-1)+h(i,k)), 1e-15*h_sum(i)) @@ -743,12 +764,14 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! tridiagonal solver for the whole column to be completed for debugging ! purposes, and also allows for something akin to convective adjustment ! in unstable interior regions? - b1 = 1.0 / (b_den_1(i)) + b1 = 1.0 / hp_a(i) c1(K) = 0.0 - dTe(k-1) = b1 * ( dTe_t2 ) - dSe(k-1) = b1 * ( dSe_t2 ) + if (CS%orig_PE_calc) then + dTe(k-1) = b1 * ( dTe_t2 ) + dSe(k-1) = b1 * ( dSe_t2 ) + endif - b_den_1(i) = h(i,k) + hp_a(i) = h(i,k) dT_to_dPE_a(i,k) = dT_to_dPE(i,k) dS_to_dPE_a(i,k) = dS_to_dPE(i,k) dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) @@ -759,17 +782,27 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! Precalculate some more temporary expressions that are independent of ! Kddt_h(K). - if (K==2) then - dT_km1_t2 = (T0(k)-T0(k-1)) - dS_km1_t2 = (S0(k)-S0(k-1)) + if (CS%orig_PE_calc) then + if (K==2) then + dT_km1_t2 = (T0(k)-T0(k-1)) + dS_km1_t2 = (S0(k)-S0(k-1)) + else + dT_km1_t2 = (T0(k)-T0(k-1)) - & + (Kddt_h(K-1) / hp_a(i)) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) + dS_km1_t2 = (S0(k)-S0(k-1)) - & + (Kddt_h(K-1) / hp_a(i)) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) + endif + dTe_term = dTe_t2 + hp_a(i) * (T0(k-1)-T0(k)) + dSe_term = dSe_t2 + hp_a(i) * (S0(k-1)-S0(k)) else - dT_km1_t2 = (T0(k)-T0(k-1)) - & - (Kddt_h(K-1) / b_den_1(i)) * ((T0(k-2) - T0(k-1)) + dTe(k-2)) - dS_km1_t2 = (S0(k)-S0(k-1)) - & - (Kddt_h(K-1) / b_den_1(i)) * ((S0(k-2) - S0(k-1)) + dSe(k-2)) + if (K<=2) then + Th_a(k-1) = h(i,k-1) * T0(k-1) ; Sh_a(k-1) = h(i,k-1) * S0(k-1) + else + Th_a(k-1) = h(i,k-1) * T0(k-1) + Kddt_h(K-1) * Te(k-2) + Sh_a(k-1) = h(i,k-1) * S0(k-1) + Kddt_h(K-1) * Se(k-2) + endif + Th_b(k) = h(i,k) * T0(k) ; Sh_b(k) = h(i,k) * S0(k) endif - dTe_term = dTe_t2 + b_den_1(i) * (T0(k-1)-T0(k)) - dSe_term = dSe_t2 + b_den_1(i) * (S0(k-1)-S0(k)) ! Using Pr=1 and the diffusivity at the bottom interface (once it is ! known), determine how much resolved mean kinetic energy (MKE) will be @@ -797,7 +830,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*conv_PErel(i) if (TKE_here > 0.0) then vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = MAX(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & + Mixing_Length_Used(k) = MAX(CS%min_mix_len,((h_tt*hb_hs(i,K))*vstar) / & ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) !Note setting Kd_guess0 to Mixing_Length_Used(K) here will ! change the answers. Therefore, skipping that. @@ -813,13 +846,23 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & Vstar_Used(k) = vstar ! Track vstar Kddt_h_g0 = Kd_guess0*dt_h - call find_PE_chg(Kddt_h_g0, h(i,k), b_den_1(i), dTe_term, dSe_term, & + if (CS%orig_PE_calc) then + call find_PE_chg_orig(Kddt_h_g0, h(i,k), hp_a(i), dTe_term, dSe_term, & dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & PE_chg=PE_chg_g0, dPEc_dKd=dPEa_dKd_g0, dPE_max=PE_chg_max, & dPEc_dKd_0=dPEc_dKd_Kd0 ) + else + call find_PE_chg(0.0, Kddt_h_g0, hp_a(i), h(i,k), & + Th_a(k-1), Sh_a(k-1), Th_b(k), Sh_b(k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), dT_to_dPE(i,k), dS_to_dPE(i,k), & + pres(i,K), dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + PE_chg=PE_chg_g0, dPEc_dKd=dPEa_dKd_g0, dPE_max=PE_chg_max, & + dPEc_dKd_0=dPEc_dKd_Kd0 ) + endif MKE_src = dMKE_max*(1.0 - exp(-Kddt_h_g0 * MKE2_Hharm)) @@ -830,7 +873,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*(conv_PErel(i)-PE_chg_max) if (TKE_here > 0.0) then vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = max(MinMixLen,((h_tt*hb_hs(i,K))*vstar) / & + Mixing_Length_Used(k) = max(CS%min_mix_len,((h_tt*hb_hs(i,K))*vstar) / & ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) if (.not.CS%Use_MLD_Iteration) then ! Note again (as prev) that using Mixing_Length_Used here @@ -845,12 +888,21 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & endif Vstar_Used(k) = vstar - call find_PE_chg(Kd(i,k)*dt_h, h(i,k), b_den_1(i), dTe_term, dSe_term, & + if (CS%orig_PE_calc) then + call find_PE_chg_orig(Kd(i,k)*dt_h, h(i,k), hp_a(i), dTe_term, dSe_term, & dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & PE_chg=dPE_conv) + else + call find_PE_chg(0.0, Kd(i,k)*dt_h, hp_a(i), h(i,k), & + Th_a(k-1), Sh_a(k-1), Th_b(k), Sh_b(k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), dT_to_dPE(i,k), dS_to_dPE(i,k), & + pres(i,K), dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + PE_chg=dPE_conv) + endif ! Should this be iterated to convergence for Kd? if (dPE_conv > 0.0) then Kd(i,k) = Kd_guess0 ; dPE_conv = PE_chg_g0 @@ -921,12 +973,21 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & MKE_src_itt(:) = 0.0 ; Kddt_h_itt(:) = 0.0 endif do itt=1,max_itt - call find_PE_chg(Kddt_h_guess, h(i,k), b_den_1(i), dTe_term, dSe_term, & + if (CS%orig_PE_calc) then + call find_PE_chg_orig(Kddt_h_guess, h(i,k), hp_a(i), dTe_term, dSe_term, & dT_km1_t2, dS_km1_t2, dT_to_dPE(i,k), dS_to_dPE(i,k), & dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), & pres(i,K), dT_to_dColHt(i,k), dS_to_dColHt(i,k), & dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & PE_chg=PE_chg, dPEc_dKd=dPEc_dKd ) + else + call find_PE_chg(0.0, Kddt_h_guess, hp_a(i), h(i,k), & + Th_a(k-1), Sh_a(k-1), Th_b(k), Sh_b(k), & + dT_to_dPE_a(i,k-1), dS_to_dPE_a(i,k-1), dT_to_dPE(i,k), dS_to_dPE(i,k), & + pres(i,K), dT_to_dColHt_a(i,k-1), dS_to_dColHt_a(i,k-1), & + dT_to_dColHt(i,k), dS_to_dColHt(i,k), & + PE_chg=dPE_conv) + endif MKE_src = dMKE_max * (1.0 - exp(-MKE2_Hharm * Kddt_h_guess)) dMKE_src_dK = dMKE_max * MKE2_Hharm * exp(-MKE2_Hharm * Kddt_h_guess) @@ -992,12 +1053,14 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & Kddt_h(K) = Kd(i,K)*dt_h ! At this point, the final value of Kddt_h(K) is known, so the ! estimated properties for layer k-1 can be calculated. - b1 = 1.0 / (b_den_1(i) + Kddt_h(K)) + b1 = 1.0 / (hp_a(i) + Kddt_h(K)) c1(K) = Kddt_h(K) * b1 - dTe(k-1) = b1 * ( Kddt_h(K)*(T0(k)-T0(k-1)) + dTe_t2 ) - dSe(k-1) = b1 * ( Kddt_h(K)*(S0(k)-S0(k-1)) + dSe_t2 ) + if (CS%orig_PE_calc) then + dTe(k-1) = b1 * ( Kddt_h(K)*(T0(k)-T0(k-1)) + dTe_t2 ) + dSe(k-1) = b1 * ( Kddt_h(K)*(S0(k)-S0(k-1)) + dSe_t2 ) + endif - b_den_1(i) = h(i,k) + (b_den_1(i) * b1) * Kddt_h(K) + hp_a(i) = h(i,k) + (hp_a(i) * b1) * Kddt_h(K) dT_to_dPE_a(i,k) = dT_to_dPE(i,k) + c1(K)*dT_to_dPE_a(i,k-1) dS_to_dPE_a(i,k) = dS_to_dPE(i,k) + c1(K)*dS_to_dPE_a(i,k-1) dT_to_dColHt_a(i,k) = dT_to_dColHt(i,k) + c1(K)*dT_to_dColHt_a(i,k-1) @@ -1032,7 +1095,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & if (debug) then ! Complete the tridiagonal solve for Te. - b1 = 1.0 / (b_den_1(i)) + b1 = 1.0 / hp_a(i) Te(nz) = b1 * (h(i,nz) * T0(nz) + Kddt_h(nz) * Te(nz-1)) Se(nz) = b1 * (h(i,nz) * S0(nz) + Kddt_h(nz) * Se(nz-1)) do k=nz-1,1,-1 @@ -1059,7 +1122,7 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !/BGR: The following lines are used for the iteration ITmax(obl_it) = max_MLD ! Track max } ITmin(obl_it) = min_MLD ! Track min } For debug purpose - ITguess(obl_it) = MLD_GUESS ! Track guess } + ITguess(obl_it) = MLD_guess ! Track guess } MLD_FOUND=0.0 ; FIRST_OBL=.true. ! MLD_FOUND=CS%ML_depth2(i,J) do k=2,nz @@ -1071,23 +1134,23 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !1. Check if guess was too shallow !Adding -1 m as cushion, will help avoid ! non-convergence flag when nearly converged. - elseif (MLD_FOUND-1.0 > MLD_GUESS) then - !elseif (MLD_FOUND > MLD_GUESS) then + elseif (MLD_FOUND-CS%MLD_tol > MLD_guess) then + !elseif (MLD_FOUND > MLD_guess) then !/ Guess was too shallow, set new minimum guess - MIN_MLD = MLD_GUESS + min_MLD = MLD_guess FIRST_OBL = .false. !Break OBL loop !2. Check if Guess minus found MLD ! is less than thickness of level (=converged) ! - We could try to add a more precise ! value for found MLD, but seems difficult to ! to contrain beyond within a level. - elseif ((MLD_GUESS-MLD_FOUND) < max(1.,h(i,k-1)*GV%H_to_m)) then + elseif ((MLD_guess-MLD_FOUND) < max(CS%MLD_tol,h(i,k-1)*GV%H_to_m)) then ! Converged. Exit iteration. FIRST_OBL = .false.!Break OBL loop OBL_CONVERGED = .true.!Break convergence loop ! Testing Output, comment for use. !print*,'Converged--------' - !print*,MLD_FOUND,MLD_GUESS + !print*,MLD_FOUND,MLD_guess !/ if (OBL_IT_STATS) then !Compute iteration statistics MAXIT = max(MAXIT,obl_it) @@ -1097,18 +1160,18 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & print*,MAXIT,MINIT,SUMIT/NUMIT endif !BGR this can be where MLD is stored for next time... - CS%ML_Depth2(i,j) = MLD_GUESS + CS%ML_Depth2(i,j) = MLD_guess !/ !2. If not, guess was too deep else !Guess was too deep, set new maximum guess - MAX_MLD = MLD_GUESS !We know this guess was too deep + max_MLD = MLD_guess !We know this guess was too deep FIRST_OBL = .false.!Break OBL loop endif endif enddo ! For next pass, guess average of minimum and maximum values. - MLD_GUESS = MIN_MLD*0.5 + MAX_MLD*0.5 + MLD_guess = min_MLD*0.5 + max_MLD*0.5 ITresult(obl_it) = MLD_FOUND endif ; enddo ! Iteration loop for converged boundary layer thickness. @@ -1194,10 +1257,157 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & end subroutine energetic_PBL +!> This subroutine calculates the change in potential energy and or derivatives +!! for several changes in an interfaces's diapycnal diffusivity times a timestep. +subroutine find_PE_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, & + dT_to_dPE_a, dS_to_dPE_a, dT_to_dPE_b, dS_to_dPE_b, & + pres, dT_to_dColHt_a, dS_to_dColHt_a, dT_to_dColHt_b, dS_to_dColHt_b, & + PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0, ColHt_cor) + real, intent(in) :: Kddt_h0 !< The previously used diffusivity at an interface times + !! the time step and divided by the average of the + !! thicknesses around the interface, in units of H (m or kg-2). + real, intent(in) :: dKddt_h !< The trial change in the diffusivity at an interface times + !! the time step and divided by the average of the + !! thicknesses around the interface, in units of H (m or kg-2). + real, intent(in) :: hp_a !< The effective pivot thickness of the layer above the + !! interface, given by h_k plus a term that + !! is a fraction (determined from the tridiagonal solver) of + !! Kddt_h for the interface above, in H. + real, intent(in) :: hp_b !< The effective pivot thickness of the layer below the + !! interface, given by h_k plus a term that + !! is a fraction (determined from the tridiagonal solver) of + !! Kddt_h for the interface above, in H. + real, intent(in) :: Th_a !< An effective temperature times a thickness in the layer + !! above, including implicit mixing effects with other + !! yet higher layers, in K H. + real, intent(in) :: Sh_a !< An effective salinity times a thickness in the layer + !! above, including implicit mixing effects with other + !! yet higher layers, in K H. + real, intent(in) :: Th_b !< An effective temperature times a thickness in the layer + !! below, including implicit mixing effects with other + !! yet lower layers, in K H. + real, intent(in) :: Sh_b !< An effective salinity times a thickness in the layer + !! below, including implicit mixing effects with other + !! yet lower layers, in K H. + real, intent(in) :: dT_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating + !! a layer's temperature change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the temperatures of all the layers above, in J m-2 K-1. + real, intent(in) :: dS_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating + !! a layer's salinity change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the salinities of all the layers above, in J m-2 ppt-1. + real, intent(in) :: dT_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating + !! a layer's temperature change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the temperatures of all the layers below, in J m-2 K-1. + real, intent(in) :: dS_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating + !! a layer's salinity change to the change in column + !! potential energy, including all implicit diffusive changes + !! in the salinities of all the layers below, in J m-2 ppt-1. + real, intent(in) :: pres !< The hydrostatic interface pressure, which is used to relate + !! the changes in column thickness to the energy that is radiated + !! as gravity waves and unavailable to drive mixing, in Pa. + real, intent(in) :: dT_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dT) relating + !! a layer's temperature change to the change in column + !! height, including all implicit diffusive changes + !! in the temperatures of all the layers above, in m K-1. + real, intent(in) :: dS_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dS) relating + !! a layer's salinity change to the change in column + !! height, including all implicit diffusive changes + !! in the salinities of all the layers above, in m ppt-1. + real, intent(in) :: dT_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dT) relating + !! a layer's temperature change to the change in column + !! height, including all implicit diffusive changes + !! in the temperatures of all the layers below, in m K-1. + real, intent(in) :: dS_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dS) relating + !! a layer's salinity change to the change in column + !! height, including all implicit diffusive changes + !! in the salinities of all the layers below, in m ppt-1. + + real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying + !! Kddt_h at the present interface, in J m-2. + real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, + !! in units of J m-2 H-1. + real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could + !! be realizedd by applying a huge value of Kddt_h at the + !! present interface, in J m-2. + real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the + !! limit where Kddt_h = 0, in J m-2 H-1. + real, optional, intent(out) :: ColHt_cor !< The correction to PE_chg that is made due to a net + !! change in the column height, in J m-2. + + real :: hps ! The sum of the two effective pivot thicknesses, in H. + real :: bdt1 ! A product of the two pivot thicknesses plus a diffusive term, in H2. + real :: dT_c ! The core term in the expressions for the temperature changes, in K H2. + real :: dS_c ! The core term in the expressions for the salinity changes, in psu H2. + real :: PEc_core ! The diffusivity-independent core term in the expressions + ! for the potential energy changes, J m-3. + real :: ColHt_core ! The diffusivity-independent core term in the expressions + ! for the column height changes, J m-3. + real :: ColHt_chg ! The change in the column height, in m. + real :: y1 ! A local temporary term, in units of H-3 or H-4 in various contexts. + + ! The expression for the change in potential energy used here is derived + ! from the expression for the final estimates of the changes in temperature + ! and salinities, and then extensively manipulated to get it into its most + ! succint form. The derivation is not necessarily obvious, but it demonstrably + ! works by comparison with separate calculations of the energy changes after + ! the tridiagonal solver for the final changes in temperature and salinity are + ! applied. + + hps = hp_a + hp_b + bdt1 = hp_a * hp_b + Kddt_h0 * hps + dT_c = hp_a * Th_b - hp_b * Th_a + dS_c = hp_a * Sh_b - hp_b * Sh_a + PEc_core = hp_b * (dT_to_dPE_a * dT_c + dS_to_dPE_a * dS_c) - & + hp_a * (dT_to_dPE_b * dT_c + dS_to_dPE_b * dS_c) + ColHt_core = hp_b * (dT_to_dColHt_a * dT_c + dS_to_dColHt_a * dS_c) - & + hp_a * (dT_to_dColHt_b * dT_c + dS_to_dColHt_b * dS_c) + + if (present(PE_chg)) then + ! Find the change in column potential energy due to the change in the + ! diffusivity at this interface by dKddt_h. + y1 = dKddt_h / (bdt1 * (bdt1 + dKddt_h * hps)) + PE_chg = PEc_core * y1 + ColHt_chg = ColHt_core * y1 + if (ColHt_chg < 0.0) PE_chg = PE_chg - pres * ColHt_chg + if (present(ColHt_cor)) ColHt_cor = -pres * min(ColHt_chg, 0.0) + else if (present(ColHt_cor)) then + y1 = dKddt_h / (bdt1 * (bdt1 + dKddt_h * hps)) + ColHt_cor = -pres * min(ColHt_core * y1, 0.0) + endif + + if (present(dPEc_dKd)) then + ! Find the derivative of the potential energy change with dKddt_h. + y1 = 1.0 / (bdt1 + dKddt_h * hps)**2 + dPEc_dKd = PEc_core * y1 + ColHt_chg = ColHt_core * y1 + if (ColHt_chg < 0.0) dPEc_dKd = dPEc_dKd - pres * ColHt_chg + endif + + if (present(dPE_max)) then + ! This expression is the limit of PE_chg for infinite dKddt_h. + y1 = 1.0 / (bdt1 * hps) + dPE_max = PEc_core * y1 + ColHt_chg = ColHt_core * y1 + if (ColHt_chg < 0.0) dPE_max = dPE_max - pres * ColHt_chg + endif + + if (present(dPEc_dKd_0)) then + ! This expression is the limit of dPEc_dKd for dKddt_h = 0. + y1 = 1.0 / bdt1**2 + dPEc_dKd_0 = PEc_core * y1 + ColHt_chg = ColHt_core * y1 + if (ColHt_chg < 0.0) dPEc_dKd_0 = dPEc_dKd_0 - pres * ColHt_chg + endif + +end subroutine find_PE_chg + !> This subroutine calculates the change in potential energy and or derivatives !! for several changes in an interfaces's diapycnal diffusivity times a timestep !! using the original form used in the first version of ePBL. -subroutine find_PE_chg(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & +subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & dT_km1_t2, dS_km1_t2, dT_to_dPE_k, dS_to_dPE_k, & dT_to_dPEa, dS_to_dPEa, pres, dT_to_dColHt_k, & dS_to_dColHt_k, dT_to_dColHta, dS_to_dColHta, & @@ -1346,7 +1556,7 @@ subroutine find_PE_chg(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & if (dColHt_dKd < 0.0) dPEc_dKd_0 = dPEc_dKd_0 - pres*dColHt_dKd endif -end subroutine find_PE_chg +end subroutine find_PE_chg_orig !> Copies the ePBL active mixed layer depth into MLD subroutine energetic_PBL_get_MLD(CS, MLD, G) @@ -1434,29 +1644,47 @@ subroutine energetic_PBL_init(Time, G, GV, param_file, diag, CS) "local value of f, as sqrt((1-of)*f^2 + of*4*omega^2).", & units="nondim", default=omega_frac_dflt) call get_param(param_file, mod, "WSTAR_USTAR_COEF", CS%wstar_ustar_coef, & - "A ratio relating the efficiency with which convectively\n"//& - "released energy is converted to a turbulent velocity,\n"//& - "relative to mechanically forced TKE. Making this larger\n"//& - "increases the BL diffusivity", & - "units=nondim", default=1.0) + "A ratio relating the efficiency with which convectively \n"//& + "released energy is converted to a turbulent velocity, \n"//& + "relative to mechanically forced TKE. Making this larger \n"//& + "increases the BL diffusivity", units="nondim", default=1.0) call get_param(param_file, mod, "VSTAR_SCALE_FACTOR", CS%vstar_scale_fac, & "An overall nondimensional scaling factor for v*. \n"//& "Making this larger decreases the PBL diffusivity.", & - "units=nondim", default=1.0) + units="nondim", default=1.0) call get_param(param_file, mod, "EKMAN_SCALE_COEF", CS%Ekman_scale_coef, & - "A nondimensional scaling factor controlling the inhibition\n"//& - "of the diffusive length scale by rotation. Making this larger\n"//& - "decreases the PBL diffusivity.", & - "units=nondim", default=1.0) + "A nondimensional scaling factor controlling the inhibition \n"//& + "of the diffusive length scale by rotation. Making this larger \n"//& + "decreases the PBL diffusivity.", units="nondim", default=1.0) call get_param(param_file, mod, "USE_MLD_ITERATION", CS%USE_MLD_ITERATION, & - "A logical that determines whether or not to use the\n"//& - "MLD to set the EPBL length scale.", default=.false.) - - + "A logical that specifies whether or not to use the \n"//& + "distance to the bottom of the actively turblent boundary \n"//& + "layer to help set the EPBL length scale.", default=.false.) + call get_param(param_file, mod, "EPBL_MLD_TOLERANCE", CS%MLD_tol, & + "The tolerance for the iteratively determined mixed \n"//& + "layer depth. This is only used with USE_MLD_ITERATION.", & + units="meter", default=1.0) + call get_param(param_file, mod, "EPBL_MIN_MIX_LEN", CS%min_mix_len, & + "The minimum mixing length scale that will be used \n"//& + "by ePBL. The default (0) does not set a minimum.", & + units="meter", default=0.0) + call get_param(param_file, mod, "EPBL_ORIGINAL_PE_CALC", CS%orig_PE_calc, & + "If true, the ePBL code uses the original form of the \n"//& + "potential energy change code. Otherwise, the newer \n"//& + "version that can work with successive increments to the \n"//& + "diffusivity in upward or downward passes is used.", default=.true.) +! call get_param(param_file, mod, "EPBL_TRANSITION_SCALE", CS%transition_scale, & +! "A scale for the mixing length in the transition layer \n"//& +! "at the edge of the boundary layer as a fraction of the \n"//& +! "boundary layer thickness. The default is 0, but a \n"//& +! "value of 0.1 might be better justified by observations.", & +! units="nondim", default=0.0) ! This gives a minimum decay scale that is typically much less than Angstrom. CS%ustar_min = 2e-4*CS%omega*(GV%Angstrom_z + GV%H_to_m*GV%H_subroundoff) - ! NOTE from AJA: The above parameter is not logged? + call log_param(param_file, mod, "EPBL_USTAR_MIN", CS%ustar_min, & + "The (tiny) minimum friction velocity used within the \n"//& + "ePBL code, derived from OMEGA and ANGSTROM.", units="meter second-1") CS%id_ML_depth = register_diag_field('ocean_model', 'ePBL_h_ML', diag%axesT1, & Time, 'Surface mixed layer depth', 'meter') From 67bebcf641604090e1a8545e3afa76a78ac355a3 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Fri, 30 Sep 2016 18:18:46 -0400 Subject: [PATCH 10/14] +Added MixLen_shape to ePBL Added a new variable to rescale and reshape the mixing length in ePBL separately from the distance to the bottom. This funciton is controlled in part by the new run-time parameter EPBL_TRANSITION_SCALE, which should approximate the thickness of a transition layer at the base of the mixed layer as a function of the mixed layer depth. By default all answers are bitwise identical, but some MOM_parameter_doc files change. --- .../vertical/MOM_energetic_PBL.F90 | 84 +++++++++++-------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/src/parameterizations/vertical/MOM_energetic_PBL.F90 b/src/parameterizations/vertical/MOM_energetic_PBL.F90 index 68cbbab491..11f79d6d51 100644 --- a/src/parameterizations/vertical/MOM_energetic_PBL.F90 +++ b/src/parameterizations/vertical/MOM_energetic_PBL.F90 @@ -114,6 +114,10 @@ module MOM_energetic_PBL ! the inhibition of the diffusive length scale by ! rotation. Making this larger decreases the ! diffusivity in the planetary boundary layer. + real :: transLay_scale ! A scale for the mixing length in the transition layer + ! at the edge of the boundary layer as a fraction of the + ! boundary layer thickness. The default is 0, but a + ! value of 0.1 might be better justified by observations. real :: MLD_tol ! A tolerance for determining the boundary layer ! thickness when Use_MLD_iteration is true, in m. real :: min_mix_len ! The minimum mixing length scale that will be @@ -230,8 +234,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & real, dimension(SZI_(G),SZK_(GV)+1) :: & Kd, & ! The diapycnal diffusivity, in m2 s-1. pres, & ! Interface pressures in Pa. - hb_hs ! The distance from the bottom over the thickness of the water, - ! times a conversion factor from H to m, in m H-1. + hb_hs ! The distance from the bottom over the thickness of the + ! water column, nondim. real, dimension(SZI_(G)) :: & mech_TKE, & ! The mechanically generated turbulent kinetic energy ! available for mixing over a time step, in J m-2 = kg s-2. @@ -279,6 +283,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! of coupling with layers above, in H. This is the first term ! in the denominator of b1 in a downward-oriented tridiagonal solver. real, dimension(SZK_(GV)+1) :: & + MixLen_shape, & ! A nondimensional shape factor for the mixing length that + ! gives it an appropriate assymptotic value at the bottom of + ! the boundary layer. Kddt_h ! The diapycnal diffusivity times a timestep divided by the ! average thicknesses around a layer, in H (m or kg m-2). real :: b1 ! b1 is inverse of the pivot used by the tridiagonal solver, in H-1. @@ -309,6 +316,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! used convert TKE back into ustar^3. real :: U_star ! The surface friction velocity, in m s-1. real :: vstar ! An in-situ turbulent velocity, in m s-1. + real :: hbs_here ! The local minimum of hb_hs and MixLen_shape, times a + ! conversion factor from H to M, in m H-1. real :: nstar_FC ! The fraction of conv_PErel that can be converted to mixing, nondim. real :: TKE_reduc ! The fraction by which TKE and other energy fields are ! reduced to support mixing, nondim. between 0 and 1. @@ -605,28 +614,35 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & nstar_k(:) = 0.0 ; nstar_k(1) = CS%nstar endif - if (.not.CS%Use_MLD_Iteration) then - h_sum(i) = H_neglect - do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo - I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) + h_sum(i) = H_neglect + do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo + I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) - h_bot(i) = 0.0 ; hb_hs(i,nz+1) = 0.0 - do k=nz,1,-1 - h_bot(i) = h_bot(i) + h(i,k) - hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs) - enddo + h_bot(i) = 0.0 ; hb_hs(i,nz+1) = 0.0 + do k=nz,1,-1 + h_bot(i) = h_bot(i) + h(i,k) + hb_hs(i,K) = h_bot(i) * I_hs + enddo + + if ((.not.CS%Use_MLD_Iteration) .or. & + (CS%transLay_scale >= 1.0) .or. (CS%transLay_scale < 0.0) ) then + do K=1,nz+1 ; MixLen_shape(K) = 1.0 ; enddo + elseif (MLD_guess <= 0.0) then + if (CS%transLay_scale > 0.0) then + do K=1,nz+1 ; MixLen_shape(K) = CS%transLay_scale ; enddo + else + do K=1,nz+1 ; MixLen_shape(K) = 1.0 ; enddo + endif else ! Reduce the mixing length based on MLD, with a quadratic ! expression that follows KPP. - I_MLD=1.0/MLD_guess + I_MLD = 1.0 / MLD_guess h_sum(i) = 0.0 - h_bot(i) = 0.0 ; hb_hs(i,1:nz+1) = 0.0 - do k=2,nz - h_sum(i) = h_sum(i)+h(i,k) - h_bot(i) = max(0.0,MLD_guess - h_sum(i)) - ! ### USE A DIFFERENT ARRAY HERE.... - hb_hs(i,K) = GV%H_to_m * (h_bot(i)*I_hs)**2!Notice the square - ! makes KPP-like. + MixLen_shape(1) = 1.0 + do K=2,nz+1 + h_sum(i) = h_sum(i)+h(i,k-1) + MixLen_shape(K) = CS%transLay_scale + (1.0 - CS%transLay_scale) * & + (max(0.0, (MLD_guess - h_sum(i))*I_MLD) )**2 enddo endif ! endif ; enddo @@ -830,13 +846,14 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*conv_PErel(i) if (TKE_here > 0.0) then vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = MAX(CS%min_mix_len,((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) + hbs_here = GV%H_to_m * min(hb_hs(i,K), MixLen_shape(K)) + Mixing_Length_Used(k) = MAX(CS%min_mix_len,((h_tt*hbs_here)*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar)) !Note setting Kd_guess0 to Mixing_Length_Used(K) here will ! change the answers. Therefore, skipping that. if (.not.CS%Use_MLD_Iteration) then - Kd_guess0 = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + Kd_guess0 = vstar * vonKar * ((h_tt*hbs_here)*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar) else Kd_guess0 = vstar * vonKar * Mixing_Length_Used(k) endif @@ -873,13 +890,14 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & TKE_here = mech_TKE(i) + CS%wstar_ustar_coef*(conv_PErel(i)-PE_chg_max) if (TKE_here > 0.0) then vstar = CS%vstar_scale_fac * (I_dtrho*TKE_here)**C1_3 - Mixing_Length_Used(k) = max(CS%min_mix_len,((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar)) + hbs_here = GV%H_to_m * min(hb_hs(i,K), MixLen_shape(K)) + Mixing_Length_Used(k) = max(CS%min_mix_len,((h_tt*hbs_here)*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar)) if (.not.CS%Use_MLD_Iteration) then ! Note again (as prev) that using Mixing_Length_Used here ! instead of redoing the computation will change answers... - Kd(i,k) = vstar * vonKar * ((h_tt*hb_hs(i,K))*vstar) / & - ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hb_hs(i,K)) + vstar) + Kd(i,k) = vstar * vonKar * ((h_tt*hbs_here)*vstar) / & + ((CS%Ekman_scale_coef * absf(i)) * (h_tt*hbs_here) + vstar) else Kd(i,k) = vstar * vonKar * Mixing_Length_Used(k) endif @@ -1673,12 +1691,12 @@ subroutine energetic_PBL_init(Time, G, GV, param_file, diag, CS) "potential energy change code. Otherwise, the newer \n"//& "version that can work with successive increments to the \n"//& "diffusivity in upward or downward passes is used.", default=.true.) -! call get_param(param_file, mod, "EPBL_TRANSITION_SCALE", CS%transition_scale, & -! "A scale for the mixing length in the transition layer \n"//& -! "at the edge of the boundary layer as a fraction of the \n"//& -! "boundary layer thickness. The default is 0, but a \n"//& -! "value of 0.1 might be better justified by observations.", & -! units="nondim", default=0.0) + call get_param(param_file, mod, "EPBL_TRANSITION_SCALE", CS%transLay_scale, & + "A scale for the mixing length in the transition layer \n"//& + "at the edge of the boundary layer as a fraction of the \n"//& + "boundary layer thickness. The default is 0, but a \n"//& + "value of 0.1 might be better justified by observations.", & + units="nondim", default=0.0) ! This gives a minimum decay scale that is typically much less than Angstrom. CS%ustar_min = 2e-4*CS%omega*(GV%Angstrom_z + GV%H_to_m*GV%H_subroundoff) From 26e86249f16d104a814c024e389e6c8b0ecb2671 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Fri, 30 Sep 2016 20:14:39 -0400 Subject: [PATCH 11/14] Rearraged interations in energetic_PBL Rearranged the iterative portion of energetic_PBL to reduce what is being done inside of the iterations, and fixed the energy diagnostics so that they do not accumulate across multiple iterations. All existing answers are bitwise identical, but it is possible that this could change answers with USE_MLD_ITERATIONS (this variant has not been tested). --- .../vertical/MOM_energetic_PBL.F90 | 259 ++++++++++-------- 1 file changed, 141 insertions(+), 118 deletions(-) diff --git a/src/parameterizations/vertical/MOM_energetic_PBL.F90 b/src/parameterizations/vertical/MOM_energetic_PBL.F90 index 11f79d6d51..4a374d5262 100644 --- a/src/parameterizations/vertical/MOM_energetic_PBL.F90 +++ b/src/parameterizations/vertical/MOM_energetic_PBL.F90 @@ -239,15 +239,16 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & real, dimension(SZI_(G)) :: & mech_TKE, & ! The mechanically generated turbulent kinetic energy ! available for mixing over a time step, in J m-2 = kg s-2. - conv_PErel, & ! The potential energy that has been convectively released + conv_PErel, & ! The potential energy that has been convectively released ! during this timestep, in J m-2 = kg s-2. A portion nstar_FC ! of conv_PErel is available to drive mixing. htot, & ! The total depth of the layers above an interface, in H. uhtot, & ! The depth integrated zonal and meridional velocities in the vhtot, & ! layers above, in H m s-1. + mech_TKE_top, & ! The value of mech_TKE at the top of the column, in J m-2. + conv_PErel_top, & ! The value of conv_PErel at the top of the column, in J m-2. Idecay_len_TKE, & ! The inverse of a turbulence decay length scale, in H-1. - h_bot, & ! The distance from the bottom, in H. h_sum, & ! The total thickness of the water column, in H. absf ! The absolute value of f, in s-1. @@ -303,6 +304,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & real :: dt_h ! The timestep divided by the averages of the thicknesses around ! a layer, times a thickness conversion factor, in H s m-2. + real :: h_bot ! The distance from the bottom, in H. + real :: h_rsum ! The running sum of h from the top, in H. real :: I_hs ! The inverse of h_sum, in H-1. real :: I_mld ! The inverse of the current value of MLD, in H-1. real :: h_tt ! The distance from the surface or up to the next interface @@ -369,6 +372,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & logical :: write_diags ! If true, write out diagnostics with this step. logical :: reset_diags ! If true, zero out the accumulated diagnostics. ! detrainment, in units of m. + ! Local column copies of energy change diagnostics, all in J m-2. + real :: dTKE_conv, dTKE_forcing, dTKE_mixing + real :: dTKE_MKE, dTKE_mech_decay, dTKE_conv_decay !---------------------------------------------------------------------- !/BGR added Aug24,2016 for adding iteration to get boundary layer depth ! - needed to compute new mixing length. @@ -498,10 +504,12 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !!OMP TKE_reduc,dTe_t2,dSe_t2,dTe,dSe,dt_h, & !!OMP Convectively_stable,sfc_disconnect,b1, & !!OMP c1,dT_km1_t2,dS_km1_t2,dTe_term, & -!!OMP dSe_term,MKE2_Hharm,vstar,h_tt, & +!!OMP dSe_term,MKE2_Hharm,vstar,h_tt,h_rsum, & !!OMP Kd_guess0,Kddt_h_g0,dPEc_dKd_Kd0, & !!OMP PE_chg_max,dPEa_dKd_g0,PE_chg_g0, & !!OMP MKE_src,dPE_conv,Kddt_h_max,Kddt_h_min, & +!!OMP dTKE_conv, dTKE_forcing, dTKE_mixing, & +!!OMP dTKE_MKE,dTKE_mech_decay,dTKE_conv_decay,& !!OMP TKE_left_max,TKE_left_min,Kddt_h_guess, & !!OMP TKE_left_itt,dPEa_dKd_itt,PE_chg_itt, & !!OMP MKE_src_itt,Kddt_h_itt,dPEc_dKd,PE_chg, & @@ -533,13 +541,87 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! and ustar and wstar available to drive mixing at the first interior ! interface. do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then - !/The following lines are for the iteration over MLD - !{ - max_MLD = 0.0 ! max_MLD will initialized as ocean bottom depth + + + U_Star = fluxes%ustar(i,j) + if (associated(fluxes%ustar_shelf) .and. associated(fluxes%frac_shelf_h)) then + if (fluxes%frac_shelf_h(i,j) > 0.0) & + U_Star = (1.0 - fluxes%frac_shelf_h(i,j)) * U_star + & + fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j) + endif + if (U_Star < CS%ustar_min) U_Star = CS%ustar_min + + if (CS%omega_frac >= 1.0) then ; absf(i) = 2.0*CS%omega + else + absf(i) = 0.25*((abs(G%CoriolisBu(I,J)) + abs(G%CoriolisBu(I-1,J-1))) + & + (abs(G%CoriolisBu(I,J-1)) + abs(G%CoriolisBu(I-1,J)))) + if (CS%omega_frac > 0.0) & + absf = sqrt(CS%omega_frac*4.0*CS%omega**2 + (1.0-CS%omega_frac)*absf**2) + endif + + mech_TKE(i) = (dt*CS%mstar*GV%Rho0)*((U_Star**3)) + conv_PErel(i) = 0.0 + + if (CS%TKE_diagnostics) then + CS%diag_TKE_wind(i,j) = CS%diag_TKE_wind(i,j) + mech_TKE(i) * IdtdR0 + if (TKE_forced(i,j,1) <= 0.0) then + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + & + max(-mech_TKE(i), TKE_forced(i,j,1)) * IdtdR0 + ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & + ! min(0.0, TKE_forced(i,j,1) + mech_TKE(i)) * IdtdR0 + else + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,1) * IdtdR0 + endif + endif + + if (TKE_forced(i,j,1) <= 0.0) then + mech_TKE(i) = mech_TKE(i) + TKE_forced(i,j,1) + if (mech_TKE(i) < 0.0) mech_TKE(i) = 0.0 + else + conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,1) + endif + +! endif ; enddo + +! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then + + h_sum(i) = H_neglect ; do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo + I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) + + h_bot = 0.0 ; hb_hs(i,nz+1) = 0.0 + do k=nz,1,-1 + h_bot = h_bot + h(i,k) + hb_hs(i,K) = h_bot * I_hs + enddo + + pres(i,1) = 0.0 do k=1,nz - max_MLD = max_MLD + h(i,k)*GV%H_to_m + dMass = GV%H_to_kg_m2 * h(i,k) + dPres = GV%g_Earth * dMass + dT_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dT(i,j,k) + dS_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dS(i,j,k) + dT_to_dColHt(i,k) = dMass * dSV_dT(i,j,k) + dS_to_dColHt(i,k) = dMass * dSV_dS(i,j,k) + + pres(i,K+1) = pres(i,K) + dPres enddo + +! endif ; enddo + + ! Note the outer i-loop and inner k-loop loop order!!! +! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then + do k=1,nz ; T0(k) = T(i,k) ; S0(k) = S(i,k) ; enddo + + ! Store the initial mechanical TKE and convectively released PE to + ! enable multiple iterations. + mech_TKE_top(i) = mech_TKE(i) ; conv_PErel_top(i) = conv_PErel(i) + + !/The following lines are for the iteration over MLD + !{ + ! max_MLD will initialized as ocean bottom depth + max_MLD = 0.0 ; do k=1,nz ; max_MLD = max_MLD + h(i,k)*GV%H_to_m ; enddo min_MLD = 0.0 !min_MLD will initialize as 0. + !/BGR: May add user-input bounds for max/min MLD !/BGR: Add MLD_guess based on stored previous value. ! note that this is different from ML_Depth already @@ -551,14 +633,21 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & !Otherwise guess middle of water column. MLD_guess = 0.5 * (min_MLD+max_MLD) endif - !/BGR: May add user-input bounds for max/min MLD ! Iterate up to MAX_OBL_IT times to determine a converged EPBL depth. OBL_CONVERGED = .false. do OBL_IT=1,MAX_OBL_IT ; if (.not. OBL_CONVERGED) then CS%ML_depth(i,j) = h(i,1)*GV%H_to_m !CS%ML_depth2(i,j) = h(i,1)*GV%H_to_m + sfc_connected(i) = .true. + mech_TKE(i) = mech_TKE_top(i) ; conv_PErel(i) = conv_PErel_top(i) + + + if (CS%TKE_diagnostics) then + dTKE_conv = 0.0 ; dTKE_forcing = 0.0 ; dTKE_mixing = 0.0 + dTKE_MKE = 0.0 ; dTKE_mech_decay = 0.0 ; dTKE_conv_decay = 0.0 + endif ! Store in 1D arrays cleared out each iteration. Only write in ! 3D arrays after convergence. @@ -566,63 +655,6 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & Vstar_Used(k) = 0.0 ; Mixing_Length_Used(k) = 0.0 enddo if (.not.CS%Use_MLD_Iteration) OBL_CONVERGED = .true. - !/This ends the new code for the iteration. - !} - U_Star = fluxes%ustar(i,j) - if (associated(fluxes%ustar_shelf) .and. associated(fluxes%frac_shelf_h)) then - if (fluxes%frac_shelf_h(i,j) > 0.0) & - U_Star = (1.0 - fluxes%frac_shelf_h(i,j)) * U_star + & - fluxes%frac_shelf_h(i,j) * fluxes%ustar_shelf(i,j) - endif - if (U_Star < CS%ustar_min) U_Star = CS%ustar_min - - if (CS%omega_frac >= 1.0) then ; absf(i) = 2.0*CS%omega - else - absf(i) = 0.25*((abs(G%CoriolisBu(I,J)) + abs(G%CoriolisBu(I-1,J-1))) + & - (abs(G%CoriolisBu(I,J-1)) + abs(G%CoriolisBu(I-1,J)))) - if (CS%omega_frac > 0.0) & - absf = sqrt(CS%omega_frac*4.0*CS%omega**2 + (1.0-CS%omega_frac)*absf**2) - endif - - mech_TKE(i) = (dt*CS%mstar*GV%Rho0)*((U_Star**3)) - conv_PErel(i) = 0.0 - - if (CS%TKE_diagnostics) then - CS%diag_TKE_wind(i,j) = CS%diag_TKE_wind(i,j) + mech_TKE(i) * IdtdR0 - if (TKE_forced(i,j,1) <= 0.0) then - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + & - max(-mech_TKE(i), TKE_forced(i,j,1)) * IdtdR0 - ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & - ! min(0.0, TKE_forced(i,j,1) + mech_TKE(i)) * IdtdR0 - else - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,1) * IdtdR0 - endif - endif - - if (TKE_forced(i,j,1) <= 0.0) then - mech_TKE(i) = mech_TKE(i) + TKE_forced(i,j,1) - if (mech_TKE(i) < 0.0) mech_TKE(i) = 0.0 - else - conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,1) - endif - - ! endif ; enddo - - ! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then - if (debug) then - mech_TKE_k(i,1) = mech_TKE(i) ; conv_PErel_k(i,1) = conv_PErel(i) - nstar_k(:) = 0.0 ; nstar_k(1) = CS%nstar - endif - - h_sum(i) = H_neglect - do k=1,nz ; h_sum(i) = h_sum(i) + h(i,k) ; enddo - I_hs = 0.0 ; if (h_sum(i) > 0.0) I_hs = 1.0 / h_sum(i) - - h_bot(i) = 0.0 ; hb_hs(i,nz+1) = 0.0 - do k=nz,1,-1 - h_bot(i) = h_bot(i) + h(i,k) - hb_hs(i,K) = h_bot(i) * I_hs - enddo if ((.not.CS%Use_MLD_Iteration) .or. & (CS%transLay_scale >= 1.0) .or. (CS%transLay_scale < 0.0) ) then @@ -636,45 +668,27 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & else ! Reduce the mixing length based on MLD, with a quadratic ! expression that follows KPP. - I_MLD = 1.0 / MLD_guess - h_sum(i) = 0.0 + I_MLD = 1.0 / MLD_guess ; h_rsum = 0.0 MixLen_shape(1) = 1.0 do K=2,nz+1 - h_sum(i) = h_sum(i)+h(i,k-1) + h_rsum = h_rsum + h(i,k-1) MixLen_shape(K) = CS%transLay_scale + (1.0 - CS%transLay_scale) * & - (max(0.0, (MLD_guess - h_sum(i))*I_MLD) )**2 + (max(0.0, (MLD_guess - h_rsum)*I_MLD) )**2 enddo endif - ! endif ; enddo - - ! Note the outer i-loop and inner k-loop loop order!!! - ! do i=is,ie ; if (G%mask2dT(i,j) > 0.5) then - do k=1,nz ; T0(k) = T(i,k) ; S0(k) = S(i,k) ; enddo - num_itts(:) = -1 - - pres(i,1) = 0.0 - do k=1,nz - dMass = GV%H_to_kg_m2 * h(i,k) - dPres = GV%g_Earth * dMass - dT_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dT(i,j,k) - dS_to_dPE(i,k) = (dMass * (pres(i,K) + 0.5*dPres)) * dSV_dS(i,j,k) - dT_to_dColHt(i,k) = dMass * dSV_dT(i,j,k) - dS_to_dColHt(i,k) = dMass * dSV_dS(i,j,k) - - pres(i,K+1) = pres(i,K) + dPres - enddo Kd(i,1) = 0.0 ; Kddt_h(1) = 0.0 hp_a(i) = h(i,1) - dT_to_dPE_a(i,1) = dT_to_dPE(i,1) - dS_to_dPE_a(i,1) = dS_to_dPE(i,1) - dT_to_dColHt_a(i,1) = dT_to_dColHt(i,1) - dS_to_dColHt_a(i,1) = dS_to_dColHt(i,1) + dT_to_dPE_a(i,1) = dT_to_dPE(i,1) ; dT_to_dColHt_a(i,1) = dT_to_dColHt(i,1) + dS_to_dPE_a(i,1) = dS_to_dPE(i,1) ; dS_to_dColHt_a(i,1) = dS_to_dColHt(i,1) + + htot(i) = h(i,1) ; uhtot(i) = u(i,1)*h(i,1) ; vhtot(i) = v(i,1)*h(i,1) - htot(i) = h(i,1) - uhtot(i) = u(i,1)*h(i,1) - vhtot(i) = v(i,1)*h(i,1) + if (debug) then + mech_TKE_k(i,1) = mech_TKE(i) ; conv_PErel_k(i,1) = conv_PErel(i) + nstar_k(:) = 0.0 ; nstar_k(1) = CS%nstar ; num_itts(:) = -1 + endif do K=2,nz ! Apply dissipation to the TKE, here applied as an exponential decay @@ -687,8 +701,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & Idecay_len_TKE(i) = (CS%TKE_decay * absf(i) / U_Star) * GV%H_to_m exp_kh = 1.0 if (Idecay_len_TKE(i) > 0.0) exp_kh = exp(-h(i,k-1)*Idecay_len_TKE(i)) - if (CS%TKE_diagnostics) CS%diag_TKE_mech_decay(i,j) = & - CS%diag_TKE_mech_decay(i,j) + (exp_kh-1.0) * mech_TKE(i) * IdtdR0 + if (CS%TKE_diagnostics) & + dTKE_mech_decay = dTKE_mech_decay + (exp_kh-1.0) * mech_TKE(i) * IdtdR0 mech_TKE(i) = mech_TKE(i) * exp_kh @@ -696,9 +710,8 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! to wstar and to drive penetrating convection. if (TKE_forced(i,j,k) > 0.0) then conv_PErel(i) = conv_PErel(i) + TKE_forced(i,j,k) - if (CS%TKE_diagnostics) then - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + CS%nstar*TKE_forced(i,j,k) * IdtdR0 - endif + if (CS%TKE_diagnostics) & + dTKE_forcing = dTKE_forcing + CS%nstar*TKE_forced(i,j,k) * IdtdR0 endif if (debug) then @@ -724,11 +737,11 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & if (TKE_forced(i,j,k) + tot_TKE < 0.0) then ! The shortwave requirements deplete all the energy in this layer. if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) + tot_TKE * IdtdR0 - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) - tot_TKE * IdtdR0 - ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + & + dTKE_mixing = dTKE_mixing + tot_TKE * IdtdR0 + dTKE_forcing = dTKE_forcing - tot_TKE * IdtdR0 + ! dTKE_unbalanced_forcing = dTKE_unbalanced_forcing + & ! (TKE_forced(i,j,k) + tot_TKE) * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + dTKE_conv_decay = dTKE_conv_decay + & (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif tot_TKE = 0.0 ; mech_TKE(i) = 0.0 ; conv_PErel(i) = 0.0 @@ -736,9 +749,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! Reduce the mechanical and convective TKE proportionately. TKE_reduc = (tot_TKE + TKE_forced(i,j,k)) / tot_TKE if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - TKE_forced(i,j,k) * IdtdR0 - CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + TKE_forced(i,j,k) * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + dTKE_mixing = dTKE_mixing - TKE_forced(i,j,k) * IdtdR0 + dTKE_forcing = dTKE_forcing + TKE_forced(i,j,k) * IdtdR0 + dTKE_conv_decay = dTKE_conv_decay + & (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif tot_TKE = TKE_reduc*tot_TKE ! = tot_TKE + TKE_forced(i,j,k) @@ -934,12 +947,12 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & conv_PErel(i) = conv_PErel(i) - dPE_conv mech_TKE(i) = mech_TKE(i) + MKE_src if (CS%TKE_diagnostics) then - CS%diag_TKE_conv(i,j) = CS%diag_TKE_conv(i,j) - CS%nstar*dPE_conv * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 + dTKE_conv = dTKE_conv - CS%nstar*dPE_conv * IdtdR0 + dTKE_MKE = dTKE_MKE + MKE_src * IdtdR0 endif if (sfc_connected(i)) then - CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) - !CS%ML_depth2(i,j) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) + CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) + !CS%ML_depth2(i,j) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) endif Kddt_h(K) = Kd(i,k)*dt_h @@ -954,17 +967,17 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & if (tot_TKE > 0.0) TKE_reduc = (tot_TKE - PE_chg_g0) / tot_TKE if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - PE_chg_g0 * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + dTKE_mixing = dTKE_mixing - PE_chg_g0 * IdtdR0 + dTKE_MKE = dTKE_MKE + MKE_src * IdtdR0 + dTKE_conv_decay = dTKE_conv_decay + & (1.0-TKE_reduc)*(CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif tot_TKE = TKE_reduc*tot_TKE mech_TKE(i) = TKE_reduc*(mech_TKE(i) + MKE_src) conv_PErel(i) = TKE_reduc*conv_PErel(i) if (sfc_connected(i)) then - CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) - !CS%ML_depth2(i,J) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) + CS%ML_depth(i,J) = CS%ML_depth(i,J) + GV%H_to_m * h(i,k) + !CS%ML_depth2(i,J) = CS%ML_depth2(i,J) + GV%H_to_m * h(i,k) endif elseif (tot_TKE == 0.0) then ! This can arise if nstar_FC = 0. @@ -1056,9 +1069,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & ! All TKE should have been consumed. if (CS%TKE_diagnostics) then - CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) - (tot_TKE + MKE_src) * IdtdR0 - CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + MKE_src * IdtdR0 - CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + & + dTKE_mixing = dTKE_mixing - (tot_TKE + MKE_src) * IdtdR0 + dTKE_MKE = dTKE_MKE + MKE_src * IdtdR0 + dTKE_conv_decay = dTKE_conv_decay + & (CS%nstar-nstar_FC) * conv_PErel(i) * IdtdR0 endif @@ -1213,6 +1226,16 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, CS, & else CONVERGED=CONVERGED+1 endif + + if (CS%TKE_diagnostics) then + CS%diag_TKE_MKE(i,j) = CS%diag_TKE_MKE(i,j) + dTKE_MKE + CS%diag_TKE_conv(i,j) = CS%diag_TKE_conv(i,j) + dTKE_conv + CS%diag_TKE_forcing(i,j) = CS%diag_TKE_forcing(i,j) + dTKE_forcing + CS%diag_TKE_mixing(i,j) = CS%diag_TKE_mixing(i,j) + dTKE_mixing + CS%diag_TKE_mech_decay(i,j) = CS%diag_TKE_mech_decay(i,j) + dTKE_mech_decay + CS%diag_TKE_conv_decay(i,j) = CS%diag_TKE_conv_decay(i,j) + dTKE_conv_decay + ! CS%diag_TKE_unbalanced_forcing(i,j) = CS%diag_TKE_unbalanced_forcing(i,j) + dTKE_unbalanced + endif if (CS%Mixing_Diagnostics) then !Write to 3-D for outputing Mixing length and ! velocity scale. From 96d066c95af03828523f469f78d8f2348c43270c Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Thu, 11 Aug 2016 16:21:12 -0400 Subject: [PATCH 12/14] Fix for a LOAR2 model crash - LOAR2 model crashed with the following traceback with a particular combination of paramter overrides THERMO_SPANS_COUPLING = True FATAL from PE 294: MPP_RESET_GROUP_UPDATE_FIELD_3D_: group%reset_index_s > group%nscalar Image PC Routine Line Source fms_LOAR2G_exec.x 0000000002F0F106 mpp_mod_mp_mpp_er 50 mpp_util_mpi.inc fms_LOAR2G_exec.x 0000000002CA7DE7 mpp_domains_mod_m 887 mpp_group_update.h fms_LOAR2G_exec.x 0000000002227039 mom_domains_mp_cr 711 MOM_domains.F90 fms_LOAR2G_exec.x 00000000022655DA mom_mp_step_mom_ 521 MOM.F90 fms_LOAR2G_exec.x 000000000216894E ocean_model_mod_m 426 ocean_model_MOM.F90 fms_LOAR2G_exec.x 0000000000401CE8 MAIN__ 916 coupler_main.F90 - Zhi found a mismatch between the logic for calling group_create and group_update that would cause this issue. He also made the fix. The model does not crash with the fix. --- src/core/MOM.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 8c023adbac..69c8225d81 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -523,8 +523,9 @@ subroutine step_MOM(fluxes, state, Time_start, time_interval, CS) call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%ustar(:,:), G%Domain) if (ASSOCIATED(fluxes%p_surf)) & call create_group_pass(CS%pass_tau_ustar_psurf, fluxes%p_surf(:,:), G%Domain) - if (CS%thickness_diffuse .OR. CS%mixedlayer_restrat) & + if ((CS%thickness_diffuse .and. (.not.CS%thickness_diffuse_first .or. CS%dt_trans == 0) ) .OR. CS%mixedlayer_restrat) & call create_group_pass(CS%pass_h, h, G%Domain) + if (CS%diabatic_first) then if (associated(CS%visc%Ray_u) .and. associated(CS%visc%Ray_v)) & call create_group_pass(CS%pass_ray, CS%visc%Ray_u, CS%visc%Ray_v, G%Domain, & From 29139b8ab14c01255cac3ab332c87c1bfc431c2c Mon Sep 17 00:00:00 2001 From: Niki Zadeh Date: Wed, 5 Oct 2016 15:53:53 -0400 Subject: [PATCH 13/14] make new arguments optional - For backward compatibility with GOLD and MOM5 adding new arguments to generic tracer routines must be "optional" and appear after all regular arguments to avoid collisions with existing arguments. --- src/tracer/MOM_generic_tracer.F90 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_generic_tracer.F90 b/src/tracer/MOM_generic_tracer.F90 index ffa9536c86..bac6c0eab8 100644 --- a/src/tracer/MOM_generic_tracer.F90 +++ b/src/tracer/MOM_generic_tracer.F90 @@ -636,9 +636,9 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G !Calculate tendencies (i.e., field changes at dt) from the sources / sinks ! - call generic_tracer_source(tv%T,tv%S,sosga,rho_dzt,dzt,hblt_depth,G%isd,G%jsd,1,dt,& + call generic_tracer_source(tv%T,tv%S,rho_dzt,dzt,hblt_depth,G%isd,G%jsd,1,dt,& G%areaT,get_diag_time_end(CS%diag),& - optics%nbands, optics%max_wavelength_band, optics%sw_pen_band, optics%opacity_band) + optics%nbands, optics%max_wavelength_band, optics%sw_pen_band, optics%opacity_band, sosga=sosga) ! This uses applyTracerBoundaryFluxesInOut to handle the change in tracer due to freshwater fluxes ! usually in ALE mode @@ -910,10 +910,9 @@ subroutine MOM_generic_tracer_surface_state(state, h, G, CS) call generic_tracer_coupler_set(state%tr_fields,& ST=state%SST,& SS=state%SSS,& - sosga=sosga, & rho=rho0,& !nnz: required for MOM5 and previous versions. ilb=G%isd, jlb=G%jsd,& - tau=1,model_time=get_diag_time_end(CS%diag)) + tau=1,sosga=sosga,model_time=get_diag_time_end(CS%diag)) !Output diagnostics via diag_manager for all tracers in this module ! if(.NOT. associated(CS%g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& From 9af2fd175395b54007d193afa04fe4c5c5ce7953 Mon Sep 17 00:00:00 2001 From: Alistair Adcroft Date: Thu, 6 Oct 2016 11:32:10 -0400 Subject: [PATCH 14/14] Cleaned up whitespace in MOM_forcing_type.F90 - Removed trailing whitespace. - No answer changes. --- src/core/MOM_forcing_type.F90 | 54 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/core/MOM_forcing_type.F90 b/src/core/MOM_forcing_type.F90 index b422df2ff3..11ecb7a3db 100644 --- a/src/core/MOM_forcing_type.F90 +++ b/src/core/MOM_forcing_type.F90 @@ -109,7 +109,7 @@ module MOM_forcing_type p_surf_full => NULL(), & !< Pressure at the top ocean interface (Pa). !! if there is sea-ice, then p_surf_flux is at ice-ocean interface p_surf => NULL(), & !< Pressure at the top ocean interface (Pa) as used - !! to drive the ocean model. If p_surf is limited, + !! to drive the ocean model. If p_surf is limited, !! p_surf may be smaller than p_surf_full, !! otherwise they are the same. p_surf_SSH => NULL() !< Pressure at the top ocean interface that is used @@ -201,7 +201,7 @@ module MOM_forcing_type integer :: id_heat_content_cond = -1, id_heat_content_surfwater= -1 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_hfrainds = -1, id_hfrunoffds = -1 ! global area integrated heat flux diagnostic handles @@ -1170,7 +1170,7 @@ subroutine register_forcing_type_diags(Time, diag, use_temperature, handles) handles%id_hfrunoffds = register_diag_field('ocean_model', 'hfrunoffds', & diag%axesT1, Time, 'Heat content (relative to 0C) of liquid+solid runoff into ocean', 'W m-2',& standard_name='temperature_flux_due_to_runoff_expressed_as_heat_flux_into_sea_water') - + handles%id_heat_content_lprec = register_diag_field('ocean_model', 'heat_content_lprec', & diag%axesT1,Time,'Heat content (relative to 0degC) of liquid precip entering ocean', & 'W/m^2') @@ -1652,7 +1652,7 @@ subroutine forcing_accumulate(flux_tmp, fluxes, dt, G, wt2) fluxes%ustar_shelf(i,j) = flux_tmp%ustar_shelf(i,j) enddo ; enddo endif - + if (associated(fluxes%iceshelf_melt) .and. associated(flux_tmp%iceshelf_melt)) then do i=isd,ied ; do j=jsd,jed fluxes%iceshelf_melt(i,j) = flux_tmp%iceshelf_melt(i,j) @@ -2017,31 +2017,31 @@ subroutine forcing_diagnostics(fluxes, state, dt, G, diag, handles) endif ! for OMIP, hfrunoffds = heat content of liquid plus frozen runoff - if (handles%id_hfrunoffds > 0) then - sum(:,:) = 0.0 - if(ASSOCIATED(fluxes%heat_content_lrunoff)) then + if (handles%id_hfrunoffds > 0) then + sum(:,:) = 0.0 + if(ASSOCIATED(fluxes%heat_content_lrunoff)) then sum(:,:) = sum(:,:) + fluxes%heat_content_lrunoff(:,:) - endif - if(ASSOCIATED(fluxes%heat_content_frunoff)) then + endif + if(ASSOCIATED(fluxes%heat_content_frunoff)) then sum(:,:) = sum(:,:) + fluxes%heat_content_frunoff(:,:) - endif + endif call post_data(handles%id_hfrunoffds, sum, diag) - endif + endif - ! for OMIP, hfrainds = heat content of lprec + fprec + cond - if (handles%id_hfrainds > 0) then - sum(:,:) = 0.0 - if(ASSOCIATED(fluxes%heat_content_lprec)) then + ! for OMIP, hfrainds = heat content of lprec + fprec + cond + if (handles%id_hfrainds > 0) then + sum(:,:) = 0.0 + if(ASSOCIATED(fluxes%heat_content_lprec)) then sum(:,:) = sum(:,:) + fluxes%heat_content_lprec(:,:) - endif - if(ASSOCIATED(fluxes%heat_content_fprec)) then + endif + if(ASSOCIATED(fluxes%heat_content_fprec)) then sum(:,:) = sum(:,:) + fluxes%heat_content_fprec(:,:) - endif - if(ASSOCIATED(fluxes%heat_content_cond)) then + endif + if(ASSOCIATED(fluxes%heat_content_cond)) then sum(:,:) = sum(:,:) + fluxes%heat_content_cond(:,:) - endif + endif call post_data(handles%id_hfrainds, sum, diag) - endif + endif if ((handles%id_LwLatSens > 0) .and. ASSOCIATED(fluxes%lw) .and. & ASSOCIATED(fluxes%latent) .and. ASSOCIATED(fluxes%sens)) then @@ -2201,7 +2201,7 @@ end subroutine forcing_diagnostics !> Conditionally allocate fields within the forcing type -subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press,iceberg) +subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press, iceberg) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(forcing), intent(inout) :: fluxes !< Forcing fields structure logical, optional, intent(in) :: stress !< If present and true, allocate taux, tauy @@ -2262,11 +2262,11 @@ subroutine allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, p call myAlloc(fluxes%rigidity_ice_v,isd,ied,JsdB,JedB, shelf) call myAlloc(fluxes%p_surf,isd,ied,jsd,jed, press) - + !These fields should only on allocated when iceberg area is being passed through the coupler. - call myAlloc(fluxes%ustar_berg,isd,ied,jsd,jed, iceberg) - call myAlloc(fluxes%area_berg,isd,ied,jsd,jed, iceberg) - call myAlloc(fluxes%mass_berg,isd,ied,jsd,jed, iceberg) + call myAlloc(fluxes%ustar_berg,isd,ied,jsd,jed, iceberg) + call myAlloc(fluxes%area_berg,isd,ied,jsd,jed, iceberg) + call myAlloc(fluxes%mass_berg,isd,ied,jsd,jed, iceberg) contains !> Allocates and zeroes-out array. @@ -2338,7 +2338,7 @@ subroutine deallocate_forcing_type(fluxes) if (associated(fluxes%rigidity_ice_u)) deallocate(fluxes%rigidity_ice_u) if (associated(fluxes%rigidity_ice_v)) deallocate(fluxes%rigidity_ice_v) if (associated(fluxes%tr_fluxes)) deallocate(fluxes%tr_fluxes) - if (associated(fluxes%ustar_berg)) deallocate(fluxes%ustar_berg) + if (associated(fluxes%ustar_berg)) deallocate(fluxes%ustar_berg) if (associated(fluxes%area_berg)) deallocate(fluxes%area_berg) if (associated(fluxes%mass_berg)) deallocate(fluxes%mass_berg) end subroutine deallocate_forcing_type