Skip to content
Snippets Groups Projects
Commit 366fcac3 authored by Evgeny Mortikov's avatar Evgeny Mortikov
Browse files

Merge branch 'Merge2Main' into 'main'

to merge

See merge request inmcm60_pbl/inmcm60_sfx!9
parents b09e08c1 4873d1bb
No related branches found
No related tags found
No related merge requests found
cmake_minimum_required(VERSION 3.0)
option(INCLUDE_CUDA "GPU build in mode" OFF)
option(INCLUDE_CXX "CXX build in mode" OFF)
project(INMCM_sfx)
enable_language(Fortran)
if(INCLUDE_CXX OR INCLUDE_CUDA)
set(MEMPROC_GIT http://tesla.parallel.ru/Lizzzka007/memory_processing.git)
include(FetchContent)
FetchContent_Declare(memory_processing
GIT_REPOSITORY ${MEMPROC_GIT}
GIT_TAG origin/main
)
FetchContent_MakeAvailable(memory_processing)
add_library(memory_processing INTERFACE)
target_compile_definitions(memory_processing INTERFACE INCLUDE_CUDA=${INCLUDE_CUDA})
endif(INCLUDE_CXX OR INCLUDE_CUDA)
if(INCLUDE_CXX)
set(RUN_MACRO -DINCLUDE_CXX)
endif(INCLUDE_CXX)
if(INCLUDE_CUDA)
enable_language(CUDA)
find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
set(RUN_MACRO -DINCLUDE_CUDA)
set(INCLUDE_CXX ON)
endif(INCLUDE_CUDA)
if(INCLUDE_CXX)
enable_language(C)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 11)
endif(INCLUDE_CXX)
set(SOURCES_F
srcF/sfx_data.f90
srcF/sfx_common.f90
srcF/sfx_def.fi
srcF/sfx_esm.f90
srcF/sfx_esm_param.f90
srcF/sfx_log.f90
srcF/sfx_log_param.f90
srcF/sfx_main.f90
srcF/sfx_phys_const.f90
srcF/sfx_surface.f90
srcF/FCWrapper.F90
)
if(INCLUDE_CXX)
set(SOURCES_C
srcC/SubFunctionsWrapper.c
)
set(SOURCES_CXX
srcCXX/Flux.cpp
srcCXX/FluxComputeFunc.cpp
srcCXX/SubFunctions.cpp
)
set(HEADERS_CXX
includeCXX/Flux.h
includeCXX/FluxComputeFunc.h
includeCXX/SubFunctions.h
)
endif(INCLUDE_CXX)
if(INCLUDE_CUDA)
set(SOURCES_CU
srcCU/Flux.cu
srcCU/FluxComputeFunc.cu
)
set(HEADERS_CU
includeCU/Flux.cuh
includeCXX/FluxComputeFunc.cuh
)
endif(INCLUDE_CUDA)
set(SOURCES ${HEADERS_CU} ${SOURCES_CU} ${HEADERS_CXX} ${SOURCES_CXX} ${SOURCES_C} ${SOURCES_F})
set(CMAKE_Fortran_FLAGS " -g -fbacktrace -ffpe-trap=zero,overflow,underflow -cpp ")
set(CMAKE_CXX_FLAGS " -g ")
set(CMAKE_C_FLAGS " -g ")
add_executable(drag ${SOURCES})
add_definitions(${RUN_MACRO})
set_property(TARGET drag PROPERTY LINKER_LANGUAGE Fortran)
if(INCLUDE_CXX OR INCLUDE_CUDA)
target_include_directories(drag PUBLIC ${memory_processing_SOURCE_DIR}/include)
target_link_libraries(drag memproc)
endif(INCLUDE_CXX OR INCLUDE_CUDA)
\ No newline at end of file
#pragma once
template<typename T>
void compute_flux_gpu(const T *ws, const T *dt, const T *st, const T *dq, const T *cflh, const T *z0,
T *zl, T *ri, T *re, T *lnzuzt, T *zu, T *zt, T *rith, T *cm, T *ch, T *ct, T *ckt,
const T g, const T Pr_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 b4, const T alfam, const T betam,
const T an, const T h1, const T x8, const T an1, const T an2, const T g0,
const T r0,
const int it, const int lu_indx,
const int grid_size);
\ No newline at end of file
#pragma once
#include "TemplateParameters.h"
#include <cstddef>
template<typename T, MemType RunMem, MemType memIn>
class Flux
{
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;
int grid_size;
bool ifAllocated;
size_t allocated_size;
public:
Flux();
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,
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);
void set_data( T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_,
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_);
~Flux();
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_,
const int maxiters_charnock, const int maxiters_convection);
};
template<typename T, MemType RunMem, MemType memIn>
class Compute_Flux
{
static Flux<T, RunMem,memIn> F;
};
\ No newline at end of file
#pragma once
template<typename T>
void compute_flux_cpu(const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_,
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 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 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 grid_size);
\ No newline at end of file
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void surf_flux_CXX (float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_,
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 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 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 grid_size);
#ifdef __cplusplus
}
#endif
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include "../includeCXX/SubFunctions.h"
// -------------------------------------------------------------------------- //
void surf_flux (float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_,
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 *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 *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 *grid_size)
{
surf_flux_CXX ( U_, dT_, Tsemi_, dQ_, h_, in_z0_m_,
zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_,
*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);
}
\ No newline at end of file
#include <iostream>
#include "../includeCXX/Flux.h"
#include "../includeCXX/FluxComputeFunc.h"
#ifdef INCLUDE_CUDA
#include "../includeCU/Flux.cuh"
#endif
#include "MemoryProcessing.h"
template<typename T, MemType RunMem, MemType memIn>
Flux<T, RunMem, memIn>::Flux()
{
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,
B1_rough = 0, B2_rough = 0,
B_max_land = 0, B_max_ocean = 0, B_max_lake = 0,
gamma_c = 0,
Re_visc_min = 0,
Pr_m = 0, nu_air = 0, g = 0;
grid_size = 0;
ifAllocated = false;
allocated_size = 0;
}
template<typename T, MemType RunMem, MemType memIn>
void Flux<T, RunMem, memIn>::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_,
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_,
B1_rough = B1_rough_, B2_rough = B2_rough_,
B_max_land = B_max_land_, B_max_ocean = B_max_ocean_,
gamma_c = gamma_c_,
Re_visc_min = Re_visc_min_,
Pr_m = Pr_m_, nu_air = nu_air_, g = g_;
grid_size = grid_size_;
if(RunMem != memIn)
{
const size_t new_size = grid_size * sizeof(T);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(U), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(dT), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Tsemi), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(dQ), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(h), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(in_z0_m), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(zeta), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Rib), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Re), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Rib_conv_lim), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(z0_m), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(z0_t), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(B), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Cm), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Ct), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Km), allocated_size, new_size);
allocated_size = 0;
memproc::realloc<RunMem>((void *&)(Pr_t_inv), allocated_size, new_size);
ifAllocated = true;
}
}
template<typename T, MemType RunMem, MemType memIn>
Flux<T, RunMem, memIn>::~Flux()
{
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,
B1_rough = 0, B2_rough = 0,
B_max_land = 0, B_max_ocean = 0, B_max_lake = 0,
gamma_c = 0,
Re_visc_min = 0,
Pr_m = 0, nu_air = 0, g = 0;
grid_size = 0;
if(ifAllocated == true)
{
memproc::dealloc<RunMem>((void*&)U);
memproc::dealloc<RunMem>((void*&)dT);
memproc::dealloc<RunMem>((void*&)Tsemi);
memproc::dealloc<RunMem>((void*&)dQ);
memproc::dealloc<RunMem>((void*&)h);
memproc::dealloc<RunMem>((void*&)zeta);
memproc::dealloc<RunMem>((void*&)Rib);
memproc::dealloc<RunMem>((void*&)Re);
memproc::dealloc<RunMem>((void*&)Rib_conv_lim);
memproc::dealloc<RunMem>((void*&)z0_m);
memproc::dealloc<RunMem>((void*&)z0_t);
memproc::dealloc<RunMem>((void*&)B);
memproc::dealloc<RunMem>((void*&)Cm);
memproc::dealloc<RunMem>((void*&)Ct);
memproc::dealloc<RunMem>((void*&)Km);
memproc::dealloc<RunMem>((void*&)Pr_t_inv);
ifAllocated = false;
allocated_size = 0;
}
}
template<typename T, MemType RunMem, MemType memIn>
void Flux<T, RunMem, memIn>::set_data(T *U_, T *dT_, T *Tsemi_, T *dQ_, T *h_, T *in_z0_m_,
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_)
{
if(RunMem == memIn)
{
U = U_;
dT = dT_;
Tsemi = Tsemi_;
dQ = dQ_;
h = h_;
in_z0_m = in_z0_m_;
zeta = zeta_;
Rib = Rib_;
Re = Re_;
Rib_conv_lim = Rib_conv_lim_;
z0_m = z0_m_;
z0_t = z0_t_;
B = B_;
Cm = Cm_;
Ct = Ct_;
Km = Km_;
Pr_t_inv = Pr_t_inv_;
}
else
{
const size_t new_size = grid_size * sizeof(T);
memproc::memcopy<RunMem, memIn>(U, U_, new_size);
memproc::memcopy<RunMem, memIn>(dT, dT_, new_size);
memproc::memcopy<RunMem, memIn>(Tsemi, Tsemi_, new_size);
memproc::memcopy<RunMem, memIn>(dQ, dQ_, new_size);
memproc::memcopy<RunMem, memIn>(h, h_, new_size);
memproc::memcopy<RunMem, memIn>(in_z0_m, in_z0_m_, new_size);
}
}
template<typename T, MemType RunMem, MemType memIn>
void Flux<T, RunMem, memIn>::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_,
const int maxiters_charnock, const int maxiters_convection)
{
if(RunMem == MemType::CPU) compute_flux_cpu(U, dT, Tsemi, dQ, h, in_z0_m,
zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, Cm, Ct, Km, Pr_t_inv,
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);
#ifdef INCLUDE_CUDA
else compute_flux_gpu(U, dT, Tsemi, dQ, h, zeta,
zl, Rib, Re, Rib_conv_lim, z0_m, z0_t, B, Cm, Ct, Km, Pr_t_inv,
g, Pr_m, kappa, Pr_t_0_inv, Pr_t_inf_inv,
alpha_m, alpha_h, b4, alfam, betam,
an, h1, x8, an1, an2, g0,
r0,
it, lu_indx,
grid_size);
#endif
if(RunMem != memIn)
{
const size_t new_size = grid_size * sizeof(T);
memproc::memcopy<memIn, RunMem>(zeta_, zeta, new_size);
memproc::memcopy<memIn, RunMem>(Rib_, Rib, new_size);
memproc::memcopy<memIn, RunMem>(Re_, Re, new_size);
memproc::memcopy<memIn, RunMem>(Rib_conv_lim_, Rib_conv_lim, new_size);
memproc::memcopy<memIn, RunMem>(z0_m_, z0_m, new_size);
memproc::memcopy<memIn, RunMem>(z0_t_, z0_t, new_size);
memproc::memcopy<memIn, RunMem>(B_, B, new_size);
memproc::memcopy<memIn, RunMem>(Cm_, Cm, new_size);
memproc::memcopy<memIn, RunMem>(Ct_, Ct, new_size);
memproc::memcopy<memIn, RunMem>(Km_, Km, new_size);
memproc::memcopy<memIn, RunMem>(Pr_t_inv_, Pr_t_inv, new_size);
}
}
template class Flux<float, MemType::CPU, MemType::CPU>;
template class Flux<double, MemType::CPU, MemType::CPU>;
#ifdef INCLUDE_CUDA
template class Flux<float, MemType::GPU, MemType::GPU>;
template class Flux<float, MemType::GPU, MemType::CPU>;
template class Flux<float, MemType::CPU, MemType::GPU>;
template class Flux<double, MemType::GPU, MemType::GPU>;
template class Flux<double, MemType::GPU, MemType::CPU>;
template class Flux<double, MemType::CPU, MemType::GPU>;
#endif
template class Compute_Flux<float, MemType::CPU, MemType::CPU>;
template class Compute_Flux<double, MemType::CPU, MemType::CPU>;
#ifdef INCLUDE_CUDA
template class Compute_Flux<float, MemType::GPU, MemType::GPU>;
template class Compute_Flux<float, MemType::GPU, MemType::CPU>;
template class Compute_Flux<float, MemType::CPU, MemType::GPU>;
template class Compute_Flux<double, MemType::GPU, MemType::GPU>;
template class Compute_Flux<double, MemType::GPU, MemType::CPU>;
template class Compute_Flux<double, MemType::CPU, MemType::GPU>;
#endif
\ No newline at end of file
#include <cmath>
#include <iostream>
#include "../includeCXX/FluxComputeFunc.h"
template<typename T>
void get_charnock_roughness(const T h, const T U,
const T kappa,
const T h_charnock, const T c1_charnock, const T c2_charnock,
T &z0_m, T &u_dyn0,
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);
printf("%f and 0.000015e0\n", z0_m);
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(const float h, const float U,
const float kappa,
const float h_charnock, const float c1_charnock, const float c2_charnock,
float &z0_m, float &u_dyn0,
const int maxiters);
template void get_charnock_roughness(const double h, const double U,
const double kappa,
const double h_charnock, const double c1_charnock, const double c2_charnock,
double &z0_m, double &u_dyn0,
const int maxiters);
template<typename T>
void get_convection_lim(const T h0_m, const T h0_t, const T B,
const T Pr_t_inf_inv, const T Pr_t_0_inv,
const T alpha_h, const T alpha_m, const T alpha_h_fix,
T &zeta_lim, T &Rib_lim, T &f_m_lim, T &f_h_lim)
{
T psi_m, psi_h, f_m, f_h, c;
c = pow(Pr_t_inf_inv / Pr_t_0_inv, 4);
zeta_lim = (2.0 * alpha_h - c * alpha_m - sqrt( (c * alpha_m)*(c * alpha_m) + 4.0 * c * alpha_h * (alpha_h - alpha_m))) / (2.0 * alpha_h*alpha_h);
f_m_lim = pow(1.0 - alpha_m * zeta_lim, 0.25);
f_h_lim = sqrt(1.0 - alpha_h * zeta_lim);
f_m = zeta_lim / h0_m;
f_h = zeta_lim / h0_t;
if (fabs(B) < 1.0e-10) f_h = f_m;
f_m = pow(1.0 - alpha_m * f_m, 0.25);
f_h = sqrt(1.0 - alpha_h_fix * f_h);
psi_m = 2.0 * (atan(f_m_lim) - atan(f_m)) + log((f_m_lim - 1.0) * (f_m + 1.0)/((f_m_lim + 1.0) * (f_m - 1.0)));
psi_h = log((f_h_lim - 1.0) * (f_h + 1.0)/((f_h_lim + 1.0) * (f_h - 1.0))) / Pr_t_0_inv;
Rib_lim = zeta_lim * psi_h / (psi_m * psi_m);
}
template void get_convection_lim(const float h0_m, const float h0_t, const float B,
const float Pr_t_inf_inv, const float Pr_t_0_inv,
const float alpha_h, const float alpha_m, const float alpha_h_fix,
float &zeta_lim, float &Rib_lim, float &f_m_lim, float &f_h_lim);
template void get_convection_lim(const double h0_m, const double h0_t, const double B,
const double Pr_t_inf_inv, const double Pr_t_0_inv,
const double alpha_h, const double alpha_m, const double alpha_h_fix,
double &zeta_lim, double &Rib_lim, double &f_m_lim, double &f_h_lim);
template<typename T>
void get_psi_stable(const T Rib, const T h0_m, const T h0_t, const T B,
const T Pr_t_0_inv, const T beta_m,
T &psi_m, T &psi_h, T &zeta)
{
T Rib_coeff, psi0_m, psi0_h, phi, c;
psi0_m = log(h0_m);
psi0_h = B / psi0_m;
Rib_coeff = beta_m * Rib;
c = (psi0_h + 1.0) / Pr_t_0_inv - 2.0 * Rib_coeff;
zeta = psi0_m * (sqrt(c*c + 4.0 * Rib_coeff * (1.0 - Rib_coeff)) - c) / (2.0 * beta_m * (1.0 - Rib_coeff));
phi = beta_m * zeta;
psi_m = psi0_m + phi;
psi_h = (psi0_m + B) / Pr_t_0_inv + phi;
}
template void get_psi_stable(const float Rib, const float h0_m, const float h0_t, const float B,
const float Pr_t_0_inv, const float beta_m,
float &psi_m, float &psi_h, float &zeta);
template void get_psi_stable(const double Rib, const double h0_m, const double h0_t, const double B,
const double Pr_t_0_inv, const double beta_m,
double &psi_m, double &psi_h, double &zeta);
template<typename T>
void get_psi_convection(const T Rib, const T h0_m, const T h0_t, const T B,
const T zeta_conv_lim, const T f_m_conv_lim, const T f_h_conv_lim,
const T Pr_t_0_inv,
const T alpha_h, const T alpha_m, const T alpha_h_fix,
T &psi_m, T &psi_h, T &zeta,
const int maxiters)
{
T zeta0_m, zeta0_h, f0_m, f0_h, p_m, p_h, a_m, a_h, c_lim, f;
p_m = 2.0 * atan(f_m_conv_lim) + log((f_m_conv_lim - 1.0) / (f_m_conv_lim + 1.0));
p_h = log((f_h_conv_lim - 1.0) / (f_h_conv_lim + 1.0));
zeta = zeta_conv_lim;
for (int i = 1; i <= maxiters + 1; i++)
{
zeta0_m = zeta / h0_m;
zeta0_h = zeta / h0_t;
if (fabs(B) < 1.0e-10)
zeta0_h = zeta0_m;
f0_m = pow(1.0 - alpha_m * zeta0_m, 0.25);
f0_h = sqrt(1.0 - alpha_h_fix * zeta0_h);
a_m = -2.0*atan(f0_m) + log((f0_m + 1.0)/(f0_m - 1.0));
a_h = log((f0_h + 1.0)/(f0_h - 1.0));
c_lim = pow(zeta_conv_lim / zeta, 1.0 / 3.0);
f = 3.0 * (1.0 - c_lim);
psi_m = f / f_m_conv_lim + p_m + a_m;
psi_h = (f / f_h_conv_lim + p_h + a_h) / Pr_t_0_inv;
if (i == maxiters + 1)
break;
zeta = Rib * psi_m * psi_m / psi_h;
}
}
template void get_psi_convection(const float Rib, const float h0_m, const float h0_t, const float B,
const float zeta_conv_lim, const float f_m_conv_lim, const float f_h_conv_lim,
const float Pr_t_0_inv,
const float alpha_h, const float alpha_m, const float alpha_h_fix,
float &psi_m, float &psi_h, float &zeta,
const int maxiters);
template void get_psi_convection(const double Rib, const double h0_m, const double h0_t, const double B,
const double zeta_conv_lim, const double f_m_conv_lim, const double f_h_conv_lim,
const double Pr_t_0_inv,
const double alpha_h, const double alpha_m, const double alpha_h_fix,
double &psi_m, double &psi_h, double &zeta,
const int maxiters);
template<typename T>
void get_psi_neutral(const T h0_m, const T h0_t, const T B,
const T Pr_t_0_inv,
T &psi_m, T &psi_h, T &zeta)
{
zeta = 0.0;
psi_m = log(h0_m);
psi_h = log(h0_t) / Pr_t_0_inv;
if (fabs(B) < 1.0e-10)
psi_h = psi_m / Pr_t_0_inv;
}
template void get_psi_neutral(const float h0_m, const float h0_t, const float B,
const float Pr_t_0_inv,
float &psi_m, float &psi_h, float &zeta);
template void get_psi_neutral(const double h0_m, const double h0_t, const double B,
const double Pr_t_0_inv,
double &psi_m, double &psi_h, double &zeta);
template<typename T>
void get_psi_semi_convection(const T Rib, const T h0_m, const T h0_t, const T B,
const T Pr_t_0_inv,
const T alpha_m, const T alpha_h_fix,
T &psi_m, T &psi_h, T &zeta,
const int maxiters)
{
T zeta0_m, zeta0_h, f0_m, f0_h, f_m, f_h;
psi_m = log(h0_m);
psi_h = log(h0_t);
if (fabs(B) < 1.0e-10)
psi_h = psi_m;
zeta = Rib * Pr_t_0_inv * psi_m * psi_m / psi_h;
for (int i = 1; i <= maxiters + 1; i++)
{
zeta0_m = zeta / h0_m;
zeta0_h = zeta / h0_t;
if (fabs(B) < 1.0e-10)
zeta0_h = zeta0_m;
f_m = pow(1.0 - alpha_m * zeta, 0.25e0);
f_h = sqrt(1.0 - alpha_h_fix * zeta);
f0_m = pow(1.0 - alpha_m * zeta0_m, 0.25e0);
f0_h = sqrt(1.0 - alpha_h_fix * zeta0_h);
f0_m = std::max(f0_m, T(1.000001e0));
f0_h = std::max(f0_h, T(1.000001e0));
psi_m = log((f_m - 1.0e0)*(f0_m + 1.0e0)/((f_m + 1.0e0)*(f0_m - 1.0e0))) + 2.0e0*(atan(f_m) - atan(f0_m));
psi_h = log((f_h - 1.0e0)*(f0_h + 1.0e0)/((f_h + 1.0e0)*(f0_h - 1.0e0))) / Pr_t_0_inv;
if (i == maxiters + 1)
break;
zeta = Rib * psi_m * psi_m / psi_h;
}
}
template void get_psi_semi_convection(const float Rib, const float h0_m, const float h0_t, const float B,
const float Pr_t_0_inv,
const float alpha_m, const float alpha_h_fix,
float &psi_m, float &psi_h, float &zeta,
const int maxiters);
template void get_psi_semi_convection(const double Rib, const double h0_m, const double h0_t, const double B,
const double Pr_t_0_inv,
const double alpha_m, const double alpha_h_fix,
double &psi_m, double &psi_h, double &zeta,
const int maxiters);
template<typename T>
void compute_flux_cpu(const T *U_, const T *dT_, const T *Tsemi_, const T *dQ_, const T *h_, const T *in_z0_m_,
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 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 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 grid_size)
{
T h, U, dT, Tsemi, dQ, z0_m;
T Re, z0_t, B, h0_m, h0_t, u_dyn0, zeta, Rib, zeta_conv_lim, Rib_conv_lim, f_m_conv_lim, f_h_conv_lim, psi_m, psi_h, phi_m, phi_h, Km, Pr_t_inv, Cm, Ct;
int surface_type;
T fval;
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;
for (int step = 0; step < grid_size; step++)
{
U = U_[step];
Tsemi = Tsemi_[step];
dT = dT_[step];
dQ = dQ_[step];
h = h_[step];
z0_m = in_z0_m_[step];
if (z0_m < 0.0) surface_type = 0;
else surface_type = 1;
if (surface_type == 0)
{
get_charnock_roughness(h, U, kappa, h_charnock, c1_charnock, c2_charnock, z0_m, u_dyn0, maxiters_charnock);
h0_m = h / z0_m;
}
if (surface_type == 1)
{
h0_m = h / z0_m;
u_dyn0 = U * kappa / log(h0_m);
}
Re = u_dyn0 * z0_m / nu_air;
if(Re <= Re_rough_min) B = B1_rough * log(B3_rough * Re) + B2_rough;
else B = B4_rough * (pow(Re, B2_rough));
if (surface_type == 0) B = std::min(B, B_max_ocean);
if (surface_type == 1) B = std::min(B, B_max_land);
if (surface_type == 2) B = std::min(B, B_max_lake);
z0_t = z0_m / exp(B);
h0_t = h / z0_t;
Rib = (g / Tsemi) * h * (dT + 0.61e0 * Tsemi * dQ) / (U*U);
get_convection_lim(h0_m, h0_t, B, Pr_t_inf_inv, Pr_t_0_inv, alpha_h, alpha_m, alpha_h_fix, zeta_conv_lim, Rib_conv_lim, f_m_conv_lim, f_h_conv_lim);
if (Rib > 0.0)
{
Rib = std::min(Rib, Rib_max);
get_psi_stable(Rib, h0_m, h0_t, B, Pr_t_0_inv, beta_m, psi_m, psi_h, zeta);
if(step == 353)
printf("get_psi_stable zeta = %f\n", zeta);
fval = beta_m * zeta;
phi_m = 1.0 + fval;
phi_h = 1.0/Pr_t_0_inv + fval;
}
else if (Rib < Rib_conv_lim)
{
get_psi_convection(Rib, h0_m, h0_t, B, zeta_conv_lim, f_m_conv_lim, f_h_conv_lim, Pr_t_0_inv, alpha_h, alpha_m, alpha_h_fix, psi_m, psi_h, zeta, maxiters_convection);
fval = pow(zeta_conv_lim / zeta, 1.0/3.0);
phi_m = fval / f_m_conv_lim;
phi_h = fval / (Pr_t_0_inv * f_h_conv_lim);
}
else if (Rib > -0.001)
{
get_psi_neutral(h0_m, h0_t, B, Pr_t_0_inv, psi_m, psi_h, zeta);
phi_m = 1.0;
phi_h = 1.0 / Pr_t_0_inv;
}
else
{
get_psi_semi_convection(Rib, h0_m, h0_t, B, Pr_t_0_inv, alpha_m, alpha_h_fix, psi_m, psi_h, zeta, maxiters_convection);
phi_m = pow(1.0 - alpha_m * zeta, -0.25);
phi_h = 1.0 / (Pr_t_0_inv * sqrt(1.0 - alpha_h_fix * zeta));
}
Cm = kappa / psi_m;
Ct = kappa / psi_h;
Km = kappa * Cm * U * h / phi_m;
Pr_t_inv = phi_m / phi_h;
zeta_[step] = zeta;
Rib_[step] = Rib;
Re_[step] = Re;
B_[step] = B;
z0_m_[step] = z0_m;
z0_t_[step] = z0_t;
Rib_conv_lim_[step] = Rib_conv_lim;
Cm_[step] = Cm;
Ct_[step] = Ct;
Km_[step] = Km;
Pr_t_inv_[step] = Pr_t_inv;
}
}
template void compute_flux_cpu(const float *U, const float *dt, const float *T_semi, const float *dq, const float *H, const float *in_z0_m,
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 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 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 grid_size);
template void compute_flux_cpu(const double *U, const double *dt, const double *T_semi, const double *dq, const double *H, const double *in_z0_m,
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 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 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 grid_size);
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include "../includeCXX/SubFunctions.h"
#include "../includeCXX/Flux.h"
#include <vector>
#ifdef INCLUDE_CUDA
Flux<float, MemType::GPU, MemType::CPU> F;
#else
Flux<float, MemType::CPU, MemType::CPU> F;
#endif
// -------------------------------------------------------------------------- //
void surf_flux_CXX (float *U_, float *dT_, float *Tsemi_, float *dQ_, float *h_, float *in_z0_m_,
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 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 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 grid_size)
{
F.set_params(grid_size, 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);
F.set_data(U_, dT_, Tsemi_, dQ_, h_, in_z0_m_,
zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_);
F.compute_flux(zeta_, Rib_, Re_, B_, z0_m_, z0_t_, Rib_conv_lim_, Cm_, Ct_, Km_, Pr_t_inv_, maxiters_charnock, maxiters_convection);
}
\ No newline at end of file
module C_FUNC
INTERFACE
#if defined(INCLUDE_CUDA) || defined(INCLUDE_CXX)
SUBROUTINE surf_flux(U, dT, Tsemi, dQ, h, in_z0_m, &
zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, &
Cm, Ct, Km, Prt_inv, &
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) 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, maxiters_convection
REAL(C_FLOAT) :: 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
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 surf_flux
#endif
END INTERFACE
end module C_FUNC
...@@ -11,6 +11,9 @@ module sfx_esm ...@@ -11,6 +11,9 @@ module sfx_esm
use sfx_data use sfx_data
use sfx_surface use sfx_surface
use sfx_esm_param use sfx_esm_param
#if defined(INCLUDE_CUDA) || defined(INCLUDE_CXX)
use C_FUNC
#endif
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
! directives list ! directives list
...@@ -51,7 +54,22 @@ contains ...@@ -51,7 +54,22 @@ contains
type (sfxDataType) sfx_cell type (sfxDataType) sfx_cell
integer i integer i
! ---------------------------------------------------------------------------- ! ----------------------------------------------------------------------------
#if defined(INCLUDE_CUDA) || defined(INCLUDE_CXX)
write(*, *) 'CXX'
call surf_flux(meteo%U, meteo%dT, meteo%Tsemi, meteo%dQ, meteo%h, meteo%z0_m, &
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, &
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, &
numerics%maxiters_charnock, numerics%maxiters_convection, &
n)
#else
write(*, *) 'FORTRAN'
do i = 1, n do i = 1, n
#ifdef SFX_FORCE_DEPRECATED_ESM_CODE #ifdef SFX_FORCE_DEPRECATED_ESM_CODE
#else #else
...@@ -65,6 +83,7 @@ contains ...@@ -65,6 +83,7 @@ contains
call push_sfx_data(sfx, sfx_cell, i) call push_sfx_data(sfx, sfx_cell, i)
#endif #endif
end do end do
#endif
end subroutine get_surface_fluxes_vec end subroutine get_surface_fluxes_vec
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
......
...@@ -11,7 +11,6 @@ module sfx_surface ...@@ -11,7 +11,6 @@ module sfx_surface
! directives list ! directives list
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
implicit none implicit none
private
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
! public interface ! public interface
...@@ -27,12 +26,13 @@ module sfx_surface ...@@ -27,12 +26,13 @@ module sfx_surface
integer, public, parameter :: surface_lake = 2 !> lake surface integer, public, parameter :: surface_lake = 2 !> lake surface
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
real, parameter :: kappa = 0.40 !> von Karman constant [n/d] real, parameter, private :: kappa = 0.40 !> von Karman constant [n/d]
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
!> Charnock parameters !> Charnock parameters
!> z0 = Re_visc_min * (nu / u_dyn) + gamma_c * (u_dyn^2 / g) !> z0 = Re_visc_min * (nu / u_dyn) + gamma_c * (u_dyn^2 / g)
! -------------------------------------------------------------------------------- ! --------------------------------------------------------------------------------
real, parameter :: gamma_c = 0.0144 real, parameter :: gamma_c = 0.0144
real, parameter :: Re_visc_min = 0.111 real, parameter :: Re_visc_min = 0.111
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment