Advances the momentum equations using an iterative explicit Runge-Kutta scheme.
This function uses a pseudo-time-stepping approach. It repeatedly applies an explicit RK scheme within a while loop until the change between iterations converges below specified tolerances (imp_atol, imp_rtol) or a maximum number of iterations (imp_MAX_IT) is reached.
This refactored version keeps the original internal loop over all blocks. All former global variables are accessed via the SimCtx. It directly calculates the full RHS (spatial + temporal terms) instead of calling a separate CalcRHS function.
149{
150
153 const PetscInt immersed = simCtx->
immersed;
154 const PetscInt ti = simCtx->
step;
155 const PetscInt tistart = simCtx->
StartStep;
156 const PetscInt imp_MAX_IT = simCtx->
imp_MAX_IT;
157 const PetscReal imp_atol = simCtx->
imp_atol;
158 const PetscReal imp_rtol = simCtx->
imp_rtol;
159 const PetscReal dt = simCtx->
dt;
160 const PetscReal st = simCtx->
st;
161 const PetscReal cfl = simCtx->
cfl;
162
163
164 PetscErrorCode ierr;
165 PetscMPIInt rank;
166 PetscInt istage, pseudot, ibi;
167 PetscReal alfa[] = {0.25, 1.0/3.0, 0.5, 1.0};
168 PetscReal ts, te, cput;
169
170
171 PetscReal normdU = 10.0, reldU = 1.0, relF = 1.0;
172 PetscReal *normdU0_bk, *normdU1_bk, *normdU_bk, *reldU_bk;
173 PetscReal *normF0_bk, *normF1_bk, *normF_bk, *relF_bk, *lambda;
174
175 PetscFunctionBeginUser;
177 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
179
180
181 ierr = PetscMalloc2(block_number, &normdU0_bk, block_number, &normdU1_bk); CHKERRQ(ierr);
182 ierr = PetscMalloc2(block_number, &normdU_bk, block_number, &reldU_bk); CHKERRQ(ierr);
183 ierr = PetscMalloc2(block_number, &normF0_bk, block_number, &normF1_bk); CHKERRQ(ierr);
184 ierr = PetscMalloc2(block_number, &normF_bk, block_number, &lambda); CHKERRQ(ierr);
185 ierr = PetscMalloc1(block_number, &relF_bk); CHKERRQ(ierr);
186
187 ierr = PetscTime(&ts); CHKERRQ(ierr);
188
189
190 if (block_number > 1) {
191
192 }
193
194 for (PetscInt bi = 0; bi < block_number; bi++) {
195
198 ierr =
FormBCS(&user[bi]); CHKERRQ(ierr);
199
200
201
202
203
204
205
206
207
208 ierr = VecDuplicate(user[bi].Ucont, &user[bi].Rhs); CHKERRQ(ierr);
209 ierr = VecDuplicate(user[bi].Ucont, &user[bi].dUcont); CHKERRQ(ierr);
210 ierr = VecDuplicate(user[bi].Ucont, &user[bi].pUcont); CHKERRQ(ierr);
211 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
212
213
215
216
217 ierr =
ComputeRHS(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
218
220
221
224 ierr = VecAXPY(user[bi].Rhs, +2.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
225 ierr = VecAXPY(user[bi].Rhs, -0.5/dt, user[bi].Ucont_rm1); CHKERRQ(ierr);
226 } else {
227 ierr = VecAXPY(user[bi].Rhs, -1.0/dt, user[bi].Ucont); CHKERRQ(ierr);
228 ierr = VecAXPY(user[bi].Rhs, +1.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
229 }
230
232 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &normF0_bk[bi]); CHKERRQ(ierr);
233 normF1_bk[bi] = 1000.0;
234 normdU1_bk[bi] = 1000.0;
235 lambda[bi] = cfl;
236
238 }
239
240
241 pseudot = 0;
242 while (((normdU > imp_atol && reldU > imp_rtol) || pseudot < 1) && pseudot < imp_MAX_IT) {
243 pseudot++;
244
245 for (PetscInt bi = 0; bi < block_number; bi++) {
246 for (istage = 0; istage < 4; istage++) {
247
249 ierr = VecWAXPY(user[bi].Ucont, lambda[bi] * alfa[istage] * dt * st, user[bi].Rhs, user[bi].pUcont); CHKERRQ(ierr);
250
251 LOG_ALLOW(
GLOBAL,
LOG_VERBOSE,
" Ucont updated as Ucont = [lambda(%.4f)]x[alfa(%.4f)]x[dt(%.4f)]x[st(%.4f)]xRhs + pUcont.\n",lambda[bi],alfa[istage],dt,st);
252
253
254 ierr = DMGlobalToLocalBegin(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
255 ierr = DMGlobalToLocalEnd(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
258 ierr =
FormBCS(&user[bi]); CHKERRQ(ierr);
259
261
262
263 ierr =
ComputeRHS(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
264
266
269 ierr = VecAXPY(user[bi].Rhs, +2.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
270 ierr = VecAXPY(user[bi].Rhs, -0.5/dt, user[bi].Ucont_rm1); CHKERRQ(ierr);
271 } else {
272 ierr = VecAXPY(user[bi].Rhs, -1.0/dt, user[bi].Ucont); CHKERRQ(ierr);
273 ierr = VecAXPY(user[bi].Rhs, +1.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
274 }
275
278 }
279
280
281
282
283
284
285
286
287
288
289
290 ierr = VecWAXPY(user[bi].dUcont, -1.0, user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
291
293
294 normdU1_bk[bi] = normdU_bk[bi];
295
296 ierr = VecNorm(user[bi].dUcont, NORM_INFINITY, &normdU_bk[bi]); CHKERRQ(ierr);
297 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &normF_bk[bi]); CHKERRQ(ierr);
298
300
301 if (pseudot == 1) {
302 normdU0_bk[bi] = normdU_bk[bi];
303 reldU_bk[bi] = 1.0;
304 normF0_bk[bi] = normF_bk[bi];
305 relF_bk[bi] = 1.0;
306 } else {
307 if (normdU0_bk[bi] > 1.0e-10) {
308 reldU_bk[bi] = normdU_bk[bi] / normdU0_bk[bi];
309 }
310 else {
311 reldU_bk[bi] = 0.0;
312 }
313 if(normF0_bk[bi] > 1.0e-10) {
314 relF_bk[bi] = normF_bk[bi] / normF0_bk[bi];
315 }else {
316 relF_bk[bi] = 0.0;
317 }
318 }
319
320
322
324
325
326 if (!rank) {
327 FILE *f;
328 char filen[80];
329 sprintf(filen,
"%s/Momentum_Solver_Convergence_History_Block_%1d.log", simCtx->
log_dir,bi);
330 f = fopen(filen, "a");
331 PetscFPrintf(PETSC_COMM_WORLD, f, "Block %d | Step: %d | Pseudo-Timestep %d | |dU| %le | |dU|/|dU_0| %le | |U| = %le \n",bi,(int)ti, (int)pseudot, normdU_bk[bi], reldU_bk[bi], normF_bk[bi]);
332 fclose(f);
333 }
334
335 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" Block %d | Step: %d | Pseudo-Timestep %d | |dU| %le | |dU|/|dU_0| %le | |U| = %le \n",bi,ti,pseudot,normdU_bk[bi], reldU_bk[bi], normF_bk[bi]);
336 }
337
338
339 normdU = -1.0e20; reldU = -1.0e20; relF = -1.0e20;
340 for (PetscInt bi = 0; bi < block_number; bi++) {
341 normdU = PetscMax(normdU_bk[bi], normdU);
342 reldU = PetscMax(reldU_bk[bi], reldU);
343 relF = PetscMax(relF_bk[bi], relF);
344 }
345
346 ierr = PetscTime(&te); CHKERRQ(ierr);
347 cput = te - ts;
349 pseudot, normdU, reldU, relF, cput);
350
351 for (PetscInt bi = 0; bi < block_number; bi++) {
352
353 if (pseudot > 1 && normF_bk[bi] > normF1_bk[bi] && normdU_bk[bi] > normdU1_bk[bi] && lambda[bi] > 0.01) {
354 lambda[bi] *= 0.5;
355 pseudot--;
356 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
" Block %d: Line search failed. Reducing lambda to %f and retrying iter.\n", bi, lambda[bi]);
357 ierr = VecCopy(user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
358 ierr = DMGlobalToLocalBegin(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
359 ierr = DMGlobalToLocalEnd(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
360 } else {
361 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
362 normF1_bk[bi] = normF_bk[bi];
363 normdU1_bk[bi] = normdU_bk[bi];
364 }
365 }
366
367 if (block_number > 1) {
369
370 }
371 }
372
373
374
375
376
377
378
379
380
381
382 for (PetscInt bi = 0; bi < block_number; bi++) {
383 ierr = VecDestroy(&user[bi].Rhs); CHKERRQ(ierr);
384 ierr = VecDestroy(&user[bi].dUcont); CHKERRQ(ierr);
385 ierr = VecDestroy(&user[bi].pUcont); CHKERRQ(ierr);
386 }
387
388 ierr = PetscFree2(normdU0_bk, normdU1_bk);CHKERRQ(ierr);
389 ierr = PetscFree2(normdU_bk, reldU_bk);CHKERRQ(ierr);
390 ierr = PetscFree2(normF0_bk, normF1_bk);CHKERRQ(ierr);
391 ierr = PetscFree2(normF_bk, lambda); CHKERRQ(ierr);
392 ierr = PetscFree(relF_bk); CHKERRQ(ierr);
393
396 PetscFunctionReturn(0);
397}
@ LOG_TRACE
Very fine-grained tracing information for in-depth debugging.
@ LOG_VERBOSE
Extremely detailed logs, typically for development use only.
char log_dir[PETSC_MAX_PATH_LEN]
#define COEF_TIME_ACCURACY
Coefficient controlling the temporal accuracy scheme (e.g., 1.5 for BDF2).