PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
Macros | Functions
wallfunction.c File Reference

Wall function implementations for near-wall turbulence modeling. More...

#include "wallfunction.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
Include dependency graph for wallfunction.c:

Go to the source code of this file.

Macros

#define KAPPA   0.41
 von Karman constant (universal turbulence constant)
 
#define LOGLAW_B   5.5
 Log-law intercept constant B for smooth walls.
 
#define VISCOUS_SUBLAYER_YPLUS   11.81
 Viscous sublayer thickness y+ threshold.
 
#define ROUGHNESS_TRANSITION_YPLUS   2.25
 Smooth-to-rough transition y+ threshold.
 
#define FULLY_ROUGH_YPLUS   90.0
 Fully rough regime y+ threshold.
 
#define DAMPING_COEFFICIENT   19.0
 Eddy viscosity damping coefficient (van Driest damping)
 

Functions

void noslip (UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, double normal_x, double normal_y, double normal_z)
 Internal helper implementation: noslip().
 
void freeslip (UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, double normal_x, double normal_y, double normal_z)
 Internal helper implementation: freeslip().
 
double E_coeff (double friction_velocity, double roughness_height, double kinematic_viscosity)
 Internal helper implementation: E_coeff().
 
double u_hydset_roughness (double kinematic_viscosity, double wall_distance, double friction_velocity, double roughness_height)
 Internal helper implementation: u_hydset_roughness().
 
double f_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
 Internal helper implementation: f_hydset().
 
double df_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
 Implementation of df_hydset().
 
double find_utau_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double initial_guess, double roughness_height)
 Implementation of find_utau_hydset().
 
double nu_t (double yplus)
 Internal helper implementation: nu_t().
 
double integrate_1 (double kinematic_viscosity, double wall_distance, double friction_velocity, int integration_mode)
 Implementation of integrate_1().
 
double taw (double kinematic_viscosity, double friction_velocity, double wall_distance, double velocity, double pressure_gradient_tangent)
 Implementation of taw().
 
double u_Cabot (double kinematic_viscosity, double wall_distance, double friction_velocity, double pressure_gradient_tangent, double wall_shear_stress)
 Implementation of u_Cabot().
 
