PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions
momentum_newton_krylov.c File Reference
#include "momentumsolvers.h"
Include dependency graph for momentum_newton_krylov.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  MomentumNewtonKrylovContext
 

Macros

#define __FUNCT__   "MomentumNewtonKrylov_Validate"
 
#define __FUNCT__   "MomentumNewtonKrylov_ClassifyRow"
 
#define __FUNCT__   "MomentumNewtonKrylov_ApplyConstraints"
 
#define __FUNCT__   "MomentumNewtonKrylov_FormResidual"
 
#define __FUNCT__   "MomentumSolver_NewtonKrylov"
 

Enumerations

enum  MomentumNewtonKrylovRowType { MOM_NK_ROW_PHYSICAL = 0 , MOM_NK_ROW_FIXED_CONDITIONED , MOM_NK_ROW_FIXED_HOMOGENEOUS , MOM_NK_ROW_PERIODIC_DUPLICATE }
 

Functions

static PetscErrorCode MomentumNewtonKrylov_Validate (UserCtx *user)
 Rejects configurations outside the audited version-one feature set.
 
static PetscErrorCode MomentumNewtonKrylov_FormResidual (SNES snes, Vec X, Vec F, void *vctx)
 Adapts a PETSc trial vector to the existing momentum residual path.
 
static PetscErrorCode MomentumNewtonKrylov_ApplyConstraints (MomentumNewtonKrylovContext *ctx, Vec X, Vec F)
 Replaces every non-independent residual row with an explicit equation.
 
static MomentumNewtonKrylovRowType MomentumNewtonKrylov_ClassifyRow (UserCtx *user, PetscInt i, PetscInt j, PetscInt k, PetscInt component, PetscInt *ri, PetscInt *rj, PetscInt *rk)
 Classifies one stored staggered component row and its periodic representative.
 
PetscErrorCode MomentumSolver_NewtonKrylov (UserCtx *user, IBMNodes *ibm, FSInfo *fsi)
 Runs one per-call matrix-free Newton–Krylov momentum solve.
 

Data Structure Documentation

◆ MomentumNewtonKrylovContext

struct MomentumNewtonKrylovContext

Definition at line 3 of file momentum_newton_krylov.c.

Collaboration diagram for MomentumNewtonKrylovContext:
[legend]
Data Fields
UserCtx * user

Macro Definition Documentation

◆ __FUNCT__ [1/5]

#define __FUNCT__   "MomentumNewtonKrylov_Validate"

Definition at line 23 of file momentum_newton_krylov.c.

◆ __FUNCT__ [2/5]

#define __FUNCT__   "MomentumNewtonKrylov_ClassifyRow"

Definition at line 23 of file momentum_newton_krylov.c.

◆ __FUNCT__ [3/5]

#define __FUNCT__   "MomentumNewtonKrylov_ApplyConstraints"

Definition at line 23 of file momentum_newton_krylov.c.

◆ __FUNCT__ [4/5]

#define __FUNCT__   "MomentumNewtonKrylov_FormResidual"

Definition at line 23 of file momentum_newton_krylov.c.

◆ __FUNCT__ [5/5]

#define __FUNCT__   "MomentumSolver_NewtonKrylov"

Definition at line 23 of file momentum_newton_krylov.c.

Enumeration Type Documentation

◆ MomentumNewtonKrylovRowType

Enumerator
MOM_NK_ROW_PHYSICAL 
MOM_NK_ROW_FIXED_CONDITIONED 
MOM_NK_ROW_FIXED_HOMOGENEOUS 
MOM_NK_ROW_PERIODIC_DUPLICATE 

Definition at line 7 of file momentum_newton_krylov.c.

Function Documentation

◆ MomentumNewtonKrylov_Validate()

static PetscErrorCode MomentumNewtonKrylov_Validate ( UserCtx user)
static

Rejects configurations outside the audited version-one feature set.

Parameters
userSingle-block momentum context to validate.
Returns
PetscErrorCode 0 when the configuration is supported.

