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;
160 PetscInt istage, pseudot, ibi;
161 PetscReal alfa[] = {0.25, 1.0/3.0, 0.5, 1.0};
162 PetscReal ts, te, cput;
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;
169 PetscFunctionBeginUser;
171 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
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);
181 ierr = PetscTime(&ts); CHKERRQ(ierr);
184 if (block_number > 1) {
188 for (PetscInt bi = 0; bi < block_number; bi++) {
192 ierr =
FormBCS(&user[bi]); CHKERRQ(ierr);
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);
211 ierr =
FormFunction1(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
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);
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);
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;
236 while (((normdU > imp_atol && reldU > imp_rtol) || pseudot < 1) && pseudot < imp_MAX_IT) {
239 for (PetscInt bi = 0; bi < block_number; bi++) {
240 for (istage = 0; istage < 4; istage++) {
243 ierr = VecWAXPY(user[bi].Ucont, lambda[bi] * alfa[istage] * dt * st, user[bi].Rhs, user[bi].pUcont); CHKERRQ(ierr);
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);
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);
257 ierr =
FormFunction1(&user[bi], user[bi].Rhs); CHKERRQ(ierr);
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);
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);
284 ierr = VecWAXPY(user[bi].dUcont, -1.0, user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
288 normdU1_bk[bi] = normdU_bk[bi];
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);
296 normdU0_bk[bi] = normdU_bk[bi];
298 normF0_bk[bi] = normF_bk[bi];
301 if (normdU0_bk[bi] > 1.0e-10) {
302 reldU_bk[bi] = normdU_bk[bi] / normdU0_bk[bi];
307 if(normF0_bk[bi] > 1.0e-10) {
308 relF_bk[bi] = normF_bk[bi] / normF0_bk[bi];
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]);
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]);
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);
340 ierr = PetscTime(&te); CHKERRQ(ierr);
343 pseudot, normdU, reldU, relF, cput);
345 for (PetscInt bi = 0; bi < block_number; bi++) {
347 if (pseudot > 1 && normF_bk[bi] > normF1_bk[bi] && normdU_bk[bi] > normdU1_bk[bi] && lambda[bi] > 0.01) {
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);
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];
361 if (block_number > 1) {
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);
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);
390 PetscFunctionReturn(0);