double f_Cabot (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
 Internal helper implementation: f_Cabot().
 
double df_Cabot (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
 Implementation of df_Cabot().
 
void find_utau_Cabot (double kinematic_viscosity, double velocity, double wall_distance, double initial_guess, double pressure_gradient_tangent, double pressure_gradient_normal, double *friction_velocity, double *wall_shear_velocity, double *wall_shear_normal)
 Implementation of find_utau_Cabot().
 
double u_Werner (double kinematic_viscosity, double wall_distance, double friction_velocity)
 Internal helper implementation: u_Werner().
 
double f_Werner (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
 Internal helper implementation: f_Werner().
 
double df_Werner (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
 Implementation of df_Werner().
 
double find_utau_Werner (double kinematic_viscosity, double velocity, double wall_distance, double initial_guess)
 Implementation of find_utau_Werner().
 
double u_loglaw (double wall_distance, double friction_velocity, double roughness_length)
 Implementation of u_loglaw().
 
double find_utau_loglaw (double velocity, double wall_distance, double roughness_length)
 Internal helper implementation: find_utau_loglaw().
 
void wall_function (UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z)
 Implementation of wall_function().
 
void wall_function_loglaw (UserCtx *user, double roughness_height, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z)
 Internal helper implementation: wall_function_loglaw().
 
void wall_function_Cabot (UserCtx *user, double roughness_height, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z, double pressure_gradient_x, double pressure_gradient_y, double pressure_gradient_z, int iteration_count)
 Internal helper implementation: wall_function_Cabot().
 

Detailed Description

Wall function implementations for near-wall turbulence modeling.

This file contains various wall function models that bridge the gap between the wall and the first computational grid point. Wall functions allow simulations to avoid resolving the viscous sublayer, reducing computational cost while maintaining reasonable accuracy for turbulent wall-bounded flows.

PHYSICAL BACKGROUND: The near-wall region in turbulent flows is characterized by three layers:

  1. Viscous sublayer (y+ < 5): Dominated by viscous effects, u+ = y+
  2. Buffer layer (5 < y+ < 30): Transition region
  3. Log-law region (y+ > 30): Inertial layer, u+ = (1/κ) ln(y+) + B where: u+ = u / u_τ (normalized velocity) y+ = y * u_τ / ν (normalized wall distance) u_τ = sqrt(τ_w / ρ) (friction velocity) κ ≈ 0.41 (von Karman constant) B ≈ 5.5 (log-law intercept for smooth walls)

IMPLEMENTED MODELS:

Author
Original implementation adapted from legacy code
Date
Enhanced with comprehensive documentation

Definition in file wallfunction.c.

Macro Definition Documentation

◆ KAPPA

#define KAPPA   0.41

von Karman constant (universal turbulence constant)

Definition at line 43 of file wallfunction.c.

◆ LOGLAW_B

#define LOGLAW_B   5.5

Log-law intercept constant B for smooth walls.

Definition at line 46 of file wallfunction.c.

◆ VISCOUS_SUBLAYER_YPLUS

#define VISCOUS_SUBLAYER_YPLUS   11.81

Viscous sublayer thickness y+ threshold.

Definition at line 49 of file wallfunction.c.

◆ ROUGHNESS_TRANSITION_YPLUS

#define ROUGHNESS_TRANSITION_YPLUS   2.25

Smooth-to-rough transition y+ threshold.

Definition at line 52 of file wallfunction.c.

◆ FULLY_ROUGH_YPLUS

#define FULLY_ROUGH_YPLUS   90.0

Fully rough regime y+ threshold.

Definition at line 55 of file wallfunction.c.

◆ DAMPING_COEFFICIENT

#define DAMPING_COEFFICIENT   19.0

Eddy viscosity damping coefficient (van Driest damping)

Definition at line 58 of file wallfunction.c.

Function Documentation

◆ noslip()

void noslip ( UserCtx user,
double  distance_reference,
double  distance_boundary,
Cmpnts  velocity_wall,
Cmpnts  velocity_reference,
Cmpnts velocity_boundary,
double  normal_x,
double  normal_y,
double  normal_z 
)

Internal helper implementation: noslip().

Applies no-slip wall boundary condition with linear interpolation.

Local to this translation unit.

Definition at line 68 of file wallfunction.c.

73{
74 (void)user;
75 (void)normal_x;
76 (void)normal_y;
77 (void)normal_z;
78 // Compute velocity difference between reference point and wall
79 double delta_u = velocity_reference.x - velocity_wall.x;
80 double delta_v = velocity_reference.y - velocity_wall.y;
81 double delta_w = velocity_reference.z - velocity_wall.z;
82
83 // Linear interpolation factor
84 double interpolation_factor = distance_boundary / distance_reference;
85
86 // Apply linear interpolation
87 (*velocity_boundary).x = interpolation_factor * delta_u;
88 (*velocity_boundary).y = interpolation_factor * delta_v;
89 (*velocity_boundary).z = interpolation_factor * delta_w;
90
91 // Add wall velocity (shift to absolute frame)
92 (*velocity_boundary).x += velocity_wall.x;
93 (*velocity_boundary).y += velocity_wall.y;
94 (*velocity_boundary).z += velocity_wall.z;
95}
PetscScalar x
Definition variables.h:101
PetscScalar z
Definition variables.h:101
PetscScalar y
Definition variables.h:101
Here is the caller graph for this function:

◆ freeslip()

void freeslip ( UserCtx user,
double  distance_reference,
double  distance_boundary,
Cmpnts  velocity_wall,
Cmpnts  velocity_reference,
Cmpnts velocity_boundary,
double  normal_x,
double  normal_y,
double  normal_z 
)

Internal helper implementation: freeslip().

Applies free-slip wall boundary condition.

Local to this translation unit.

Definition at line 101 of file wallfunction.c.

106{
107 (void)user;
108 // Extract normal components of velocities
109 double wall_normal_velocity = velocity_wall.x * normal_x +
110 velocity_wall.y * normal_y +
111 velocity_wall.z * normal_z;
112
113 double reference_normal_velocity = velocity_reference.x * normal_x +
114 velocity_reference.y * normal_y +
115 velocity_reference.z * normal_z;
116
117 // Interpolate normal velocity component
118 double boundary_normal_velocity = wall_normal_velocity +
119 (reference_normal_velocity - wall_normal_velocity) * (distance_boundary / distance_reference);
120
121 // Extract tangential velocity components (extrapolated from reference point)
122 double tangential_u = velocity_reference.x - reference_normal_velocity * normal_x;
123 double tangential_v = velocity_reference.y - reference_normal_velocity * normal_y;
124 double tangential_w = velocity_reference.z - reference_normal_velocity * normal_z;
125
126 // Reconstruct total velocity: U = U_t + U_n * n
127 (*velocity_boundary).x = tangential_u + boundary_normal_velocity * normal_x;
128 (*velocity_boundary).y = tangential_v + boundary_normal_velocity * normal_y;
129 (*velocity_boundary).z = tangential_w + boundary_normal_velocity * normal_z;
130}
Here is the caller graph for this function:

◆ E_coeff()

double E_coeff ( double  friction_velocity,
double  roughness_height,
double  kinematic_viscosity 
)

Internal helper implementation: E_coeff().

Computes roughness-modified log-law coefficient E.

Local to this translation unit.

Definition at line 140 of file wallfunction.c.

141{
142 // Compute roughness Reynolds number
143 double roughness_reynolds = friction_velocity * roughness_height / kinematic_viscosity;
144
145 double roughness_correction;
146
147 if (roughness_reynolds <= ROUGHNESS_TRANSITION_YPLUS) {
148 // Hydraulically smooth regime: no correction needed
149 roughness_correction = 0.0;
150 }
151 else if (roughness_reynolds < FULLY_ROUGH_YPLUS) {
152 // Transitional regime: smooth interpolation using sine function
153 // This provides a gradual transition between smooth and rough wall behavior
154 double max_correction = LOGLAW_B - 8.5 + (1.0 / KAPPA) * log(roughness_reynolds);
155
156 roughness_correction = max_correction *
157 sin(0.4258 * (log(roughness_reynolds) - 0.811));
158 }
159 else {
160 // Fully rough regime: maximum correction
161 roughness_correction = LOGLAW_B - 8.5 + (1.0 / KAPPA) * log(roughness_reynolds);
162 }
163
164 // Return E = exp[κ(B - ΔB)]
165 return exp(KAPPA * (LOGLAW_B - roughness_correction));
166}
#define ROUGHNESS_TRANSITION_YPLUS
Smooth-to-rough transition y+ threshold.
#define LOGLAW_B
Log-law intercept constant B for smooth walls.
#define FULLY_ROUGH_YPLUS
Fully rough regime y+ threshold.
#define KAPPA
von Karman constant (universal turbulence constant)
Here is the caller graph for this function:

◆ u_hydset_roughness()

double u_hydset_roughness ( double  kinematic_viscosity,
double  wall_distance,
double  friction_velocity,
double  roughness_height 
)

Internal helper implementation: u_hydset_roughness().

Computes velocity from log-law for rough walls.

Local to this translation unit.

Definition at line 172 of file wallfunction.c.

174{
175 // Normalized wall distance
176 double yplus = friction_velocity * wall_distance / kinematic_viscosity;
177
178 // Threshold values for regime transitions
179 const double viscous_limit = VISCOUS_SUBLAYER_YPLUS;
180 const double loglayer_limit = 300.0;
181
182 double tangential_velocity;
183
184 if (yplus <= viscous_limit) {
185 // Viscous sublayer: linear velocity profile
186 tangential_velocity = friction_velocity * yplus;
187 }
188 else if (yplus <= loglayer_limit) {
189 // Log-layer: logarithmic velocity profile with roughness correction
190 double E = E_coeff(friction_velocity, roughness_height, kinematic_viscosity);
191 tangential_velocity = (friction_velocity / KAPPA) * log(E * yplus);
192 }
193 else {
194 // Outside valid range (wake region or beyond)
195 tangential_velocity = -1.0;
196 }
197
198 return tangential_velocity;
199}
#define VISCOUS_SUBLAYER_YPLUS
Viscous sublayer thickness y+ threshold.
double E_coeff(double friction_velocity, double roughness_height, double kinematic_viscosity)
Internal helper implementation: E_coeff().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_hydset()

double f_hydset ( double  kinematic_viscosity,
double  known_velocity,
double  wall_distance,
double  friction_velocity_guess,
double  roughness_height 
)

Internal helper implementation: f_hydset().

Residual function for friction velocity equation (log-law with roughness)

Local to this translation unit.

Definition at line 209 of file wallfunction.c.

212{
213 double yplus = friction_velocity_guess * wall_distance / kinematic_viscosity;
214 double residual;
215
216 if (yplus <= VISCOUS_SUBLAYER_YPLUS) {
217 // Viscous sublayer: u = u_τ * y+
218 residual = friction_velocity_guess * yplus - known_velocity;
219 }
220 else {
221 // Log-layer: u = (u_τ / κ) * ln(E * y+)
222 double E = E_coeff(friction_velocity_guess, roughness_height, kinematic_viscosity);
223 residual = friction_velocity_guess * (1.0 / KAPPA * log(E * yplus)) - known_velocity;
224 }
225
226 return residual;
227}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ df_hydset()

double df_hydset ( double  kinematic_viscosity,
double  known_velocity,
double  wall_distance,
double  friction_velocity_guess,
double  roughness_height 
)

Implementation of df_hydset().

Numerical derivative of residual function.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
df_hydset()

Definition at line 235 of file wallfunction.c.

238{
239 const double perturbation = 1.e-7;
240
241 double f_plus = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
242 friction_velocity_guess + perturbation, roughness_height);
243
244 double f_minus = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
245 friction_velocity_guess - perturbation, roughness_height);
246
247 return (f_plus - f_minus) / (2.0 * perturbation);
248}
double f_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
Internal helper implementation: f_hydset().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_utau_hydset()

double find_utau_hydset ( double  kinematic_viscosity,
double  known_velocity,
double  wall_distance,
double  initial_guess,
double  roughness_height 
)

Implementation of find_utau_hydset().

Solves for friction velocity using Newton-Raphson iteration.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
find_utau_hydset()

Definition at line 256 of file wallfunction.c.

259{
260 double friction_velocity = initial_guess;
261 double friction_velocity_old = initial_guess;
262
263 const int max_iterations = 30;
264 const double convergence_tolerance = 1.e-7;
265
266 int iteration;
267 for (iteration = 0; iteration < max_iterations; iteration++) {
268 // Newton-Raphson update
269 double residual = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
270 friction_velocity_old, roughness_height);
271 double derivative = df_hydset(kinematic_viscosity, known_velocity, wall_distance,
272 friction_velocity_old, roughness_height);
273
274 friction_velocity = friction_velocity_old - residual / derivative;
275
276 // Check convergence
277 if (fabs(friction_velocity - friction_velocity_old) < convergence_tolerance) {
278 break;
279 }
280
281 friction_velocity_old = friction_velocity;
282 }
283
284 // Warn if convergence not achieved
285 if (iteration == max_iterations) {
287 "WARNING: u_tau iteration did not converge after %d iterations. "
288 "Final difference: %le\n",
289 iteration, fabs(friction_velocity - friction_velocity_old));
290 }
291
292 return friction_velocity;
293}
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:44
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:199
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:31
double df_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
Implementation of df_hydset().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nu_t()

