PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
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)
 Applies no-slip wall boundary condition with linear interpolation.
 
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)
 Applies free-slip wall boundary condition.
 
double E_coeff (double friction_velocity, double roughness_height, double kinematic_viscosity)
 Computes roughness-modified log-law coefficient E.
 
double u_hydset_roughness (double kinematic_viscosity, double wall_distance, double friction_velocity, double roughness_height)
 Computes velocity from log-law for rough walls.
 
double f_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
 Residual function for friction velocity equation (log-law with roughness)
 
double df_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
 Numerical derivative of residual function.
 
double find_utau_hydset (double kinematic_viscosity, double known_velocity, double wall_distance, double initial_guess, double roughness_height)
 Solves for friction velocity using Newton-Raphson iteration.
 
double nu_t (double yplus)
 Computes turbulent eddy viscosity ratio (ν_t / ν)
 
double integrate_1 (double kinematic_viscosity, double wall_distance, double friction_velocity, int integration_mode)
 Integrates eddy viscosity profile from wall to distance y.
 
double taw (double kinematic_viscosity, double friction_velocity, double wall_distance, double velocity, double pressure_gradient_tangent)
 Computes wall shear stress with pressure gradient effects.
 
double u_Cabot (double kinematic_viscosity, double wall_distance, double friction_velocity, double pressure_gradient_tangent, double wall_shear_stress)
 Computes velocity using Cabot wall function.
 
double f_Cabot (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
 Residual function for Cabot wall function.
 
double df_Cabot (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
 Numerical derivative for Cabot wall function.
 
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)
 Solves for friction velocity using Cabot wall function.
 
double u_Werner (double kinematic_viscosity, double wall_distance, double friction_velocity)
 Computes velocity using Werner-Wengle wall function.
 
double f_Werner (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
 Residual function for Werner-Wengle iteration.
 
double df_Werner (double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
 Numerical derivative for Werner-Wengle iteration.
 
double find_utau_Werner (double kinematic_viscosity, double velocity, double wall_distance, double initial_guess)
 Solves for friction velocity using Werner-Wengle wall function.
 
double u_loglaw (double wall_distance, double friction_velocity, double roughness_length)
 Computes velocity using simple log-law (smooth wall with roughness offset)
 
double find_utau_loglaw (double velocity, double wall_distance, double roughness_length)
 Solves for friction velocity using simple log-law (explicit formula)
 
static double sign (double value)
 Returns the sign of a number.
 
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)
 Applies standard wall function with Werner-Wengle model.
 
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)
 Applies log-law wall function with roughness correction.
 
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)
 Applies Cabot non-equilibrium wall function with pressure gradients.
 

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:

  • No-slip: Linear interpolation for stationary walls
  • Free-slip: Normal interpolation, tangential extrapolation
  • Werner-Wengle: Algebraic wall function
  • Log-law: Standard equilibrium wall function with roughness
  • Cabot: Non-equilibrium wall function with pressure gradient effects
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 
)

Applies no-slip wall boundary condition with linear interpolation.

This function enforces a no-slip boundary condition (zero velocity at the wall) by linearly interpolating between the wall velocity (typically zero) and the velocity at a reference point in the flow.

MATHEMATICAL FORMULATION: For a point at distance sb from the wall, with a reference velocity Uc at distance sc from the wall: U_boundary = U_wall + (U_reference - U_wall) * (sb / sc)

PHYSICAL INTERPRETATION: This provides a first-order approximation assuming linear velocity variation in the near-wall region, which is valid in the viscous sublayer.

Parameters
[in]userSimulation context (unused but required for interface)
[in]distance_referenceWall-normal distance to reference point (sc)
[in]distance_boundaryWall-normal distance to boundary point (sb)
[in]velocity_wallVelocity at the wall (Ua), typically zero
[in]velocity_referenceVelocity at reference point (Uc)
[out]velocity_boundaryComputed velocity at boundary point (Ub)
[in]normal_xX-component of wall normal vector
[in]normal_yY-component of wall normal vector
[in]normal_zZ-component of wall normal vector
Note
For moving walls, velocity_wall would be non-zero
The normal vector should point INTO the fluid domain

Definition at line 93 of file wallfunction.c.

98{
99 // Compute velocity difference between reference point and wall
100 double delta_u = velocity_reference.x - velocity_wall.x;
101 double delta_v = velocity_reference.y - velocity_wall.y;
102 double delta_w = velocity_reference.z - velocity_wall.z;
103
104 // Linear interpolation factor
105 double interpolation_factor = distance_boundary / distance_reference;
106
107 // Apply linear interpolation
108 (*velocity_boundary).x = interpolation_factor * delta_u;
109 (*velocity_boundary).y = interpolation_factor * delta_v;
110 (*velocity_boundary).z = interpolation_factor * delta_w;
111
112 // Add wall velocity (shift to absolute frame)
113 (*velocity_boundary).x += velocity_wall.x;
114 (*velocity_boundary).y += velocity_wall.y;
115 (*velocity_boundary).z += velocity_wall.z;
116}
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 
)

Applies free-slip wall boundary condition.

Free-slip conditions allow tangential flow but enforce zero normal velocity. This is appropriate for inviscid walls or symmetry planes where there is no shear stress but flow cannot penetrate the boundary.