Definition at line 29 of file momentum_newton_krylov.c.

30{
31 SimCtx *simCtx;
32 PetscReal mask_max = 0.0;
33
34 PetscFunctionBeginUser;
35 PetscCheck(user != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
36 "Newton Krylov requires a non-NULL UserCtx.");
37 simCtx = user->simCtx;
38 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
39 "Newton Krylov requires UserCtx::simCtx.");
40 PetscCheck(simCtx->block_number == 1, PETSC_COMM_WORLD, PETSC_ERR_SUP,
41 "Newton Krylov version one supports exactly one block (got %d).",
42 simCtx->block_number);
43 PetscCheck(!simCtx->immersed, PETSC_COMM_WORLD, PETSC_ERR_SUP,
44 "Newton Krylov version one does not support immersed boundaries.");
45 PetscCheck(!simCtx->movefsi && !simCtx->rotatefsi, PETSC_COMM_WORLD, PETSC_ERR_SUP,
46 "Newton Krylov version one does not support moving or rotating bodies/FSI.");
47 PetscCheck(!simCtx->moveframe && !simCtx->rotateframe, PETSC_COMM_WORLD, PETSC_ERR_SUP,
48 "Newton Krylov version one does not support moving or rotating reference frames.");
49 PetscCheck(!simCtx->rans, PETSC_COMM_WORLD, PETSC_ERR_SUP,
50 "Newton Krylov version one does not support RANS.");
51 PetscCheck(!simCtx->clark, PETSC_COMM_WORLD, PETSC_ERR_SUP,
52 "Newton Krylov version one does not support the Clark model.");
53 PetscCheck(!simCtx->TwoD, PETSC_COMM_WORLD, PETSC_ERR_SUP,
54 "Newton Krylov version one does not support TwoD component masking.");
55 PetscCheck(!simCtx->wallfunction, PETSC_COMM_WORLD, PETSC_ERR_SUP,
56 "Newton Krylov version one does not support wall functions.");
57 PetscCheck(simCtx->StartStep == 0, PETSC_COMM_WORLD, PETSC_ERR_SUP,
58 "Newton Krylov version one supports fresh starts only (StartStep must be zero)." );
59
60 for (PetscInt face = 0; face < 6; ++face) {
61 const BoundaryFaceConfig *cfg = &user->boundary_faces[face];
62 PetscBool supported = PETSC_FALSE;
63
64 switch (cfg->handler_type) {
66 supported = (PetscBool)(cfg->mathematical_type == WALL);
67 break;
71 supported = (PetscBool)(cfg->mathematical_type == INLET);
72 break;
74 supported = (PetscBool)(cfg->mathematical_type == OUTLET);
75 break;
77 supported = (PetscBool)(cfg->mathematical_type == PERIODIC);
78 break;
79 default:
80 supported = PETSC_FALSE;
81 break;
82 }
83 PetscCheck(supported, PETSC_COMM_WORLD, PETSC_ERR_SUP,
84 "Newton Krylov version one does not support boundary face %d with mathematical type %d and handler %d.",
85 face, (PetscInt)cfg->mathematical_type, (PetscInt)cfg->handler_type);
86 }
87
90 PETSC_COMM_WORLD, PETSC_ERR_SUP, "Newton Krylov requires paired x-periodic faces.");
93 PETSC_COMM_WORLD, PETSC_ERR_SUP, "Newton Krylov requires paired y-periodic faces.");
96 PETSC_COMM_WORLD, PETSC_ERR_SUP, "Newton Krylov requires paired z-periodic faces.");
97
98 PetscCheck(user->Nvert != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
99 "Newton Krylov requires the cell-mask vector Nvert.");
100 PetscCall(VecMax(user->Nvert, NULL, &mask_max));
101 PetscCheck(mask_max <= 0.1, PETSC_COMM_WORLD, PETSC_ERR_SUP,
102 "Newton Krylov version one does not define equations for masked solid cells (max Nvert=%g).",
103 (double)mask_max);
104 PetscFunctionReturn(PETSC_SUCCESS);
105}
PetscInt clark
Definition variables.h:789
PetscInt movefsi
Definition variables.h:714
@ INLET
Definition variables.h:288
@ OUTLET
Definition variables.h:287
@ PERIODIC
Definition variables.h:290
@ WALL
Definition variables.h:284
PetscInt moveframe
Definition variables.h:715
PetscInt TwoD
Definition variables.h:715
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:895
PetscInt block_number
Definition variables.h:767
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:878
PetscInt rans
Definition variables.h:788
@ BC_HANDLER_PERIODIC_GEOMETRIC
Definition variables.h:314
@ BC_HANDLER_INLET_PARABOLIC
Definition variables.h:307
@ BC_HANDLER_INLET_CONSTANT_VELOCITY
Definition variables.h:306
@ BC_HANDLER_INLET_PROFILE_FROM_FILE
Definition variables.h:308
@ BC_HANDLER_WALL_NOSLIP
Definition variables.h:303
@ BC_HANDLER_OUTLET_CONSERVATION
Definition variables.h:312
BCHandlerType handler_type
Definition variables.h:367
PetscInt StartStep
Definition variables.h:694
PetscInt rotatefsi
Definition variables.h:714
PetscInt wallfunction
Definition variables.h:789
Vec Nvert
Definition variables.h:903
BCType mathematical_type
Definition variables.h:366
PetscInt rotateframe
Definition variables.h:715
PetscInt immersed
Definition variables.h:714
@ BC_FACE_NEG_X
Definition variables.h:260
@ BC_FACE_POS_Z
Definition variables.h:262
@ BC_FACE_POS_Y
Definition variables.h:261
@ BC_FACE_NEG_Z
Definition variables.h:262
@ BC_FACE_POS_X
Definition variables.h:260
@ BC_FACE_NEG_Y
Definition variables.h:261
Holds the complete configuration for one of the six boundary faces.
Definition variables.h:364
The master context for the entire simulation.
Definition variables.h:684
Here is the caller graph for this function:

