Computes the dynamic Smagorinsky constant (Cs) for the LES model.
Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/les.h.
43{
44 PetscErrorCode ierr;
46
47 PetscFunctionBeginUser;
49
50
51
52
53
55 ierr = VecSet(user->
CS, 0.0); CHKERRQ(ierr);
59 PetscFunctionReturn(0);
60 }
61
62
63
66 ierr = VecSet(user->
CS, simCtx->
Const_CS); CHKERRQ(ierr);
69 PetscFunctionReturn(0);
70 }
71
72
73
74 DM da = user->
da, fda = user->
fda;
75 DMDALocalInfo info;
76 PetscInt i, j, k, p, q, r;
77 PetscInt xs, xe, ys, ye, zs, ze;
78 PetscInt mx, my, mz;
79 PetscInt lxs, lxe, lys, lye, lzs, lze;
80
81
82
83 Vec lSx, lSy, lSz, lS_abs;
84 Vec lLM, lMM;
85
86
87 ierr = DMDAGetLocalInfo(da, &info); CHKERRQ(ierr);
88 mx = info.mx; my = info.my; mz = info.mz;
89 xs = info.xs; xe = xs + info.xm;
90 ys = info.ys; ye = ys + info.ym;
91 zs = info.zs; ze = zs + info.zm;
92
93
94 lxs = xs; lxe = xe; lys = ys; lye = ye; lzs = zs; lze = ze;
95 if (xs==0) lxs = xs+1;
96 if (ys==0) lys = ys+1;
97 if (zs==0) lzs = zs+1;
98 if (xe==mx) lxe = xe-1;
99 if (ye==my) lye = ye-1;
100 if (ze==mz) lze = ze-1;
101
102
103 ierr = VecDuplicate(user->
lUcont, &lSx); CHKERRQ(ierr);
104 ierr = VecDuplicate(user->
lUcont, &lSy); CHKERRQ(ierr);
105 ierr = VecDuplicate(user->
lUcont, &lSz); CHKERRQ(ierr);
106 ierr = VecDuplicate(user->
lP, &lS_abs); CHKERRQ(ierr);
107 ierr = VecDuplicate(user->
lP, &lLM); CHKERRQ(ierr);
108 ierr = VecDuplicate(user->
lP, &lMM); CHKERRQ(ierr);
109 ierr = VecSet(lLM, 0.0); CHKERRQ(ierr);
110 ierr = VecSet(lMM, 0.0); CHKERRQ(ierr);
111
112
113 Cmpnts ***ucat, ***csi, ***eta, ***zet;
114 PetscReal ***nvert, ***Cs_arr, ***aj, ***S_abs_arr, ***LM_arr, ***MM_arr;
115 Cmpnts ***Sx_arr, ***Sy_arr, ***Sz_arr;
116
117 ierr = DMDAVecGetArray(fda, user->
lUcat, &ucat); CHKERRQ(ierr);
118 ierr = DMDAVecGetArrayRead(fda, user->
lCsi, (
Cmpnts***)&csi); CHKERRQ(ierr);
119 ierr = DMDAVecGetArrayRead(fda, user->
lEta, (
Cmpnts***)&eta); CHKERRQ(ierr);
120 ierr = DMDAVecGetArrayRead(fda, user->
lZet, (
Cmpnts***)&zet); CHKERRQ(ierr);
121 ierr = DMDAVecGetArrayRead(da, user->
lNvert, (PetscReal***)&nvert); CHKERRQ(ierr);
122 ierr = DMDAVecGetArrayRead(da, user->
lAj, (PetscReal***)&aj); CHKERRQ(ierr);
123 ierr = DMDAVecGetArray(da, user->
CS, &Cs_arr); CHKERRQ(ierr);
124
125 ierr = DMDAVecGetArray(fda, lSx, &Sx_arr); CHKERRQ(ierr);
126 ierr = DMDAVecGetArray(fda, lSy, &Sy_arr); CHKERRQ(ierr);
127 ierr = DMDAVecGetArray(fda, lSz, &Sz_arr); CHKERRQ(ierr);
128 ierr = DMDAVecGetArray(da, lS_abs, &S_abs_arr); CHKERRQ(ierr);
129 ierr = DMDAVecGetArray(da, lLM, &LM_arr); CHKERRQ(ierr);
130 ierr = DMDAVecGetArray(da, lMM, &MM_arr); CHKERRQ(ierr);
131
132
133 for (k=lzs; k<lze; k++)
134 for (j=lys; j<lye; j++)
135 for (i=lxs; i<lxe; i++) {
136 if( nvert[k][j][i] > 1.1) continue;
137
140
142 double Sxy = 0.5 * (dudx.
y + dvdx.
x);
143 double Sxz = 0.5 * (dudx.
z + dwdx.
x);
145 double Syz = 0.5 * (dvdx.
z + dwdx.
y);
147 double Syx = Sxy, Szx = Sxz, Szy = Syz;
148
149 S_abs_arr[k][j][i] = sqrt( 2.0 * (Sxx*Sxx + Sxy*Sxy + Sxz*Sxz +
150 Syx*Syx + Syy*Syy + Syz*Syz +
151 Szx*Szx + Szy*Szy + Szz*Szz) );
152
153
154 Sx_arr[k][j][i] = dudx;
155 Sy_arr[k][j][i] = dvdx;
156 Sz_arr[k][j][i] = dwdx;
157 }
158
159
160 for (k=lzs; k<lze; k++)
161 for (j=lys; j<lye; j++)
162 for (i=lxs; i<lxe; i++) {
163 if(nvert[k][j][i] > 1.1) {
164 LM_arr[k][j][i] = 0.0;
165 MM_arr[k][j][i] = 0.0;
166 continue;
167 }
168
169
170 double u[3][3][3], v[3][3][3], w[3][3][3];
171 double S_abs_stencil[3][3][3];
172 double S11[3][3][3], S12[3][3][3], S13[3][3][3];
173 double S22[3][3][3], S23[3][3][3], S33[3][3][3];
174 double weights[3][3][3];
175
176 for(r=-1; r<=1; r++)
177 for(q=-1; q<=1; q++)
178 for(p=-1; p<=1; p++) {
179 int R=r+1, Q=q+1, P=p+1;
180 int KK=k+r, JJ=j+q, II=i+p;
181
182 u[R][Q][P] = ucat[KK][JJ][II].
x;
183 v[R][Q][P] = ucat[KK][JJ][II].
y;
184 w[R][Q][P] = ucat[KK][JJ][II].
z;
185
186
187 S11[R][Q][P] = Sx_arr[KK][JJ][II].
x;
188 S12[R][Q][P] = 0.5 * (Sx_arr[KK][JJ][II].
y + Sy_arr[KK][JJ][II].
x);
189 S13[R][Q][P] = 0.5 * (Sx_arr[KK][JJ][II].
z + Sz_arr[KK][JJ][II].
x);
190 S22[R][Q][P] = Sy_arr[KK][JJ][II].
y;
191 S23[R][Q][P] = 0.5 * (Sy_arr[KK][JJ][II].
z + Sz_arr[KK][JJ][II].
y);
192 S33[R][Q][P] = Sz_arr[KK][JJ][II].
z;
193
194 S_abs_stencil[R][Q][P] = S_abs_arr[KK][JJ][II];
195 weights[R][Q][P] = aj[KK][JJ][II];
196 }
197
198
202
209
211
212
213 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];
214 for(r=0; r<3; r++) for(q=0; q<3; q++) for(p=0; p<3; p++) {
215 uu[r][q][p] = u[r][q][p] * u[r][q][p];
216 uv[r][q][p] = u[r][q][p] * v[r][q][p];
217 uw[r][q][p] = u[r][q][p] * w[r][q][p];
218 vv[r][q][p] = v[r][q][p] * v[r][q][p];
219 vw[r][q][p] = v[r][q][p] * w[r][q][p];
220 ww[r][q][p] = w[r][q][p] * w[r][q][p];
221 }
228
229
230 double L11 = uu_filt - u_filt * u_filt;
231 double L12 = uv_filt - u_filt * v_filt;
232 double L13 = uw_filt - u_filt * w_filt;
233 double L22 = vv_filt - v_filt * v_filt;
234 double L23 = vw_filt - v_filt * w_filt;
235 double L33 = ww_filt - w_filt * w_filt;
236
237
238 double grid_filter_width, test_filter_width;
240 grid_filter_width = pow(1.0 / aj[k][j][i], 1.0/3.0);
241 test_filter_width = 2.0 * grid_filter_width;
242
243 double alpha = pow(test_filter_width / grid_filter_width, 2.0);
244
245 double M11 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S11_filt - S_abs_filt * S11_filt);
246 double M12 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S12_filt - S_abs_filt * S12_filt);
247 double M13 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S13_filt - S_abs_filt * S13_filt);
248 double M22 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S22_filt - S_abs_filt * S22_filt);
249 double M23 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S23_filt - S_abs_filt * S23_filt);
250 double M33 = -2.0 * grid_filter_width * grid_filter_width * (alpha * S_abs_filt * S33_filt - S_abs_filt * S33_filt);
251
252
253 LM_arr[k][j][i] = L11*M11 + 2*L12*M12 + 2*L13*M13 + L22*M22 + 2*L23*M23 + L33*M33;
254 MM_arr[k][j][i] = M11*M11 + 2*M12*M12 + 2*M13*M13 + M22*M22 + 2*M23*M23 + M33*M33;
255 }
256
257
258
259
260
261
262
263
264 for (k=lzs; k<lze; k++)
265 for (j=lys; j<lye; j++)
266 for (i=lxs; i<lxe; i++) {
267 if(nvert[k][j][i] > 1.1) {
268 Cs_arr[k][j][i] = 0.0;
269 continue;
270 }
271
272 double C_sq = 0.0;
274 C_sq = LM_arr[k][j][i] / MM_arr[k][j][i];
275 }
276
277
278 double Cs_val = (C_sq > 0.0) ? sqrt(C_sq) : 0.0;
279 Cs_arr[k][j][i] = PetscMin(PetscMax(Cs_val, 0.0), simCtx->
max_cs);
280 }
281
282
283
284
285 ierr = DMDAVecRestoreArray(fda, user->
lUcat, &ucat); CHKERRQ(ierr);
286 ierr = DMDAVecRestoreArrayRead(fda, user->
lCsi, (
Cmpnts***)&csi); CHKERRQ(ierr);
287 ierr = DMDAVecRestoreArrayRead(fda, user->
lEta, (
Cmpnts***)&eta); CHKERRQ(ierr);
288 ierr = DMDAVecRestoreArrayRead(fda, user->
lZet, (
Cmpnts***)&zet); CHKERRQ(ierr);
289 ierr = DMDAVecRestoreArrayRead(da, user->
lNvert, (PetscReal***)&nvert); CHKERRQ(ierr);
290 ierr = DMDAVecRestoreArrayRead(da, user->
lAj, (PetscReal***)&aj); CHKERRQ(ierr);
291 ierr = DMDAVecRestoreArray(da, user->
CS, &Cs_arr); CHKERRQ(ierr);
292 ierr = DMDAVecRestoreArray(fda, lSx, &Sx_arr); CHKERRQ(ierr);
293 ierr = DMDAVecRestoreArray(fda, lSy, &Sy_arr); CHKERRQ(ierr);
294 ierr = DMDAVecRestoreArray(fda, lSz, &Sz_arr); CHKERRQ(ierr);
295 ierr = DMDAVecRestoreArray(da, lS_abs, &S_abs_arr); CHKERRQ(ierr);
296 ierr = DMDAVecRestoreArray(da, lLM, &LM_arr); CHKERRQ(ierr);
297 ierr = DMDAVecRestoreArray(da, lMM, &MM_arr); CHKERRQ(ierr);
298
299
300 ierr = VecDestroy(&lSx); CHKERRQ(ierr);
301 ierr = VecDestroy(&lSy); CHKERRQ(ierr);
302 ierr = VecDestroy(&lSz); CHKERRQ(ierr);
303 ierr = VecDestroy(&lS_abs); CHKERRQ(ierr);
304 ierr = VecDestroy(&lLM); CHKERRQ(ierr);
305 ierr = VecDestroy(&lMM); CHKERRQ(ierr);
306
308
309 PetscReal max_norm;
310 ierr = VecMax(user->
CS, NULL, &max_norm); CHKERRQ(ierr);
312
314 PetscFunctionReturn(0);
315}
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.
static PetscErrorCode FinalizeSmagorinskyConstantField(UserCtx *user)
Synchronizes the completed Smagorinsky coefficient field.
#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.