DECOMPOSITION: Velocity is decomposed into normal and tangential components: U = U_n * n + U_t where U_n = U · n (normal component) U_t = U - U_n * n (tangential component)

BOUNDARY CONDITIONS:

  • Normal component: Interpolated from interior (∂U_n/∂n ≠ 0)
  • Tangential component: Extrapolated from interior (∂U_t/∂n = 0)
Parameters
[in]userSimulation context
[in]distance_referenceWall-normal distance to reference point
[in]distance_boundaryWall-normal distance to boundary point
[in]velocity_wallVelocity at the wall
[in]velocity_referenceVelocity at reference point
[out]velocity_boundaryComputed velocity at boundary point
[in]normal_xX-component of wall normal vector
[in]normal_yY-component of wall normal vector
[in]normal_zZ-component of wall normal vector

Definition at line 145 of file wallfunction.c.

150{
151 // Extract normal components of velocities
152 double wall_normal_velocity = velocity_wall.x * normal_x +
153 velocity_wall.y * normal_y +
154 velocity_wall.z * normal_z;
155
156 double reference_normal_velocity = velocity_reference.x * normal_x +
157 velocity_reference.y * normal_y +
158 velocity_reference.z * normal_z;
159
160 // Interpolate normal velocity component
161 double boundary_normal_velocity = wall_normal_velocity +
162 (reference_normal_velocity - wall_normal_velocity) * (distance_boundary / distance_reference);
163
164 // Extract tangential velocity components (extrapolated from reference point)
165 double tangential_u = velocity_reference.x - reference_normal_velocity * normal_x;
166 double tangential_v = velocity_reference.y - reference_normal_velocity * normal_y;
167 double tangential_w = velocity_reference.z - reference_normal_velocity * normal_z;
168
169 // Reconstruct total velocity: U = U_t + U_n * n
170 (*velocity_boundary).x = tangential_u + boundary_normal_velocity * normal_x;
171 (*velocity_boundary).y = tangential_v + boundary_normal_velocity * normal_y;
172 (*velocity_boundary).z = tangential_w + boundary_normal_velocity * normal_z;
173}

◆ E_coeff()

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

Computes roughness-modified log-law coefficient E.

The coefficient E accounts for wall roughness effects on the log-law: u+ = (1/κ) ln(E * y+)

ROUGHNESS REGIMES:

  1. Hydraulically smooth (ks+ < 2.25): E = exp(κ*B), no roughness effect
  2. Transitional (2.25 < ks+ < 90): Smooth interpolation between regimes
  3. Fully rough (ks+ > 90): E modified by roughness height where ks+ = u_τ * ks / ν (roughness Reynolds number)
Parameters
[in]friction_velocityFriction velocity u_τ
[in]roughness_heightEquivalent sand grain roughness height ks
[in]kinematic_viscosityKinematic viscosity ν
Returns
Roughness-modified log-law coefficient E
Note
This follows the Nikuradse sand grain roughness correlation

Definition at line 198 of file wallfunction.c.

199{
200 // Compute roughness Reynolds number
201 double roughness_reynolds = friction_velocity * roughness_height / kinematic_viscosity;
202
203 double roughness_correction;
204
205 if (roughness_reynolds <= ROUGHNESS_TRANSITION_YPLUS) {
206 // Hydraulically smooth regime: no correction needed
207 roughness_correction = 0.0;
208 }
209 else if (roughness_reynolds < FULLY_ROUGH_YPLUS) {
210 // Transitional regime: smooth interpolation using sine function
211 // This provides a gradual transition between smooth and rough wall behavior
212 double transition_factor = log(roughness_reynolds) - log(ROUGHNESS_TRANSITION_YPLUS);
213 double max_correction = LOGLAW_B - 8.5 + (1.0 / KAPPA) * log(roughness_reynolds);
214
215 roughness_correction = max_correction *
216 sin(0.4258 * (log(roughness_reynolds) - 0.811));
217 }
218 else {
219 // Fully rough regime: maximum correction
220 roughness_correction = LOGLAW_B - 8.5 + (1.0 / KAPPA) * log(roughness_reynolds);
221 }
222
223 // Return E = exp[κ(B - ΔB)]
224 return exp(KAPPA * (LOGLAW_B - roughness_correction));
225}
#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 
)

Computes velocity from log-law for rough walls.

Calculates the tangential velocity at a given wall distance using the roughness-modified log-law of the wall.

APPLICABLE REGIMES:

  • Viscous sublayer (y+ < 11.53): u+ = y+
  • Log-layer (11.53 < y+ < 300): u+ = (1/κ) ln(E * y+)
  • Outer layer (y+ > 300): Returns -1 (invalid, wake region)
Parameters
[in]kinematic_viscosityKinematic viscosity ν
[in]wall_distanceDistance from wall y
[in]friction_velocityFriction velocity u_τ
[in]roughness_heightEquivalent sand grain roughness ks
Returns
Tangential velocity u_t, or -1 if outside valid range
Note
The upper limit y+ < 300 ensures we stay within the log-layer
For y+ > 300, wake effects become important and log-law is invalid

Definition at line 247 of file wallfunction.c.