double nu_t ( double  yplus)

Internal helper implementation: nu_t().

Computes turbulent eddy viscosity ratio (ν_t / ν)

Local to this translation unit.

Definition at line 303 of file wallfunction.c.

304{
305 // van Driest damping function: [1 - exp(-y+ / A+)]²
306 double damping_function = 1.0 - exp(-yplus / DAMPING_COEFFICIENT);
307
308 // Mixing length model: ν_t / ν = κ * y+ * D²
309 return KAPPA * yplus * damping_function * damping_function;
310}
#define DAMPING_COEFFICIENT
Eddy viscosity damping coefficient (van Driest damping)
Here is the caller graph for this function:

◆ integrate_1()

double integrate_1 ( double  kinematic_viscosity,
double  wall_distance,
double  friction_velocity,
int  integration_mode 
)

Implementation of integrate_1().

Integrates eddy viscosity profile from wall to distance y.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
integrate_1()

Definition at line 318 of file wallfunction.c.

320{
321 const int num_points = 30;
322 double step_size = wall_distance / (num_points - 1);
323 double integral_values[num_points];
324
325 // Compute integrand at each point
326 for (int i = 0; i < num_points; i++) {
327 double current_distance = i * step_size;
328 double yplus = current_distance * friction_velocity / kinematic_viscosity;
329 double eddy_viscosity_ratio = nu_t(yplus);
330
331 if (integration_mode == 0) {
332 // Mode 0: integrand = 1 / [(1 + ν_t/ν) * ν]
333 integral_values[i] = 1.0 / ((1.0 + eddy_viscosity_ratio) * kinematic_viscosity);
334 }
335 else {
336 // Mode 1: integrand = y / [(1 + ν_t/ν) * ν]
337 integral_values[i] = current_distance /
338 ((1.0 + eddy_viscosity_ratio) * kinematic_viscosity);
339 }
340 }
341
342 // Trapezoidal rule integration with corrected endpoints
343 double integral_sum = 0.0;
344
345 // Interior points: weight = (f[i-1] + 2*f[i] + f[i+1]) * dy/4
346 for (int i = 1; i < num_points - 1; i++) {
347 integral_sum += (integral_values[i-1] + 2.0 * integral_values[i] +
348 integral_values[i+1]) * 0.25 * step_size;
349 }
350
351 // Endpoint correction for higher accuracy
352 integral_sum += 0.1667 * step_size *
353 (2.0 * integral_values[0] + integral_values[1] +
354 2.0 * integral_values[num_points-1] + integral_values[num_points-2]);
355
356 return integral_sum;
357}
double nu_t(double yplus)
Internal helper implementation: nu_t().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ taw()

