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.
143{
144
147 const PetscInt immersed = simCtx->
immersed;
148 const PetscInt ti = simCtx->
step;
149 const PetscInt tistart = simCtx->
StartStep;
150 const PetscInt imp_MAX_IT = simCtx->
imp_MAX_IT;
151 const PetscReal imp_atol = simCtx->
imp_atol;
152 const PetscReal imp_rtol = simCtx->
imp_rtol;
153 const PetscReal dt = simCtx->
dt;
154 const PetscReal st = simCtx->
st;
155 const PetscReal cfl = simCtx->
cfl;
156
157
158 PetscErrorCode ierr;
159 PetscMPIInt rank;
160 PetscInt istage, pseudot, ibi;
161 PetscReal alfa[] = {0.25, 1.0/3.0, 0.5, 1.0};
162 PetscReal ts, te, cput;
163
164
165 PetscReal normdU = 10.0, reldU = 1.0, relF = 1.0;
166 PetscReal *normdU0_bk, *normdU1_bk, *normdU_bk, *reldU_bk;
167 PetscReal *normF0_bk, *normF1_bk, *normF_bk, *relF_bk, *lambda;
168
169 PetscFunctionBeginUser;
171 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
173
174
175 ierr = PetscMalloc2(block_number, &normdU0_bk, block_number, &normdU1_bk); CHKERRQ(ierr);
176 ierr = PetscMalloc2(block_number, &normdU_bk, block_number, &reldU_bk); CHKERRQ(ierr);
177 ierr = PetscMalloc2(block_number, &normF0_bk, block_number, &normF1_bk); CHKERRQ(ierr);
178 ierr = PetscMalloc2(block_number, &normF_bk, block_number, &lambda); CHKERRQ(ierr);
179 ierr = PetscMalloc1(block_number, &relF_bk); CHKERRQ(ierr);
180
181 ierr = PetscTime(&ts); CHKERRQ(ierr);
182
183
184 if (block_number > 1) {
185
186 }
187
188 for (PetscInt bi = 0; bi < block_number; bi++) {
189
192 ierr =
FormBCS(&user[bi]); CHKERRQ(ierr);
193
194
195
196
197
198
199
200
201
202 ierr = VecDuplicate(user[bi].Ucont, &user[bi].Rhs); CHKERRQ(ierr);
203 ierr = VecDuplicate(user[bi].Ucont, &user[bi].dUcont); CHKERRQ(ierr);
204 ierr = VecDuplicate(user[bi].Ucont, &user[bi].pUcont); CHKERRQ(ierr);
205 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
206
207
209
210
211 ierr =
FormFunction1(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
212
214
215
218 ierr = VecAXPY(user[bi].Rhs, +2.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
219 ierr = VecAXPY(user[bi].Rhs, -0.5/dt, user[bi].Ucont_rm1); CHKERRQ(ierr);
220 } else {
221 ierr = VecAXPY(user[bi].Rhs, -1.0/dt, user[bi].Ucont); CHKERRQ(ierr);
222 ierr = VecAXPY(user[bi].Rhs, +1.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
223 }
224
226 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &normF0_bk[bi]); CHKERRQ(ierr);
227 normF1_bk[bi] = 1000.0;
228 normdU1_bk[bi] = 1000.0;
229 lambda[bi] = cfl;
230
232 }
233
234
235 pseudot = 0;
236 while (((normdU > imp_atol && reldU > imp_rtol) || pseudot < 1) && pseudot < imp_MAX_IT) {
237 pseudot++;
238
239 for (PetscInt bi = 0; bi < block_number; bi++) {
240 for (istage = 0; istage < 4; istage++) {
241
243 ierr = VecWAXPY(user[bi].Ucont, lambda[bi] * alfa[istage] * dt * st, user[bi].Rhs, user[bi].pUcont); CHKERRQ(ierr);
244
245 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" Ucont updated as Ucont = [lambda(%.4f)]x[alfa(%.4f)]x[dt(%.4f)]x[st(%.4f)]xRhs + pUcont.\n",lambda[bi],alfa[istage],dt,st);
246
247
248 ierr = DMGlobalToLocalBegin(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
249 ierr = DMGlobalToLocalEnd(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
252 ierr =
FormBCS(&user[bi]); CHKERRQ(ierr);
253
255
256
257 ierr =
FormFunction1(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
258
260
263 ierr = VecAXPY(user[bi].Rhs, +2.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
264 ierr = VecAXPY(user[bi].Rhs, -0.5/dt, user[bi].Ucont_rm1); CHKERRQ(ierr);
265 } else {
266 ierr = VecAXPY(user[bi].Rhs, -1.0/dt, user[bi].Ucont); CHKERRQ(ierr);
267 ierr = VecAXPY(user[bi].Rhs, +1.0/dt, user[bi].Ucont_o); CHKERRQ(ierr);
268 }
269
272 }
273
274
275
276
277
278
279
280
281
282
283
284 ierr = VecWAXPY(user[bi].dUcont, -1.0, user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
285
287
288 normdU1_bk[bi] = normdU_bk[bi];
289
290 ierr = VecNorm(user[bi].dUcont, NORM_INFINITY, &normdU_bk[bi]); CHKERRQ(ierr);
291 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &normF_bk[bi]); CHKERRQ(ierr);
292
294
295 if (pseudot == 1) {
296 normdU0_bk[bi] = normdU_bk[bi];
297 reldU_bk[bi] = 1.0;
298 normF0_bk[bi] = normF_bk[bi];
299 relF_bk[bi] = 1.0;
300 } else {
301 if (normdU0_bk[bi] > 1.0e-10) {
302 reldU_bk[bi] = normdU_bk[bi] / normdU0_bk[bi];
303 }
304 else {
305 reldU_bk[bi] = 0.0;
306 }
307 if(normF0_bk[bi] > 1.0e-10) {
308 relF_bk[bi] = normF_bk[bi] / normF0_bk[bi];
309 }else {
310 relF_bk[bi] = 0.0;
311 }
312 }
313
314
316
318
319
320 if (!rank) {
321 FILE *f;
322 char filen[80];
323 sprintf(filen, "logs/Momentum_Solver_Convergence_History_Block_%1d.log", bi);
324 f = fopen(filen, "a");
325 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]);
326 fclose(f);
327 }
328
329 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]);
330 }
331
332
333 normdU = -1.0e20; reldU = -1.0e20; relF = -1.0e20;
334 for (PetscInt bi = 0; bi < block_number; bi++) {
335 normdU = PetscMax(normdU_bk[bi], normdU);
336 reldU = PetscMax(reldU_bk[bi], reldU);
337 relF = PetscMax(relF_bk[bi], relF);
338 }
339
340 ierr = PetscTime(&te); CHKERRQ(ierr);
341 cput = te - ts;
343 pseudot, normdU, reldU, relF, cput);
344
345 for (PetscInt bi = 0; bi < block_number; bi++) {
346
347 if (pseudot > 1 && normF_bk[bi] > normF1_bk[bi] && normdU_bk[bi] > normdU1_bk[bi] && lambda[bi] > 0.01) {
348 lambda[bi] *= 0.5;
349 pseudot--;
350 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
" Block %d: Line search failed. Reducing lambda to %f and retrying iter.\n", bi, lambda[bi]);
351 ierr = VecCopy(user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
352 ierr = DMGlobalToLocalBegin(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
353 ierr = DMGlobalToLocalEnd(user[bi].fda, user[bi].Ucont, INSERT_VALUES, user[bi].lUcont); CHKERRQ(ierr);
354 } else {
355 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
356 normF1_bk[bi] = normF_bk[bi];
357 normdU1_bk[bi] = normdU_bk[bi];
358 }
359 }
360
361 if (block_number > 1) {
363
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376 for (PetscInt bi = 0; bi < block_number; bi++) {
377 ierr = VecDestroy(&user[bi].Rhs); CHKERRQ(ierr);
378 ierr = VecDestroy(&user[bi].dUcont); CHKERRQ(ierr);
379 ierr = VecDestroy(&user[bi].pUcont); CHKERRQ(ierr);
380 }
381
382 ierr = PetscFree2(normdU0_bk, normdU1_bk);CHKERRQ(ierr);
383 ierr = PetscFree2(normdU_bk, reldU_bk);CHKERRQ(ierr);
384 ierr = PetscFree2(normF0_bk, normF1_bk);CHKERRQ(ierr);
385 ierr = PetscFree2(normF_bk, lambda); CHKERRQ(ierr);
386 ierr = PetscFree(relF_bk); CHKERRQ(ierr);
387
390 PetscFunctionReturn(0);
391}
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
#define COEF_TIME_ACCURACY
Coefficient controlling the temporal accuracy scheme (e.g., 1.5 for BDF2).