249{
250 // Normalized wall distance
251 double yplus = friction_velocity * wall_distance / kinematic_viscosity;
252
253 // Threshold values for regime transitions
254 const double viscous_limit = VISCOUS_SUBLAYER_YPLUS;
255 const double loglayer_limit = 300.0;
256
257 double tangential_velocity;
258
259 if (yplus <= viscous_limit) {
260 // Viscous sublayer: linear velocity profile
261 tangential_velocity = friction_velocity * yplus;
262 }
263 else if (yplus <= loglayer_limit) {
264 // Log-layer: logarithmic velocity profile with roughness correction
265 double E = E_coeff(friction_velocity, roughness_height, kinematic_viscosity);
266 tangential_velocity = (friction_velocity / KAPPA) * log(E * yplus);
267 }
268 else {
269 // Outside valid range (wake region or beyond)
270 tangential_velocity = -1.0;
271 }
272
273 return tangential_velocity;
274}
#define VISCOUS_SUBLAYER_YPLUS
Viscous sublayer thickness y+ threshold.
double E_coeff(double friction_velocity, double roughness_height, double kinematic_viscosity)
Computes roughness-modified log-law coefficient E.
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 
)

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

This function computes the residual for Newton-Raphson iteration: f(u_τ) = u_predicted(u_τ) - u_known where u_predicted comes from the log-law or linear law depending on y+.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]known_velocityKnown velocity at distance y
[in]wall_distanceDistance from wall
[in]friction_velocity_guessCurrent guess for u_τ
[in]roughness_heightWall roughness height
Returns
Residual value (should be zero at solution)

Definition at line 294 of file wallfunction.c.

297{
298 double yplus = friction_velocity_guess * wall_distance / kinematic_viscosity;
299 double residual;
300
301 if (yplus <= VISCOUS_SUBLAYER_YPLUS) {
302 // Viscous sublayer: u = u_τ * y+
303 residual = friction_velocity_guess * yplus - known_velocity;
304 }
305 else {
306 // Log-layer: u = (u_τ / κ) * ln(E * y+)
307 double E = E_coeff(friction_velocity_guess, roughness_height, kinematic_viscosity);
308 residual = friction_velocity_guess * (1.0 / KAPPA * log(E * yplus)) - known_velocity;
309 }
310
311 return residual;
312}
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 
)

Numerical derivative of residual function.

Computes df/du_τ using finite differences for Newton-Raphson iteration.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]known_velocityKnown velocity
[in]wall_distanceDistance from wall
[in]friction_velocity_guessCurrent guess for u_τ
[in]roughness_heightWall roughness
Returns
Derivative df/du_τ

Definition at line 326 of file wallfunction.c.

329{
330 const double perturbation = 1.e-7;
331
332 double f_plus = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
333 friction_velocity_guess + perturbation, roughness_height);
334
335 double f_minus = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
336 friction_velocity_guess - perturbation, roughness_height);
337
338 return (f_plus - f_minus) / (2.0 * perturbation);
339}
double f_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
Residual function for friction velocity equation (log-law with roughness)
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 
)

Solves for friction velocity using Newton-Raphson iteration.

Given a known velocity at a known distance from the wall, this function iteratively solves for the friction velocity u_τ that satisfies the roughness-modified log-law or linear law.

ALGORITHM: Newton-Raphson: u_τ^(n+1) = u_τ^n - f(u_τ^n) / f'(u_τ^n) Convergence criterion: |u_τ^(n+1) - u_τ^n| < 1e-7

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]known_velocityVelocity at reference point
[in]wall_distanceDistance from wall to reference point
[in]initial_guessInitial guess for u_τ
[in]roughness_heightWall roughness height
Returns
Converged friction velocity u_τ
Note
Maximum 30 iterations; warns if convergence not achieved
Typical convergence in 3-5 iterations for good initial guess

Definition at line 362 of file wallfunction.c.

365{
366 double friction_velocity = initial_guess;
367 double friction_velocity_old = initial_guess;
368
369 const int max_iterations = 30;
370 const double convergence_tolerance = 1.e-7;
371
372 int iteration;
373 for (iteration = 0; iteration < max_iterations; iteration++) {
374 // Newton-Raphson update
375 double residual = f_hydset(kinematic_viscosity, known_velocity, wall_distance,
376 friction_velocity_old, roughness_height);
377 double derivative = df_hydset(kinematic_viscosity, known_velocity, wall_distance,
378 friction_velocity_old, roughness_height);
379
380 friction_velocity = friction_velocity_old - residual / derivative;
381
382 // Check convergence
383 if (fabs(friction_velocity - friction_velocity_old) < convergence_tolerance) {
384 break;
385 }
386
387 friction_velocity_old = friction_velocity;
388 }
389
390 // Warn if convergence not achieved
391 if (iteration == max_iterations) {
393 "WARNING: u_tau iteration did not converge after %d iterations. "
394 "Final difference: %le\n",
395 iteration, fabs(friction_velocity - friction_velocity_old));
396 }
397
398 return friction_velocity;
399}
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:45
#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:200
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
double df_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
Numerical derivative of residual function.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nu_t()

double nu_t ( double  yplus)

Computes turbulent eddy viscosity ratio (ν_t / ν)

Uses the mixing length model with van Driest damping: ν_t / ν = κ * y+ * [1 - exp(-y+ / A+)]² where A+ ≈ 19 is the damping coefficient.

PHYSICAL INTERPRETATION:

  • Near wall (y+ → 0): ν_t → 0 (viscous effects dominate)
  • Far from wall (y+ >> A+): ν_t ~ κ * y+ (mixing length theory)
  • Damping function smoothly transitions between these limits
Parameters
[in]yplusNormalized wall distance y+ = y * u_τ / ν
Returns
Eddy viscosity ratio ν_t / ν
Note
This is the standard mixing length model with van Driest damping
Valid in the inner layer (y+ < 50-100)

Definition at line 423 of file wallfunction.c.

424{
425 // van Driest damping function: [1 - exp(-y+ / A+)]²
426 double damping_function = 1.0 - exp(-yplus / DAMPING_COEFFICIENT);
427
428 // Mixing length model: ν_t / ν = κ * y+ * D²
429 return KAPPA * yplus * damping_function * damping_function;
430}
#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 
)

Integrates eddy viscosity profile from wall to distance y.

Computes integrals needed for non-equilibrium wall functions: If mode=0: ∫[0 to y] dy / (ν + ν_t) If mode=1: ∫[0 to y] y dy / (ν + ν_t)

These integrals appear in the solution of the momentum equation with pressure gradients in the near-wall region.

NUMERICAL METHOD:

  • Trapezoidal rule with 30 integration points
  • Higher-order correction at endpoints for accuracy
Parameters
[in]kinematic_viscosityKinematic viscosity ν
[in]wall_distanceDistance from wall y
[in]friction_velocityFriction velocity u_τ
[in]integration_mode0 for F integral, 1 for Fy integral
Returns
Value of the integral
Note
Used in Cabot wall function for pressure gradient effects

Definition at line 454 of file wallfunction.c.

456{
457 const int num_points = 30;
458 double step_size = wall_distance / (num_points - 1);
459 double integral_values[num_points];
460
461 // Compute integrand at each point
462 for (int i = 0; i < num_points; i++) {
463 double current_distance = i * step_size;
464 double yplus = current_distance * friction_velocity / kinematic_viscosity;
465 double eddy_viscosity_ratio = nu_t(yplus);
466
467 if (integration_mode == 0) {
468 // Mode 0: integrand = 1 / [(1 + ν_t/ν) * ν]
469 integral_values[i] = 1.0 / ((1.0 + eddy_viscosity_ratio) * kinematic_viscosity);
470 }
471 else {
472 // Mode 1: integrand = y / [(1 + ν_t/ν) * ν]
473 integral_values[i] = current_distance /
474 ((1.0 + eddy_viscosity_ratio) * kinematic_viscosity);
475 }
476 }
477
478 // Trapezoidal rule integration with corrected endpoints
479 double integral_sum = 0.0;
480
481 // Interior points: weight = (f[i-1] + 2*f[i] + f[i+1]) * dy/4
482 for (int i = 1; i < num_points - 1; i++) {
483 integral_sum += (integral_values[i-1] + 2.0 * integral_values[i] +
484 integral_values[i+1]) * 0.25 * step_size;
485 }
486
487 // Endpoint correction for higher accuracy
488 integral_sum += 0.1667 * step_size *
489 (2.0 * integral_values[0] + integral_values[1] +
490 2.0 * integral_values[num_points-1] + integral_values[num_points-2]);
491
492 return integral_sum;
493}
double nu_t(double yplus)
Computes turbulent eddy viscosity ratio (ν_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 
)

Computes wall shear stress with pressure gradient effects.

Solves the integrated momentum equation in the near-wall region: τ_w = (u - dp/dx * F_y) / F_1 where F_1 and F_y are integrals of the effective viscosity profile.

This accounts for non-equilibrium effects due to streamwise pressure gradients.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]friction_velocityFriction velocity u_τ
[in]wall_distanceDistance from wall
[in]velocityVelocity at wall_distance
[in]pressure_gradient_tangentTangential pressure gradient dp/ds
Returns
Wall shear stress τ_w
Note
This is more accurate than equilibrium wall functions in separated flows

Definition at line 517 of file wallfunction.c.

519{
520 // Compute integrated viscosity profiles
521 double F1 = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 0);
522 double Fy = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 1);
523
524 // Apply momentum balance: τ_w * F1 = u - (dp/dx) * Fy
525 return (1.0 / F1) * (velocity - pressure_gradient_tangent * Fy);
526}
double integrate_1(double kinematic_viscosity, double wall_distance, double friction_velocity, int integration_mode)
Integrates eddy viscosity profile from wall to distance y.
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 
)

Computes velocity using Cabot wall function.

Reconstructs velocity from wall shear stress and pressure gradient: u = τ_w * F1 + (dp/dx) * Fy

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]wall_distanceDistance from wall
[in]friction_velocityFriction velocity
[in]pressure_gradient_tangentTangential pressure gradient
[in]wall_shear_stressWall shear stress
Returns
Velocity at wall_distance

Definition at line 541 of file wallfunction.c.