double taw ( double  kinematic_viscosity,
double  friction_velocity,
double  wall_distance,
double  velocity,
double  pressure_gradient_tangent 
)

Implementation of taw().

Computes wall shear stress with pressure gradient effects.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
taw()

Definition at line 369 of file wallfunction.c.

371{
372 // Compute integrated viscosity profiles
373 double F1 = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 0);
374 double Fy = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 1);
375
376 // Apply momentum balance: τ_w * F1 = u - (dp/dx) * Fy
377 return (1.0 / F1) * (velocity - pressure_gradient_tangent * Fy);
378}
double integrate_1(double kinematic_viscosity, double wall_distance, double friction_velocity, int integration_mode)
Implementation of integrate_1().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ u_Cabot()

double u_Cabot ( double  kinematic_viscosity,
double  wall_distance,
double  friction_velocity,
double  pressure_gradient_tangent,
double  wall_shear_stress 
)

Implementation of u_Cabot().

Computes velocity using Cabot wall function.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
u_Cabot()

Definition at line 386 of file wallfunction.c.

389{
390 double F1 = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 0);
391 double Fy = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 1);
392
393 return wall_shear_stress * F1 + pressure_gradient_tangent * Fy;
394}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_Cabot()

double f_Cabot ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  friction_velocity_guess,
double  pressure_gradient_tangent,
double  pressure_gradient_normal 
)