◆ MomentumNewtonKrylov_FormResidual()

static PetscErrorCode MomentumNewtonKrylov_FormResidual ( SNES  snes,
Vec  X,
Vec  F,
void *  vctx 
)
static

Adapts a PETSc trial vector to the existing momentum residual path.

Supported handlers may overwrite flux totals and other diagnostics on every call, but repeatability tests require those values not to affect a later call at the same X. No histories, pressure, viscosity, or controller state advance is performed here.

Parameters
snesCalling nonlinear solver.
XTrial solution (read-only).
FResidual output.
vctxPointer to MomentumNewtonKrylovContext.
Returns
PetscErrorCode 0 on success.

Definition at line 259 of file momentum_newton_krylov.c.

260{
262 UserCtx *user = ctx->user;
263 const char *staggered_fields[] = {"Ucont"};
264
265 PetscFunctionBeginUser;
266 (void)snes;
267 PetscCall(VecCopy(X, user->Ucont));
268 PetscCall(SynchronizePeriodicStaggeredFields(user, 1, staggered_fields));
269 PetscCall(ApplyBoundaryConditions(user));
270 PetscCall(ComputeTotalResidual(user));
271 PetscCall(VecCopy(user->Rhs, F));
272 PetscCall(VecScale(F, -1.0));
273 PetscCall(MomentumNewtonKrylov_ApplyConstraints(ctx, X, F));
274 PetscFunctionReturn(PETSC_SUCCESS);
275}
PetscErrorCode SynchronizePeriodicStaggeredFields(UserCtx *user, PetscInt num_fields, const char *field_names[])
Synchronizes persistent component-staggered vector fields.
PetscErrorCode ApplyBoundaryConditions(UserCtx *user)
Main boundary-condition orchestrator executed during solver timestepping.
static PetscErrorCode MomentumNewtonKrylov_ApplyConstraints(MomentumNewtonKrylovContext *ctx, Vec X, Vec F)
Replaces every non-independent residual row with an explicit equation.
PetscErrorCode ComputeTotalResidual(UserCtx *user)
Computes the shared spatial-plus-BDF momentum residual in user->Rhs.
Vec Rhs
Definition variables.h:911
Vec Ucont
Definition variables.h:903
User-defined context containing data specific to a single computational grid level.
Definition variables.h:875
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomentumNewtonKrylov_ApplyConstraints()

static PetscErrorCode MomentumNewtonKrylov_ApplyConstraints ( MomentumNewtonKrylovContext ctx,
Vec  X,
Vec  F 
)
static

Replaces every non-independent residual row with an explicit equation.

Conditioned face-normal rows use F=X-Uconditioned, unconditioned legacy dummy/tangential rows use F=X, and periodic duplicates use Fdup=Xdup-Xrep. These equations prevent the zero Jacobian rows produced by simply retaining EnforceRHSBoundaryConditions() zeros in a matrix-free Newton operator. Immersed, masked, TwoD, and interface rows are rejected before this callback is installed.

Parameters
ctxActive solve context.
XUnconditioned PETSc trial state.
FResidual vector to update in place.
Returns
PetscErrorCode 0 on success.

Definition at line 195 of file momentum_newton_krylov.c.

197{
198 UserCtx *user = ctx->user;
199 DMDALocalInfo info = user->info;
200 Vec local_x = NULL;
201 Cmpnts ***x = NULL, ***conditioned = NULL, ***f = NULL, ***lx = NULL;
202 const PetscInt xs = info.xs, xe = info.xs + info.xm;
203 const PetscInt ys = info.ys, ye = info.ys + info.ym;
204 const PetscInt zs = info.zs, ze = info.zs + info.zm;
205
206 PetscFunctionBeginUser;
207 PetscCall(DMGetLocalVector(user->fda, &local_x));
208 PetscCall(DMGlobalToLocalBegin(user->fda, X, INSERT_VALUES, local_x));
209 PetscCall(DMGlobalToLocalEnd(user->fda, X, INSERT_VALUES, local_x));
210 PetscCall(DMDAVecGetArrayRead(user->fda, X, &x));
211 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &conditioned));
212 PetscCall(DMDAVecGetArray(user->fda, F, &f));
213 PetscCall(DMDAVecGetArrayRead(user->fda, local_x, &lx));
214
215 for (PetscInt k = zs; k < ze; ++k) {
216 for (PetscInt j = ys; j < ye; ++j) {
217 for (PetscInt i = xs; i < xe; ++i) {
218 PetscScalar *fv = &f[k][j][i].x;
219 const PetscScalar *xv = &x[k][j][i].x;
220 const PetscScalar *cv = &conditioned[k][j][i].x;
221
222 for (PetscInt component = 0; component < 3; ++component) {
223 PetscInt ri, rj, rk;
225 user, i, j, k, component, &ri, &rj, &rk);
226 const PetscScalar *rv = &lx[rk][rj][ri].x;
227
228 if (row == MOM_NK_ROW_FIXED_CONDITIONED) fv[component] = xv[component] - cv[component];
229 else if (row == MOM_NK_ROW_FIXED_HOMOGENEOUS) fv[component] = xv[component];
230 else if (row == MOM_NK_ROW_PERIODIC_DUPLICATE) fv[component] = xv[component] - rv[component];
231 }
232 }
233 }
234 }
235
236 PetscCall(DMDAVecRestoreArrayRead(user->fda, local_x, &lx));
237 PetscCall(DMDAVecRestoreArray(user->fda, F, &f));
238 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &conditioned));
239 PetscCall(DMDAVecRestoreArrayRead(user->fda, X, &x));
240 PetscCall(DMRestoreLocalVector(user->fda, &local_x));
241 PetscFunctionReturn(PETSC_SUCCESS);
242}
static MomentumNewtonKrylovRowType MomentumNewtonKrylov_ClassifyRow(UserCtx *user, PetscInt i, PetscInt j, PetscInt k, PetscInt component, PetscInt *ri, PetscInt *rj, PetscInt *rk)
Classifies one stored staggered component row and its periodic representative.
PetscScalar x
Definition variables.h:101
DMDALocalInfo info
Definition variables.h:882
A 3D point or vector with PetscScalar components.
Definition variables.h:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MomentumNewtonKrylov_ClassifyRow()

static MomentumNewtonKrylovRowType MomentumNewtonKrylov_ClassifyRow ( UserCtx user,
PetscInt  i,
PetscInt  j,
PetscInt  k,
PetscInt  component,
PetscInt *  ri,
PetscInt *  rj,
PetscInt *  rk 
)
static

Classifies one stored staggered component row and its periodic representative.

Negative nonperiodic planes and positive dummy planes are zeroed by the legacy residual treatment. Only a face-normal row actually written by its boundary handler is conditioned; the remaining zeroed rows use F=X. Periodic endpoint rows use the same wrapped representatives as SynchronizePeriodicStaggeredFields(). At periodic/nonperiodic intersections the periodic equation owns rows that a shrunken boundary-handler loop does not condition.

Parameters
userBlock context containing boundary metadata and global dimensions.
iGlobal i index.
jGlobal j index.
kGlobal k index.
componentStored component, 0=x, 1=y, 2=z.
riReturned periodic representative i index.
rjReturned periodic representative j index.
rkReturned periodic representative k index.
Returns
Exact version-one row category.

Definition at line 129 of file momentum_newton_krylov.c.

132{
133 const PetscInt mx = user->info.mx, my = user->info.my, mz = user->info.mz;
134 const PetscInt coord[3] = {i, j, k};
135 const PetscInt size[3] = {mx, my, mz};
136 const BCFace neg_face[3] = {BC_FACE_NEG_X, BC_FACE_NEG_Y, BC_FACE_NEG_Z};
137 PetscBool periodic[3], periodic_duplicate = PETSC_FALSE;
138 PetscBool residual_zeroed = PETSC_FALSE, conditioned = PETSC_FALSE;
139
140 *ri = i; *rj = j; *rk = k;
141 for (PetscInt axis = 0; axis < 3; ++axis) {
142 periodic[axis] = (PetscBool)(
143 user->boundary_faces[neg_face[axis]].mathematical_type == PERIODIC);
144 if (periodic[axis] && coord[axis] == 0) {
145 periodic_duplicate = PETSC_TRUE;
146 if (axis == 0) *ri = -2;
147 else if (axis == 1) *rj = -2;
148 else *rk = -2;
149 }
150 if (periodic[axis] && coord[axis] == size[axis] - 1) {
151 periodic_duplicate = PETSC_TRUE;
152 if (axis == 0) *ri = mx + 1;
153 else if (axis == 1) *rj = my + 1;
154 else *rk = mz + 1;
155 }
156
157 if (!periodic[axis] && coord[axis] == 0) residual_zeroed = PETSC_TRUE;
158 if (coord[axis] == size[axis] - 1) residual_zeroed = PETSC_TRUE;
159 if (!periodic[axis] && coord[axis] == size[axis] - 2 && component == axis)
160 residual_zeroed = PETSC_TRUE;
161 }
162
163 if (!periodic[component] &&
164 (coord[component] == 0 || coord[component] == size[component] - 2)) {
165 PetscBool tangential_interior = PETSC_TRUE;
166 for (PetscInt axis = 0; axis < 3; ++axis) {
167 if (axis == component) continue;
168 if (coord[axis] < 1 || coord[axis] > size[axis] - 2)
169 tangential_interior = PETSC_FALSE;
170 }
171 conditioned = tangential_interior;
172 }
173
174 if (conditioned) return MOM_NK_ROW_FIXED_CONDITIONED;
175 if (periodic_duplicate) return MOM_NK_ROW_PERIODIC_DUPLICATE;
176 if (residual_zeroed) return MOM_NK_ROW_FIXED_HOMOGENEOUS;
177 return MOM_NK_ROW_PHYSICAL;
178}
BCFace
Identifies the six logical faces of a structured computational block.
Definition variables.h:259
Here is the caller graph for this function:

