From f7b7dcd5d2fc436f2d499a4335df37361aba1f2b Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 12 Sep 2023 15:15:46 +0200 Subject: [PATCH] update changes to subcycling, try to make energy diagnostic consistent with subcycling --- src/gen_modules_diag.F90 | 4 +- src/io_meandata.F90 | 94 ++++---- src/oce_ale.F90 | 119 +++++++--- src/oce_ale_ssh_splitexpl_subcycl.F90 | 301 ++++++++++---------------- src/oce_dyn.F90 | 66 +++--- 5 files changed, 290 insertions(+), 294 deletions(-) diff --git a/src/gen_modules_diag.F90 b/src/gen_modules_diag.F90 index cc678bf56..c8ac0eca3 100644 --- a/src/gen_modules_diag.F90 +++ b/src/gen_modules_diag.F90 @@ -76,7 +76,9 @@ module diagnostics logical :: ldiag_vorticity =.false. logical :: ldiag_extflds =.false. - namelist /diag_list/ ldiag_solver, lcurt_stress_surf, ldiag_curl_vel3, ldiag_Ri, ldiag_TurbFlux, ldiag_dMOC, ldiag_DVD, ldiag_salt3D, ldiag_forc, ldiag_vorticity, ldiag_extflds + namelist /diag_list/ ldiag_solver, lcurt_stress_surf, ldiag_curl_vel3, ldiag_Ri, & + ldiag_TurbFlux, ldiag_dMOC, ldiag_DVD, ldiag_salt3D, ldiag_forc, & + ldiag_vorticity, ldiag_extflds contains diff --git a/src/io_meandata.F90 b/src/io_meandata.F90 index 37819c762..314ee73a2 100644 --- a/src/io_meandata.F90 +++ b/src/io_meandata.F90 @@ -487,6 +487,8 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh) if (Fer_GM) then call def_stream( nod2D , myDim_nod2D , 'fer_C', 'GM, depth independent speed', 'm/s' , fer_c(:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) end if +CASE ('cfl_z ') + call def_stream((/nl, nod2D/), (/nl, myDim_nod2D/), 'cfl_z', 'vertical CFL criteria', '?', dynamics%cfl_z(:,:), io_list(i)%freq, io_list(i)%unit, io_list(i)%precision, partit, mesh) !_______________________________________________________________________________ ! Density MOC diagnostics @@ -716,72 +718,72 @@ subroutine ini_mean_io(ice, dynamics, tracers, partit, mesh) end if if (dynamics%ldiag_ke) then - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_u_xVEL', 'work of advection [u]', 'm2/s2', dynamics%ke_adv_xVEL(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_v_xVEL', 'work of advection [v]', 'm2/s2', dynamics%ke_adv_xVEL(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_u_xVEL', 'work of advection [u]', 'm2/s2', dynamics%ke_adv_xVEL(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_v_xVEL', 'work of advection [v]', 'm2/s2', dynamics%ke_adv_xVEL(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_u_xVEL', 'work Coriolis :) [u]', 'm2/s2', dynamics%ke_cor_xVEL(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_v_xVEL', 'work Coriolis :) [v]', 'm2/s2', dynamics%ke_cor_xVEL(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_u_xVEL', 'work Coriolis :) [u]', 'm2/s2', dynamics%ke_cor_xVEL(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_v_xVEL', 'work Coriolis :) [v]', 'm2/s2', dynamics%ke_cor_xVEL(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_u_xVEL', 'work of pressure gradient [x]', 'm2/s2', dynamics%ke_pre_xVEL(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_v_xVEL', 'work of pressure gradient [y]', 'm2/s2', dynamics%ke_pre_xVEL(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_u_xVEL', 'work of pressure gradient [x]', 'm2/s2', dynamics%ke_pre_xVEL(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_v_xVEL', 'work of pressure gradient [y]', 'm2/s2', dynamics%ke_pre_xVEL(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_u_xVEL', 'work of hor. visc. [x]', 'm2/s2', dynamics%ke_hvis_xVEL(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_v_xVEL', 'work of hor. visc. [y]', 'm2/s2', dynamics%ke_hvis_xVEL(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_u_xVEL', 'work of hor. visc. [x]', 'm2/s2', dynamics%ke_hvis_xVEL(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_v_xVEL', 'work of hor. visc. [y]', 'm2/s2', dynamics%ke_hvis_xVEL(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_u_xVEL', 'work of ver. visc. [x]', 'm2/s2', dynamics%ke_vvis_xVEL(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_v_xVEL', 'work of ver. visc. [y]', 'm2/s2', dynamics%ke_vvis_xVEL(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_u_xVEL', 'work of ver. visc. [x]', 'm2/s2', dynamics%ke_vvis_xVEL(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_v_xVEL', 'work of ver. visc. [y]', 'm2/s2', dynamics%ke_vvis_xVEL(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_du2', 'KE change [0.5 du2]', 'm2/s2', dynamics%ke_du2(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_dv2', 'KE change [0.5 dv2]', 'm2/s2', dynamics%ke_du2(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_du2', 'KE change [0.5 du2]', 'm2/s2', dynamics%ke_du2(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_dv2', 'KE change [0.5 dv2]', 'm2/s2', dynamics%ke_du2(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'W_x_RHO', 'buoyancy work = ke_pre x VEL', 'm2/s2', dynamics%ke_wrho(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'W_x_RHO', 'buoyancy work = ke_pre x VEL', 'm2/s2', dynamics%ke_wrho(:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_wind_x_xVEL', 'work of wind [x]', 'm2/s2', dynamics%ke_wind_xVEL(1,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_wind_y_xVEL', 'work of wind [y]', 'm2/s2', dynamics%ke_wind_xVEL(2,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_wind_x_xVEL', 'work of wind [x]', 'm2/s2', dynamics%ke_wind_xVEL(1,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_wind_y_xVEL', 'work of wind [y]', 'm2/s2', dynamics%ke_wind_xVEL(2,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_drag_x_xVEL', 'work of drag [x]', 'm2/s2', dynamics%ke_drag_xVEL(1,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_drag_y_xVEL', 'work of drag [y]', 'm2/s2', dynamics%ke_drag_xVEL(2,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_drag_x_xVEL', 'work of drag [x]', 'm2/s2', dynamics%ke_drag_xVEL(1,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_drag_y_xVEL', 'work of drag [y]', 'm2/s2', dynamics%ke_drag_xVEL(2,:), io_list(i)%freq, 'y', 8, partit, mesh) ! same as above but without multiplying with UMEAN (for later computation of turbulence fluxes) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_u', 'advection *dT [u]', 'm/s', dynamics%ke_adv(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_v', 'advection *dT [v]', 'm/s', dynamics%ke_adv(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_u', 'advection *dT [u]', 'm/s', dynamics%ke_adv(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_adv_v', 'advection *dT [v]', 'm/s', dynamics%ke_adv(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_u', 'Coriolis *dT [X]', 'm/s', dynamics%ke_cor(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_v', 'Coriolis *dT [Y]', 'm/s', dynamics%ke_cor(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_u', 'Coriolis *dT [X]', 'm/s', dynamics%ke_cor(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_cor_v', 'Coriolis *dT [Y]', 'm/s', dynamics%ke_cor(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_u', 'pressure gradient *dT [x]', 'm/s', dynamics%ke_pre(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_v', 'pressure gradient *dT [y]', 'm/s', dynamics%ke_pre(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_u', 'pressure gradient *dT [x]', 'm/s', dynamics%ke_pre(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_pre_v', 'pressure gradient *dT [y]', 'm/s', dynamics%ke_pre(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_u', 'hor. visc. [x] *dT', 'm/s', dynamics%ke_hvis(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_v', 'hor. visc. [y] *dT', 'm/s', dynamics%ke_hvis(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_u', 'hor. visc. [x] *dT', 'm/s', dynamics%ke_hvis(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_hvis_v', 'hor. visc. [y] *dT', 'm/s', dynamics%ke_hvis(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_u', 'ver. visc. [x] *dT', 'm/s', dynamics%ke_vvis(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_v', 'ver. visc. [y] *dT', 'm/s', dynamics%ke_vvis(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_u', 'ver. visc. [x] *dT', 'm/s', dynamics%ke_vvis(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_vvis_v', 'ver. visc. [y] *dT', 'm/s', dynamics%ke_vvis(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_Umean', 'mean U', 'm/s', dynamics%ke_umean(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_Vmean', 'mean V', 'm/s', dynamics%ke_umean(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_Umean', 'mean U', 'm/s', dynamics%ke_umean(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_Vmean', 'mean V', 'm/s', dynamics%ke_umean(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_U2mean', 'U2 mean', 'm/s', dynamics%ke_u2mean(1,:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_V2mean', 'V2 mean', 'm/s', dynamics%ke_u2mean(2,:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_U2mean', 'U2 mean', 'm/s', dynamics%ke_u2mean(1,:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/), 'ke_V2mean', 'V2 mean', 'm/s', dynamics%ke_u2mean(2,:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'ke_dW', 'd/dz (vertical VEL)', 'm/s', dynamics%ke_dW(:,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'ke_PFULL', 'full Pressure', 'm/s', dynamics%ke_Pfull(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'ke_dW', 'd/dz (vertical VEL)', 'm/s', dynamics%ke_dW(:,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/), 'ke_PFULL', 'full Pressure', 'm/s', dynamics%ke_Pfull(:,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_wind_x', 'wind [x] *dT', 'm/s', dynamics%ke_wind(1,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_wind_y', 'wind [y] *dT', 'm/s', dynamics%ke_wind(2,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_wind_x', 'wind [x] *dT', 'm/s', dynamics%ke_wind(1,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_wind_y', 'wind [y] *dT', 'm/s', dynamics%ke_wind(2,:), io_list(i)%freq, 'y', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_drag_x', 'drag [x] *dT', 'm/s', dynamics%ke_drag(1,:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(elem2D, myDim_elem2D, 'ke_drag_y', 'drag [y] *dT', 'm/s', dynamics%ke_drag(2,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_drag_x', 'drag [x] *dT', 'm/s', dynamics%ke_drag(1,:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(elem2D, myDim_elem2D, 'ke_drag_y', 'drag [y] *dT', 'm/s', dynamics%ke_drag(2,:), io_list(i)%freq, 'y', 8, partit, mesh) ! surface fields for APE input computations... - call def_stream(nod2D , myDim_nod2D , 'ke_J', 'surface temperature flux [Js]','°C/s', dynamics%ke_J(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_G', 'surface salinity flux [Gs]','PSU/s', dynamics%ke_G(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_D', 'surface density', 'kg/m^3', dynamics%ke_D(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_D2', 'surface density squared', 'kg^2/m^6', dynamics%ke_D2(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_n0', 'dRHO/dz', 'kg/m^4', dynamics%ke_n0(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_JD', 'surface temperature flux [Js] * RHO','°C*kg/s/m^3', dynamics%ke_JD(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_GD', 'surface salinity flux [Gs] * RHO','PSU*kg/s/m^3', dynamics%ke_GD(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_swA', 'Thermal expansion coeff (alpha)', '1/°C', dynamics%ke_swA(:), io_list(i)%freq, 'm', 8, partit, mesh) - call def_stream(nod2D , myDim_nod2D , 'ke_swB', 'Taline contraction coeff (beta)', '1/PSU', dynamics%ke_swB(:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_J', 'surface temperature flux [Js]','°C/s', dynamics%ke_J(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_G', 'surface salinity flux [Gs]','PSU/s', dynamics%ke_G(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_D', 'surface density', 'kg/m^3', dynamics%ke_D(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_D2', 'surface density squared', 'kg^2/m^6', dynamics%ke_D2(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_n0', 'dRHO/dz', 'kg/m^4', dynamics%ke_n0(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_JD', 'surface temperature flux [Js] * RHO','°C*kg/s/m^3', dynamics%ke_JD(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_GD', 'surface salinity flux [Gs] * RHO','PSU*kg/s/m^3', dynamics%ke_GD(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_swA', 'Thermal expansion coeff (alpha)', '1/°C', dynamics%ke_swA(:), io_list(i)%freq, 'y', 8, partit, mesh) + call def_stream(nod2D , myDim_nod2D , 'ke_swB', 'Taline contraction coeff (beta)', '1/PSU', dynamics%ke_swB(:), io_list(i)%freq, 'y', 8, partit, mesh) end if end subroutine diff --git a/src/oce_ale.F90 b/src/oce_ale.F90 index 95c40e829..5d1d64778 100644 --- a/src/oce_ale.F90 +++ b/src/oce_ale.F90 @@ -3337,10 +3337,10 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) !___________________________________________________________________________ t0=MPI_Wtime() - water_flux = 0.0_WP - heat_flux = 0.0_WP - stress_surf= 0.0_WP - stress_node_surf= 0.0_WP +!PS water_flux = 0.0_WP +!PS heat_flux = 0.0_WP +!PS stress_surf= 0.0_WP +!PS stress_node_surf= 0.0_WP !___________________________________________________________________________ ! calculate equation of state, density, pressure and mixed layer depths @@ -3459,16 +3459,32 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) call compute_vel_rhs(ice, dynamics, partit, mesh) !___________________________________________________________________________ + ! Energy diagnostic contribution if (dynamics%ldiag_ke) then + ! if use solver + if (.not. dynamics%use_ssh_splitexpl_subcycl) then !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) - do elem=1, myDim_elem2D - nzmax = nlevels(elem) - nzmin = ulevels(elem) - do nz=nzmin,nzmax-1 - dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) + end do end do - end do !$OMP END PARALLEL DO + + ! if use splitexpl subcycl. UV_rhs in units of transport --> therefor *1/helem + else +!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)/helem(nz,elem) + end do + end do +!$OMP END PARALLEL DO + end if end if !___________________________________________________________________________ @@ -3479,26 +3495,51 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) call viscosity_filter(dynamics%opt_visc, dynamics, partit, mesh) !___________________________________________________________________________ + ! Energy diagnostic contribution if (dynamics%ldiag_ke) then + ! if use solver + if (.not. dynamics%use_ssh_splitexpl_subcycl) then !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) - do elem=1, myDim_elem2D - nzmax = nlevels(elem) - nzmin = ulevels(elem) - do nz=nzmin,nzmax-1 - dynamics%ke_hvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)-dynamics%ke_rhs_bak(:,nz,elem) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_hvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) - dynamics%ke_rhs_bak(:,nz,elem) + end do end do - end do !$OMP END PARALLEL DO - !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) - do elem=1, myDim_elem2D - nzmax = nlevels(elem) - nzmin = ulevels(elem) - do nz=nzmin,nzmax-1 - dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) + end do end do - end do !$OMP END PARALLEL DO + + ! if use splitexpl subcycl. UV_rhs in units of transport --> therefor *1/helem + else +!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_hvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)/helem(nz,elem) - dynamics%ke_rhs_bak(:,nz,elem) + end do + end do +!$OMP END PARALLEL DO +!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_rhs_bak(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)/helem(nz,elem) + end do + end do +!$OMP END PARALLEL DO + + end if end if !___________________________________________________________________________ @@ -3513,15 +3554,28 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) !___________________________________________________________________________ if (dynamics%ldiag_ke) then + ! if use solver + if (.not. dynamics%use_ssh_splitexpl_subcycl) then !$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(elem, nz, nzmin, nzmax) - do elem=1, myDim_elem2D - nzmax = nlevels(elem) - nzmin = ulevels(elem) - do nz=nzmin,nzmax-1 - dynamics%ke_vvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)-dynamics%ke_rhs_bak(:,nz,elem) + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_vvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem) - dynamics%ke_rhs_bak(:,nz,elem) + end do end do - end do !$OMP END PARALLEL DO + + ! if use splitexpl subcycl. UV_rhs in units of transport --> therefor *1/helem + else + do elem=1, myDim_elem2D + nzmax = nlevels(elem) + nzmin = ulevels(elem) + do nz=nzmin,nzmax-1 + dynamics%ke_vvis(:,nz,elem)=dynamics%UV_rhs(:,nz,elem)/helem(nz,elem) - dynamics%ke_rhs_bak(:,nz,elem) + end do + end do + end if end if t2=MPI_Wtime() @@ -3588,14 +3642,17 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) else ! Compute vertical integral of transport velocity rhs omitting the contributions from ! the elevation and Coriolis. + t30=MPI_Wtime() call compute_BT_rhs_SE_vtransp(dynamics, partit, mesh) ! Do barotropic step, get eta_{n+1} and BT transport call compute_BT_step_SE_ale(dynamics, partit, mesh) + t3=MPI_Wtime() ! Trim U to be consistent with BT transport call update_trim_vel_ale_vtransp(1, dynamics, partit, mesh) - + t4=MPI_Wtime() + t5=t4 end if ! --> if (.not. dynamics%use_ssh_splitexpl_subcycl) then !___________________________________________________________________________ @@ -3672,7 +3729,7 @@ subroutine oce_timestep_ale(n, ice, dynamics, tracers, partit, mesh) !___________________________________________________________________________ ! write energy diagnostic info (dynamics%ldiag_ke = .true.) - if (dynamics%ldiag_ke) then + if ( (dynamics%ldiag_ke) .and. (mod(n,logfile_outfreq)==0) ) then call write_enegry_info(dynamics, partit, mesh) end if diff --git a/src/oce_ale_ssh_splitexpl_subcycl.F90 b/src/oce_ale_ssh_splitexpl_subcycl.F90 index 94d8c5d8c..17d0e8a86 100644 --- a/src/oce_ale_ssh_splitexpl_subcycl.F90 +++ b/src/oce_ale_ssh_splitexpl_subcycl.F90 @@ -348,143 +348,6 @@ subroutine momentum_adv_scalar_transpv(dynamics, partit, mesh) end do ! --> do ed=1, myDim_edge2D !$OMP END DO - - - - - - - - -!PS !___________________________________________________________________________ -!PS ! 2nd. compute horizontal advection component: u*du/dx, u*dv/dx & v*du/dy, v*dv/dy -!PS ! loop over triangle edges -!PS !$OMP DO -!PS do ed=1, myDim_edge2D -!PS ! local indice of nodes that span up edge ed -!PS ednodes = edges(:,ed) -!PS -!PS ! local index of element that contribute to edge -!PS edelem = edge_tri(1:2,ed) -!PS -!PS !_______________________________________________________________________ -!PS ! index off surface layer in case of cavity !=1 and index of mid depth -!PS ! bottom layer -!PS ul1 = ulevels(edelem(1)) -!PS nl1 = nlevels(edelem(1))-1 -!PS x1 = edge_cross_dxdy(1,ed) -!PS y1 = edge_cross_dxdy(2,ed) -!PS ul2 = 0 -!PS nl2 = nl -!PS -!PS !_______________________________________________________________________ -!PS if (edelem(2) > 0) then -!PS ul2 = ulevels(edelem(2)) -!PS nl2 = nlevels(edelem(2))-1 -!PS x2 = edge_cross_dxdy(3,ed) -!PS y2 = edge_cross_dxdy(4,ed) -!PS end if -!PS -!PS !_______________________________________________________________________ -!PS ! nl12 ... minimum number of layers -1 between element edelem(1) & edelem(2) that -!PS ! contribute to edge ed -!PS ! nu12 ... upper index of layers between element edelem(1) & edelem(2) that -!PS ! contribute to edge ed -!PS ! be carefull !!! --> if ed is a boundary edge than edelem(1)~=0 and edelem(2)==0 -!PS ! that means nl1>0, nl2==0, nl12=min(nl1,nl2)=0 !!! -!PS ul12 = max(ul1, ul2) -!PS nl12 = min(nl1, nl2) -!PS -!PS !_______________________________________________________________________ -!PS ! (A1) goes only into this loop when the edge has only facing element -!PS ! edelem(1) --> so the edge is a boundary edge --> this is for ocean -!PS ! surface in case of cavity -!PS do nz=ul1, ul12-1 -!PS un= (UVh(2, nz, edelem(1))*x1 - UVh(1, nz, edelem(1))*y1) -!PS uu=un*UV(1, nz, edelem(1)) ! the momentum to be carried depends on velocities -!PS vv=un*UV(2, nz, edelem(1)) -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=ul1, ul12-1 -!PS -!PS !_______________________________________________________________________ -!PS ! (C1) remaining segments from the shared lower lyer index nl12 to bottom -!PS ! of element edelem(1) -!PS do nz=nl12+1, nl1 -!PS un= (UVh(2, nz, edelem(1))*x1 - UVh(1, nz, edelem(1))*y1) -!PS uu=un*UV(1, nz, edelem(1)) ! the momentum to be carried depends on velocities -!PS vv=un*UV(2, nz, edelem(1)) -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=nl12+1, nl1 -!PS -!PS if (edelem(2) > 0) then -!PS !_______________________________________________________________________ -!PS ! (A2) goes only into this loop when the edge has a facing elemenmt -!PS ! edelem(2) --> so the edge is a boundary edge --> this is for ocean -!PS ! surface in case of cavity -!PS do nz=ul2, ul12-1 -!PS un=-(UVh(2, nz, edelem(2))*x2- UVh(1, nz, edelem(2))*y2) -!PS uu=un*UV(1, nz, edelem(2)) -!PS vv=un*UV(2, nz, edelem(2)) -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=ul2, ul12-1 -!PS -!PS !_______________________________________________________________________ -!PS ! (B) Both segments -!PS ! loop over depth layers from shared upper layer index ul12 to shared -!PS ! lower layer index nl12 -!PS do nz=ul12, nl12 -!PS un= (UVh(2, nz, edelem(1))*x1 - UVh(1, nz, edelem(1))*y1) & -!PS -(UVh(2, nz, edelem(2))*x2 - UVh(1, nz, edelem(2))*y2) -!PS uu=un*(UV(1, nz, edelem(1)) + UV(1, nz, edelem(2)))*0.5_WP! the momentum to be carried depends on velocities -!PS vv=un*(UV(2, nz, edelem(1)) + UV(2, nz, edelem(2)))*0.5_WP -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=ul12, nl12 -!PS -!PS !_______________________________________________________________________ -!PS ! (C2) remaining segments from the shared lower lyer index nl12 to bottom -!PS ! of element edelem(1) -!PS do nz=nl12+1, nl2 -!PS un=-(UVh(2, nz, edelem(2))*x2- UVh(1, nz, edelem(2))*y2) -!PS uu=un*UV(1, nz, edelem(2)) -!PS vv=un*UV(2, nz, edelem(2)) -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=nl12+1, nl2 -!PS else -!PS -!PS !_______________________________________________________________________ -!PS ! (B) Both segments -!PS ! loop over depth layers from shared upper layer index ul12 to shared -!PS ! lower layer index nl12 -!PS do nz=ul12, nl12 -!PS un= (UVh(2, nz, edelem(1))*x1 - UVh(1, nz, edelem(1))*y1) -!PS uu=un*UV(1, nz, edelem(1))! the momentum to be carried depends on velocities -!PS vv=un*UV(2, nz, edelem(1)) -!PS UVnode_rhs(1, nz, ednodes(1))=UVnode_rhs(1, nz, ednodes(1))+uu -!PS UVnode_rhs(1, nz, ednodes(2))=UVnode_rhs(1, nz, ednodes(2))-uu -!PS UVnode_rhs(2, nz, ednodes(1))=UVnode_rhs(2, nz, ednodes(1))+vv -!PS UVnode_rhs(2, nz, ednodes(2))=UVnode_rhs(2, nz, ednodes(2))-vv -!PS end do ! --> do nz=ul12, nl12 -!PS end if -!PS -!PS end do ! --> do ed=1, myDim_edge2D -!PS !$OMP END DO - - !___________________________________________________________________________ ! divide total nodal momentum advection by scalar area !$OMP DO @@ -678,22 +541,7 @@ subroutine impl_vert_visc_ale_vtransp(dynamics, partit, mesh) ! therefor divide with helem uu(nzmin:nzmax-1)=(UVh(1, nzmin:nzmax-1, elem)+UV_rhs(1, nzmin:nzmax-1, elem))/helem(nzmin:nzmax-1, elem) !! u*=U*/h vv(nzmin:nzmax-1)=(UVh(2, nzmin:nzmax-1, elem)+UV_rhs(2, nzmin:nzmax-1, elem))/helem(nzmin:nzmax-1, elem) - - !_______________________________________________________________ -!PS if ( any(uu(nzmin:nzmax-1)/=uu(nzmin:nzmax-1)) .or. & -!PS any(vv(nzmin:nzmax-1)/=vv(nzmin:nzmax-1)) ) then -!PS write(*,*) ' --> subroutine impl_vert_visc_ale_vtransp --> found Nan in uu=UVh=UV_rhs' -!PS write(*,*) ' mype =', mype -!PS write(*,*) ' elem =', elem -!PS write(*,*) ' uu(nzmin:nzmax-1)=', uu(nzmin:nzmax-1) -!PS write(*,*) ' vv(nzmin:nzmax-1)=', vv(nzmin:nzmax-1) -!PS write(*,*) ' UV_rhs(1,nz,elem)=', UV_rhs( 1, nz, elem) -!PS write(*,*) ' UV_rhs(2,nz,elem)=', UV_rhs( 2, nz, elem) -!PS write(*,*) ' UVh( 1, nz, elem)=', UVh( 1, nz, elem) -!PS write(*,*) ' UVh( 2, nz, elem)=', UVh( 2, nz, elem) -!PS write(*,*) ' helem(nz, elem) =', helem(nz, elem) -!PS end if - + !_______________________________________________________________________ ! Operator + rhs ! Regular part of coefficients: @@ -822,6 +670,7 @@ subroutine compute_BT_rhs_SE_vtransp(dynamics, partit, mesh) USE MOD_MESH USE MOD_DYN USE g_config, only: dt, r_restart + USE g_comm_auto IMPLICIT NONE type(t_dyn) , intent(inout), target :: dynamics type(t_partit), intent(inout), target :: partit @@ -901,6 +750,7 @@ subroutine compute_BT_rhs_SE_vtransp(dynamics, partit, mesh) ! UVBT_4AB ... is U_bt in barotropic equation ! --> d/dt*U_bt + f*e_z x U_bt + g*H*grad_H(eta) = R_bt UVBT_4AB(3:4,elem)=UVBT_4AB(1:2,elem) + end do !$OMP END DO !$OMP END PARALLEL @@ -931,8 +781,10 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) USE MOD_PARSUP USE MOD_MESH USE MOD_DYN - use g_comm_auto - USE g_config, only: dt + USE g_comm_auto + USE g_config, only: dt, which_ALE, use_cavity_fw2press + USE g_support, only: integrate_nod + use o_ARRAYS, only: water_flux IMPLICIT NONE !___________________________________________________________________________ type(t_dyn) , intent(inout), target :: dynamics @@ -941,11 +793,10 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) !___________________________________________________________________________ real(kind=WP) :: dtBT, BT_inv, hh, f, rx, ry, a, b, d, c1, c2, ax, ay real(kind=WP) :: deltaX1, deltaY1, deltaX2, deltaY2, thetaBT - integer :: step, elem, elnodes(3), edge, ednodes(2), edelem(2) + integer :: step, elem, edge, node, elnodes(3), ednodes(2), edelem(2) real(kind=WP) :: update_ubt, update_vbt, vi, len, nzmax real(kind=WP), allocatable :: bottomdrag(:), UVBT_harmvisc(:,:) - !___________________________________________________________________________ ! pointer on necessary derived types real(kind=WP), dimension(:) , pointer :: eta_n @@ -979,7 +830,6 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) dtBT = dt/dynamics%splitexpl_BTsteps BT_inv = 1.0_WP/(1.0_WP*dynamics%splitexpl_BTsteps) - !___SPLIT-EXPLICITE STABILIZATION___________________________________________ ! trim R (UVBT_rhs): ! UVBT_rhs --> UVBT_rhs - div_h Ah H^n div_h(Ubt^n/H^n) + Cd*|Ubot|* Ubt^n/H^n @@ -989,7 +839,6 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) ! --> use only harmonmic viscosity operator applied to the barotropic ! velocity if (dynamics%splitexpl_visc) then - !_______________________________________________________________________ ! remove viscosity do edge=1, myDim_edge2D+eDim_edge2D @@ -1033,9 +882,6 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) !$OMP END ORDERED #endif end do ! --> do edge=1, myDim_edge2D+eDim_edge2D - - call exchange_elem_begin(UVBT_rhs, partit) - call exchange_elem_end(partit) end if ! --> if (dynamics%splitexpl_visc) then !___________________________________________________________________________ @@ -1072,6 +918,7 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) ! elem indices that participate in edge edelem = edge_tri(:,edge) + nzmax = minval(nlevels(edelem)) hh = -zbar(nzmax) len = sqrt(sum(elem_area(edelem))) @@ -1079,7 +926,7 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) update_ubt=(UVBT(1, edelem(1))-UVBT(1, edelem(2)))/hh update_vbt=(UVBT(2, edelem(1))-UVBT(2, edelem(2)))/hh vi=update_ubt*update_ubt + update_vbt*update_vbt - vi=dt*sqrt(max(dynamics%splitexpl_visc_gamma0, & + vi=dt*sqrt(max(dynamics%splitexpl_visc_gamma0, & max(dynamics%splitexpl_visc_gamma1*sqrt(vi), & dynamics%splitexpl_visc_gamma2*vi) & )*len) @@ -1106,9 +953,6 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) !$OMP END ORDERED #endif end do ! --> do edge=1, myDim_edge2D+eDim_edge2D - - call exchange_elem_begin(UVBT_harmvisc, partit) - call exchange_elem_end(partit) end if ! -> if (dynamics%splitexpl_visc) then !_______________________________________________________________________ @@ -1137,13 +981,13 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) ! (We do it here based on increments since it saves us some significant ! digits for the accuracy) ! Increments: - ! deltaU = Ubt^(n+(m+1)/M)-Ubt^(n+m/M) - ! Ubt^(n+(m+1)/M)+Ubt^(n+m/M) = Ubt^(n+(m+1)/M)-Ubt^(n+m/M)+2*Ubt^(n+m/M) - ! = deltaU + 2*Ubt^(n+m/M) + ! deltaU = Ubt^(n+(m+1)/M)-Ubt^(n+m/M) + ! Ubt^(n+(m+1)/M)+Ubt^(n+m/M) = Ubt^(n+(m+1)/M)-Ubt^(n+m/M)+2*Ubt^(n+m/M) + ! = deltaU + 2*Ubt^(n+m/M) ! - ! Ubt^(n+(m+1)/M)-Ubt^(n+m/M) = - dt/M*[ + 0.5*f*e_z x (Ubt^(n+(m+1)/M) + Ubt^(n+m/M)) - ! - h*H^m*grad_H*eta^(n+m/M) - ! - Rbt-->UVBT_rhs ] + ! Ubt^(n+(m+1)/M)-Ubt^(n+m/M) = - dt/M*[ + 0.5*f*e_z x (Ubt^(n+(m+1)/M) + Ubt^(n+m/M)) + ! - h*H^m*grad_H*eta^(n+m/M) + ! - Rbt-->UVBT_rhs ] ! ! deltaU - dt/(2*M)*f*deltaV = dt/M*f*Vbt^(n+m/M) - h*H^m*gradx_H*eta^(n+m/M) + Rbtx ! deltaV + dt/(2*M)*f*deltaU = -dt/M*f*Ubt^(n+m/M) - h*H^m*grady_H*eta^(n+m/M) + Rbty @@ -1178,6 +1022,8 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) ! Ubt^(n+(m+1)/M) = Ubt^(n+(m)/M) + AAA ! equation (6) in T. Banerjee et al.,Split-Explicite external ! mode solver in FESOM2, + + ! compute barotropic velocity at time step (n+(m+1)/M) UVBT( 1, elem) = UVBT(1, elem) + ax UVBT( 2, elem) = UVBT(2, elem) + ay @@ -1199,6 +1045,8 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) UVBT_mean( 2, elem) = UVBT_mean( 2, elem) + UVBT_theta(2, elem)*BT_inv end do + call exchange_elem_begin(UVBT, partit) + call exchange_elem_end(partit) !_______________________________________________________________________ ! Store mid-step velocity (to trim 3D velocities in momentum) @@ -1230,18 +1078,28 @@ subroutine compute_BT_step_SE_ale(dynamics, partit, mesh) ! advance ssh --> eta^(n+(m+1)/M) = eta^(n+(m)/M) - dt/M * div_H * [...] ! equation (6) in T. Banerjee et al.,Split-Explicite external ! mode solver in FESOM2, - eta_n(ednodes(1))=eta_n(ednodes(1)) + (c1+c2)*dtBT/area(1,ednodes(1)) - eta_n(ednodes(2))=eta_n(ednodes(2)) - (c1+c2)*dtBT/area(1,ednodes(2)) + eta_n(ednodes(1))=eta_n(ednodes(1)) + (c1+c2)*dtBT/areasvol(1,ednodes(1)) + eta_n(ednodes(2))=eta_n(ednodes(2)) - (c1+c2)*dtBT/areasvol(1,ednodes(2)) end do + !_______________________________________________________________________ + ! Apply freshwater boundary condition + if ( .not. trim(which_ALE)=='linfs') then + do node=1,myDim_nod2D + eta_n(node)=eta_n(node) - dtBT*water_flux(node) + end do + end if + !_______________________________________________________________________ call exchange_nod(eta_n, partit) end do ! --> do step=1, dynamics%splitexpl_BTsteps + deallocate(bottomdrag, UVBT_harmvisc) hbar_old = hbar - hbar = eta_n + hbar = eta_n + end subroutine compute_BT_step_SE_ale ! ! @@ -1261,6 +1119,7 @@ subroutine update_trim_vel_ale_vtransp(mode, dynamics, partit, mesh) type(t_mesh) , intent(inout) , target :: mesh integer :: elem, nz, nzmin, nzmax real(kind=WP) :: ubar, vbar, hh_inv + real(kind=WP) :: usum(2), udiff(2) !___________________________________________________________________________ ! pointer on necessary derived types real(kind=WP), dimension(:,:,:), pointer :: UVh, UV, UV_rhs @@ -1287,21 +1146,77 @@ subroutine update_trim_vel_ale_vtransp(mode, dynamics, partit, mesh) nzmin = ulevels(elem) nzmax = nlevels(elem)-1 + !___________________________________________________________________ ubar = 0.0_WP vbar = 0.0_WP hh_inv = 0.0_WP do nz=nzmin, nzmax - !_______________________________________________________________ - ! Update transport velocities: U^(n+1/2,**) = U^(n+1/2,*) + U_rhs - UVh(1, nz, elem)=UVh(1, nz, elem)+UV_rhs(1, nz, elem) - UVh(2, nz, elem)=UVh(2, nz, elem)+UV_rhs(2, nz, elem) - + !PS !___________________________________________________________ + !PS ! Update transport velocities: U^(n+1/2,**) = U^(n+1/2,*) + U_rhs + !PS UVh(1, nz, elem)=UVh(1, nz, elem)+UV_rhs(1, nz, elem) + !PS UVh(2, nz, elem)=UVh(2, nz, elem)+UV_rhs(2, nz, elem) + !PS + !PS !___________________________________________________________ + !PS ! vertically integrate updated transport velocity: sum(k, U_k^(n+1/2,**) ) + !PS ubar = ubar+UVh(1, nz, elem) + !PS vbar = vbar+UVh(2, nz, elem) + !PS hh_inv= hh_inv+helem(nz,elem) !_______________________________________________________________ ! vertically integrate updated transport velocity: sum(k, U_k^(n+1/2,**) ) - ubar = ubar+UVh(1, nz, elem) - vbar = vbar+UVh(2, nz, elem) + ! --> the actual update of the transport velocity is done after the + ! if (dynamics%ldiag_ke) block + ubar = ubar+UVh(1, nz, elem) + UV_rhs(1, nz, elem) + vbar = vbar+UVh(2, nz, elem) + UV_rhs(2, nz, elem) hh_inv= hh_inv+helem(nz,elem) end do + hh_inv=1.0_WP/hh_inv + + !___________________________________________________________________ + if (dynamics%ldiag_ke) then + DO nz=nzmin, nzmax + ! U_(n+1) - U_n = Urhs_n |* (U_(n+1)+U_n) + ! U_(n+1)^2 - U_n^2 = Urhs_n * (U_(n+1)+U_n) + ! | + ! +-> U_(n+1) = U_n+Urhs_n + ! U_(n+1)^2 - U_n^2 = Urhs_n * (2*U_n + Urhs) + ! | | + ! v v + ! udiff usum + usum(1) = 2.0_WP*UVh(1,nz,elem) + UV_rhs(1, nz, elem) + (UVBT_mean(1, elem)-ubar)*helem(nz,elem)*hh_inv + usum(2) = 2.0_WP*UVh(2,nz,elem) + UV_rhs(2, nz, elem) + (UVBT_mean(2, elem)-vbar)*helem(nz,elem)*hh_inv + ! transform: transport vel --> velocity + usum(1) = usum(1)/helem(nz,elem) + usum(2) = usum(2)/helem(nz,elem) + + udiff(1) = UV_rhs(1, nz, elem) + (UVBT_mean(1, elem)-ubar)*helem(nz,elem)*hh_inv + udiff(2) = UV_rhs(2, nz, elem) + (UVBT_mean(2, elem)-vbar)*helem(nz,elem)*hh_inv + ! transform: transport vel --> velocity + udiff(1) = udiff(1)/helem(nz,elem) + udiff(2) = udiff(2)/helem(nz,elem) + + ! (U_(n+1)^2 - U_n^2)/2 = usum*udiff/2 + dynamics%ke_du2( :,nz,elem) = usum*udiff/2.0_WP + + dynamics%ke_pre_xVEL( :,nz,elem) = usum*dynamics%ke_pre (:,nz,elem)/2.0_WP + dynamics%ke_adv_xVEL( :,nz,elem) = usum*dynamics%ke_adv (:,nz,elem)/2.0_WP + dynamics%ke_cor_xVEL( :,nz,elem) = usum*dynamics%ke_cor (:,nz,elem)/2.0_WP + dynamics%ke_hvis_xVEL(:,nz,elem) = usum*dynamics%ke_hvis(:,nz,elem)/2.0_WP + dynamics%ke_vvis_xVEL(:,nz,elem) = usum*dynamics%ke_vvis(:,nz,elem)/2.0_WP + + ! U_(n+0.5) = U_n + 0.5*Urhs + dynamics%ke_umean( :,nz,elem) = usum/2.0_WP + ! U_(n+0.5)^2 + dynamics%ke_u2mean( :,nz,elem) = (usum*usum)/4.0_WP + + if (nz==nzmin) then + dynamics%ke_wind_xVEL(:,elem) = usum*dynamics%ke_wind(:,elem)/2.0_WP + end if + + if (nz==nzmax) then + dynamics%ke_drag_xVEL(:,elem) = usum*dynamics%ke_drag(:,elem)/2.0_WP + end if + END DO + end if !___________________________________________________________________ ! finalize horizontal transport by making vertically integrated @@ -1311,15 +1226,17 @@ subroutine update_trim_vel_ale_vtransp(mode, dynamics, partit, mesh) ! mode solver in FESOM2, ! U_k^(n+1/2) = U^(n+1/2,**) ! + [<>^(n+1/2) - sum(k, U_k^(n+1/2,**)] * h_k^(n+1/2)/sum(k,h_k^(n+1/2)) - hh_inv=1.0_WP/hh_inv ! Postpone AB and 2nd order, just use available thickness DO nz=nzmin, nzmax - UVh(1, nz, elem)= UVh(1, nz, elem)+(UVBT_mean(1, elem)-ubar)*helem(nz,elem)*hh_inv - UVh(2, nz, elem)= UVh(2, nz, elem)+(UVBT_mean(2, elem)-vbar)*helem(nz,elem)*hh_inv + !PS UVh(1, nz, elem)= UVh(1, nz, elem)+(UVBT_mean(1, elem)-ubar)*helem(nz,elem)*hh_inv + !PS UVh(2, nz, elem)= UVh(2, nz, elem)+(UVBT_mean(2, elem)-vbar)*helem(nz,elem)*hh_inv + UVh(1, nz, elem)= UVh(1, nz, elem) + UV_rhs(1, nz, elem) + (UVBT_mean(1, elem)-ubar)*helem(nz,elem)*hh_inv + UVh(2, nz, elem)= UVh(2, nz, elem) + UV_rhs(2, nz, elem) + (UVBT_mean(2, elem)-vbar)*helem(nz,elem)*hh_inv UV( 1, nz, elem)= UVh(1, nz, elem)/helem(nz,elem) ! velocities are still needed UV( 2, nz, elem)= UVh(2, nz, elem)/helem(nz,elem) - end do end do + + !_______________________________________________________________________ call exchange_elem(UVh, partit) ! This exchange can be avoided, but test first. call exchange_elem(UV, partit) @@ -1328,18 +1245,20 @@ subroutine update_trim_vel_ale_vtransp(mode, dynamics, partit, mesh) ! Velocity will be used to advance momentum else do elem=1, myDim_elem2D + nzmin = ulevels(elem) + nzmax = nlevels(elem)-1 + + !___________________________________________________________________ ubar = 0.0_WP vbar = 0.0_WP hh_inv = 0.0_WP - - nzmin = ulevels(elem) - nzmax = nlevels(elem)-1 do nz=nzmin, nzmax ubar=ubar+UVh(1, nz, elem) vbar=vbar+UVh(2, nz, elem) hh_inv=hh_inv+helem(nz,elem) end do + !___________________________________________________________________ hh_inv=1.0_WP/hh_inv ! Postpone 2nd order, just use available thickness do nz=nzmin, nzmax UVh(1, nz, elem)= UVh(1, nz, elem)+(UVBT_12(1, elem)-ubar)*helem(nz,elem)*hh_inv @@ -1348,8 +1267,10 @@ subroutine update_trim_vel_ale_vtransp(mode, dynamics, partit, mesh) UV( 2, nz, elem)= UVh(2, nz, elem)/helem(nz,elem) ! to compute momentum advection end do end do + !___________________________________________________________________ call exchange_elem(UVh, partit) ! call exchange_elem(UV , partit) ! Check if this is needed + end if ! --> if (mode==1) then end subroutine update_trim_vel_ale_vtransp ! @@ -1396,7 +1317,7 @@ subroutine compute_thickness_zstar(dynamics, partit, mesh) nzmin = ulevels(elem) nzmax = nlevels(elem)-1 elnodes=elem2D_nodes(:,elem) - do nz=nzmin, nzmax + do nz=nzmin, nzmax-1 helem(nz,elem)=sum(hnode_new(nz,elnodes))/3.0_WP end do end do diff --git a/src/oce_dyn.F90 b/src/oce_dyn.F90 index 92faffb55..57ac24fe7 100755 --- a/src/oce_dyn.F90 +++ b/src/oce_dyn.F90 @@ -99,32 +99,46 @@ SUBROUTINE update_vel(dynamics, partit, mesh) nzmax = nlevels(elem) if (dynamics%ldiag_ke) then - DO nz=nzmin, nzmax-1 - dynamics%ke_pre(1,nz,elem) =dynamics%ke_pre(1,nz,elem) + Fx - dynamics%ke_pre(2,nz,elem) =dynamics%ke_pre(2,nz,elem) + Fy - - usum(1)=2.0_WP*UV(1,nz,elem)+(UV_rhs(1,nz,elem) + Fx) - usum(2)=2.0_WP*UV(2,nz,elem)+(UV_rhs(2,nz,elem) + Fy) - - udiff(1)=UV_rhs(1,nz,elem) + Fx - udiff(2)=UV_rhs(2,nz,elem) + Fy - dynamics%ke_du2 (:,nz,elem) = usum*udiff/2.0_WP - dynamics%ke_pre_xVEL (:,nz,elem) = usum*dynamics%ke_pre (:,nz,elem)/2.0_WP - dynamics%ke_adv_xVEL (:,nz,elem) = usum*dynamics%ke_adv (:,nz,elem)/2.0_WP - dynamics%ke_cor_xVEL (:,nz,elem) = usum*dynamics%ke_cor (:,nz,elem)/2.0_WP - dynamics%ke_hvis_xVEL(:,nz,elem) = usum*dynamics%ke_hvis(:,nz,elem)/2.0_WP - dynamics%ke_vvis_xVEL(:,nz,elem) = usum*dynamics%ke_vvis(:,nz,elem)/2.0_WP - dynamics%ke_umean(:,nz,elem) = usum/2.0_WP - dynamics%ke_u2mean(:,nz,elem) = (usum*usum)/4.0_WP - - if (nz==nzmin) then - dynamics%ke_wind_xVEL(:,elem)=usum*dynamics%ke_wind(:,elem)/2.0_WP - end if - - if (nz==nzmax-1) then - dynamics%ke_drag_xVEL(:,elem)=usum*dynamics%ke_drag(:,elem)/2.0_WP - end if - END DO + DO nz=nzmin, nzmax-1 + dynamics%ke_pre(1,nz,elem) =dynamics%ke_pre(1,nz,elem) + Fx + dynamics%ke_pre(2,nz,elem) =dynamics%ke_pre(2,nz,elem) + Fy + + + ! U_(n+1) - U_n = Urhs_n |* (U_(n+1)+U_n) + ! U_(n+1)^2 - U_n^2 = Urhs_n * (U_(n+1)+U_n) + ! | + ! +-> U_(n+1) = U_n+Urhs_n + ! U_(n+1)^2 - U_n^2 = Urhs_n * (2*U_n + Urhs) + ! | | + ! v v + ! udiff usum + usum(1) = 2.0_WP*UV(1,nz,elem)+(UV_rhs(1,nz,elem) + Fx) + usum(2) = 2.0_WP*UV(2,nz,elem)+(UV_rhs(2,nz,elem) + Fy) + udiff(1) = UV_rhs(1,nz,elem) + Fx + udiff(2) = UV_rhs(2,nz,elem) + Fy + + ! (U_(n+1)^2 - U_n^2)/2 = usum*udiff/2 + dynamics%ke_du2 (:,nz,elem) = usum*udiff/2.0_WP + + dynamics%ke_pre_xVEL (:,nz,elem) = usum*dynamics%ke_pre (:,nz,elem)/2.0_WP + dynamics%ke_adv_xVEL (:,nz,elem) = usum*dynamics%ke_adv (:,nz,elem)/2.0_WP + dynamics%ke_cor_xVEL (:,nz,elem) = usum*dynamics%ke_cor (:,nz,elem)/2.0_WP + dynamics%ke_hvis_xVEL(:,nz,elem) = usum*dynamics%ke_hvis(:,nz,elem)/2.0_WP + dynamics%ke_vvis_xVEL(:,nz,elem) = usum*dynamics%ke_vvis(:,nz,elem)/2.0_WP + + ! U_(n+0.5) = U_n + 0.5*Urhs + dynamics%ke_umean( :,nz,elem) = usum/2.0_WP + ! U_(n+0.5)^2 + dynamics%ke_u2mean( :,nz,elem) = (usum*usum)/4.0_WP + + if (nz==nzmin) then + dynamics%ke_wind_xVEL(:,elem) = usum*dynamics%ke_wind(:,elem)/2.0_WP + end if + + if (nz==nzmax-1) then + dynamics%ke_drag_xVEL(:,elem) = usum*dynamics%ke_drag(:,elem)/2.0_WP + end if + END DO end if DO nz=nzmin, nzmax-1