Internal helper implementation: f_Cabot().

Residual function for Cabot wall function.

Local to this translation unit.

Definition at line 400 of file wallfunction.c.

403{
404 (void)pressure_gradient_normal;
405 double wall_shear = taw(kinematic_viscosity, friction_velocity_guess,
406 wall_distance, velocity, pressure_gradient_tangent);
407
408 return friction_velocity_guess - sqrt(fabs(wall_shear));
409}
double taw(double kinematic_viscosity, double friction_velocity, double wall_distance, double velocity, double pressure_gradient_tangent)
Implementation of taw().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ df_Cabot()

double df_Cabot ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  friction_velocity_guess,
double  pressure_gradient_tangent,
double  pressure_gradient_normal 
)

Implementation of df_Cabot().

Numerical derivative for Cabot wall function.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
df_Cabot()

Definition at line 417 of file wallfunction.c.

420{
421 const double perturbation = 1.e-7;
422
423 double f_plus = f_Cabot(kinematic_viscosity, velocity, wall_distance,
424 friction_velocity_guess + perturbation,
425 pressure_gradient_tangent, pressure_gradient_normal);
426
427 double f_minus = f_Cabot(kinematic_viscosity, velocity, wall_distance,
428 friction_velocity_guess - perturbation,
429 pressure_gradient_tangent, pressure_gradient_normal);
430
431 return (f_plus - f_minus) / (2.0 * perturbation);
432}
double f_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
Internal helper implementation: f_Cabot().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_utau_Cabot()

void find_utau_Cabot ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  initial_guess,
double  pressure_gradient_tangent,
double  pressure_gradient_normal,
double *  friction_velocity,
double *  wall_shear_velocity,
double *  wall_shear_normal 
)

Implementation of find_utau_Cabot().

Solves for friction velocity using Cabot wall function.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
find_utau_Cabot()

Definition at line 440 of file wallfunction.c.

444{
445 double current_guess = initial_guess;
446 double new_guess;
447
448 const int max_iterations = 30;
449 const double convergence_tolerance = 1.e-10;
450
451 int iteration;
452 for (iteration = 0; iteration < max_iterations; iteration++) {
453 double residual = f_Cabot(kinematic_viscosity, velocity, wall_distance,
454 current_guess, pressure_gradient_tangent,
455 pressure_gradient_normal);
456
457 double derivative = df_Cabot(kinematic_viscosity, velocity, wall_distance,
458 current_guess, pressure_gradient_tangent,
459 pressure_gradient_normal);
460
461 new_guess = fabs(current_guess - residual / derivative);
462
463 if (fabs(current_guess - new_guess) < convergence_tolerance) {
464 break;
465 }
466
467 current_guess = new_guess;
468 }
469
470 if (fabs(current_guess - new_guess) > 1.e-5 && iteration >= 29) {
471 printf("\n!!!!!!!! Cabot Iteration Failed !!!!!!!!\n");
472 }
473
474 *friction_velocity = new_guess;
475 *wall_shear_velocity = taw(kinematic_viscosity, new_guess, wall_distance,
476 velocity, pressure_gradient_tangent);
477 *wall_shear_normal = taw(kinematic_viscosity, new_guess, wall_distance,
478 0.0, pressure_gradient_normal);
479}
double df_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
Implementation of df_Cabot().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ u_Werner()

double u_Werner ( double  kinematic_viscosity,
double  wall_distance,
double  friction_velocity 
)

Internal helper implementation: u_Werner().

Computes velocity using Werner-Wengle wall function.

Local to this translation unit.

Definition at line 489 of file wallfunction.c.

491{
492 double yplus = friction_velocity * wall_distance / kinematic_viscosity;
493
494 // Werner-Wengle constants
495 const double power_law_coefficient = 8.3;
496 const double power_law_exponent = 1.0 / 7.0;
497
498 double velocity;
499
500 if (yplus <= VISCOUS_SUBLAYER_YPLUS) {
501 // Viscous sublayer: u+ = y+
502 velocity = yplus * friction_velocity;
503 }
504 else {
505 // Power-law region: u+ = A * (y+)^B
506 velocity = power_law_coefficient * pow(yplus, power_law_exponent) * friction_velocity;
507 }
508
509 return velocity;
510}
Here is the caller graph for this function:

◆ f_Werner()

double f_Werner ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  friction_velocity 
)

Internal helper implementation: f_Werner().

Residual function for Werner-Wengle iteration.

Local to this translation unit.

Definition at line 516 of file wallfunction.c.

518{
519 const double power_law_coefficient = 8.3;
520 const double power_law_exponent = 1.0 / 7.0;
521
522 // Transition point between viscous and power-law regions
523 double transition_distance = VISCOUS_SUBLAYER_YPLUS * kinematic_viscosity / friction_velocity;
524
525 // Transition velocity
526 double transition_velocity = kinematic_viscosity / (2.0 * transition_distance) *
527 pow(power_law_coefficient, 2.0 / (1.0 - power_law_exponent));
528
529 double residual;
530
531 if (fabs(velocity) <= transition_velocity) {
532 // Viscous sublayer regime
533 residual = friction_velocity * friction_velocity -
534 velocity / wall_distance * kinematic_viscosity;
535 }
536 else {
537 // Power-law regime (more complex inversion formula)
538 double term1 = 0.5 * (1.0 - power_law_exponent) *
539 pow(power_law_coefficient, (1.0 + power_law_exponent) /
540 (1.0 - power_law_exponent)) *
541 pow(kinematic_viscosity / wall_distance, 1.0 + power_law_exponent);
542
543 double term2 = (1.0 + power_law_exponent) / power_law_coefficient *
544 pow(kinematic_viscosity / wall_distance, power_law_exponent) *
545 fabs(velocity);
546
547 residual = friction_velocity * friction_velocity -
548 velocity / fabs(velocity) * pow(term1 + term2, 2.0 / (1.0 + power_law_exponent));
549 }
550
551 return residual;
552}
Here is the caller graph for this function:

◆ df_Werner()

double df_Werner ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  friction_velocity 
)

Implementation of df_Werner().

Numerical derivative for Werner-Wengle iteration.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
df_Werner()

Definition at line 560 of file wallfunction.c.

562{
563 const double perturbation = 1.e-7;
564
565 double f_plus = f_Werner(kinematic_viscosity, velocity, wall_distance,
566 friction_velocity + perturbation);
567
568 double f_minus = f_Werner(kinematic_viscosity, velocity, wall_distance,
569 friction_velocity - perturbation);
570
571 return (f_plus - f_minus) / (2.0 * perturbation);
572}
double f_Werner(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
Internal helper implementation: f_Werner().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_utau_Werner()

double find_utau_Werner ( double  kinematic_viscosity,
double  velocity,
double  wall_distance,
double  initial_guess 
)

Implementation of find_utau_Werner().

Solves for friction velocity using Werner-Wengle wall function.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
find_utau_Werner()

Definition at line 580 of file wallfunction.c.

582{
583 double current_guess = initial_guess;
584 double new_guess;
585
586 const int max_iterations = 20;
587 const double convergence_tolerance = 1.e-7;
588
589 int iteration;
590 for (iteration = 0; iteration < max_iterations; iteration++) {
591 double residual = f_Werner(kinematic_viscosity, velocity, wall_distance, current_guess);
592 double derivative = df_Werner(kinematic_viscosity, velocity, wall_distance, current_guess);
593
594 new_guess = current_guess - residual / derivative;
595
596 if (fabs(current_guess - new_guess) < convergence_tolerance) {
597 break;
598 }
599
600 current_guess = new_guess;
601 }
602
603 if (fabs(current_guess - new_guess) > 1.e-5 && iteration >= 19) {
604 printf("\n!!!!!!!! Werner-Wengle Iteration Failed !!!!!!!!\n");
605 }
606
607 return new_guess;
608}
double df_Werner(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
Implementation of df_Werner().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ u_loglaw()

double u_loglaw ( double  wall_distance,
double  friction_velocity,
double  roughness_length 
)

Implementation of u_loglaw().

Computes velocity using simple log-law (smooth wall with roughness offset)

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
u_loglaw()

Definition at line 620 of file wallfunction.c.

621{
622 return friction_velocity * (1.0 / KAPPA) * log((roughness_length + wall_distance) / roughness_length);
623}
Here is the caller graph for this function:

◆ find_utau_loglaw()

double find_utau_loglaw ( double  velocity,
double  wall_distance,
double  roughness_length 
)

Internal helper implementation: find_utau_loglaw().

Solves for friction velocity using simple log-law (explicit formula)

Local to this translation unit.

Definition at line 629 of file wallfunction.c.

630{
631 return KAPPA * velocity / log((wall_distance + roughness_length) / roughness_length);
632}
Here is the caller graph for this function:

◆ wall_function()

void wall_function ( UserCtx user,
double  distance_reference,
double  distance_boundary,
Cmpnts  velocity_wall,
Cmpnts  velocity_reference,
Cmpnts velocity_boundary,
PetscReal *  friction_velocity,
double  normal_x,
double  normal_y,
double  normal_z 
)

Implementation of wall_function().

Applies standard wall function with Werner-Wengle model.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/wallfunction.h.

See also
wall_function()

Definition at line 648 of file wallfunction.c.

652{
653 SimCtx *simCtx = user->simCtx;
654 double kinematic_viscosity = 1.0 / simCtx->ren;
655
656 // Decompose velocity into components
657 double delta_u = velocity_reference.x - velocity_wall.x;
658 double delta_v = velocity_reference.y - velocity_wall.y;
659 double delta_w = velocity_reference.z - velocity_wall.z;
660
661 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
662
663 double tangential_u = delta_u - normal_velocity * normal_x;
664 double tangential_v = delta_v - normal_velocity * normal_y;
665 double tangential_w = delta_w - normal_velocity * normal_z;
666
667 double tangential_magnitude = sqrt(tangential_u * tangential_u +
668 tangential_v * tangential_v +
669 tangential_w * tangential_w);
670
671 // Apply Werner-Wengle wall function
672 double utau_guess = 0.05;
673 double tangential_modeled = u_Werner(kinematic_viscosity, distance_boundary, utau_guess);
674 if (friction_velocity) {
675 // Werner-Wengle path currently uses a fixed u_tau estimate.
676 *friction_velocity = (PetscReal)utau_guess;
677 }
678
679 // Scale tangential components
680 if (tangential_magnitude > 1.e-10) {
681 tangential_u *= tangential_modeled / tangential_magnitude;
682 tangential_v *= tangential_modeled / tangential_magnitude;
683 tangential_w *= tangential_modeled / tangential_magnitude;
684 }
685 else {
686 tangential_u = tangential_v = tangential_w = 0.0;
687 }
688
689 // Reconstruct velocity: U = U_t + U_n * n
690 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
691 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
692 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
693
694 // Add wall velocity
695 (*velocity_boundary).x += velocity_wall.x;
696 (*velocity_boundary).y += velocity_wall.y;
697 (*velocity_boundary).z += velocity_wall.z;
698}
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:814
PetscReal ren
Definition variables.h:691
The master context for the entire simulation.
Definition variables.h:643
double u_Werner(double kinematic_viscosity, double wall_distance, double friction_velocity)
Internal helper implementation: u_Werner().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wall_function_loglaw()

void wall_function_loglaw ( UserCtx user,
double  roughness_height,
double  distance_reference,
double  distance_boundary,
Cmpnts  velocity_wall,
Cmpnts  velocity_reference,
Cmpnts velocity_boundary,
PetscReal *  friction_velocity,
double  normal_x,
double  normal_y,
double  normal_z 
)

Internal helper implementation: wall_function_loglaw().

Applies log-law wall function with roughness correction.

Local to this translation unit.

Definition at line 704 of file wallfunction.c.

709{
710 SimCtx *simCtx = user->simCtx;
711 double kinematic_viscosity = 1.0 / simCtx->ren;
712
713 // Decompose velocity
714 double delta_u = velocity_reference.x - velocity_wall.x;
715 double delta_v = velocity_reference.y - velocity_wall.y;
716 double delta_w = velocity_reference.z - velocity_wall.z;
717
718 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
719
720 double tangential_u = delta_u - normal_velocity * normal_x;
721 double tangential_v = delta_v - normal_velocity * normal_y;
722 double tangential_w = delta_w - normal_velocity * normal_z;
723
724 double tangential_magnitude = sqrt(tangential_u * tangential_u +
725 tangential_v * tangential_v +
726 tangential_w * tangential_w);
727
728 // Solve for friction velocity
729 *friction_velocity = find_utau_hydset(kinematic_viscosity, tangential_magnitude,
730 distance_reference, 0.001, roughness_height);
731
732 // Compute wall function velocity
733 double tangential_modeled = u_hydset_roughness(kinematic_viscosity, distance_boundary,
734 *friction_velocity, roughness_height);
735
736 // Check if outside valid range (y+ > 300)
737 if (tangential_modeled < 0.0) {
738 tangential_modeled = tangential_magnitude;
739 }
740
741 // Scale tangential components
742 if (tangential_magnitude > 1.e-10) {
743 tangential_u *= tangential_modeled / tangential_magnitude;
744 tangential_v *= tangential_modeled / tangential_magnitude;
745 tangential_w *= tangential_modeled / tangential_magnitude;
746 }
747 else {
748 tangential_u = tangential_v = tangential_w = 0.0;
749 }
750
751 // Reconstruct total velocity
752 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
753 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
754 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
755
756 // Add wall velocity
757 (*velocity_boundary).x += velocity_wall.x;
758 (*velocity_boundary).y += velocity_wall.y;
759 (*velocity_boundary).z += velocity_wall.z;
760}
double u_hydset_roughness(double kinematic_viscosity, double wall_distance, double friction_velocity, double roughness_height)
Internal helper implementation: u_hydset_roughness().
double find_utau_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double initial_guess, double roughness_height)
Implementation of find_utau_hydset().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wall_function_Cabot()

void wall_function_Cabot ( UserCtx user,
double  roughness_height,
double  distance_reference,
double  distance_boundary,
Cmpnts  velocity_wall,
Cmpnts  velocity_reference,
Cmpnts velocity_boundary,
PetscReal *  friction_velocity,
double  normal_x,
double  normal_y,
double  normal_z,
double  pressure_gradient_x,
double  pressure_gradient_y,
double  pressure_gradient_z,
int  iteration_count 
)

Internal helper implementation: wall_function_Cabot().

Applies Cabot non-equilibrium wall function with pressure gradients.

Local to this translation unit.

Definition at line 766 of file wallfunction.c.

773{
774 (void)roughness_height;
775 SimCtx *simCtx = user->simCtx;
776 double kinematic_viscosity = 1.0 / simCtx->ren;
777
778 // Decompose velocity
779 double delta_u = velocity_reference.x - velocity_wall.x;
780 double delta_v = velocity_reference.y - velocity_wall.y;
781 double delta_w = velocity_reference.z - velocity_wall.z;
782
783 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
784
785 double tangential_u = delta_u - normal_velocity * normal_x;
786 double tangential_v = delta_v - normal_velocity * normal_y;
787 double tangential_w = delta_w - normal_velocity * normal_z;
788
789 double tangential_magnitude = sqrt(tangential_u * tangential_u +
790 tangential_v * tangential_v +
791 tangential_w * tangential_w);
792
793 // Compute tangential pressure gradient
794 double pressure_gradient_tangent = 0.0;
795 if (tangential_magnitude > 1.e-10) {
796 pressure_gradient_tangent = (pressure_gradient_x * tangential_u +
797 pressure_gradient_y * tangential_v +
798 pressure_gradient_z * tangential_w) / tangential_magnitude;
799 }
800
801 // Normal pressure gradient (currently set to zero)
802 double pressure_gradient_normal = 0.0;
803
804 // Solve for friction velocity (only on first iteration or periodically)
805 if (iteration_count == 0 || iteration_count > 4) {
806 double utau, wall_shear1, wall_shear2;
807 find_utau_Cabot(kinematic_viscosity, tangential_magnitude, distance_reference,
808 0.01, pressure_gradient_tangent, pressure_gradient_normal,
809 &utau, &wall_shear1, &wall_shear2);
810 *friction_velocity = utau;
811 }
812
813 // Compute wall function velocity with pressure gradient correction
814 double tangential_modeled = u_Cabot(kinematic_viscosity, distance_boundary,
815 *friction_velocity, pressure_gradient_tangent,
816 taw(kinematic_viscosity, *friction_velocity,
817 distance_reference, tangential_magnitude,
818 pressure_gradient_tangent));
819
820 // Scale tangential components
821 if (tangential_magnitude > 1.e-10) {
822 tangential_u *= tangential_modeled / tangential_magnitude;
823 tangential_v *= tangential_modeled / tangential_magnitude;
824 tangential_w *= tangential_modeled / tangential_magnitude;
825 }
826 else {
827 tangential_u = tangential_v = tangential_w = 0.0;
828 }
829
830 // Reconstruct total velocity
831 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
832 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
833 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
834
835 // Add wall velocity
836 (*velocity_boundary).x += velocity_wall.x;
837 (*velocity_boundary).y += velocity_wall.y;
838 (*velocity_boundary).z += velocity_wall.z;
839}
double u_Cabot(double kinematic_viscosity, double wall_distance, double friction_velocity, double pressure_gradient_tangent, double wall_shear_stress)
Implementation of u_Cabot().
void find_utau_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double initial_guess, double pressure_gradient_tangent, double pressure_gradient_normal, double *friction_velocity, double *wall_shear_velocity, double *wall_shear_normal)
Implementation of find_utau_Cabot().
Here is the call graph for this function:
Here is the caller graph for this function: