Computes the dynamic Smagorinsky constant (Cs) for the LES model.
This function implements the dynamic procedure for calculating the Smagorinsky constant at each grid point. It involves test-filtering the velocity field and strain rate tensor to determine the constant locally. The calculation can be computationally expensive and is typically run less frequently than every time step, controlled by simCtx->dynamic_freq.
24{
25 PetscErrorCode ierr;
27
28 PetscFunctionBeginUser;
30
31
32
33
34
36 ierr = VecSet(user->
CS, 0.0); CHKERRQ(ierr);
39 PetscFunctionReturn(0);
40 }
41
42
43
44 if (simCtx->
les == 1) {
46 ierr = VecSet(user->
CS, simCtx->
Const_CS); CHKERRQ(ierr);
48 PetscFunctionReturn(0);
49 }
50
51
52
53 DM da = user->
da, fda = user->
fda;
54 DMDALocalInfo info;
55 PetscInt i, j, k, p, q, r;
56 PetscInt xs, xe, ys, ye, zs, ze;
57 PetscInt mx, my, mz;
58 PetscInt lxs, lxe, lys, lye, lzs, lze;
59
60
61
62 Vec lSx, lSy, lSz, lS_abs;
63 Vec lLM, lMM;
64
65
66 ierr = DMDAGetLocalInfo(da, &info); CHKERRQ(ierr);
67 mx = info.mx; my = info.my; mz = info.mz;
68 xs = info.xs; xe = xs + info.xm;
69 ys = info.ys; ye = ys + info.ym;
70 zs = info.zs; ze = zs + info.zm;
71
72
73 lxs = xs; lxe = xe; lys = ys; lye = ye; lzs = zs; lze = ze;
74 if (xs==0) lxs = xs+1;
75 if (ys==0) lys = ys+1;
76 if (zs==0) lzs = zs+1;
77 if (xe==mx) lxe = xe-1;
78 if (ye==my) lye = ye-1;
79 if (ze==mz) lze = ze-1;
80
81
82 ierr = VecDuplicate(user->
lUcont, &lSx); CHKERRQ(ierr);
83 ierr = VecDuplicate(user->
lUcont, &lSy); CHKERRQ(ierr);
84 ierr = VecDuplicate(user->
lUcont, &lSz); CHKERRQ(ierr);
85 ierr = VecDuplicate(user->
lP, &lS_abs); CHKERRQ(ierr);
86 ierr = VecDuplicate(user->
lP, &lLM); CHKERRQ(ierr);
87 ierr = VecDuplicate(user->
lP, &lMM); CHKERRQ(ierr);
88 ierr = VecSet(lLM, 0.0); CHKERRQ(ierr);
89 ierr = VecSet(lMM, 0.0); CHKERRQ(ierr);
90
91
92 Cmpnts ***ucat, ***csi, ***eta, ***zet;
93 PetscReal ***nvert, ***Cs_arr, ***aj, ***S_abs_arr, ***LM_arr, ***MM_arr;
94 Cmpnts ***Sx_arr, ***Sy_arr, ***Sz_arr;
95
96 ierr = DMDAVecGetArray(fda, user->
lUcat, &ucat); CHKERRQ(ierr);
97 ierr = DMDAVecGetArrayRead(fda, user->
lCsi, (
Cmpnts***)&csi); CHKERRQ(ierr);
98 ierr = DMDAVecGetArrayRead(fda, user->
lEta, (
Cmpnts***)&eta); CHKERRQ(ierr);
99 ierr = DMDAVecGetArrayRead(fda, user->
lZet, (
Cmpnts***)&zet); CHKERRQ(ierr);
100 ierr = DMDAVecGetArrayRead(da, user->
lNvert, (PetscReal***)&nvert); CHKERRQ(ierr);
101 ierr = DMDAVecGetArrayRead(da, user->
lAj, (PetscReal***)&aj); CHKERRQ(ierr);
102 ierr = DMDAVecGetArray(da, user->
CS, &Cs_arr); CHKERRQ(ierr);
103
104 ierr = DMDAVecGetArray(fda, lSx, &Sx_arr); CHKERRQ(ierr);
105 ierr = DMDAVecGetArray(fda, lSy, &Sy_arr); CHKERRQ(ierr);
106 ierr = DMDAVecGetArray(fda, lSz, &Sz_arr); CHKERRQ(ierr);
107 ierr = DMDAVecGetArray(da, lS_abs, &S_abs_arr); CHKERRQ(ierr);
108 ierr = DMDAVecGetArray(da, lLM, &LM_arr); CHKERRQ(ierr);
109 ierr = DMDAVecGetArray(da, lMM, &MM_arr); CHKERRQ(ierr);
110
111
112 for (k=lzs; k<lze; k++)
113 for (j=lys; j<lye; j++)
114 for (i=lxs; i<lxe; i++) {
115 if( nvert[k][j][i] > 1.1) continue;
116
119
121 double Sxy = 0.5 * (dudx.
y + dvdx.
x);
122 double Sxz = 0.5 * (dudx.
z + dwdx.
x);
124 double Syz = 0.5 * (dvdx.
z + dwdx.
y);
126 double Syx = Sxy, Szx = Sxz, Szy = Syz;
127
128 S_abs_arr[k][j][i] = sqrt( 2.0 * (Sxx*Sxx + Sxy*Sxy + Sxz*Sxz +
129 Syx*Syx + Syy*Syy + Syz*Syz +
130 Szx*Szx + Szy*Szy + Szz*Szz) );
131
132
133 Sx_arr[k][j][i] = dudx;
134 Sy_arr[k][j][i] = dvdx;
135 Sz_arr[k][j][i] = dwdx;
136 }
137
138
139 for (k=lzs; k<lze; k++)
140 for (j=lys; j<lye; j++)
141 for (i=lxs; i<lxe; i++) {
142 if(nvert[k][j][i] > 1.1) {
143 LM_arr[k][j][i] = 0.0;
144 MM_arr[k][j][i] = 0.0;
145 continue;
146 }
147
148
149 double u[3][3][3], v[3][3][3], w[3][3][3];
150 double S_abs_stencil[3][3][3];
151 double S11[3][3][3], S12[3][3][3], S13[3][3][3];
152 double S22[3][3][3], S23[3][3][3], S33[3][3][3];
153 double weights[3][3][3];
154
155 for(r=-1; r<=1; r++)
156 for(q=-1; q<=1; q++)
157 for(p=-1; p<=1; p++) {
158 int R=r+1, Q=q+1, P=p+1;
159 int KK=k+r, JJ=j+q, II=i+p;
160
161 u[R][Q][P] = ucat[KK][JJ][II].
x;
162 v[R][Q][P] = ucat[KK][JJ][II].
y;
163 w[R][Q][P] = ucat[KK][JJ][II].
z;
164
165
166 S11[R][Q][P] = Sx_arr[KK][JJ][II].
x;
167 S12[R][Q][P] = 0.5 * (Sx_arr[KK][JJ][II].
y + Sy_arr[KK][JJ][II].
x);
168 S13[R][Q][P] = 0.5 * (Sx_arr[KK][JJ][II].
z + Sz_arr[KK][JJ][II].
x);
169 S22[R][Q][P] = Sy_arr[KK][JJ][II].
y;
170 S23[R][Q][P] = 0.5 * (Sy_arr[KK][JJ][II].
z + Sz_arr[KK][JJ][II].
y);
171 S33[R][Q][P] = Sz_arr[KK][JJ][II].
z;
172
173 S_abs_stencil[R][Q][P] = S_abs_arr[KK][JJ][II];
174 weights[R][Q][P] = aj[KK][JJ][II];
175 }
176
177
181
188
190
191
192 double uu[3][3][3], uv[3][3][3], uw[3][3][3], vv[3][3][3], vw[3][3][3], ww[3][3][3];
193 for(r=0; r<3; r++) for(q=0; q<3; q++) for(p=0; p<3; p++) {
194 uu[r][q][p] = u[r][q][p] * u[r][q][p];
195 uv[r][q][p] = u[r][q][p] * v[r][q][p];
196 uw[r][q][p] = u[r][q][p] * w[r][q][p];
197 vv[r][q][p] = v[r][q][p] * v[r][q][p];
198 vw[r][q][p] = v[r][q][p] * w[r][q][p];
199 ww[r][q][p] = w[r][q][p] * w[r][q][p];
200 }
207
208
209 double L11 = uu_filt - u_filt * u_filt;
210 double L12 = uv_filt - u_filt * v_filt;
211 double L13 = uw_filt - u_filt * w_filt;
212 double L22 = vv_filt - v_filt * v_filt;
213 double L23 = vw_filt - v_filt * w_filt;
214 double L33 = ww_filt - w_filt * w_filt;
215
216
217 double grid_filter_width, test_filter_width;
219 grid_filter_width = pow(1.0 / aj[k][j][i], 1.0/3.0);
220 test_filter_width = 2.0 * grid_filter_width;
221
222 double alpha = pow(test_filter_width / grid_filter_width, 2.0);
223
224 double M11 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S11_filt - S_abs_filt * S11_filt);
225 double M12 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S12_filt - S_abs_filt * S12_filt);
226 double M13 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S13_filt - S_abs_filt * S13_filt);
227 double M22 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S22_filt - S_abs_filt * S22_filt);
228 double M23 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S23_filt - S_abs_filt * S23_filt);
229 double M33 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S33_filt - S_abs_filt * S33_filt);
230
231
232 LM_arr[k][j][i] = L11*M11 + 2*L12*M12 + 2*L13*M13 + L22*M22 + 2*L23*M23 + L33*M33;
233 MM_arr[k][j][i] = M11*M11 + 2*M12*M12 + 2*M13*M13 + M22*M22 + 2*M23*M23 + M33*M33;
234 }
235
236
237
238
239
240
241
242
243 for (k=lzs; k<lze; k++)
244 for (j=lys; j<lye; j++)
245 for (i=lxs; i<lxe; i++) {
246 if(nvert[k][j][i] > 1.1) {
247 Cs_arr[k][j][i] = 0.0;
248 continue;
249 }
250
251 double C_sq = 0.0;
253 C_sq = LM_arr[k][j][i] / MM_arr[k][j][i];
254 }
255
256
257 double Cs_val = (C_sq > 0.0) ? sqrt(C_sq) : 0.0;
258 Cs_arr[k][j][i] = PetscMin(PetscMax(Cs_val, 0.0), simCtx->
max_cs);
259 }
260
261
262
263
264 ierr = DMDAVecRestoreArray(fda, user->
lUcat, &ucat); CHKERRQ(ierr);
265 ierr = DMDAVecRestoreArrayRead(fda, user->
lCsi, (
Cmpnts***)&csi); CHKERRQ(ierr);
266 ierr = DMDAVecRestoreArrayRead(fda, user->
lEta, (
Cmpnts***)&eta); CHKERRQ(ierr);
267 ierr = DMDAVecRestoreArrayRead(fda, user->
lZet, (
Cmpnts***)&zet); CHKERRQ(ierr);
268 ierr = DMDAVecRestoreArrayRead(da, user->
lNvert, (PetscReal***)&nvert); CHKERRQ(ierr);
269 ierr = DMDAVecRestoreArrayRead(da, user->
lAj, (PetscReal***)&aj); CHKERRQ(ierr);
270 ierr = DMDAVecRestoreArray(da, user->
CS, &Cs_arr); CHKERRQ(ierr);
271 ierr = DMDAVecRestoreArray(fda, lSx, &Sx_arr); CHKERRQ(ierr);
272 ierr = DMDAVecRestoreArray(fda, lSy, &Sy_arr); CHKERRQ(ierr);
273 ierr = DMDAVecRestoreArray(fda, lSz, &Sz_arr); CHKERRQ(ierr);
274 ierr = DMDAVecRestoreArray(da, lS_abs, &S_abs_arr); CHKERRQ(ierr);
275 ierr = DMDAVecRestoreArray(da, lLM, &LM_arr); CHKERRQ(ierr);
276 ierr = DMDAVecRestoreArray(da, lMM, &MM_arr); CHKERRQ(ierr);
277
278
279 ierr = VecDestroy(&lSx); CHKERRQ(ierr);
280 ierr = VecDestroy(&lSy); CHKERRQ(ierr);
281 ierr = VecDestroy(&lSz); CHKERRQ(ierr);
282 ierr = VecDestroy(&lS_abs); CHKERRQ(ierr);
283 ierr = VecDestroy(&lLM); CHKERRQ(ierr);
284 ierr = VecDestroy(&lMM); CHKERRQ(ierr);
285
286
287 ierr = DMGlobalToLocalBegin(da, user->
CS, INSERT_VALUES, user->
lCs); CHKERRQ(ierr);
288 ierr = DMGlobalToLocalEnd(da, user->
CS, INSERT_VALUES, user->
lCs); CHKERRQ(ierr);
289
290 PetscReal max_norm;
291 ierr = VecMax(user->
CS, NULL, &max_norm); CHKERRQ(ierr);
293
295 PetscFunctionReturn(0);
296}
double ApplyLESTestFilter(const SimCtx *simCtx, double values[3][3][3], double weights[3][3][3])
Applies a numerical "test filter" to a 3x3x3 stencil of data points.
PetscErrorCode ComputeCellCharacteristicLengthScale(PetscReal ajc, Cmpnts csi, Cmpnts eta, Cmpnts zet, double *dx, double *dy, double *dz)
Computes characteristic length scales (dx, dy, dz) for a curvilinear cell.
#define GLOBAL
Scope for global logging across all processes.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
@ LOG_INFO
Informational messages about program execution.
@ LOG_DEBUG
Detailed debugging information.
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
PetscErrorCode ComputeVectorFieldDerivatives(UserCtx *user, PetscInt i, PetscInt j, PetscInt k, Cmpnts ***field_data, Cmpnts *dudx, Cmpnts *dvdx, Cmpnts *dwdx)
Computes the derivatives of a cell-centered vector field at a specific grid point.
SimCtx * simCtx
Back-pointer to the master simulation context.
A 3D point or vector with PetscScalar components.
The master context for the entire simulation.