◆ MomentumSolver_NewtonKrylov()

PetscErrorCode MomentumSolver_NewtonKrylov ( UserCtx user,
IBMNodes ibm,
FSInfo fsi 
)

Runs one per-call matrix-free Newton–Krylov momentum solve.

Solves one physical momentum step with matrix-free Newton–Krylov.

Parameters
userSingle-block momentum context.
ibmMust be NULL in version one.
fsiMust be NULL in version one.
Returns
0 on convergence or an error after restoring the canonical entry state.

Definition at line 286 of file momentum_newton_krylov.c.

287{
288 PetscErrorCode ierr = PETSC_SUCCESS, cleanup_ierr;
289 SimCtx *simCtx;
290 SNES snes = NULL;
291 Mat J = NULL;
292 Vec solution = NULL, entry_backup = NULL;
293 KSP ksp = NULL;
294 PC pc = NULL;
295 const char *pc_type = NULL;
296 PetscBool pc_is_none = PETSC_FALSE;
297 PetscBool restore_entry = PETSC_FALSE;
298 PetscBool rhs_created = PETSC_FALSE;
299 SNESConvergedReason reason = SNES_CONVERGED_ITERATING;
300 PetscInt nonlinear_its = 0, function_evals = 0, linear_its = 0;
301 PetscReal final_norm = PETSC_MAX_REAL;
303 const char *staggered_fields[] = {"Ucont"};
304
305 PetscFunctionBeginUser;
306 PetscCall(MomentumNewtonKrylov_Validate(user));
307 PetscCheck(ibm == NULL && fsi == NULL, PETSC_COMM_WORLD, PETSC_ERR_SUP,
308 "Newton Krylov version one does not accept IBM or FSI objects.");
309 PetscCheck(user->Rhs == NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
310 "Newton Krylov requires UserCtx::Rhs to be unallocated on entry.");
311 simCtx = user->simCtx;
312
313 ierr = VecDuplicate(user->Ucont, &solution); if (ierr) goto cleanup;
314 ierr = VecDuplicate(user->Ucont, &entry_backup); if (ierr) goto cleanup;
315 ierr = VecDuplicate(user->Ucont, &user->Rhs); if (ierr) goto cleanup;
316 rhs_created = PETSC_TRUE;
317 ierr = SNESCreate(PetscObjectComm((PetscObject)user->Ucont), &snes); if (ierr) goto cleanup;
318
319 ierr = SynchronizePeriodicStaggeredFields(user, 1, staggered_fields); if (ierr) goto cleanup;
320 ierr = ApplyBoundaryConditions(user); if (ierr) goto cleanup;
321 ierr = VecCopy(user->Ucont, entry_backup); if (ierr) goto cleanup;
322 restore_entry = PETSC_TRUE;
323 ierr = VecCopy(user->Ucont, solution); if (ierr) goto cleanup;
324
325 ctx.user = user;
326 ierr = SNESSetOptionsPrefix(snes, "mom_nk_"); if (ierr) goto cleanup;
327 ierr = SNESSetType(snes, SNESNEWTONLS); if (ierr) goto cleanup;
328 ierr = SNESSetDM(snes, user->fda); if (ierr) goto cleanup;
329 ierr = SNESSetFunction(snes, NULL, MomentumNewtonKrylov_FormResidual, &ctx); if (ierr) goto cleanup;
330 ierr = MatCreateSNESMF(snes, &J); if (ierr) goto cleanup;
331 ierr = SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL); if (ierr) goto cleanup;
332 ierr = SNESGetKSP(snes, &ksp); if (ierr) goto cleanup;
333 ierr = KSPSetType(ksp, KSPGMRES); if (ierr) goto cleanup;
334 ierr = KSPGetPC(ksp, &pc); if (ierr) goto cleanup;
335 ierr = PCSetType(pc, PCNONE); if (ierr) goto cleanup;
336 ierr = SNESSetFromOptions(snes); if (ierr) goto cleanup;
337 ierr = PCGetType(pc, &pc_type); if (ierr) goto cleanup;
338 ierr = PetscStrcmp(pc_type, PCNONE, &pc_is_none); if (ierr) goto cleanup;
339 if (!pc_is_none) {
341 "Newton Krylov version one requires PCNONE; option processing selected PC type '%s'.\n",
342 pc_type ? pc_type : "(unset)");
343 ierr = PETSC_ERR_SUP;
344 goto cleanup;
345 }
346
347 ierr = SNESSolve(snes, NULL, solution);
348 if (ierr) goto cleanup;
349 ierr = SNESGetConvergedReason(snes, &reason); if (ierr) goto cleanup;
350 ierr = SNESGetIterationNumber(snes, &nonlinear_its); if (ierr) goto cleanup;
351 ierr = SNESGetNumberFunctionEvals(snes, &function_evals); if (ierr) goto cleanup;
352 ierr = SNESGetLinearSolveIterations(snes, &linear_its); if (ierr) goto cleanup;
353 ierr = SNESGetFunctionNorm(snes, &final_norm); if (ierr) goto cleanup;
354
355 if (reason > 0) {
356 ierr = VecCopy(solution, user->Ucont); if (ierr) goto cleanup;
357 simCtx->mom_last_converged = PETSC_TRUE;
358 } else {
359 ierr = VecCopy(entry_backup, user->Ucont); if (ierr) goto cleanup;
360 simCtx->mom_last_converged = PETSC_FALSE;
361 }
362 ierr = SynchronizePeriodicStaggeredFields(user, 1, staggered_fields); if (ierr) goto cleanup;
363 ierr = ApplyBoundaryConditions(user); if (ierr) goto cleanup;
364 restore_entry = PETSC_FALSE;
365
367 "Newton Krylov momentum solve: reason=%s (%d), Newton iterations=%d, residual evaluations=%d, Krylov iterations=%d, final norm=%.6e, state=%s.\n",
368 SNESConvergedReasons[reason], (PetscInt)reason, nonlinear_its, function_evals,
369 linear_its, (double)final_norm, reason > 0 ? "committed" : "rolled back");
370 if (reason <= 0) ierr = PETSC_ERR_CONV_FAILED;
371
372cleanup:
373 if (restore_entry && entry_backup) {
374 cleanup_ierr = VecCopy(entry_backup, user->Ucont);
375 if (!ierr) ierr = cleanup_ierr;
376 cleanup_ierr = SynchronizePeriodicStaggeredFields(user, 1, staggered_fields);
377 if (!ierr) ierr = cleanup_ierr;
378 cleanup_ierr = ApplyBoundaryConditions(user);
379 if (!ierr) ierr = cleanup_ierr;
380 simCtx->mom_last_converged = PETSC_FALSE;
381 }
382 if (rhs_created) {
383 cleanup_ierr = VecDestroy(&user->Rhs);
384 if (!ierr) ierr = cleanup_ierr;
385 }
386 cleanup_ierr = VecDestroy(&entry_backup); if (!ierr) ierr = cleanup_ierr;
387 cleanup_ierr = VecDestroy(&solution); if (!ierr) ierr = cleanup_ierr;
388 cleanup_ierr = MatDestroy(&J); if (!ierr) ierr = cleanup_ierr;
389 cleanup_ierr = SNESDestroy(&snes); if (!ierr) ierr = cleanup_ierr;
390 PetscFunctionReturn(ierr);
391}
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:45
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:199
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
Definition logging.h:83
@ LOG_ERROR
Critical errors that may halt the program.
Definition logging.h:28
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:30
static PetscErrorCode MomentumNewtonKrylov_Validate(UserCtx *user)
Rejects configurations outside the audited version-one feature set.
static PetscErrorCode MomentumNewtonKrylov_FormResidual(SNES snes, Vec X, Vec F, void *ctx)
Adapts a PETSc trial vector to the existing momentum residual path.
PetscBool mom_last_converged
Definition variables.h:738
Here is the call graph for this function: