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

Implements numerical filtering schemes for Large Eddy Simulation (LES). More...

#include "Filter.h"
#include <math.h>
Include dependency graph for Filter.c:

Go to the source code of this file.

Macros

#define __FUNCT__   "ApplyLESTestFilter"
 

Functions

static double ApplySimpsonRuleHomogeneousFilter (double values[3][3][3])
 Internal helper implementation: ApplySimpsonRuleHomogeneousFilter().
 
static double ApplyVolumeWeightedBoxFilter (double values[3][3][3], double weights[3][3][3])
 Internal helper implementation: ApplyVolumeWeightedBoxFilter().
 
double ApplyLESTestFilter (const SimCtx *simCtx, double values[3][3][3], double weights[3][3][3])
 Internal helper implementation: ApplyLESTestFilter().
 

Detailed Description

Implements numerical filtering schemes for Large Eddy Simulation (LES).

This file contains the functions necessary to apply a "test filter" to the resolved velocity field, which is a core component of the dynamic Smagorinsky turbulence model. The choice of filter (e.g., a general 3D box filter or a specialized 2D homogeneous filter) is determined by the simulation's configuration.

Definition in file Filter.c.

Macro Definition Documentation

◆ __FUNCT__

#define __FUNCT__   "ApplyLESTestFilter"

Definition at line 118 of file Filter.c.

Function Documentation

◆ ApplySimpsonRuleHomogeneousFilter()

static double ApplySimpsonRuleHomogeneousFilter ( double  values[3][3][3])
static

Internal helper implementation: ApplySimpsonRuleHomogeneousFilter().

Local to this translation unit.

Definition at line 22 of file Filter.c.

23{
24 // The stencil only uses the central j-plane (j-index = 1, corresponding to the y-direction).
25 // The formula is a weighted sum of the 9 points in that plane.
26 const double corners = values[0][1][0] + values[2][1][0] + values[0][1][2] + values[2][1][2]; // 4 corner points
27 const double edges = values[0][1][1] + values[1][1][0] + values[2][1][1] + values[1][1][2]; // 4 edge-center points
28 const double center = values[1][1][1]; // 1 center point
29
30 // The weights (1, 4, 16) and normalization factor (36) come from the 2D Simpson's rule.
31 return (corners + 4.0 * edges + 16.0 * center) / 36.0;
32}
Here is the caller graph for this function:

◆ ApplyVolumeWeightedBoxFilter()

static double ApplyVolumeWeightedBoxFilter ( double  values[3][3][3],
double  weights[3][3][3] 
)
static

Internal helper implementation: ApplyVolumeWeightedBoxFilter().

Local to this translation unit.

Definition at line 39 of file Filter.c.

40{
41 // v1...v8 store the sum of (value * weight) for each of the 8 sub-cubes.
42 // w1...w8 store the sum of (weight) for each of the 8 sub-cubes.
43 double v1, v2, v3, v4, v5, v6, v7, v8;
44 double w1, w2, w3, w4, w5, w6, w7, w8;
45
46 // --- Calculations for the 4 sub-cubes on the bottom layer (k-indices 0 and 1) ---
47
48 // Bottom-Back-Left sub-cube (i-indices: 0,1; j-indices: 0,1; k-indices: 0,1)
49 v1 = ( values[0][0][0]*weights[0][0][0] + values[1][0][0]*weights[1][0][0] + values[0][1][0]*weights[0][1][0] + values[1][1][0]*weights[1][1][0] +
50 values[0][0][1]*weights[0][0][1] + values[1][0][1]*weights[1][0][1] + values[0][1][1]*weights[0][1][1] + values[1][1][1]*weights[1][1][1] );
51 w1 = ( weights[0][0][0] + weights[1][0][0] + weights[0][1][0] + weights[1][1][0] +
52 weights[0][0][1] + weights[1][0][1] + weights[0][1][1] + weights[1][1][1] );
53
54 // Bottom-Back-Right sub-cube (i-indices: 1,2; j-indices: 0,1; k-indices: 0,1)
55 v2 = ( values[1][0][0]*weights[1][0][0] + values[2][0][0]*weights[2][0][0] + values[1][1][0]*weights[1][1][0] + values[2][1][0]*weights[2][1][0] +
56 values[1][0][1]*weights[1][0][1] + values[2][0][1]*weights[2][0][1] + values[1][1][1]*weights[1][1][1] + values[2][1][1]*weights[2][1][1] );
57 w2 = ( weights[1][0][0] + weights[2][0][0] + weights[1][1][0] + weights[2][1][0] +
58 weights[1][0][1] + weights[2][0][1] + weights[1][1][1] + weights[2][1][1] );
59
60 // Bottom-Front-Left sub-cube (i-indices: 0,1; j-indices: 1,2; k-indices: 0,1)
61 v3 = ( values[0][1][0]*weights[0][1][0] + values[1][1][0]*weights[1][1][0] + values[0][2][0]*weights[0][2][0] + values[1][2][0]*weights[1][2][0] +
62 values[0][1][1]*weights[0][1][1] + values[1][1][1]*weights[1][1][1] + values[0][2][1]*weights[0][2][1] + values[1][2][1]*weights[1][2][1] );
63 w3 = ( weights[0][1][0] + weights[1][1][0] + weights[0][2][0] + weights[1][2][0] +
64 weights[0][1][1] + weights[1][1][1] + weights[0][2][1] + weights[1][2][1] );
65
66 // Bottom-Front-Right sub-cube (i-indices: 1,2; j-indices: 1,2; k-indices: 0,1)
67 v4 = ( values[1][1][0]*weights[1][1][0] + values[2][1][0]*weights[2][1][0] + values[1][2][0]*weights[1][2][0] + values[2][2][0]*weights[2][2][0] +
68 values[1][1][1]*weights[1][1][1] + values[2][1][1]*weights[2][1][1] + values[1][2][1]*weights[1][2][1] + values[2][2][1]*weights[2][2][1] );
69 w4 = ( weights[1][1][0] + weights[2][1][0] + weights[1][2][0] + weights[2][2][0] +
70 weights[1][1][1] + weights[2][1][1] + weights[1][2][1] + weights[2][2][1] );
71
72
73 // --- Calculations for the 4 sub-cubes on the top layer (k-indices 1 and 2) ---
74
75 // Top-Back-Left sub-cube (i-indices: 0,1; j-indices: 0,1; k-indices: 1,2)
76 v5 = ( values[0][0][1]*weights[0][0][1] + values[1][0][1]*weights[1][0][1] + values[0][1][1]*weights[0][1][1] + values[1][1][1]*weights[1][1][1] +
77 values[0][0][2]*weights[0][0][2] + values[1][0][2]*weights[1][0][2] + values[0][1][2]*weights[0][1][2] + values[1][1][2]*weights[1][1][2] );
78 w5 = ( weights[0][0][1] + weights[1][0][1] + weights[0][1][1] + weights[1][1][1] +
79 weights[0][0][2] + weights[1][0][2] + weights[0][1][2] + weights[1][1][2] );
80
81 // Top-Back-Right sub-cube (i-indices: 1,2; j-indices: 0,1; k-indices: 1,2)
82 v6 = ( values[1][0][1]*weights[1][0][1] + values[2][0][1]*weights[2][0][1] + values[1][1][1]*weights[1][1][1] + values[2][1][1]*weights[2][1][1] +
83 values[1][0][2]*weights[1][0][2] + values[2][0][2]*weights[2][0][2] + values[1][1][2]*weights[1][1][2] + values[2][1][2]*weights[2][1][2] );
84 w6 = ( weights[1][0][1] + weights[2][0][1] + weights[1][1][1] + weights[2][1][1] +
85 weights[1][0][2] + weights[2][0][2] + weights[1][1][2] + weights[2][1][2] );
86
87 // Top-Front-Left sub-cube (i-indices: 0,1; j-indices: 1,2; k-indices: 1,2)
88 v7 = ( values[0][1][1]*weights[0][1][1] + values[1][1][1]*weights[1][1][1] + values[0][2][1]*weights[0][2][1] + values[1][2][1]*weights[1][2][1] +
89 values[0][1][2]*weights[0][1][2] + values[1][1][2]*weights[1][1][2] + values[0][2][2]*weights[0][2][2] + values[1][2][2]*weights[1][2][2] );
90 w7 = ( weights[0][1][1] + weights[1][1][1] + weights[0][2][1] + weights[1][2][1] +
91 weights[0][1][2] + weights[1][1][2] + weights[0][2][2] + weights[1][2][2] );
92
93 // Top-Front-Right sub-cube (i-indices: 1,2; j-indices: 1,2; k-indices: 1,2)
94 v8 = ( values[1][1][1]*weights[1][1][1] + values[2][1][1]*weights[2][1][1] + values[1][2][1]*weights[1][2][1] + values[2][2][1]*weights[2][2][1] +
95 values[1][1][2]*weights[1][1][2] + values[2][1][2]*weights[2][1][2] + values[1][2][2]*weights[1][2][2] + values[2][2][2]*weights[2][2][2] );
96 w8 = ( weights[1][1][1] + weights[2][1][1] + weights[1][2][1] + weights[2][2][1] +
97 weights[1][1][2] + weights[2][1][2] + weights[1][2][2] + weights[2][2][2] );
98
99 // Sum the contributions from all 8 octants.
100 double total_weighted_value = v1+v2+v3+v4+v5+v6+v7+v8;
101 double total_weight = w1+w2+w3+w4+w5+w6+w7+w8;
102
103 // Production safety check: avoid division by zero if all weights are zero
104 // (e.g., if the stencil is entirely inside a solid body).
105 if (fabs(total_weight) < 1.0e-12) {
106 return 0.0;
107 }
108
109 return total_weighted_value / total_weight;
110}
Here is the caller graph for this function:

◆ ApplyLESTestFilter()

double ApplyLESTestFilter ( const SimCtx simCtx,
double  values[3][3][3],
double  weights[3][3][3] 
)

Internal helper implementation: ApplyLESTestFilter().

Applies a numerical "test filter" to a 3x3x3 stencil of data points.

Local to this translation unit.

Definition at line 123 of file Filter.c.

124{
125 // This function acts as a dispatcher. It reads the simulation configuration
126 // and calls the appropriate internal filtering routine.
127 if (simCtx->testfilter_ik) {
128 // If the "-testfilter_ik" flag is set, it indicates that the simulation
129 // is homogeneous in the i and k directions, so we use the specialized,
130 // more accurate Simpson's rule filter. The `weights` are ignored in this case.
132 } else {
133 // This is the default case for general, non-uniform, curvilinear grids.
134 // The volume-weighted box filter is used to ensure correct averaging.
135 return ApplyVolumeWeightedBoxFilter(values, weights);
136 }
137}
static double ApplyVolumeWeightedBoxFilter(double values[3][3][3], double weights[3][3][3])
Internal helper implementation: ApplyVolumeWeightedBoxFilter().
Definition Filter.c:39
static double ApplySimpsonRuleHomogeneousFilter(double values[3][3][3])
Internal helper implementation: ApplySimpsonRuleHomogeneousFilter().
Definition Filter.c:22
PetscInt testfilter_ik
Definition variables.h:735
Here is the call graph for this function:
Here is the caller graph for this function: