From 9570b4ec27e945a92169782a91259cd900b690be Mon Sep 17 00:00:00 2001 From: Lizzzka007 <gashchuk2011@mail.ru> Date: Wed, 20 Dec 2023 00:27:31 +0300 Subject: [PATCH] . --- includeCU/sfx_compute_sheba.cuh | 17 +++ includeCU/sfx_surface.cuh | 9 ++ includeCXX/sfx_call_class_func.h | 17 ++- includeCXX/sfx_compute_sheba.h | 11 +- includeCXX/sfx_esm.h | 2 +- includeCXX/sfx_sheba.h | 35 +++-- includeCXX/sfx_surface.h | 16 ++ srcC/sfx_call_cxx.c | 36 ++++- srcCU/sfx_compute_esm.cu | 18 ++- srcCU/sfx_surface.cu | 46 ++++++ srcCXX/sfx_call_class_func.cpp | 42 +++++- srcCXX/sfx_compute_esm.cpp | 45 +----- srcCXX/sfx_compute_sheba.cpp | 250 ++++++++++++++++++++++++++++--- srcCXX/sfx_esm.cpp | 2 +- srcCXX/sfx_sheba.cpp | 81 ++++++---- srcCXX/sfx_surface.cpp | 87 +++++++++++ srcF/sfx_esm.f90 | 5 +- srcF/sfx_fc_wrapper.F90 | 30 +++- 18 files changed, 614 insertions(+), 135 deletions(-) create mode 100644 includeCU/sfx_compute_sheba.cuh create mode 100644 includeCU/sfx_surface.cuh create mode 100644 includeCXX/sfx_surface.h create mode 100644 srcCU/sfx_surface.cu create mode 100644 srcCXX/sfx_surface.cpp diff --git a/includeCU/sfx_compute_sheba.cuh b/includeCU/sfx_compute_sheba.cuh new file mode 100644 index 0000000..acd67d6 --- /dev/null +++ b/includeCU/sfx_compute_sheba.cuh @@ -0,0 +1,17 @@ +#pragma once + +template<typename T> +void compute_flux_sheba_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, + const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_, + const T kappa, const T Pr_t_0_inv, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h, + const T Re_rough_min, + const T B1_rough, const T B2_rough, + const T B_max_land, const T B_max_ocean, const T B_max_lake, + const T gamma_c, const T Re_visc_min, + const T Pr_m, const T nu_air, const T g, + const int maxiters_charnock, + const int grid_size); \ No newline at end of file diff --git a/includeCU/sfx_surface.cuh b/includeCU/sfx_surface.cuh new file mode 100644 index 0000000..002336c --- /dev/null +++ b/includeCU/sfx_surface.cuh @@ -0,0 +1,9 @@ +#pragma once + +// template<typename T> +// __device__ void get_charnock_roughness(T &z0_m, T &u_dyn0, +// const T h, const T U, +// const T kappa, +// const T h_charnock, const T c1_charnock, const T c2_charnock, +// const int maxiters); + \ No newline at end of file diff --git a/includeCXX/sfx_call_class_func.h b/includeCXX/sfx_call_class_func.h index 08c9164..317f3d9 100644 --- a/includeCXX/sfx_call_class_func.h +++ b/includeCXX/sfx_call_class_func.h @@ -4,7 +4,7 @@ extern "C" { #endif - void surf_flux_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, + void surf_flux_esm_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, const float kappa, const float Pr_t_0_inv, const float Pr_t_inf_inv, const float alpha_m, const float alpha_h, const float alpha_h_fix, @@ -16,6 +16,21 @@ extern "C" { const int maxiters_charnock, const int maxiters_convection, const int grid_size); + void surf_flux_sheba_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, + float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, + const float kappa, const float Pr_t_0_inv, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h, + const float Re_rough_min, + const float B1_rough, const float B2_rough, + const float B_max_land, const float B_max_ocean, const float B_max_lake, + const float gamma_c, const float Re_visc_min, + const float Pr_m, const float nu_air, const float g, + const int maxiters_charnock, + const int grid_size); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/includeCXX/sfx_compute_sheba.h b/includeCXX/sfx_compute_sheba.h index 92516a2..d13bf59 100644 --- a/includeCXX/sfx_compute_sheba.h +++ b/includeCXX/sfx_compute_sheba.h @@ -3,12 +3,15 @@ template<typename T> void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_, - const T kappa, const T Pr_t_0_inv, const T Pr_t_inf_inv, - const T alpha_m, const T alpha_h, const T alpha_h_fix, - const T beta_m, const T beta_h, const T Rib_max, const T Re_rough_min, + const T kappa, const T Pr_t_0_inv, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h, + const T Re_rough_min, const T B1_rough, const T B2_rough, const T B_max_land, const T B_max_ocean, const T B_max_lake, const T gamma_c, const T Re_visc_min, const T Pr_m, const T nu_air, const T g, - const int maxiters_charnock, const int maxiters_convection, + const int maxiters_charnock, const int grid_size); \ No newline at end of file diff --git a/includeCXX/sfx_esm.h b/includeCXX/sfx_esm.h index 5f47957..1b7067c 100644 --- a/includeCXX/sfx_esm.h +++ b/includeCXX/sfx_esm.h @@ -33,7 +33,7 @@ public: const T Pr_m, const T nu_air, const T g); ~FluxEsm(); - void compute_flux(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, + void compute_flux_esm(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_, const int maxiters_charnock, const int maxiters_convection); diff --git a/includeCXX/sfx_sheba.h b/includeCXX/sfx_sheba.h index 3b2cfd3..ce911e0 100644 --- a/includeCXX/sfx_sheba.h +++ b/includeCXX/sfx_sheba.h @@ -9,33 +9,38 @@ private: T *U, *dT, *Tsemi, *dQ, *h, *in_z0_m; T *zeta, *Rib, *Re, *B, *z0_m, *z0_t, *Rib_conv_lim, *Cm, *Ct, *Km, *Pr_t_inv; - // T kappa, Pr_t_0_inv, Pr_t_inf_inv, - // alpha_m, alpha_h, alpha_h_fix, - // beta_m, beta_h, - // Rib_max, Re_rough_min, - // B1_rough, B2_rough, - // B_max_land, B_max_ocean, B_max_lake, - // gamma_c, - // Re_visc_min, - // Pr_m, nu_air, g; + T kappa, Pr_t_0_inv, Pr_t_inf_inv, + alpha_m, alpha_h, + a_m, a_h, + b_m, b_h, + c_h, + Rib_max, Re_rough_min, + B1_rough, B2_rough, + B_max_land, B_max_ocean, B_max_lake, + gamma_c, + Re_visc_min, + Pr_m, nu_air, g; int grid_size; bool ifAllocated; size_t allocated_size; public: FluxSheba(); - void set_params(const int grid_size, const T kappa, const T Pr_t_0_inv, const T Pr_t_inf_inv, - const T alpha_m, const T alpha_h, const T alpha_h_fix, - const T beta_m, const T beta_h, const T Rib_max, const T Re_rough_min, + void set_params(const int grid_size, const T kappa, const T Pr_t_0_inv, + const T alpha_m, const T alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h, + const T Re_rough_min, const T B1_rough, const T B2_rough, const T B_max_land, const T B_max_ocean, const T B_max_lake, const T gamma_c, const T Re_visc_min, const T Pr_m, const T nu_air, const T g); - ~Flux(); + ~FluxSheba(); - void compute_flux(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, + void compute_flux_sheba(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_, - const int maxiters_charnock, const int maxiters_convection); + const int maxiters_charnock); private: void set_data( T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, diff --git a/includeCXX/sfx_surface.h b/includeCXX/sfx_surface.h new file mode 100644 index 0000000..d82fec0 --- /dev/null +++ b/includeCXX/sfx_surface.h @@ -0,0 +1,16 @@ +#pragma once + +template<typename T> +void get_charnock_roughness(T &z0_m, T &u_dyn0, + const T h, const T U, + const T kappa, + const T h_charnock, const T c1_charnock, const T c2_charnock, + const int maxiters); + +template<typename T> +void get_thermal_roughness(T &z0_t, T &B, + const T z0_m, const T Re, + const T Re_rough_min, + const T B1_rough, const T B2_rough, const T B3_rough, const T B4_rough, + const T B_max_ocean, const T B_max_lake, const T B_max_land, + const int surface_type); \ No newline at end of file diff --git a/srcC/sfx_call_cxx.c b/srcC/sfx_call_cxx.c index 007d00c..be43297 100644 --- a/srcC/sfx_call_cxx.c +++ b/srcC/sfx_call_cxx.c @@ -2,7 +2,8 @@ #include <stdio.h> #include "../includeCXX/sfx_call_class_func.h" // -------------------------------------------------------------------------- // -void get_surface_fluxes (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, + +void get_surface_fluxes_esm (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, const float *kappa, const float *Pr_t_0_inv, const float *Pr_t_inf_inv, const float *alpha_m, const float *alpha_h, const float *alpha_h_fix, @@ -14,7 +15,7 @@ void get_surface_fluxes (float *zeta_, float *Rib_, float *Re_, float *B_, float const int *maxiters_charnock, const int *maxiters_convection, const int *grid_size) { - surf_flux_CXX ( zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, + surf_flux_esm_CXX ( zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, U_, dT_, Tsemi_, dQ_, h_, in_z0_m_, *kappa, *Pr_t_0_inv, *Pr_t_inf_inv, *alpha_m, *alpha_h, *alpha_h_fix, @@ -25,4 +26,35 @@ void get_surface_fluxes (float *zeta_, float *Rib_, float *Re_, float *B_, float *Pr_m, *nu_air, *g, *maxiters_charnock, *maxiters_convection, *grid_size); +} + +void get_surface_fluxes_sheba (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, + float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, + const float *kappa, const float *Pr_t_0_inv, + const float *alpha_m, const float *alpha_h, + const float *a_m, const float *a_h, + const float *b_m, const float *b_h, + const float *c_h, + const float *Re_rough_min, + const float *B1_rough, const float *B2_rough, + const float *B_max_land, const float *B_max_ocean, const float *B_max_lake, + const float *gamma_c, const float *Re_visc_min, + const float *Pr_m, const float *nu_air, const float *g, + const int *maxiters_charnock, + const int *grid_size) +{ + surf_flux_sheba_CXX ( zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, + U_, dT_, Tsemi_, dQ_, h_, in_z0_m_, + *kappa, *Pr_t_0_inv, + *alpha_m, *alpha_h, + *a_m, *a_h, + *b_m, *b_h, + *c_h, + *Re_rough_min, + *B1_rough, *B2_rough, + *B_max_land, *B_max_ocean, *B_max_lake, + *gamma_c, *Re_visc_min, + *Pr_m, *nu_air, *g, + *maxiters_charnock, + *grid_size); } \ No newline at end of file diff --git a/srcCU/sfx_compute_esm.cu b/srcCU/sfx_compute_esm.cu index b9c4e2c..302494a 100644 --- a/srcCU/sfx_compute_esm.cu +++ b/srcCU/sfx_compute_esm.cu @@ -1,6 +1,7 @@ #include <cmath> #include <iostream> #include "../includeCU/sfx_compute_esm.cuh" +#include "../includeCU/sfx_surface.cuh" template<typename T> __device__ void get_charnock_roughness(T &z0_m, T &u_dyn0, @@ -45,7 +46,8 @@ template __device__ void get_charnock_roughness(double &z0_m, double &u_dyn0, const double kappa, const double h_charnock, const double c1_charnock, const double c2_charnock, const int maxiters); - + + template<typename T> __device__ void get_convection_lim(T &zeta_lim, T &Rib_lim, T &f_m_lim, T &f_h_lim, const T h0_m, const T h0_t, const T B, @@ -237,7 +239,7 @@ template __device__ void get_psi_semi_convection(double &psi_m, double &psi_h, d const int maxiters); template<typename T> -__global__ void compute_flux_esm_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, +__global__ void kernel_compute_flux_esm_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_, const T kappa, const T Pr_t_0_inv, const T Pr_t_inf_inv, const T alpha_m, const T alpha_h, const T alpha_h_fix, @@ -351,7 +353,7 @@ __global__ void compute_flux_esm_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, } } -template __global__ void compute_flux_esm_gpu(float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, +template __global__ void kernel_compute_flux_esm_gpu(float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, const float *U, const float *dt, const float *T_semi, const float *dq, const float *H, const float *in_z0_m, const float kappa, const float Pr_t_0_inv, const float Pr_t_inf_inv, const float alpha_m, const float alpha_h, const float alpha_h_fix, @@ -362,7 +364,7 @@ template __global__ void compute_flux_esm_gpu(float *zeta_, float *Rib_, float * const float Pr_m, const float nu_air, const float g, const int maxiters_charnock, const int maxiters_convection, const int grid_size); -template __global__ void compute_flux_esm_gpu(double *zeta_, double *Rib_, double *Re_, double *B_, double *z0_m_, double *z0_t_, double *Rib_conv_lim_, double *Cm_, double *Ct_, double *Km_, double *Pr_t_inv_, +template __global__ void kernel_compute_flux_esm_gpu(double *zeta_, double *Rib_, double *Re_, double *B_, double *z0_m_, double *z0_t_, double *Rib_conv_lim_, double *Cm_, double *Ct_, double *Km_, double *Pr_t_inv_, const double *U, const double *dt, const double *T_semi, const double *dq, const double *H, const double *in_z0_m, const double kappa, const double Pr_t_0_inv, const double Pr_t_inf_inv, const double alpha_m, const double alpha_h, const double alpha_h_fix, @@ -375,7 +377,7 @@ template __global__ void compute_flux_esm_gpu(double *zeta_, double *Rib_, doubl const int grid_size); template<typename T> -void compute_flux_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, +void compute_flux_esm_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_, const T kappa, const T Pr_t_0_inv, const T Pr_t_inf_inv, const T alpha_m, const T alpha_h, const T alpha_h_fix, @@ -391,7 +393,7 @@ void compute_flux_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *R dim3 cuBlock = dim3(1024, 1, 1); dim3 cuGrid = dim3(BlockCount, 1, 1); - compute_flux<<<cuGrid, cuBlock>>>(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, + kernel_compute_flux_esm_gpu<<<cuGrid, cuBlock>>>(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, U_, dT_, Tsemi_, dQ_, h_, in_z0_m_, kappa, Pr_t_0_inv, Pr_t_inf_inv, alpha_m, alpha_h, alpha_h_fix, @@ -404,7 +406,7 @@ void compute_flux_gpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *R grid_size); } -template void compute_flux_gpu(float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, +template void compute_flux_esm_gpu(float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, const float *U, const float *dt, const float *T_semi, const float *dq, const float *H, const float *in_z0_m, const float kappa, const float Pr_t_0_inv, const float Pr_t_inf_inv, const float alpha_m, const float alpha_h, const float alpha_h_fix, @@ -415,7 +417,7 @@ template void compute_flux_gpu(float *zeta_, float *Rib_, float *Re_, float *B_, const float Pr_m, const float nu_air, const float g, const int maxiters_charnock, const int maxiters_convection, const int grid_size); -template void compute_flux_gpu(double *zeta_, double *Rib_, double *Re_, double *B_, double *z0_m_, double *z0_t_, double *Rib_conv_lim_, double *Cm_, double *Ct_, double *Km_, double *Pr_t_inv_, +template void compute_flux_esm_gpu(double *zeta_, double *Rib_, double *Re_, double *B_, double *z0_m_, double *z0_t_, double *Rib_conv_lim_, double *Cm_, double *Ct_, double *Km_, double *Pr_t_inv_, const double *U, const double *dt, const double *T_semi, const double *dq, const double *H, const double *in_z0_m, const double kappa, const double Pr_t_0_inv, const double Pr_t_inf_inv, const double alpha_m, const double alpha_h, const double alpha_h_fix, diff --git a/srcCU/sfx_surface.cu b/srcCU/sfx_surface.cu new file mode 100644 index 0000000..d15f64e --- /dev/null +++ b/srcCU/sfx_surface.cu @@ -0,0 +1,46 @@ +#include "../includeCU/sfx_surface.cuh" + +// template<typename T> +// __device__ void get_charnock_roughness(T &z0_m, T &u_dyn0, +// const T h, const T U, +// const T kappa, +// const T h_charnock, const T c1_charnock, const T c2_charnock, +// const int maxiters) +// { +// T Uc, a, b, c, c_min, f; + +// Uc = U; +// a = 0.0; +// b = 25.0; +// c_min = log(h_charnock) / kappa; + +// for (int i = 0; i < maxiters; i++) +// { +// f = c1_charnock - 2.0 * log(Uc); +// for (int j = 0; j < maxiters; j++) +// { +// c = (f + 2.0 * log(b)) / kappa; +// if (U <= 8.0e0) +// a = log(1.0 + c2_charnock * ( pow(b / Uc, 3) ) ) / kappa; +// c = max(c - a, c_min); +// b = c; +// } +// z0_m = h_charnock * exp(-c * kappa); +// z0_m = max(z0_m, T(0.000015e0)); +// Uc = U * log(h_charnock / z0_m) / log(h / z0_m); +// } + +// u_dyn0 = Uc / c; +// } + +// template __device__ void get_charnock_roughness(float &z0_m, float &u_dyn0, +// const float h, const float U, +// const float kappa, +// const float h_charnock, const float c1_charnock, const float c2_charnock, +// const int maxiters); +// template __device__ void get_charnock_roughness(double &z0_m, double &u_dyn0, +// const double h, const double U, +// const double kappa, +// const double h_charnock, const double c1_charnock, const double c2_charnock, +// const int maxiters); + \ No newline at end of file diff --git a/srcCXX/sfx_call_class_func.cpp b/srcCXX/sfx_call_class_func.cpp index 2090d62..9bc7ac4 100644 --- a/srcCXX/sfx_call_class_func.cpp +++ b/srcCXX/sfx_call_class_func.cpp @@ -2,10 +2,11 @@ #include <stdio.h> #include "../includeCXX/sfx_call_class_func.h" #include "../includeCXX/sfx_esm.h" +#include "../includeCXX/sfx_sheba.h" #include <vector> // -------------------------------------------------------------------------- // -void surf_flux_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, +void surf_flux_esm_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, const float kappa, const float Pr_t_0_inv, const float Pr_t_inf_inv, const float alpha_m, const float alpha_h, const float alpha_h_fix, @@ -31,7 +32,44 @@ void surf_flux_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_ gamma_c, Re_visc_min, Pr_m, nu_air, g); - F.compute_flux(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, + F.compute_flux_esm(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, U_, dT_, Tsemi_, dQ_, h_, in_z0_m_, maxiters_charnock, maxiters_convection); +} + +void surf_flux_sheba_CXX (float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, + float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_, + const float kappa, const float Pr_t_0_inv, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h, + const float Re_rough_min, + const float B1_rough, const float B2_rough, + const float B_max_land, const float B_max_ocean, const float B_max_lake, + const float gamma_c, const float Re_visc_min, + const float Pr_m, const float nu_air, const float g, + const int maxiters_charnock, + const int grid_size) +{ +#ifdef INCLUDE_CUDA + static FluxSheba<float, MemType::CPU, MemType::CPU, MemType::GPU> F; +#else + static FluxSheba<float, MemType::CPU, MemType::CPU, MemType::CPU> F; +#endif + + F.set_params(grid_size, kappa, Pr_t_0_inv, + alpha_m, alpha_h, + a_m, a_h, + b_m, b_h, + c_h, + Re_rough_min, + B1_rough, B2_rough, + B_max_land, B_max_ocean, B_max_lake, + gamma_c, Re_visc_min, + Pr_m, nu_air, g); + + F.compute_flux_sheba(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, + U_, dT_, Tsemi_, dQ_, h_, in_z0_m_, + maxiters_charnock); } \ No newline at end of file diff --git a/srcCXX/sfx_compute_esm.cpp b/srcCXX/sfx_compute_esm.cpp index b50f49d..9a30be0 100644 --- a/srcCXX/sfx_compute_esm.cpp +++ b/srcCXX/sfx_compute_esm.cpp @@ -1,50 +1,7 @@ #include <cmath> #include <iostream> #include "../includeCXX/sfx_compute_esm.h" - -template<typename T> -void get_charnock_roughness(T &z0_m, T &u_dyn0, - const T h, const T U, - const T kappa, - const T h_charnock, const T c1_charnock, const T c2_charnock, - const int maxiters) -{ - T Uc, a, b, c, c_min, f; - - Uc = U; - a = 0.0; - b = 25.0; - c_min = log(h_charnock) / kappa; - - for (int i = 0; i < maxiters; i++) - { - f = c1_charnock - 2.0 * log(Uc); - for (int j = 0; j < maxiters; j++) - { - c = (f + 2.0 * log(b)) / kappa; - if (U <= 8.0e0) - a = log(1.0 + c2_charnock * ( pow(b / Uc, 3) ) ) / kappa; - c = std::max(c - a, c_min); - b = c; - } - z0_m = h_charnock * exp(-c * kappa); - z0_m = std::max(z0_m, T(0.000015e0)); - Uc = U * log(h_charnock / z0_m) / log(h / z0_m); - } - - u_dyn0 = Uc / c; -} - -template void get_charnock_roughness(float &z0_m, float &u_dyn0, - const float h, const float U, - const float kappa, - const float h_charnock, const float c1_charnock, const float c2_charnock, - const int maxiters); -template void get_charnock_roughness(double &z0_m, double &u_dyn0, - const double h, const double U, - const double kappa, - const double h_charnock, const double c1_charnock, const double c2_charnock, - const int maxiters); +#include "../includeCXX/sfx_surface.h" template<typename T> void get_convection_lim(T &zeta_lim, T &Rib_lim, T &f_m_lim, T &f_h_lim, diff --git a/srcCXX/sfx_compute_sheba.cpp b/srcCXX/sfx_compute_sheba.cpp index ad420c0..1aa7252 100644 --- a/srcCXX/sfx_compute_sheba.cpp +++ b/srcCXX/sfx_compute_sheba.cpp @@ -1,18 +1,221 @@ #include <cmath> #include <iostream> #include "../includeCXX/sfx_compute_sheba.h" +#include "../includeCXX/sfx_surface.h" + +template<typename T> +void get_psi_mh(T &psi_m, T &psi_h, + const T zeta_m, const T zeta_h, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h) +{ + T x_m, x_h; + T q_m, q_h; + + if (zeta_m >= 0.0) + { + q_m = pow((1.0 - b_m) / b_m, 1.0 / 3.0); + x_m = pow(1.0 + zeta_m, 1.0 / 3.0); + + psi_m = -3.0 * (a_m / b_m) * (x_m - 1.0) + 0.5 * (a_m / b_m) * q_m * (2.0 * log((x_m + q_m) / (1.0 + q_m)) - log((x_m * x_m - x_m * q_m + q_m * q_m) / (1.0 - q_m + q_m * q_m)) + 2.0 * sqrt(3.0) * (atan((2.0 * x_m - q_m) / (sqrt(3.0) * q_m)) - atan((2.0 - q_m) / (sqrt(3.0) * q_m)))); + } + else + { x_m = pow(1.0 - alpha_m * zeta_m, 0.25); + psi_m = (4.0 * atan(1.0) / 2.0) + 2.0 * log(0.5 * (1.0 + x_m)) + log(0.5 * (1.0 + x_m * x_m)) - 2.0 * atan(x_m); + } + + if (zeta_h >= 0.0) + { + q_h = sqrt(c_h * c_h - 4.0); + x_h = zeta_h; + + psi_h = -0.5 * b_h * log(1.0 + c_h * x_h + x_h * x_h) + ((-a_h / q_h) + ((b_h * c_h) / (2.0 * q_h))) * (log((2.0 * x_h + c_h - q_h) / (2.0 * x_h + c_h + q_h)) - log((c_h - q_h) / (c_h + q_h))); + } + else + { + x_h = pow(1.0 - alpha_h * zeta_h, 0.25); + psi_h = 2.0 * log(0.5 * (1.0 + x_h * x_h)); + } +} + +template void get_psi_mh(float &psi_m, float &psi_h, + const float zeta_m, const float zeta_h, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h); +template void get_psi_mh(double &psi_m, double &psi_h, + const double zeta_m, const double zeta_h, + const double alpha_m, const double alpha_h, + const double a_m, const double a_h, + const double b_m, const double b_h, + const double c_h); + +template<typename T> +void get_psi(T &psi_m, T &psi_h, + const T zeta, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h) +{ + T x_m, x_h; + T q_m, q_h; + + if (zeta >= 0.0) + { + q_m = pow((1.0 - b_m) / b_m, 1.0 / 3.0); + q_h = sqrt(c_h * c_h - 4.0); + + x_m = pow(1.0 + zeta, 1.0 / 3.0); + x_h = zeta; + + psi_m = -3.0 * (a_m / b_m) * (x_m - 1.0) + 0.5 * (a_m / b_m) * q_m * (2.0 * log((x_m + q_m) / (1.0 + q_m)) - log((x_m * x_m - x_m * q_m + q_m * q_m) / (1.0 - q_m + q_m * q_m)) + 2.0 * sqrt(3.0) * (atan((2.0 * x_m - q_m) / (sqrt(3.0) * q_m)) - atan((2.0 - q_m) / (sqrt(3.0) * q_m)))); + + psi_h = -0.5 * b_h * log(1.0 + c_h * x_h + x_h * x_h) + ((-a_h / q_h) + ((b_h * c_h) / (2.0 * q_h))) * (log((2.0 * x_h + c_h - q_h) / (2.0 * x_h + c_h + q_h)) - log((c_h - q_h) / (c_h + q_h))); + } + else + { + x_m = pow(1.0 - alpha_m * zeta, 0.25); + x_h = pow(1.0 - alpha_h * zeta, 0.25); + + psi_m = (4.0 * atan(1.0) / 2.0) + 2.0 * log(0.5 * (1.0 + x_m)) + log(0.5 * (1.0 + x_m * x_m)) - 2.0 * atan(x_m); + psi_h = 2.0 * log(0.5 * (1.0 + x_h * x_h)); + } +} + +template void get_psi(float &psi_m, float &psi_h, + const float zeta, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h); +template void get_psi(double &psi_m, double &psi_h, + const double zeta, + const double alpha_m, const double alpha_h, + const double a_m, const double a_h, + const double b_m, const double b_h, + const double c_h); + +template<typename T> +void get_dynamic_scales(T &Udyn, T &Tdyn, T &Qdyn, T &zeta, + const T U, const T Tsemi, const T dT, const T dQ, const T z, const T z0_m, const T z0_t, const T beta, + const T kappa, const T Pr_t_0_inv, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h, + const int maxiters) +{ + T psi_m, psi_h, psi0_m, psi0_h, Linv; + const T gamma = 0.61; + + Udyn = kappa * U / log(z / z0_m); + Tdyn = kappa * dT * Pr_t_0_inv / log(z / z0_t); + Qdyn = kappa * dQ * Pr_t_0_inv / log(z / z0_t); + zeta = 0.0; + + // --- no wind + if (Udyn < 1e-5) + return; + + Linv = kappa * beta * (Tdyn + gamma * Qdyn * Tsemi) / (Udyn * Udyn); + zeta = z * Linv; + + // --- near neutral case + if (Linv < 1e-5) + return; + + for (int i = 0; i < maxiters; i++) + { + get_psi(psi_m, psi_h, zeta, alpha_m, alpha_h, + a_m, a_h, + b_m, b_h, + c_h); + + get_psi_mh(psi0_m, psi0_h, z0_m * Linv, z0_t * Linv, + alpha_m, alpha_h, + a_m, a_h, + b_m, b_h, + c_h); + + Udyn = kappa * U / (log(z / z0_m) - (psi_m - psi0_m)); + Tdyn = kappa * dT * Pr_t_0_inv / (log(z / z0_t) - (psi_h - psi0_h)); + Qdyn = kappa * dQ * Pr_t_0_inv / (log(z / z0_t) - (psi_h - psi0_h)); + + if (Udyn < 1e-5) break; + + Linv = kappa * beta * (Tdyn + gamma * Qdyn * Tsemi) / (Udyn * Udyn); + zeta = z * Linv; + } +} + +template void get_dynamic_scales(float &Udyn, float &Tdyn, float &Qdyn, float & zeta, + const float U, const float Tsemi, const float dT, const float dQ, const float z, const float z0_m, const float z0_t, const float beta, + const float kappa, const float Pr_t_0_inv, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h, + const int maxiters); +template void get_dynamic_scales(double &Udyn, double &Tdyn, double &Qdyn, double & zeta, + const double U, const double Tsemi, const double dT, const double dQ, const double z, const double z0_m, const double z0_t, const double beta, + const double kappa, const double Pr_t_0_inv, + const double alpha_m, const double alpha_h, + const double a_m, const double a_h, + const double b_m, const double b_h, + const double c_h, + const int maxiters); + +template<typename T> +void get_phi(T &phi_m, T &phi_h, + const T zeta, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h) +{ + if (zeta >= 0.0) + { + phi_m = 1.0 + (a_m * zeta * pow(1.0 + zeta, 1.0 / 3.0) ) / (1.0 + b_m * zeta); + phi_h = 1.0 + (a_h * zeta + b_h * zeta * zeta) / (1.0 + c_h * zeta + zeta * zeta); + } + else + { + phi_m = pow(1.0 - alpha_m * zeta, -0.25); + phi_h = pow(1.0 - alpha_h * zeta, -0.5); + } +} + +template void get_phi(float &phi_m, float &phi_h, + const float zeta, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h); +template void get_phi(double &phi_m, double &phi_h, + const double zeta, + const double alpha_m, const double alpha_h, + const double a_m, const double a_h, + const double b_m, const double b_h, + const double c_h); template<typename T> void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_, - const T kappa, const T Pr_t_0_inv, const T Pr_t_inf_inv, - const T alpha_m, const T alpha_h, const T alpha_h_fix, - const T beta_m, const T beta_h, const T Rib_max, const T Re_rough_min, + const T kappa, const T Pr_t_0_inv, + const T alpha_m, const T alpha_h, + const T a_m, const T a_h, + const T b_m, const T b_h, + const T c_h, + const T Re_rough_min, const T B1_rough, const T B2_rough, const T B_max_land, const T B_max_ocean, const T B_max_lake, const T gamma_c, const T Re_visc_min, const T Pr_m, const T nu_air, const T g, - const int maxiters_charnock, const int maxiters_convection, + const int maxiters_charnock, const int grid_size) { T h, U, dT, Tsemi, dQ, z0_m; @@ -20,6 +223,9 @@ void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_ zeta, Rib, Udyn, Tdyn, Qdyn, phi_m, phi_h, Km, Pr_t_inv, Cm, Ct; + const T B3_rough = kappa * Pr_m, B4_rough =(0.14 * (pow(30.0, B2_rough))) * (pow(Pr_m, 0.8)); + const T h_charnock = 10.0, c1_charnock = log(h_charnock * (g / gamma_c)), c2_charnock = Re_visc_min * nu_air * c1_charnock; + int surface_type; for (int step = 0; step < grid_size; step++) @@ -34,19 +240,19 @@ void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_ if (z0_m < 0.0) surface_type = 0; else surface_type = 1; - if (surface_type == surface_ocean) + if (surface_type == 0) { - get_charnock_roughness(z0_m, u_dyn0, U, h, numerics%maxiters_charnock); + get_charnock_roughness(z0_m, u_dyn0, h, U, kappa, h_charnock, c1_charnock, c2_charnock, maxiters_charnock); h0_m = h / z0_m; } - if (surface_type == surface_land) + if (surface_type == 1) { h0_m = h / z0_m; u_dyn0 = U * kappa / log(h0_m); } Re = u_dyn0 * z0_m / nu_air; - get_thermal_roughness(z0_t, B, z0_m, Re, surface_type); + get_thermal_roughness(z0_t, B, z0_m, Re, Re_rough_min, B1_rough, B2_rough, B3_rough, B4_rough, B_max_ocean, B_max_lake, B_max_land, surface_type); // --- define relative height [thermal] h0_t = h / z0_t; @@ -56,10 +262,10 @@ void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_ // --- get the fluxes // ---------------------------------------------------------------------------- - get_dynamic_scales(Udyn, Tdyn, Qdyn, zeta, U, Tsemi, dT, dQ, h, z0_m, z0_t, (g / Tsemi), 10); + get_dynamic_scales(Udyn, Tdyn, Qdyn, zeta, U, Tsemi, dT, dQ, h, z0_m, z0_t, (g / Tsemi), kappa, Pr_t_0_inv, alpha_m, alpha_h, a_m, a_h, b_m, b_h, c_h, 10); // ---------------------------------------------------------------------------- - get_phi(phi_m, phi_h, zeta); + get_phi(phi_m, phi_h, zeta, alpha_m, alpha_h, a_m, a_h, b_m, b_h, c_h); // ---------------------------------------------------------------------------- // --- define transfer coeff. (momentum) & (heat) @@ -80,7 +286,7 @@ void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_ B_[step] = B; z0_m_[step] = z0_m; z0_t_[step] = z0_t; - Rib_conv_lim_[step] = Rib_conv_lim; + Rib_conv_lim_[step] = 0.0; Cm_[step] = Cm; Ct_[step] = Ct; Km_[step] = Km; @@ -90,23 +296,29 @@ void compute_flux_sheba_cpu(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_ template void compute_flux_sheba_cpu(float *zeta_, float *Rib_, float *Re_, float *B_, float *z0_m_, float *z0_t_, float *Rib_conv_lim_, float *Cm_, float *Ct_, float *Km_, float *Pr_t_inv_, const float *U, const float *dt, const float *T_semi, const float *dq, const float *H, const float *in_z0_m, - const float kappa, const float Pr_t_0_inv, const float Pr_t_inf_inv, - const float alpha_m, const float alpha_h, const float alpha_h_fix, - const float beta_m, const float beta_h, const float Rib_max, const float Re_rough_min, + const float kappa, const float Pr_t_0_inv, + const float alpha_m, const float alpha_h, + const float a_m, const float a_h, + const float b_m, const float b_h, + const float c_h, + const float Re_rough_min, const float B1_rough, const float B2_rough, const float B_max_land, const float B_max_ocean, const float B_max_lake, const float gamma_c, const float Re_visc_min, const float Pr_m, const float nu_air, const float g, - const int maxiters_charnock, const int maxiters_convection, + const int maxiters_charnock, const int grid_size); template void compute_flux_sheba_cpu(double *zeta_, double *Rib_, double *Re_, double *B_, double *z0_m_, double *z0_t_, double *Rib_conv_lim_, double *Cm_, double *Ct_, double *Km_, double *Pr_t_inv_, const double *U, const double *dt, const double *T_semi, const double *dq, const double *H, const double *in_z0_m, - const double kappa, const double Pr_t_0_inv, const double Pr_t_inf_inv, - const double alpha_m, const double alpha_h, const double alpha_h_fix, - const double beta_m, const double beta_h, const double Rib_max, const double Re_rough_min, + const double kappa, const double Pr_t_0_inv, + const double alpha_m, const double alpha_h, + const double a_m, const double a_h, + const double b_m, const double b_h, + const double c_h, + const double Re_rough_min, const double B1_rough, const double B2_rough, const double B_max_land, const double B_max_ocean, const double B_max_lake, const double gamma_c, const double Re_visc_min, const double Pr_m, const double nu_air, const double g, - const int maxiters_charnock, const int maxiters_convection, + const int maxiters_charnock, const int grid_size); \ No newline at end of file diff --git a/srcCXX/sfx_esm.cpp b/srcCXX/sfx_esm.cpp index 5564c28..5d0a9de 100644 --- a/srcCXX/sfx_esm.cpp +++ b/srcCXX/sfx_esm.cpp @@ -183,7 +183,7 @@ void FluxEsm<T, memIn, memOut, RunMem>::set_data(T *zeta_, T *Rib_, T *Re_, T *B } template<typename T, MemType memIn, MemType memOut, MemType RunMem > -void FluxEsm<T, memIn, memOut, RunMem>::compute_FluxEsm(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, +void FluxEsm<T, memIn, memOut, RunMem>::compute_flux_esm(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_, const int maxiters_charnock, const int maxiters_convection) { diff --git a/srcCXX/sfx_sheba.cpp b/srcCXX/sfx_sheba.cpp index 5edfa73..66d9a81 100644 --- a/srcCXX/sfx_sheba.cpp +++ b/srcCXX/sfx_sheba.cpp @@ -12,10 +12,12 @@ template<typename T, MemType memIn, MemType memOut, MemType RunMem > FluxSheba<T, memIn, memOut, RunMem>::FluxSheba() { - kappa = 0, Pr_t_0_inv = 0, Pr_t_inf_inv = 0, - alpha_m = 0, alpha_h = 0, alpha_h_fix = 0, - beta_m = 0, beta_h = 0, - Rib_max = 0, Re_rough_min = 0, + kappa = 0, Pr_t_0_inv = 0, + alpha_m = 0, alpha_h = 0, + a_m = 0, a_h = 0, + b_m = 0, b_h = 0, + c_h = 0, + Re_rough_min = 0, B1_rough = 0, B2_rough = 0, B_max_land = 0, B_max_ocean = 0, B_max_lake = 0, gamma_c = 0, @@ -29,18 +31,23 @@ FluxSheba<T, memIn, memOut, RunMem>::FluxSheba() } template<typename T, MemType memIn, MemType memOut, MemType RunMem > -void FluxSheba<T, memIn, memOut, RunMem>::set_params(const int grid_size_, const T kappa_, const T Pr_t_0_inv_, const T Pr_t_inf_inv_, - const T alpha_m_, const T alpha_h_, const T alpha_h_fix_, - const T beta_m_, const T beta_h_, const T Rib_max_, const T Re_rough_min_, +void FluxSheba<T, memIn, memOut, RunMem>::set_params(const int grid_size_, const T kappa_, const T Pr_t_0_inv_, + const T alpha_m_, const T alpha_h_, + const float a_m_, const float a_h_, + const float b_m_, const float b_h_, + const float c_h_, + const T Re_rough_min_, const T B1_rough_, const T B2_rough_, const T B_max_land_, const T B_max_ocean_, const T B_max_lake_, const T gamma_c_, const T Re_visc_min_, const T Pr_m_, const T nu_air_, const T g_) { - kappa = kappa_, Pr_t_0_inv = Pr_t_0_inv_, Pr_t_inf_inv = Pr_t_inf_inv_, - alpha_m = alpha_m_, alpha_h = alpha_h_, alpha_h_fix = alpha_h_fix_, - beta_m = beta_m_, beta_h = beta_h_, - Rib_max = Rib_max_, Re_rough_min = Re_rough_min_, B_max_lake = B_max_lake_, + kappa = kappa_, Pr_t_0_inv = Pr_t_0_inv_, + alpha_m = alpha_m_, alpha_h = alpha_h_, + a_m = a_m_, a_h = a_h_, + b_m = b_m_, b_h = b_h_, + c_h = c_h_, + Re_rough_min = Re_rough_min_, B_max_lake = B_max_lake_, B1_rough = B1_rough_, B2_rough = B2_rough_, B_max_land = B_max_land_, B_max_ocean = B_max_ocean_, gamma_c = gamma_c_, @@ -99,10 +106,12 @@ void FluxSheba<T, memIn, memOut, RunMem>::set_params(const int grid_size_, const template<typename T, MemType memIn, MemType memOut, MemType RunMem > FluxSheba<T, memIn, memOut, RunMem>::~FluxSheba() { - kappa = 0, Pr_t_0_inv = 0, Pr_t_inf_inv = 0, - alpha_m = 0, alpha_h = 0, alpha_h_fix = 0, - beta_m = 0, beta_h = 0, - Rib_max = 0, Re_rough_min = 0, + kappa = 0, Pr_t_0_inv = 0, + alpha_m = 0, alpha_h = 0, + a_m = 0, a_h = 0, + b_m = 0, b_h = 0, + c_h = 0, + Re_rough_min = 0, B1_rough = 0, B2_rough = 0, B_max_land = 0, B_max_ocean = 0, B_max_lake = 0, gamma_c = 0, @@ -183,37 +192,43 @@ void FluxSheba<T, memIn, memOut, RunMem>::set_data(T *zeta_, T *Rib_, T *Re_, T } template<typename T, MemType memIn, MemType memOut, MemType RunMem > -void FluxSheba<T, memIn, memOut, RunMem>::compute_FluxSheba(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, +void FluxSheba<T, memIn, memOut, RunMem>::compute_flux_sheba(T *zeta_, T *Rib_, T *Re_, T *B_, T *z0_m_, T *z0_t_, T *Rib_conv_lim_, T *Cm_, T *Ct_, T *Km_, T *Pr_t_inv_, T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_, - const int maxiters_charnock, const int maxiters_convection) + const int maxiters_charnock) { set_data(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, U_, dT_, Tsemi_, dQ_, h_, in_z0_m_); - if(RunMem == MemType::CPU) compute_FluxSheba_cpu(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, Cm, Ct, Km, Pr_t_inv, + if(RunMem == MemType::CPU) compute_flux_sheba_cpu(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, Cm, Ct, Km, Pr_t_inv, U, dT, Tsemi, dQ, h, in_z0_m, - kappa, Pr_t_0_inv, Pr_t_inf_inv, - alpha_m, alpha_h, alpha_h_fix, - beta_m, beta_h, Rib_max, Re_rough_min, + kappa, Pr_t_0_inv, + alpha_m, alpha_h, + a_m, a_h, + b_m, b_h, + c_h, + Re_rough_min, B1_rough, B2_rough, B_max_land, B_max_ocean, B_max_lake, gamma_c, Re_visc_min, Pr_m, nu_air, g, - maxiters_charnock, maxiters_convection, + maxiters_charnock, grid_size); #ifdef INCLUDE_CUDA - else compute_FluxSheba_gpu(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, Cm, Ct, Km, Pr_t_inv, - U, dT, Tsemi, dQ, h, in_z0_m, - kappa, Pr_t_0_inv, Pr_t_inf_inv, - alpha_m, alpha_h, alpha_h_fix, - beta_m, beta_h, Rib_max, Re_rough_min, - B1_rough, B2_rough, - B_max_land, B_max_ocean, B_max_lake, - gamma_c, Re_visc_min, - Pr_m, nu_air, g, - maxiters_charnock, maxiters_convection, - grid_size); + // else compute_flux_sheba_gpu(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, Cm, Ct, Km, Pr_t_inv, + // U, dT, Tsemi, dQ, h, in_z0_m, + // kappa, Pr_t_0_inv, + // alpha_m, alpha_h, + // a_m, a_h, + // b_m, b_h, + // c_h, + // Re_rough_min, + // B1_rough, B2_rough, + // B_max_land, B_max_ocean, B_max_lake, + // gamma_c, Re_visc_min, + // Pr_m, nu_air, g, + // maxiters_charnock, + // grid_size); #endif if(RunMem != memOut) diff --git a/srcCXX/sfx_surface.cpp b/srcCXX/sfx_surface.cpp new file mode 100644 index 0000000..2bb012c --- /dev/null +++ b/srcCXX/sfx_surface.cpp @@ -0,0 +1,87 @@ +#include "../includeCXX/sfx_surface.h" +#include <cmath> +#include <iostream> + +template<typename T> +void get_charnock_roughness(T &z0_m, T &u_dyn0, + const T h, const T U, + const T kappa, + const T h_charnock, const T c1_charnock, const T c2_charnock, + const int maxiters) +{ + T Uc, a, b, c, c_min, f; + + Uc = U; + a = 0.0; + b = 25.0; + c_min = log(h_charnock) / kappa; + + for (int i = 0; i < maxiters; i++) + { + f = c1_charnock - 2.0 * log(Uc); + for (int j = 0; j < maxiters; j++) + { + c = (f + 2.0 * log(b)) / kappa; + if (U <= 8.0e0) + a = log(1.0 + c2_charnock * ( pow(b / Uc, 3) ) ) / kappa; + c = std::max(c - a, c_min); + b = c; + } + z0_m = h_charnock * exp(-c * kappa); + z0_m = std::max(z0_m, T(0.000015e0)); + Uc = U * log(h_charnock / z0_m) / log(h / z0_m); + } + + u_dyn0 = Uc / c; +} + +template void get_charnock_roughness(float &z0_m, float &u_dyn0, + const float h, const float U, + const float kappa, + const float h_charnock, const float c1_charnock, const float c2_charnock, + const int maxiters); +template void get_charnock_roughness(double &z0_m, double &u_dyn0, + const double h, const double U, + const double kappa, + const double h_charnock, const double c1_charnock, const double c2_charnock, + const int maxiters); + +template<typename T> +void get_thermal_roughness(T &z0_t, T &B, + const T z0_m, const T Re, + const T Re_rough_min, + const T B1_rough, const T B2_rough, const T B3_rough, const T B4_rough, + const T B_max_ocean, const T B_max_lake, const T B_max_land, + const int surface_type) +{ + // --- define B = log(z0_m / z0_t) + if (Re <= Re_rough_min) + B = B1_rough * log(B3_rough * Re) + B2_rough; + else + // *: B4 takes into account Re value at z' ~ O(10) z0 + B = B4_rough * (pow(Re, B2_rough)); + + // --- apply max restriction based on surface type + if (surface_type == 0) + B = std::min(B, B_max_ocean); + else if (surface_type == 1) + B = std::min(B, B_max_lake); + else if (surface_type == 2) + B = std::min(B, B_max_land); + + // --- define roughness [thermal] + z0_t = z0_m / exp(B); +} + +template void get_thermal_roughness(float &z0_t, float &B, + const float z0_m, const float Re, + const float Re_rough_min, + const float B1_rough, const float B2_rough, const float B3_rough, const float B4_rough, + const float B_max_ocean, const float B_max_lake, const float B_max_land, + const int surface_type); +template void get_thermal_roughness(double &z0_t, double &B, + const double z0_m, const double Re, + const double Re_rough_min, + const double B1_rough, const double B2_rough, const double B3_rough, const double B4_rough, + const double B_max_ocean, const double B_max_lake, const double B_max_land, + const int surface_type); \ No newline at end of file diff --git a/srcF/sfx_esm.f90 b/srcF/sfx_esm.f90 index 4b37e91..5c540cc 100644 --- a/srcF/sfx_esm.f90 +++ b/srcF/sfx_esm.f90 @@ -55,7 +55,7 @@ contains integer i ! ---------------------------------------------------------------------------- #if defined(INCLUDE_CUDA) || defined(INCLUDE_CXX) - call get_surface_fluxes(sfx%zeta, sfx%Rib, sfx%Re, sfx%B, sfx%z0_m, sfx%z0_t, & + call get_surface_fluxes_esm(sfx%zeta, sfx%Rib, sfx%Re, sfx%B, sfx%z0_m, sfx%z0_t, & sfx%Rib_conv_lim, sfx%Cm, sfx%Ct, sfx%Km, sfx%Pr_t_inv, & meteo%U, meteo%dT, meteo%Tsemi, meteo%dQ, meteo%h, meteo%z0_m, & kappa, Pr_t_0_inv, Pr_t_inf_inv, & @@ -86,7 +86,6 @@ contains end subroutine get_surface_fluxes_vec ! -------------------------------------------------------------------------------- -#if !defined(INCLUDE_CUDA) && !defined(INCLUDE_CXX) ! -------------------------------------------------------------------------------- subroutine get_surface_fluxes(sfx, meteo, numerics) !< @brief surface flux calculation for single cell @@ -261,7 +260,7 @@ contains end subroutine get_surface_fluxes ! -------------------------------------------------------------------------------- -#endif + ! convection universal functions shortcuts ! -------------------------------------------------------------------------------- function f_m_conv(zeta) diff --git a/srcF/sfx_fc_wrapper.F90 b/srcF/sfx_fc_wrapper.F90 index 4e23a17..8a9bea8 100644 --- a/srcF/sfx_fc_wrapper.F90 +++ b/srcF/sfx_fc_wrapper.F90 @@ -1,7 +1,7 @@ module C_FUNC INTERFACE #if defined(INCLUDE_CUDA) || defined(INCLUDE_CXX) - SUBROUTINE get_surface_fluxes(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, & + SUBROUTINE get_surface_fluxes_esm(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, & Cm, Ct, Km, Prt_inv, & U, dT, Tsemi, dQ, h, in_z0_m, & kappa, Pr_t_0_inv, Pr_t_inf_inv, & @@ -22,7 +22,33 @@ module C_FUNC B_max_lake, gamma_c, Re_visc_min, Pr_m, nu_air, g REAL(C_FLOAT), dimension(grid_size) :: U, dT, Tsemi, dQ, h, in_z0_m, zeta, Rib, Re, & Rib_conv_lim, z0_m, z0_t, B, Cm, Ct, Km, Prt_inv - END SUBROUTINE get_surface_fluxes + END SUBROUTINE get_surface_fluxes_esm + + SUBROUTINE get_surface_fluxes_sheba(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, & + Cm, Ct, Km, Prt_inv, & + U, dT, Tsemi, dQ, h, in_z0_m, & + kappa, Pr_t_0_inv, & + alpha_m, alpha_h, & + a_m, a_h, & + b_m, b_h, & + c_h, & + Re_rough_min, & + B1_rough, B2_rough, & + B_max_land, B_max_ocean, B_max_lake, & + gamma_c, Re_visc_min, & + Pr_m, nu_air, g, & + maxiters_charnock, & + grid_size) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT + USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT + IMPLICIT NONE + INTEGER(C_INT) :: grid_size, maxiters_charnock + REAL(C_FLOAT) :: kappa, Pr_t_0_inv, Pr_t_inf_inv, alpha_m, alpha_h, a_m, a_h, b_m, b_h, & + c_h, Rib_max, Re_rough_min, B1_rough, B2_rough, B_max_land, B_max_ocean, & + B_max_lake, gamma_c, Re_visc_min, Pr_m, nu_air, g + REAL(C_FLOAT), dimension(grid_size) :: U, dT, Tsemi, dQ, h, in_z0_m, zeta, Rib, Re, & + Rib_conv_lim, z0_m, z0_t, B, Cm, Ct, Km, Prt_inv + END SUBROUTINE get_surface_fluxes_sheba #endif END INTERFACE end module C_FUNC -- GitLab