diff --git a/src/MOD_DYN.F90 b/src/MOD_DYN.F90 index ded902231..cd23263fd 100644 --- a/src/MOD_DYN.F90 +++ b/src/MOD_DYN.F90 @@ -115,7 +115,8 @@ MODULE MOD_DYN real(kind=WP), allocatable, dimension(:,:,:) :: ke_adv_AB, ke_cor_AB real(kind=WP), allocatable, dimension(:,:,:) :: ke_rhs_bak ! surface fields to compute APE generation - real(kind=WP), allocatable, dimension(:) :: ke_J, ke_D, ke_G, ke_D2, ke_n0, ke_JD, ke_GD, ke_swA, ke_swB + real(kind=WP), allocatable, dimension(:) :: ke_J, ke_D, ke_G, ke_D2, ke_JD, ke_GD, ke_swA, ke_swB + real(kind=WP), allocatable, dimension(:,:) :: ke_n0, ke_Dx, ke_Dy, ke_DU, ke_DV, ke_elemD, ke_elemD2 !___________________________________________________________________________ contains diff --git a/src/io_meandata.F90 b/src/io_meandata.F90 index 6ff0dce80..7abfe02cd 100644 --- a/src/io_meandata.F90 +++ b/src/io_meandata.F90 @@ -758,11 +758,18 @@ subroutine ini_mean_io(ice, dynamics, tracers, 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) + ! fields required to compute the energy conversions between Pm<->Pe, as well as Pm & Pe + call def_stream((/nl-1, nod2D/), (/nl-1, myDim_nod2D/) , 'ke_n0', 'dRHO/dz', 'kg/m^4', dynamics%ke_n0(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_Dx', 'dRHO/dx', 'kg/m^4', dynamics%ke_Dx(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_Dy', 'dRHO/dy', 'kg/m^4', dynamics%ke_Dy(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_DU', 'RHO*U', 'kg*s/m^2', dynamics%ke_DU(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_DV', 'RHO*V', 'kg*s/m^2', dynamics%ke_DV(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_elemD', 'RHO* on elem', 'kg/m^3', dynamics%ke_elemD(:,:), io_list(i)%freq, 'm', 8, partit, mesh) + call def_stream((/nl-1, elem2D/), (/nl-1, myDim_elem2D/) , 'ke_elemD2', 'RHO*^2 on elem', 'kg2/m^6', dynamics%ke_elemD2(:,:), io_list(i)%freq, 'm', 8, partit, mesh) end if end subroutine ! diff --git a/src/oce_dyn.F90 b/src/oce_dyn.F90 index 01cfad89b..f8dd2bc9e 100755 --- a/src/oce_dyn.F90 +++ b/src/oce_dyn.F90 @@ -718,7 +718,7 @@ SUBROUTINE compute_apegen(dynamics, tracers, partit, mesh) type(t_mesh) , intent(in) , target :: mesh real(kind=WP), dimension(:,:), pointer :: salt !___________________________________________________________________________ - integer :: n, nzmin + integer :: n, k, nzmin, nzmax real(kind=WP) :: JS, GS, D !___________________________________________________________________________ #include "associate_part_def.h" @@ -730,6 +730,7 @@ SUBROUTINE compute_apegen(dynamics, tracers, partit, mesh) DO n=1, myDim_nod2D nzmin=ulevels_nod2D(n) + nzmax=nlevels_nod2D(n) ! heat and salinity fluxes at node=n JS= heat_flux_in(n) / vcpw GS=(relax_salt(n) + water_flux(n) * salt(nzmin,n)) @@ -738,7 +739,11 @@ SUBROUTINE compute_apegen(dynamics, tracers, partit, mesh) dynamics%ke_G (n)=GS dynamics%ke_D (n)=D dynamics%ke_D2 (n)=D**2 - dynamics%ke_n0 (n)=-bvfreq (nzmin,n)*density_0/g + !this we need in 3D + !dynamics%ke_n0 (n)=-bvfreq (nzmin,n)*density_0/g + DO k=nzmin, nzmax-1 + dynamics%ke_n0(k, n)=-bvfreq (k, n)*density_0/g + END DO dynamics%ke_JD(n) =JS*D dynamics%ke_GD(n) =GS*D dynamics%ke_D (n) =D @@ -758,8 +763,52 @@ SUBROUTINE compute_apegen(dynamics, tracers, partit, mesh) call exchange_nod(dynamics%ke_swA, partit) call exchange_nod(dynamics%ke_swB, partit) END SUBROUTINE compute_apegen - - +! compute energy conversion (Pm<->Pe), as well as Pm & Pe +SUBROUTINE compute_PePm(dynamics, tracers, partit, mesh) + USE MOD_MESH + USE MOD_PARTIT + USE MOD_TRACER + USE MOD_PARSUP + use MOD_DYN + USE o_PARAM + USE g_comm_auto + USE o_ARRAYS + IMPLICIT NONE + type(t_dyn) , intent(inout), target :: dynamics + type(t_tracer), intent(in) , target :: tracers + type(t_partit), intent(inout), target :: partit + type(t_mesh) , intent(in) , target :: mesh + !___________________________________________________________________________ + real(kind=WP), dimension(:,:,:), pointer :: UV + integer :: elem, k, nzmin, nzmax, elnodes(3) + real(kind=WP) :: dens + !___________________________________________________________________________ +#include "associate_part_def.h" +#include "associate_mesh_def.h" +#include "associate_part_ass.h" +#include "associate_mesh_ass.h" + UV => dynamics%uv(:,:,:) + DO elem=1, myDim_elem2D + elnodes=elem2D_nodes(:,elem) + nzmin = ulevels(elem) + nzmax = nlevels(elem) + DO k=nzmin, nzmax-1 + dynamics%ke_Dx(k,elem)=sum(gradient_sca(1:3,elem)*density_m_rho0(k,elnodes)) + dynamics%ke_Dy(k,elem)=sum(gradient_sca(4:6,elem)*density_m_rho0(k,elnodes)) + dens=sum(density_m_rho0(k,elnodes))/3.0_WP + dynamics%ke_DU(k,elem)=dens*UV(1,k,elem) + dynamics%ke_DV(k,elem)=dens*UV(2,k,elem) + dynamics%ke_elemD (k,elem)=dens + dynamics%ke_elemD2(k,elem)=dens**2 + END DO + END DO + call exchange_elem(dynamics%ke_Dx, partit) + call exchange_elem(dynamics%ke_Dy, partit) + call exchange_elem(dynamics%ke_DU, partit) + call exchange_elem(dynamics%ke_DV, partit) + call exchange_elem(dynamics%ke_elemD, partit) + call exchange_elem(dynamics%ke_elemD2, partit) +END SUBROUTINE compute_PePm ! ! !_______________________________________________________________________________ diff --git a/src/oce_setup_step.F90 b/src/oce_setup_step.F90 index e6ea48722..bc2fdff14 100755 --- a/src/oce_setup_step.F90 +++ b/src/oce_setup_step.F90 @@ -521,9 +521,11 @@ SUBROUTINE dynamics_init(dynamics, partit, mesh) allocate(dynamics%ke_wind_xVEL(2, elem_size)) allocate(dynamics%ke_drag_xVEL(2, elem_size)) allocate(dynamics%ke_J(node_size), dynamics%ke_D(node_size), dynamics%ke_G(node_size), & - dynamics%ke_D2(node_size), dynamics%ke_n0(node_size), dynamics%ke_JD(node_size), & + dynamics%ke_D2(node_size), dynamics%ke_JD(node_size), & dynamics%ke_GD(node_size), dynamics%ke_swA(node_size), dynamics%ke_swB(node_size)) - + allocate(dynamics%ke_n0(nl-1, node_size)) + allocate(dynamics%ke_Dx(nl-1, elem_size), dynamics%ke_Dy(nl-1, elem_size), dynamics%ke_DU(nl-1, elem_size),& + dynamics%ke_DV(nl-1, elem_size), dynamics%ke_elemD(nl-1, elem_size), dynamics%ke_elemD2(nl-1, elem_size)) dynamics%ke_adv =0.0_WP dynamics%ke_cor =0.0_WP dynamics%ke_pre =0.0_WP @@ -556,6 +558,14 @@ SUBROUTINE dynamics_init(dynamics, partit, mesh) dynamics%ke_GD =0.0_WP dynamics%ke_swA =0.0_WP dynamics%ke_swB =0.0_WP + dynamics%ke_Dx =0.0_WP + dynamics%ke_Dy =0.0_WP + dynamics%ke_DU =0.0_WP + dynamics%ke_DV =0.0_WP + dynamics%ke_elemD =0.0_WP + dynamics%ke_elemD2 =0.0_WP + + end if END SUBROUTINE dynamics_init !