apply operator for Arc Length pre-conditioner solves K*pc_x = pc_f solves K*xLambda = -dF_lambda solves ddlambda = ( res_lambda - db*xLambda )/( diag + db*pc_x ) calculate pc_x = pc_x + ddlambda*xLambda
243 {
245 void *void_ctx;
246 CHKERR PCShellGetContext(pc, &void_ctx);
248 void *void_MatCtx;
249 MatShellGetContext(ctx->
shellAij, &void_MatCtx);
251 PetscBool same;
252 PetscObjectTypeCompare((PetscObject)ctx->
kSP, KSPPREONLY, &same);
253
254 double res_lambda;
256
257
258 CHKERR KSPSetInitialGuessNonzero(ctx->
kSP, PETSC_FALSE);
259 CHKERR KSPSetInitialGuessKnoll(ctx->
kSP, PETSC_FALSE);
261 double db_dot_pc_x;
263
264
265 if (same != PETSC_TRUE) {
266 CHKERR KSPSetInitialGuessNonzero(ctx->
kSP, PETSC_TRUE);
267 } else {
268 CHKERR KSPSetInitialGuessNonzero(ctx->
kSP, PETSC_FALSE);
269 }
271 double db_dot_x_lambda;
273
274
276 double ddlambda = -(res_lambda - db_dot_pc_x) / denominator;
277
278
281
282 if (ddlambda != ddlambda || denominator == 0) {
283
284 double nrm2_pc_f, nrm2_db, nrm2_pc_x, nrm2_xLambda;
285 CHKERR VecNorm(pc_f, NORM_2, &nrm2_pc_f);
287 CHKERR VecNorm(pc_x, NORM_2, &nrm2_pc_x);
289
290 MOFEM_LOG(
"WORLD", Sev::error) <<
"problem with ddlambda=" << ddlambda;
291 MOFEM_LOG(
"WORLD", Sev::error) <<
"res_lambda=" << res_lambda;
292 MOFEM_LOG(
"WORLD", Sev::error) <<
"denominator=" << denominator;
293 MOFEM_LOG(
"WORLD", Sev::error) <<
"db_dot_pc_x=" << db_dot_pc_x;
294 MOFEM_LOG(
"WORLD", Sev::error) <<
"db_dot_x_lambda=" << db_dot_x_lambda;
296 MOFEM_LOG(
"WORLD", Sev::error) <<
"nrm2_db=" << nrm2_db;
297 MOFEM_LOG(
"WORLD", Sev::error) <<
"nrm2_pc_f=" << nrm2_pc_f;
298 MOFEM_LOG(
"WORLD", Sev::error) <<
"nrm2_pc_x=" << nrm2_pc_x;
299 MOFEM_LOG(
"WORLD", Sev::error) <<
"nrm2_xLambda=" << nrm2_xLambda;
300
302 "Increment of lambda is not number");
303
304 }
305
306
307 if (0) {
309 CHKERR VecDuplicate(pc_x, &y);
311 CHKERR VecAXPY(y, -1, pc_f);
312 double res_lambda_y;
314 double zero;
316 double norm_y;
317 CHKERR VecNorm(y, NORM_2, &norm_y);
318 MOFEM_LOG_C(
"WORLD", Sev::noisy,
"Debug res y = %3.4e res_lambda_y = %3.4e",
319 norm_y, res_lambda_y);
321 }
322
324}
#define MOFEM_LOG_C(channel, severity, format,...)
@ MOFEM_DATA_INCONSISTENCY
#define MOFEM_LOG(channel, severity)
Log.
const FTensor::Tensor2< T, Dim, Dim > Vec
SmartPetscObj< Vec > xLambda
solution of eq. K*xLambda = F_lambda
structure for Arc Length pre-conditioner
SmartPetscObj< Mat > shellAij