544{
545 double F1 = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 0);
546 double Fy = integrate_1(kinematic_viscosity, wall_distance, friction_velocity, 1);
547
548 return wall_shear_stress * F1 + pressure_gradient_tangent * Fy;
549}
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 
)

Residual function for Cabot wall function.

Computes: f(u_τ) = u_τ - sqrt(|τ_w(u_τ)|) This enforces consistency between u_τ and τ_w.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]velocityVelocity
[in]wall_distanceDistance from wall
[in]friction_velocity_guessGuess for u_τ
[in]pressure_gradient_tangentTangential pressure gradient
[in]pressure_gradient_normalNormal pressure gradient (currently unused)
Returns
Residual value

Definition at line 565 of file wallfunction.c.

568{
569 double wall_shear = taw(kinematic_viscosity, friction_velocity_guess,
570 wall_distance, velocity, pressure_gradient_tangent);
571
572 return friction_velocity_guess - sqrt(fabs(wall_shear));
573}
double taw(double kinematic_viscosity, double friction_velocity, double wall_distance, double velocity, double pressure_gradient_tangent)
Computes wall shear stress with pressure gradient effects.
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 
)

Numerical derivative for Cabot wall function.

Definition at line 578 of file wallfunction.c.

581{
582 const double perturbation = 1.e-7;
583
584 double f_plus = f_Cabot(kinematic_viscosity, velocity, wall_distance,
585 friction_velocity_guess + perturbation,
586 pressure_gradient_tangent, pressure_gradient_normal);
587
588 double f_minus = f_Cabot(kinematic_viscosity, velocity, wall_distance,
589 friction_velocity_guess - perturbation,
590 pressure_gradient_tangent, pressure_gradient_normal);
591
592 return (f_plus - f_minus) / (2.0 * perturbation);
593}
double f_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
Residual function for Cabot wall function.
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 
)

Solves for friction velocity using Cabot wall function.

This non-equilibrium wall function accounts for pressure gradient effects, making it more accurate in separated or strongly accelerating/decelerating flows.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]velocityVelocity at reference point
[in]wall_distanceDistance from wall
[in]initial_guessInitial guess for u_τ
[in]pressure_gradient_tangentTangential pressure gradient
[in]pressure_gradient_normalNormal pressure gradient
[out]friction_velocityConverged friction velocity
[out]wall_shear_velocityWall shear stress for velocity
[out]wall_shear_normalWall shear stress for normal pressure gradient

Definition at line 611 of file wallfunction.c.

615{
616 double current_guess = initial_guess;
617 double new_guess;
618
619 const int max_iterations = 30;
620 const double convergence_tolerance = 1.e-10;
621
622 int iteration;
623 for (iteration = 0; iteration < max_iterations; iteration++) {
624 double residual = f_Cabot(kinematic_viscosity, velocity, wall_distance,
625 current_guess, pressure_gradient_tangent,
626 pressure_gradient_normal);
627
628 double derivative = df_Cabot(kinematic_viscosity, velocity, wall_distance,
629 current_guess, pressure_gradient_tangent,
630 pressure_gradient_normal);
631
632 new_guess = fabs(current_guess - residual / derivative);
633
634 if (fabs(current_guess - new_guess) < convergence_tolerance) {
635 break;
636 }
637
638 current_guess = new_guess;
639 }
640
641 if (fabs(current_guess - new_guess) > 1.e-5 && iteration >= 29) {
642 printf("\n!!!!!!!! Cabot Iteration Failed !!!!!!!!\n");
643 }
644
645 *friction_velocity = new_guess;
646 *wall_shear_velocity = taw(kinematic_viscosity, new_guess, wall_distance,
647 velocity, pressure_gradient_tangent);
648 *wall_shear_normal = taw(kinematic_viscosity, new_guess, wall_distance,
649 0.0, pressure_gradient_normal);
650}
double df_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity_guess, double pressure_gradient_tangent, double pressure_gradient_normal)
Numerical derivative for Cabot wall function.
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 
)

Computes velocity using Werner-Wengle wall function.

Algebraic wall function that provides explicit relation: u+ = y+ for y+ < 11.81 (viscous sublayer) u+ = A * (y+)^B for y+ ≥ 11.81 (power law) where A = 8.3, B = 1/7 are empirical constants.

ADVANTAGES:

  • Explicit (no iteration required)
  • Computationally cheap
  • Reasonable accuracy for equilibrium boundary layers

LIMITATIONS:

  • Less accurate than log-law for high Reynolds numbers
  • No pressure gradient effects
Parameters
[in]kinematic_viscosityKinematic viscosity
[in]wall_distanceDistance from wall
[in]friction_velocityFriction velocity
Returns
Tangential velocity

Definition at line 678 of file wallfunction.c.

680{
681 double yplus = friction_velocity * wall_distance / kinematic_viscosity;
682
683 // Werner-Wengle constants
684 const double power_law_coefficient = 8.3;
685 const double power_law_exponent = 1.0 / 7.0;
686
687 double velocity;
688
689 if (yplus <= VISCOUS_SUBLAYER_YPLUS) {
690 // Viscous sublayer: u+ = y+
691 velocity = yplus * friction_velocity;
692 }
693 else {
694 // Power-law region: u+ = A * (y+)^B
695 velocity = power_law_coefficient * pow(yplus, power_law_exponent) * friction_velocity;
696 }
697
698 return velocity;
699}
Here is the caller graph for this function:

◆ f_Werner()

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

Residual function for Werner-Wengle iteration.

Computes residual: f(u_τ) = u_τ² - g(u, y, ν) where g is derived from the velocity profile inversion.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]velocityKnown velocity
[in]wall_distanceDistance from wall
[in]friction_velocityGuess for friction velocity
Returns
Residual value

Definition at line 713 of file wallfunction.c.

715{
716 const double power_law_coefficient = 8.3;
717 const double power_law_exponent = 1.0 / 7.0;
718
719 // Transition point between viscous and power-law regions
720 double transition_distance = VISCOUS_SUBLAYER_YPLUS * kinematic_viscosity / friction_velocity;
721
722 // Transition velocity
723 double transition_velocity = kinematic_viscosity / (2.0 * transition_distance) *
724 pow(power_law_coefficient, 2.0 / (1.0 - power_law_exponent));
725
726 double residual;
727
728 if (fabs(velocity) <= transition_velocity) {
729 // Viscous sublayer regime
730 residual = friction_velocity * friction_velocity -
731 velocity / wall_distance * kinematic_viscosity;
732 }
733 else {
734 // Power-law regime (more complex inversion formula)
735 double term1 = 0.5 * (1.0 - power_law_exponent) *
736 pow(power_law_coefficient, (1.0 + power_law_exponent) /
737 (1.0 - power_law_exponent)) *
738 pow(kinematic_viscosity / wall_distance, 1.0 + power_law_exponent);
739
740 double term2 = (1.0 + power_law_exponent) / power_law_coefficient *
741 pow(kinematic_viscosity / wall_distance, power_law_exponent) *
742 fabs(velocity);
743
744 residual = friction_velocity * friction_velocity -
745 velocity / fabs(velocity) * pow(term1 + term2, 2.0 / (1.0 + power_law_exponent));
746 }
747
748 return residual;
749}
Here is the caller graph for this function:

◆ df_Werner()

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

Numerical derivative for Werner-Wengle iteration.

Definition at line 754 of file wallfunction.c.

756{
757 const double perturbation = 1.e-7;
758
759 double f_plus = f_Werner(kinematic_viscosity, velocity, wall_distance,
760 friction_velocity + perturbation);
761
762 double f_minus = f_Werner(kinematic_viscosity, velocity, wall_distance,
763 friction_velocity - perturbation);
764
765 return (f_plus - f_minus) / (2.0 * perturbation);
766}
double f_Werner(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
Residual function for Werner-Wengle iteration.
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 
)

Solves for friction velocity using Werner-Wengle wall function.

Parameters
[in]kinematic_viscosityKinematic viscosity
[in]velocityVelocity at reference point
[in]wall_distanceDistance from wall
[in]initial_guessInitial guess for u_τ
Returns
Converged friction velocity

Definition at line 777 of file wallfunction.c.

779{
780 double current_guess = initial_guess;
781 double new_guess;
782
783 const int max_iterations = 20;
784 const double convergence_tolerance = 1.e-7;
785
786 int iteration;
787 for (iteration = 0; iteration < max_iterations; iteration++) {
788 double residual = f_Werner(kinematic_viscosity, velocity, wall_distance, current_guess);
789 double derivative = df_Werner(kinematic_viscosity, velocity, wall_distance, current_guess);
790
791 new_guess = current_guess - residual / derivative;
792
793 if (fabs(current_guess - new_guess) < convergence_tolerance) {
794 break;
795 }
796
797 current_guess = new_guess;
798 }
799
800 if (fabs(current_guess - new_guess) > 1.e-5 && iteration >= 19) {
801 printf("\n!!!!!!!! Werner-Wengle Iteration Failed !!!!!!!!\n");
802 }
803
804 return new_guess;
805}
double df_Werner(double kinematic_viscosity, double velocity, double wall_distance, double friction_velocity)
Numerical derivative for Werner-Wengle iteration.
Here is the call graph for this function:

◆ u_loglaw()

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

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

Simple logarithmic profile: u = (u_τ / κ) * ln((y + y0) / y0) where y0 is a roughness length scale.

Parameters
[in]wall_distanceDistance from wall
[in]friction_velocityFriction velocity
[in]roughness_lengthRoughness length scale y0
Returns
Velocity
Note
This is a simplified model; use u_hydset_roughness for better accuracy

Definition at line 825 of file wallfunction.c.

826{
827 return friction_velocity * (1.0 / KAPPA) * log((roughness_length + wall_distance) / roughness_length);
828}

◆ find_utau_loglaw()

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

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

Explicit inversion: u_τ = κ * u / ln((y + y0) / y0)

Parameters
[in]velocityKnown velocity
[in]wall_distanceDistance from wall
[in]roughness_lengthRoughness length scale
Returns
Friction velocity

Definition at line 840 of file wallfunction.c.

841{
842 return KAPPA * velocity / log((wall_distance + roughness_length) / roughness_length);
843}

◆ sign()

static double sign ( double  value)
static

Returns the sign of a number.

Parameters
[in]valueInput value
Returns
+1 if positive, -1 if negative, 0 if zero

Definition at line 855 of file wallfunction.c.

856{
857 if (value > 0) return 1.0;
858 else if (value < 0) return -1.0;
859 else return 0.0;
860}
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 
)

Applies standard wall function with Werner-Wengle model.

This is a high-level interface that:

  1. Decomposes velocity into normal/tangential components
  2. Applies wall function to tangential velocity
  3. Interpolates normal velocity
  4. Reconstructs total velocity
Parameters
[in]userSimulation context
[in]distance_referenceDistance to reference point
[in]distance_boundaryDistance to boundary point
[in]velocity_wallWall velocity
[in]velocity_referenceReference velocity
[out]velocity_boundaryOutput boundary velocity
[out]friction_velocityOutput friction velocity
[in]normal_xX-component of wall normal
[in]normal_yY-component of wall normal
[in]normal_zZ-component of wall normal

Definition at line 886 of file wallfunction.c.

890{
891 SimCtx *simCtx = user->simCtx;
892 double kinematic_viscosity = 1.0 / simCtx->ren;
893
894 // Decompose velocity into components
895 double delta_u = velocity_reference.x - velocity_wall.x;
896 double delta_v = velocity_reference.y - velocity_wall.y;
897 double delta_w = velocity_reference.z - velocity_wall.z;
898
899 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
900
901 double tangential_u = delta_u - normal_velocity * normal_x;
902 double tangential_v = delta_v - normal_velocity * normal_y;
903 double tangential_w = delta_w - normal_velocity * normal_z;
904
905 double tangential_magnitude = sqrt(tangential_u * tangential_u +
906 tangential_v * tangential_v +
907 tangential_w * tangential_w);
908
909 // Apply Werner-Wengle wall function
910 double utau_guess = 0.05;
911 double tangential_modeled = u_Werner(kinematic_viscosity, distance_boundary, utau_guess);
912
913 // Scale tangential components
914 if (tangential_magnitude > 1.e-10) {
915 tangential_u *= tangential_modeled / tangential_magnitude;
916 tangential_v *= tangential_modeled / tangential_magnitude;
917 tangential_w *= tangential_modeled / tangential_magnitude;
918 }
919 else {
920 tangential_u = tangential_v = tangential_w = 0.0;
921 }
922
923 // Reconstruct velocity: U = U_t + U_n * n
924 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
925 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
926 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
927
928 // Add wall velocity
929 (*velocity_boundary).x += velocity_wall.x;
930 (*velocity_boundary).y += velocity_wall.y;
931 (*velocity_boundary).z += velocity_wall.z;
932}
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:731
PetscReal ren
Definition variables.h:632
The master context for the entire simulation.
Definition variables.h:585
double u_Werner(double kinematic_viscosity, double wall_distance, double friction_velocity)
Computes velocity using Werner-Wengle wall function.
Here is the call 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 
)

Applies log-law wall function with roughness correction.

This is the recommended wall function interface for most applications. It uses the roughness-corrected log-law which is accurate for both smooth and rough walls.

Parameters
[in]userSimulation context
[in]roughness_heightWall roughness height ks
[in]distance_referenceDistance to reference point
[in]distance_boundaryDistance to boundary point
[in]velocity_wallWall velocity (typically zero)
[in]velocity_referenceReference velocity
[out]velocity_boundaryOutput boundary velocity
[out]friction_velocityOutput friction velocity u_τ
[in]normal_xX-component of wall normal
[in]normal_yY-component of wall normal
[in]normal_zZ-component of wall normal
Note
Sets velocity to reference value if y+ > 300 (outside log-layer)

Definition at line 955 of file wallfunction.c.

960{
961 SimCtx *simCtx = user->simCtx;
962 double kinematic_viscosity = 1.0 / simCtx->ren;
963
964 // Decompose velocity
965 double delta_u = velocity_reference.x - velocity_wall.x;
966 double delta_v = velocity_reference.y - velocity_wall.y;
967 double delta_w = velocity_reference.z - velocity_wall.z;
968
969 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
970
971 double tangential_u = delta_u - normal_velocity * normal_x;
972 double tangential_v = delta_v - normal_velocity * normal_y;
973 double tangential_w = delta_w - normal_velocity * normal_z;
974
975 double tangential_magnitude = sqrt(tangential_u * tangential_u +
976 tangential_v * tangential_v +
977 tangential_w * tangential_w);
978
979 // Solve for friction velocity
980 *friction_velocity = find_utau_hydset(kinematic_viscosity, tangential_magnitude,
981 distance_reference, 0.001, roughness_height);
982
983 // Compute wall function velocity
984 double tangential_modeled = u_hydset_roughness(kinematic_viscosity, distance_boundary,
985 *friction_velocity, roughness_height);
986
987 // Check if outside valid range (y+ > 300)
988 if (tangential_modeled < 0.0) {
989 tangential_modeled = tangential_magnitude;
990 }
991
992 // Scale tangential components
993 if (tangential_magnitude > 1.e-10) {
994 tangential_u *= tangential_modeled / tangential_magnitude;
995 tangential_v *= tangential_modeled / tangential_magnitude;
996 tangential_w *= tangential_modeled / tangential_magnitude;
997 }
998 else {
999 tangential_u = tangential_v = tangential_w = 0.0;
1000 }
1001
1002 // Reconstruct total velocity
1003 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
1004 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
1005 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
1006
1007 // Add wall velocity
1008 (*velocity_boundary).x += velocity_wall.x;
1009 (*velocity_boundary).y += velocity_wall.y;
1010 (*velocity_boundary).z += velocity_wall.z;
1011}
double u_hydset_roughness(double kinematic_viscosity, double wall_distance, double friction_velocity, double roughness_height)
Computes velocity from log-law for rough walls.
double find_utau_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double initial_guess, double roughness_height)
Solves for friction velocity using Newton-Raphson iteration.
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 
)

Applies Cabot non-equilibrium wall function with pressure gradients.

This wall function accounts for pressure gradient effects and is most accurate in separated or strongly accelerating/decelerating flows.

Parameters
[in]userSimulation context
[in]roughness_heightWall roughness (currently unused in this version)
[in]distance_referenceDistance to reference point
[in]distance_boundaryDistance to boundary point
[in]velocity_wallWall velocity
[in]velocity_referenceReference velocity
[out]velocity_boundaryOutput boundary velocity
[out]friction_velocityOutput friction velocity
[in]normal_xX-component of wall normal
[in]normal_yY-component of wall normal
[in]normal_zZ-component of wall normal
[in]pressure_gradient_xX-component of pressure gradient
[in]pressure_gradient_yY-component of pressure gradient
[in]pressure_gradient_zZ-component of pressure gradient
[in]iteration_countCurrent iteration count
Note
Only updates friction velocity every 5 iterations for stability
Normal pressure gradient currently set to zero

Definition at line 1038 of file wallfunction.c.

1045{
1046 SimCtx *simCtx = user->simCtx;
1047 double kinematic_viscosity = 1.0 / simCtx->ren;
1048
1049 // Decompose velocity
1050 double delta_u = velocity_reference.x - velocity_wall.x;
1051 double delta_v = velocity_reference.y - velocity_wall.y;
1052 double delta_w = velocity_reference.z - velocity_wall.z;
1053
1054 double normal_velocity = delta_u * normal_x + delta_v * normal_y + delta_w * normal_z;
1055
1056 double tangential_u = delta_u - normal_velocity * normal_x;
1057 double tangential_v = delta_v - normal_velocity * normal_y;
1058 double tangential_w = delta_w - normal_velocity * normal_z;
1059
1060 double tangential_magnitude = sqrt(tangential_u * tangential_u +
1061 tangential_v * tangential_v +
1062 tangential_w * tangential_w);
1063
1064 // Compute tangential pressure gradient
1065 double pressure_gradient_tangent = 0.0;
1066 if (tangential_magnitude > 1.e-10) {
1067 pressure_gradient_tangent = (pressure_gradient_x * tangential_u +
1068 pressure_gradient_y * tangential_v +
1069 pressure_gradient_z * tangential_w) / tangential_magnitude;
1070 }
1071
1072 // Normal pressure gradient (currently set to zero)
1073 double pressure_gradient_normal = 0.0;
1074
1075 // Solve for friction velocity (only on first iteration or periodically)
1076 if (iteration_count == 0 || iteration_count > 4) {
1077 double utau, wall_shear1, wall_shear2;
1078 find_utau_Cabot(kinematic_viscosity, tangential_magnitude, distance_reference,
1079 0.01, pressure_gradient_tangent, pressure_gradient_normal,
1080 &utau, &wall_shear1, &wall_shear2);
1081 *friction_velocity = utau;
1082 }
1083
1084 // Compute wall function velocity with pressure gradient correction
1085 double tangential_modeled = u_Cabot(kinematic_viscosity, distance_boundary,
1086 *friction_velocity, pressure_gradient_tangent,
1087 taw(kinematic_viscosity, *friction_velocity,
1088 distance_reference, tangential_magnitude,
1089 pressure_gradient_tangent));
1090
1091 // Scale tangential components
1092 if (tangential_magnitude > 1.e-10) {
1093 tangential_u *= tangential_modeled / tangential_magnitude;
1094 tangential_v *= tangential_modeled / tangential_magnitude;
1095 tangential_w *= tangential_modeled / tangential_magnitude;
1096 }
1097 else {
1098 tangential_u = tangential_v = tangential_w = 0.0;
1099 }
1100
1101 // Reconstruct total velocity
1102 (*velocity_boundary).x = tangential_u + (distance_boundary / distance_reference) * normal_velocity * normal_x;
1103 (*velocity_boundary).y = tangential_v + (distance_boundary / distance_reference) * normal_velocity * normal_y;
1104 (*velocity_boundary).z = tangential_w + (distance_boundary / distance_reference) * normal_velocity * normal_z;
1105
1106 // Add wall velocity
1107 (*velocity_boundary).x += velocity_wall.x;
1108 (*velocity_boundary).y += velocity_wall.y;
1109 (*velocity_boundary).z += velocity_wall.z;
1110}
double u_Cabot(double kinematic_viscosity, double wall_distance, double friction_velocity, double pressure_gradient_tangent, double wall_shear_stress)
Computes velocity using Cabot wall function.
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)
Solves for friction velocity using Cabot wall function.
Here is the call graph for this function: