#pragma once // [bl-turb-scalar.h]: boundary-layer scalar turbulence statistics and budgets // // -------------------------------------------------------------------------------------------- // #include "wstgrid3d.h" // // *[Note]: we need gcz >= 2 for computation of production terms: // _ // dC // - w'w' -- // dz // namespace nse { // Heat eq. balance // -------------------------------------------------------------------------------------------- // template< typename T > void heat_eq( T* heat_balance, // node: [W] T* turbulent_heat_flux, // node: [W] T* heat_stress, // node: [W] const T* const Tw_flux, // node: [W] const T* const T_grad, // node: [W] const T c_diffusivity, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // SVA production // -------------------------------------------------------------------------------------------- // template< typename T > void SVA_production(T* _SVA_production, // node: [C] const T* const CW_bottom, // node: [C (W -- C)] const T* const CW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // SVA transport // -------------------------------------------------------------------------------------------- // template< typename T > void SVA_transport(T* _SVA_transport, // node: [C] const T* const cc_w_flux, // node: [W] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // SVA dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void SVA_dissipation(T* _SVA_dissipation, // node: [C] const T* const C_dissipation, // node: [C] const T* const C, // node: [C] const T c_diffusivity, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // SVA iso dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void SVA_iso_dissipation(T* _SVA_iso_dissipation, // node: [C] const T* const C_iso_dissipation, // node: [C] const T* const C, // node: [C] const T c_diffusivity, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: production // -------------------------------------------------------------------------------------------- // template< typename T > void cu_production_shear(T* _cu_production_shear, // node: [C] const T* const CW_bottom_u, // node: [C (W -- C)] const T* const CW_top_u, // node: [C (W -- C)] const T* const C, // node: [C] const T* const U, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cu_production_gradC(T* _cu_production_gradC, // node: [C] const T* const UW_bottom, // node: [C (W -- C)] const T* const UW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const U, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cv_production_shear(T* _cv_production_shear, // node: [C] const T* const CW_bottom_v, // node: [C (W -- C)] const T* const CW_top_v, // node: [C (W -- C)] const T* const C, // node: [C] const T* const V, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cv_production_gradC(T* _cv_production_gradC, // node: [C] const T* const VW_bottom, // node: [C (W -- C)] const T* const VW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const V, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cw_production_shear(T* _cw_production_shear, // node: [W] const T* const CW_bottom_w, // node: [W (C -- W)] const T* const CW_top_w, // node: [W (C -- W)] const T* const C, // node: [W] const T* const W, // node: [C] const wstGrid3d< T >& grid); template< typename T > void cw_production_gradC(T* _cw_production_gradC, // node: [W] const T* const W2_w, // node: [W] const T* const W2_c, // node: [C] const T* const C, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: transport // -------------------------------------------------------------------------------------------- // template< typename T > void cu_transport(T* _cu_transport, // node: [C] const T* const cuw_flux, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cv_transport(T* _cv_transport, // node: [C] const T* const cvw_flux, // node: [W] const wstGrid3d< T >& grid); template< typename T > void cw_transport(T* _cw_transport, // node: [W] const T* const cww_flux, // node: [C] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: pressure scrambles // -------------------------------------------------------------------------------------------- // template< typename T > void cw_pressure_work(T* _cw_pressure_work, // node: [W] const T* const cp_flux, // node: [C] const wstGrid3d< T >& grid); template< typename T > void cu_pressure_gradc(T* _cu_pressure_gradc, // node: [C] // computing as: // p'*dc'/dx = { d(c'p')/dx = 0 } - c'*dp'/dx // const T* const c_dpdx_turb, // node: [C] const wstGrid3d< T >& grid); template< typename T > void cv_pressure_gradc(T* _cv_pressure_gradc, // node: [C] // computing as: // p'*dc'/dy = { d(c'p')/dy = 0 } - c'*dp'/dy // const T* const c_dpdy_turb, // node: [C] const wstGrid3d< T >& grid); template< typename T > void cw_pressure_gradc(T* _cw_pressure_gradc, // node: [W] // computing as: // p'*dc'/dz = d(c'p')/dz - c'*dp'/dz // const T* const _cw_pressure_work, // node: [W] const T* const c_dpdz_turb, // node: [W] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void cu_dissipation(T* _cu_dissipation, // node: [C] const T* const CU_dissipation, // node: [C] const T* const C, // node: [C] const T* const U, // node: [C] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid); template< typename T > void cv_dissipation(T* _cv_dissipation, // node: [C] const T* const CV_dissipation, // node: [C] const T* const C, // node: [C] const T* const V, // node: [C] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid); template< typename T > void cw_dissipation(T* _cw_dissipation, // node: [W] const T* const CW_dissipation, // node: [W] const T* const C, // node: [C] const T* const W, // node: [W] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // c'w' flux budget: buoyancy // -------------------------------------------------------------------------------------------- // template< typename T > void cw_buoyancy(T* _cw_buoyancy, // node: [W] const T* const C2_c, // node: [C] const T* const C2_w, // node: [W] const T* const C, // node: [C] const T c_Richardson, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // TPE structure // -------------------------------------------------------------------------------------------- // template< typename T > void TPE_structure(T* TPE, // node: [C] T* TPE_heat_flux, T* TPE_diffusion, // node: [C] T* TPE_dissipation, T* TPE_iso_dissipation, // node: [C] const T* const TVA_production, // node: [C] const T* const TVA_diffusion, // node: [C] const T* const TVA_dissipation, // node: [C] const T* const TVA_iso_dissipation, // node: [C] const T* const T2, // node: [C] const T* const Tc, // node: [C] const T* const T_grad, // node: [W] const T c_Richardson, const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // // Energy structure // -------------------------------------------------------------------------------------------- // template< typename T > void energy_structure(T* TKE_share, T* TPE_share, // node: [C] const T* const TKE, // node: [C] const T* const TPE, // node: [C] const wstGrid3d< T >& grid); // -------------------------------------------------------------------------------------------- // } // Heat eq. balance // -------------------------------------------------------------------------------------------- // template< typename T > void nse::heat_eq( T* heat_balance, // node: [W] T* turbulent_heat_flux, // node: [W] T* heat_stress, // node: [W] const T* const Tw_flux, // node: [W] const T* const T_grad, // node: [W] const T c_diffusivity, const wstGrid3d< T >& grid) // integrated [T] averaged heat equation // _ // ____ 1 1 dT // - T'w' + -- -- -- = const // Re Pr dz // (1) (2) // (1) - turbulent heat flux // (2) - heat stress // terms are defined at [W] nodes (averaged in [W] nodes) // // [T'w', dT/dz] have to be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(heat_balance, \ turbulent_heat_flux, heat_stress) for (k = grid.gcz; k <= grid.nz - grid.gcz; k++) { // all [W] nodes turbulent_heat_flux[k] = -Tw_flux[k]; heat_stress[k] = c_diffusivity * T_grad[k]; heat_balance[k] = turbulent_heat_flux[k] + heat_stress[k]; } } // -------------------------------------------------------------------------------------------- // // SVA production // -------------------------------------------------------------------------------------------- // template< typename T > void nse::SVA_production( T* _SVA_production, // node: [C] const T* const CW_bottom, // node: [C (W -- C)] const T* const CW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid) // production term of scalar variance equation defined at [C] node // _ // ____ dC // - c'w' * -- // dz // [W] average has to be known at all [W] nodes, including walls // [C] average has to be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_SVA_production) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _SVA_production[k] = -(T) 0.5 * ( // discretization is based on ADV. form // // correct for SKEW.form (checked) // (CW_bottom[k] - C[k] * W[k]) * (C[k] - C[k - 1]) * grid.dzi[k] + (CW_top[k] - C[k] * W[k + 1]) * (C[k + 1] - C[k]) * grid.dzi[k]); } } // -------------------------------------------------------------------------------------------- // // SVA transport // -------------------------------------------------------------------------------------------- // template< typename T > void nse::SVA_transport( T* _SVA_transport, // node: [C] const T* const cc_w_flux, // node: [W] const wstGrid3d< T >& grid) // transport term of scalar variance equation defined at [C] node // ______________ // d[(c')^2 * w')] // - ---------------- // dz // [c'c'w'] flux has to be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(_SVA_transport) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _SVA_transport[k] = -(T) 0.5 * (cc_w_flux[k + 1] - cc_w_flux[k]) * grid.dzi[k]; } } // -------------------------------------------------------------------------------------------- // // SVA dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void nse::SVA_dissipation( T* _SVA_dissipation, // node: [C] const T* const C_dissipation, // node: [C] const T* const C, // node: [C] const T c_diffusivity, const wstGrid3d< T >& grid) // dissipation component of scalar variance equation defined at [C] node // ___________ // d^2(c') // k * c' ------- // dx(j)^2 // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_SVA_dissipation) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _SVA_dissipation[k] = C_dissipation[k] - c_diffusivity * (C[k] * ((C[k + 1] - C[k]) * grid.dzp2i[k] - (C[k] - C[k - 1]) * grid.dzm2i[k])); } } // -------------------------------------------------------------------------------------------- // // SVA iso dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void nse::SVA_iso_dissipation( T* _SVA_iso_dissipation, // node: [C] const T* const C_iso_dissipation, // node: [C] const T* const C, // node: [C] const T c_diffusivity, const wstGrid3d< T >& grid) // isotropic dissipation component of scalar variance equation defined at [C] node // _____________ // d(c') d(c') // - k * ----- * ----- // dx(j) dx(j) // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_SVA_iso_dissipation) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _SVA_iso_dissipation[k] = -(C_iso_dissipation[k] - c_diffusivity * ( (T)0.5 * (C[k + 1] - C[k]) * (C[k + 1] - C[k]) * grid.dzp2i[k] + (T)0.5 * (C[k] - C[k - 1]) * (C[k] - C[k - 1]) * grid.dzm2i[k])); } } // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: production // -------------------------------------------------------------------------------------------- // template< typename T > void nse::cu_production_shear( T* _cu_production_shear, // node: [C] const T* const CW_bottom_u, // node: [C (W -- C)] const T* const CW_top_u, // node: [C (W -- C)] const T* const C, // node: [C] const T* const U, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid) // // production [shear] term of [c'u'] budget equation defined at [C] node // _ // ____ dU // - c'w' * -- // dz // // [W] average has to be known at all [W] nodes, including walls // [U] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cu_production_shear) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cu_production_shear[k] = -(T)0.5 * ( // discretization is based on ADV. form // (CW_bottom_u[k] - C[k] * W[k]) * (U[k] - U[k - 1]) * grid.dzi[k] + (CW_top_u[k] - C[k] * W[k + 1]) * (U[k + 1] - U[k]) * grid.dzi[k]); } } template< typename T > void nse::cu_production_gradC( T* _cu_production_gradC, // node: [C] const T* const UW_bottom, // node: [C (W -- C)] const T* const UW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const U, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid) // // production [gradC] term of [c'u'] budget equation defined at [C] node // _ // ____ dC // - u'w' * -- // dz // // [W] average has to be known at all [W] nodes, including walls // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cu_production_gradC) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cu_production_gradC[k] = -(T)0.5 * ( // discretization is based on ADV. form // (UW_bottom[k] - U[k] * W[k]) * (C[k] - C[k - 1]) * grid.dzi[k] + (UW_top[k] - U[k] * W[k + 1]) * (C[k + 1] - C[k]) * grid.dzi[k]); } } template< typename T > void nse::cv_production_shear( T* _cv_production_shear, // node: [C] const T* const CW_bottom_v, // node: [C (W -- C)] const T* const CW_top_v, // node: [C (W -- C)] const T* const C, // node: [C] const T* const V, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid) // // production [shear] term of [c'v'] budget equation defined at [C] node // _ // ____ dV // - c'w' * -- // dz // // [W] average has to be known at all [W] nodes, including walls // [V] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cv_production_shear) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cv_production_shear[k] = -(T)0.5 * ( // discretization is based on ADV. form // (CW_bottom_v[k] - C[k] * W[k]) * (V[k] - V[k - 1]) * grid.dzi[k] + (CW_top_v[k] - C[k] * W[k + 1]) * (V[k + 1] - V[k]) * grid.dzi[k]); } } template< typename T > void nse::cv_production_gradC( T* _cv_production_gradC, // node: [C] const T* const VW_bottom, // node: [C (W -- C)] const T* const VW_top, // node: [C (W -- C)] const T* const C, // node: [C] const T* const V, // node: [C] const T* const W, // node: [W] const wstGrid3d< T >& grid) // // production [gradC] term of [c'v'] budget equation defined at [C] node // _ // ____ dC // - v'w' * -- // dz // // [W] average has to be known at all [W] nodes, including walls // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cv_production_gradC) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cv_production_gradC[k] = -(T)0.5 * ( // discretization is based on ADV. form // (VW_bottom[k] - V[k] * W[k]) * (C[k] - C[k - 1]) * grid.dzi[k] + (VW_top[k] - V[k] * W[k + 1]) * (C[k + 1] - C[k]) * grid.dzi[k]); } } template< typename T > void nse::cw_production_shear( T* _cw_production_shear, // node: [W] const T* const CW_bottom_w, // node: [W (C -- W)] const T* const CW_top_w, // node: [W (C -- W)] const T* C, // node: [C] const T* W, // node: [W] const wstGrid3d< T >& grid) // // production [shear] term of [c'w'] budget equation defined at [W] node // _ // ____ dW // - c'w' * -- // dz // // [W] average has to be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(_cw_production_shear) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { // all [W] nodes, excluding walls _cw_production_shear[k] = - ( // discretization is based on ADV. form // (CW_bottom_w[k] - (T)0.25 * (C[k] + C[k - 1]) * (W[k] + W[k - 1])) * (W[k] - W[k - 1]) * grid.dzmi[k] + (CW_top_w[k] - (T)0.25 * (C[k] + C[k - 1]) * (W[k] + W[k + 1])) * (W[k + 1] - W[k]) * grid.dzmi[k]); } w_dirichlet_bc_z(_cw_production_shear, (T)0, (T)0, grid); } template< typename T > void nse::cw_production_gradC( T* _cw_production_gradC, // node: [W] const T* const W2_w, // node: [W] const T* const W2_c, // node: [C] const T* C, // node: [C] const T* W, // node: [W] const wstGrid3d< T >& grid) // // production [gradC] term of [c'w'] budget equation defined at [W] node // _ // ____ dC // - w'w' * -- // dz // // [W^2, W] averages have to be known at all [W] nodes, including walls // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cw_production_gradC) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { // all [W] nodes, excluding walls _cw_production_gradC[k] = - ( // discretization is based on ADV. form // (W2_c[k] - W[k] * W[k + 1]) * (C[k + 1] - C[k]) * grid.dziq[k] + (W2_c[k - 1] - W[k] * W[k - 1]) * (C[k - 1] - C[k - 2]) * grid.dziq[k - 1] + (W2_w[k] - W[k] * W[k]) * (C[k] - C[k - 1]) * (grid.dziq[k] + grid.dziq[k - 1])); } w_dirichlet_bc_z(_cw_production_gradC, (T)0, (T)0, grid); } // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: transport // -------------------------------------------------------------------------------------------- // template< typename T > void nse::cu_transport(T* _cu_transport, // node: [C] const T* const cuw_flux, // node: [W] const wstGrid3d< T >& grid) // // transport term of [c'u'] equation defined at [C] node // ______________ // d[(c'u') * u'] // - ---------------- // dz // [c'u'w'] flux has be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(_cu_transport) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cu_transport[k] = -(cuw_flux[k + 1] - cuw_flux[k]) * grid.dzi[k]; } } template< typename T > void nse::cv_transport(T* _cv_transport, // node: [C] const T* const cvw_flux, // node: [W] const wstGrid3d< T >& grid) // // transport term of [c'v'] equation defined at [C] node // ______________ // d[(c'v') * v'] // - ---------------- // dz // [c'v'w'] flux has be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(_cv_transport) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cv_transport[k] = -(cvw_flux[k + 1] - cvw_flux[k]) * grid.dzi[k]; } } template< typename T > void nse::cw_transport(T* _cw_transport, // node: [W] const T* const cww_flux, // node: [C] const wstGrid3d< T >& grid) // // transport term of [c'w'] budget equation defined at [W] node // ______________ // d[(c'w') * w'] // - ---------------- // dz // [c'w'w'] flux has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cw_transport) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cw_transport[k] = -(cww_flux[k] - cww_flux[k - 1]) * (T)2.0 * grid.dzmi[k]; } } // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: pressure scrambles // -------------------------------------------------------------------------------------------- // template< typename T > void nse::cw_pressure_work(T* _cw_pressure_work, // node: [W] const T* const cp_flux, // node: [C] const wstGrid3d< T >& grid) // // pressure work term of [c'w'] budget equation defined at [W] // ______ // d[c'p'] // - -------- // dz // [c'p'] flux has to be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cw_pressure_work) for (k = grid.gcz; k <= grid.nz - grid.gcz; k++) { // all [W] nodes _cw_pressure_work[k] = -(cp_flux[k] - cp_flux[k - 1]) * (T)2.0 * grid.dzmi[k]; } } template< typename T > void nse::cu_pressure_gradc( T* _cu_pressure_gradc, // node: [C] const T* const c_dpdx_turb, // node: [C] const wstGrid3d< T >& grid) // // p'*dc'/dx = { d(c'p')/dx = 0 } - c'*dp'/dx // { int k; #pragma omp parallel for private(k) shared(_cu_pressure_gradc) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cu_pressure_gradc[k] = - c_dpdx_turb[k]; } } template< typename T > void nse::cv_pressure_gradc( T* _cv_pressure_gradc, // node: [C] const T* const c_dpdy_turb, // node: [C] const wstGrid3d< T >& grid) // // p'*dc'/dy = { d(c'p')/dy = 0 } - c'*dp'/dy // { int k; #pragma omp parallel for private(k) shared(_cv_pressure_gradc) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { _cv_pressure_gradc[k] = -c_dpdy_turb[k]; } } template< typename T > void nse::cw_pressure_gradc( T* _cw_pressure_gradc, // node: [W] const T* const _cw_pressure_work, // node: [W] const T* const c_dpdz_turb, // node: [W] const wstGrid3d< T >& grid) // // p'*dc'/dz = d(c'p')/dz - c'*dp'/dz // { int k; #pragma omp parallel for private(k) shared(_cw_pressure_gradc) for (k = grid.gcz; k <= grid.nz - grid.gcz; k++) { // all [W] nodes _cw_pressure_gradc[k] = -_cw_pressure_work[k] - c_dpdz_turb[k]; } } // -------------------------------------------------------------------------------------------- // // c'ui' flux budget: dissipation // -------------------------------------------------------------------------------------------- // template< typename T > void nse::cu_dissipation( T* _cu_dissipation, // node: [C] const T* const CU_dissipation, // node: [C] const T* const C, // node: [C] const T* const U, // node: [C] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid) // // ___________ ___________ // d^2(c') d^2(u') // k * u' ------- + nu * c' ------- // dx(j)^2 dx(j)^2 // // [U, C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; T C_diffusion, U_diffusion; #pragma omp parallel for private(k, C_diffusion, U_diffusion) shared(_cu_dissipation) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { C_diffusion = c_diffusivity * ((C[k + 1] - C[k]) * grid.dzp2i[k] - (C[k] - C[k - 1]) * grid.dzm2i[k]); U_diffusion = c_kinematic_viscosity * ((U[k + 1] - U[k]) * grid.dzp2i[k] - (U[k] - U[k - 1]) * grid.dzm2i[k]); _cu_dissipation[k] = CU_dissipation[k] - (C[k] * U_diffusion + C_diffusion * U[k]); } } template< typename T > void nse::cv_dissipation( T* _cv_dissipation, // node: [C] const T* const CV_dissipation, // node: [C] const T* const C, // node: [C] const T* const V, // node: [C] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid) // // ___________ ___________ // d^2(c') d^2(v') // k * v' ------- + nu * c' ------- // dx(j)^2 dx(j)^2 // // [V, C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; T C_diffusion, V_diffusion; #pragma omp parallel for private(k, C_diffusion, V_diffusion) shared(_cv_dissipation) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { C_diffusion = c_diffusivity * ((C[k + 1] - C[k]) * grid.dzp2i[k] - (C[k] - C[k - 1]) * grid.dzm2i[k]); V_diffusion = c_kinematic_viscosity * ((V[k + 1] - V[k]) * grid.dzp2i[k] - (V[k] - V[k - 1]) * grid.dzm2i[k]); _cv_dissipation[k] = CV_dissipation[k] - (C[k] * V_diffusion + C_diffusion * V[k]); } } template< typename T > void nse::cw_dissipation( T* _cw_dissipation, // node: [W] const T* const CW_dissipation, // node: [W] const T* const C, // node: [C] const T* const W, // node: [W] const T c_diffusivity, const T c_kinematic_viscosity, const wstGrid3d< T >& grid) // // ___________ ___________ // d^2(c') d^2(w') // k * w' ------- + nu * c' ------- // dx(j)^2 dx(j)^2 // // [CW-dissipation, W] averages have to be known at all [W] nodes, including walls // [C] average has be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { T *C_diffusion, *W_diffusion; int c_buf_id = memStx::get_buf(&C_diffusion, grid.nz); int w_buf_id = memStx::get_buf(&W_diffusion, grid.nz); null(C_diffusion, grid.nz); null(W_diffusion, grid.nz); int k; #pragma omp parallel for private(k) shared(C_diffusion, W_diffusion) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { C_diffusion[k] = c_diffusivity * ((C[k + 1] - C[k]) * grid.dzp2i[k] - (C[k] - C[k - 1]) * grid.dzm2i[k]); W_diffusion[k] = c_kinematic_viscosity * ((W[k + 1] - W[k]) * grid.dzm2i[k] - (W[k] - W[k - 1]) * grid.dzp2i[k - 1]); } // assuming W = 0 & ~linear[laplace(W)] = 0 at walls -> no need for laplace(C) b.c. // w_dirichlet_bc_z(W_diffusion, (T)0, (T)0, grid); #pragma omp parallel for private(k) shared(_cw_dissipation,\ C_diffusion, W_diffusion) for (k = grid.gcz; k <= grid.nz - grid.gcz; k++) { // all [W] nodes _cw_dissipation[k] = CW_dissipation[k] - (T)0.5 * ( (C[k] + C[k - 1]) * W_diffusion[k] + W[k] * (C_diffusion[k] + C_diffusion[k - 1])); } memStx::free_buf(c_buf_id); memStx::free_buf(w_buf_id); } // -------------------------------------------------------------------------------------------- // // c'w' flux budget: buoyancy // -------------------------------------------------------------------------------------------- // template< typename T > void nse::cw_buoyancy( T* _cw_buoyancy, // node: [W] const T* const C2_c, // node: [C] const T* const C2_w, // node: [W] const T* const C, // node: [C] const T c_Richardson, const wstGrid3d< T >& grid) // // ____ // Ri * c'c' // // [C^2 at W-node] average has to be known at all [W] nodes, including walls // [C, C^2 at C-node] averages have be known at all [C] nodes and ghost nodes: (k + 1/2), (k - 1/2) { int k; #pragma omp parallel for private(k) shared(_cw_buoyancy) for (k = grid.gcz; k <= grid.nz - grid.gcz; k++) { // all [W] nodes _cw_buoyancy[k] = (T)0.25 * c_Richardson * ( C2_c[k] - C[k] * C[k] + C2_c[k - 1] - C[k - 1] * C[k - 1] + (T)2.0 * (C2_w[k] - C[k] * C[k - 1]) ); } } // -------------------------------------------------------------------------------------------- // // TPE structure // -------------------------------------------------------------------------------------------- // template< typename T > void nse::TPE_structure( T* TPE, // node: [C] T* TPE_heat_flux, T* TPE_diffusion, // node: [C] T* TPE_dissipation, T* TPE_iso_dissipation, // node: [C] const T* const TVA_production, // node: [C] const T* const TVA_diffusion, // node: [C] const T* const TVA_dissipation, // node: [C] const T* const TVA_iso_dissipation, // node: [C] const T* const T2, // node: [C] const T* const Tc, // node: [C] const T* const T_grad, // node: [W] const T c_Richardson, const wstGrid3d< T >& grid) // // TPE = 1/2*T'T'*Ri(b)/[dT/dz] // TPE balance: [temperature variance] * (Ri(b)/[dT/dz]) // // [dT/dz] has to be known at all [W] nodes, including walls { int k; #pragma omp parallel for private(k) shared(TPE,\ TPE_heat_flux, TPE_diffusion, TPE_dissipation, TPE_iso_dissipation) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { TPE[k] = (T)0.5 * (T2[k] - Tc[k] * Tc[k]) * (c_Richardson / ((T)0.5 * (T_grad[k] + T_grad[k + 1]))); TPE_heat_flux[k] = TVA_production[k] * (c_Richardson / ((T)0.5 * (T_grad[k] + T_grad[k + 1]))); TPE_diffusion[k] = TVA_diffusion[k] * (c_Richardson / ((T)0.5 * (T_grad[k] + T_grad[k + 1]))); TPE_dissipation[k] = TVA_dissipation[k] * (c_Richardson / ((T)0.5 * (T_grad[k] + T_grad[k + 1]))); TPE_iso_dissipation[k] = TVA_iso_dissipation[k] * (c_Richardson / ((T)0.5 * (T_grad[k] + T_grad[k + 1]))); } } // -------------------------------------------------------------------------------------------- // // Energy structure // -------------------------------------------------------------------------------------------- // template< typename T > void nse::energy_structure( T* TKE_share, T* TPE_share, // node: [C] const T* const TKE, // node: [C] const T* const TPE, // node: [C] const wstGrid3d< T >& grid) // // TKE-TPE shares // { int k; #pragma omp parallel for private(k) shared(TKE_share, TPE_share) for (k = grid.gcz; k < grid.nz - grid.gcz; k++) { TKE_share[k] = TKE[k] / (TKE[k] + TPE[k]); TPE_share[k] = TPE[k] / (TKE[k] + TPE[k]); } } // -------------------------------------------------------------------------------------------- //