47 real(kind=
rp),
intent(in) :: magu, ri_b, h, z0, l, kappa
52 l, utau, kappa)
result(heat_flux)
54 real(kind=
rp),
intent(in) :: ts, ti, ri_b, h, magu
55 real(kind=
rp),
intent(in) :: z0h, pr, l, utau, kappa
56 real(kind=
rp) :: heat_flux
72 subroutine compute_ri_b(bc_type, g_dot_n, hi, ti, ts, magu, kappa, q, Ri_b)
73 character(len=*),
intent(in) :: bc_type
74 real(kind=
rp),
intent(in) :: hi, ti, ts
75 real(kind=
rp),
intent(in) :: magu, kappa, g_dot_n
76 real(kind=
rp),
intent(inout) :: q, ri_b
80 ri_b = - g_dot_n*hi / ti*q / (magu**3*kappa**2)
82 ri_b = g_dot_n*hi/ti*(ti - ts)/magu**2
84 call neko_error(
"Invalid specified temperature b.c. type " // &
85 "('neumann' or 'dirichlet'?)")
91 character(len=*),
intent(in) :: bc_type
92 real(kind=
rp),
intent(in) :: hi, ti, kappa, utau, z0h,bc_value
93 real(kind=
rp),
intent(inout) :: q,ts
101 q = kappa*utau*(ts - ti)/log(hi/z0h)
103 call neko_error(
"Invalid specified temperature b.c. type " // &
104 "('neumann' or 'dirichlet'?)")
111 real(kind=
rp),
intent(in) :: ri_b, ri_threshold
113 if (ri_b > ri_threshold)
then
116 elseif (ri_b < -ri_threshold)
then
128 n_x, n_y, n_z, h, tau_x, tau_y, tau_z, n_nodes, &
129 kappa, mu_w, rho_w, g_vec, Pr, z0, z0h_in, bc_type, bc_value, tstep, &
130 Ri_b_diagn, L_ob_diagn, utau_diagn, magu_diagn, ti_diagn, ts_diagn,&
132 integer,
intent(in) :: n_nodes, tstep
133 real(kind=
rp),
dimension(n_nodes),
intent(in) :: u, v, w, temp, temp_w
134 real(kind=
rp),
dimension(n_nodes),
intent(in) :: n_x, n_y, n_z, h
135 real(kind=
rp),
intent(in) :: kappa, z0, z0h_in, bc_value, pr
136 real(kind=
rp),
dimension(3),
intent(in) :: g_vec
137 real(kind=
rp),
dimension(n_nodes),
intent(in) :: mu_w, rho_w
138 real(kind=
rp) :: g_dot_n
139 character(len=*),
intent(in) :: bc_type
140 real(kind=
rp),
dimension(n_nodes),
intent(inout) :: tau_x, tau_y, tau_z
142 real(kind=
rp) :: ui, vi, wi, hi, rho, mu
143 real(kind=
rp) :: normu, z0h
145 real(kind=
rp),
parameter :: tol = 0.001_rp
146 real(kind=
rp),
parameter :: nr_step = 0.001_rp
147 real(kind=
rp),
parameter :: ri_threshold = 0.0001_rp
148 character(len=LOG_SIZE) :: log_buf
149 real(kind=
rp) :: utau, ri_b, l_ob, magu, q, ti, ts
150 real(kind=
rp),
dimension(n_nodes),
intent(inout) :: ri_b_diagn, l_ob_diagn
151 real(kind=
rp),
dimension(n_nodes),
intent(inout) :: utau_diagn, magu_diagn
152 real(kind=
rp),
dimension(n_nodes),
intent(inout) :: ti_diagn, ts_diagn
153 real(kind=
rp),
dimension(n_nodes),
intent(inout) :: q_diagn
168 normu = ui * n_x(i) + vi * n_y(i) + wi * n_z(i)
169 ui = ui - normu * n_x(i)
170 vi = vi - normu * n_y(i)
171 wi = wi - normu * n_z(i)
174 magu = sqrt(ui**2 + vi**2 + wi**2)
175 magu =
max(magu, 1.0e-6_rp)
176 utau = magu*kappa / log(hi/z0)
181 z0h = z0 * exp(z0h_in*sqrt((utau*z0)/(mu/rho)))
191 g_dot_n = abs(g_vec(1)*n_x(i) + g_vec(2)*n_y(i) + g_vec(3)*n_z(i))
194 call compute_ri_b(bc_type, g_dot_n, hi, ti, ts, magu, kappa, q, ri_b)
200 utau = sqrt(
tau_ptr(magu, ri_b, hi, z0, l, kappa))
201 select case (bc_type)
204 ts = ti - (q * pr * log(hi/z0h)) / (
max(utau, 1e-6_rp) * kappa)
208 q =
heat_flux_ptr(ti, ts, ri_b, hi, magu, z0h, pr, l, utau, kappa)
210 call neko_error(
"Invalid specified temperature b.c. type " // &
211 "('neumann' or 'dirichlet'?)")
216 magu =
max(magu, 1.0e-6_rp)
217 tau_x(i) = -rho*utau**2 * ui / magu
218 tau_y(i) = -rho*utau**2 * vi / magu
219 tau_z(i) = -rho*utau**2 * wi / magu
220 if (abs(ri_b) <= ri_threshold)
then
224 l_ob = -(ts*utau**3)/(kappa*g_dot_n*q)
232 ts_diagn(i) = temp_w(i)
242 real(kind=
rp),
intent(in) :: magu, ri_b, h, z0, l, kappa
250 l, utau, kappa)
result(heat_flux)
251 real(kind=
rp),
intent(in) :: ts, ti, ri_b, h, magu
252 real(kind=
rp),
intent(in) :: z0h, pr, l, utau, kappa
253 real(kind=
rp) :: heat_flux
255 heat_flux = (ti - ts)/(log(h/z0h)) * &
261 real(kind=
rp),
intent(in) :: ri_b
262 real(kind=
rp) :: f_tau
264 f_tau = 0.17 * (0.25 + 0.75 / (1.0 + 4.0*ri_b))
268 real(kind=
rp),
intent(in) :: ri_b
269 real(kind=
rp) :: f_theta
271 f_theta = -0.145 / (1.0 + 4.0 * ri_b)
277 real(kind=
rp),
intent(in) :: magu, ri_b, h, z0, l, kappa
279 real(kind=
rp) :: a, b, c
281 a = kappa / log(h/z0)
283 c = 7.4 * a**2 * b * (h/z0)**0.5
289 l, utau, kappa)
result(heat_flux)
290 real(kind=
rp),
intent(in) :: ts, ti, ri_b, h, magu
291 real(kind=
rp),
intent(in) :: z0h, pr, l, utau, kappa
292 real(kind=
rp) :: heat_flux
293 real(kind=
rp) :: a, b, c
295 a = kappa / log(h/z0h)
297 c = 5.3 * a**2 * b * (h/z0h)**0.5
299 heat_flux = - a**2 / 0.74 * magu * &
305 real(kind=
rp),
intent(in) :: ri_b, c
306 real(kind=
rp) :: f_tau
308 f_tau = 1.0 - 2*ri_b / (1.0 + c * abs(ri_b)**0.5)
312 real(kind=
rp),
intent(in) :: ri_b, c
313 real(kind=
rp) :: f_theta
315 f_theta = 1.0 - 2*ri_b / (1.0 + c * abs(ri_b)**0.5)
320 real(kind=
rp),
intent(in) :: magu, ri_b, h, z0, l, kappa
323 tau = (kappa*magu/log(h/z0))**2
327 l, utau, kappa)
result(heat_flux)
328 real(kind=
rp),
intent(in) :: ts, ti, ri_b, h, magu
329 real(kind=
rp),
intent(in) :: z0h, pr, l, utau, kappa
330 real(kind=
rp) :: heat_flux
332 heat_flux = kappa*utau * (ti - ts)/log(h/z0h)
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
real(kind=rp) function, public glsum(a, n)
Sum a vector of length n.
real(kind=rp) function, public glmax(a, n)
Max of a vector of length n.
real(kind=rp) function, public glmin(a, n)
Min of a vector of length n.
integer, parameter, public rp
Global precision used in computations.
Implements the CPU kernel for the richardson_t type.
subroutine assign_bc_value(bc_type, bc_value, q, ts, ti, kappa, utau, z0h, hi)
Initialises q when the temperature surface bc is dirichlet.
procedure(heat_flux_interface), pointer heat_flux_ptr
real(kind=rp) function f_theta_convective(ri_b, c)
subroutine, public richardson_compute_cpu(u, v, w, temp, temp_w, n_x, n_y, n_z, h, tau_x, tau_y, tau_z, n_nodes, kappa, mu_w, rho_w, g_vec, pr, z0, z0h_in, bc_type, bc_value, tstep, ri_b_diagn, l_ob_diagn, utau_diagn, magu_diagn, ti_diagn, ts_diagn, q_diagn)
Main routine to compute the surface stresses based on richardson.
real(kind=rp) function f_tau_stable(ri_b)
real(kind=rp) function heat_flux_neutral(ti, ts, ri_b, h, magu, z0h, pr, l, utau, kappa)
real(kind=rp) function f_theta_stable(ri_b)
real(kind=rp) function tau_convective(magu, ri_b, h, z0, l, kappa)
Similarity laws and corrections for the UNSTABLE (convective) regime: Based on Louis 1979.
subroutine set_stability_regime(ri_b, ri_threshold)
Sets the stability regime based on the Richardson number value (quite arbitrary).
real(kind=rp) function f_tau_convective(ri_b, c)
procedure(tau_interface), pointer tau_ptr
real(kind=rp) function heat_flux_stable(ti, ts, ri_b, h, magu, z0h, pr, l, utau, kappa)
real(kind=rp) function tau_stable(magu, ri_b, h, z0, l, kappa)
Similarity laws and corrections for the STABLE regime: Based on Mauritsen et al. 2007.
real(kind=rp) function heat_flux_convective(ti, ts, ri_b, h, magu, z0h, pr, l, utau, kappa)
real(kind=rp) function tau_neutral(magu, ri_b, h, z0, l, kappa)
Similarity laws and corrections for the NEUTRAL regime:
subroutine compute_ri_b(bc_type, g_dot_n, hi, ti, ts, magu, kappa, q, ri_b)
Computes the Richardson number.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.