libMesh
petsc_nonlinear_solver.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #include "libmesh/libmesh_common.h"
21 
22 #ifdef LIBMESH_HAVE_PETSC
23 
24 // C++ includes
25 
26 // Local Includes
27 #include "libmesh/libmesh_logging.h"
28 #include "libmesh/nonlinear_implicit_system.h"
29 #include "libmesh/petsc_nonlinear_solver.h"
30 #include "libmesh/petsc_linear_solver.h"
31 #include "libmesh/petsc_vector.h"
32 #include "libmesh/petsc_matrix.h"
33 #include "libmesh/dof_map.h"
34 #include "libmesh/preconditioner.h"
35 #include "libmesh/solver_configuration.h"
36 
37 /* DMlibMesh include. */
38 #include "libmesh/petscdmlibmesh.h"
39 
40 // Pick the right version of the petsc line search getter function name
41 #if PETSC_VERSION_LESS_THAN(3,4,0)
42 # define SNESGETLINESEARCH SNESGetSNESLineSearch
43 #else
44 # define SNESGETLINESEARCH SNESGetLineSearch
45 #endif
46 
47 namespace libMesh
48 {
50 {
51 public:
53  PetscErrorCode ierr_in) :
54  solver(solver_in),
55  sys(sys_in),
56  ierr(ierr_in)
57  {}
58 
61  PetscErrorCode ierr;
62 };
63 
65 libmesh_petsc_snes_residual_helper (SNES snes, Vec x, void * ctx)
66 {
67  LOG_SCOPE("residual()", "PetscNonlinearSolver");
68 
69  PetscErrorCode ierr = 0;
70 
71  libmesh_assert(x);
73 
74  // No way to safety-check this cast, since we got a void *...
76  static_cast<PetscNonlinearSolver<Number> *> (ctx);
77 
78  // Get the current iteration number from the snes object,
79  // store it in the PetscNonlinearSolver object for possible use
80  // by the user's residual function.
81  {
82  PetscInt n_iterations = 0;
83  ierr = SNESGetIterationNumber(snes, &n_iterations);
84  CHKERRABORT(solver->comm().get(),ierr);
85  solver->_current_nonlinear_iteration_number = cast_int<unsigned>(n_iterations);
86  }
87 
88  NonlinearImplicitSystem & sys = solver->system();
89 
90  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
91 
92  PetscVector<Number> X_global(x, sys.comm());
93 
94  // Use the system's update() to get a good local version of the
95  // parallel solution. This operation does not modify the incoming
96  // "x" vector, it only localizes information from "x" into
97  // sys.current_local_solution.
98  X_global.swap(X_sys);
99  sys.update();
100  X_global.swap(X_sys);
101 
102  // Enforce constraints (if any) exactly on the
103  // current_local_solution. This is the solution vector that is
104  // actually used in the computation of the residual below, and is
105  // not locked by debug-enabled PETSc the way that "x" is.
107 
108  return ResidualContext(solver, sys, ierr);
109 }
110 
111 //--------------------------------------------------------------------
112 // Functions with C linkage to pass to PETSc. PETSc will call these
113 // methods as needed.
114 //
115 // Since they must have C linkage they have no knowledge of a namespace.
116 // Give them an obscure name to avoid namespace pollution.
117 extern "C"
118 {
119 
120  //-------------------------------------------------------------------
121  // this function is called by PETSc at the end of each nonlinear step
122  PetscErrorCode
123  libmesh_petsc_snes_monitor (SNES, PetscInt its, PetscReal fnorm, void *)
124  {
125  //PetscErrorCode ierr=0;
126 
127  //if (its > 0)
128  libMesh::out << " NL step "
129  << std::setw(2) << its
130  << std::scientific
131  << ", |residual|_2 = " << fnorm
132  << std::endl;
133 
134  //return ierr;
135  return 0;
136  }
137 
138 #ifdef LIBMESH_ENABLE_DEPRECATED
139  PetscErrorCode
140  __libmesh_petsc_snes_monitor (SNES, PetscInt its, PetscReal fnorm, void *)
141  {
142  libmesh_deprecated();
143  return libmesh_petsc_snes_monitor(nullptr, its, fnorm, nullptr);
144  }
145 #endif
146 
147 
148  //---------------------------------------------------------------
149  // this function is called by PETSc to evaluate the residual at X
150  PetscErrorCode
151  libmesh_petsc_snes_residual (SNES snes, Vec x, Vec r, void * ctx)
152  {
154 
155  libmesh_assert(r);
156  PetscVector<Number> R(r, rc.sys.comm());
157 
158  if (rc.solver->_zero_out_residual)
159  R.zero();
160 
161  //-----------------------------------------------------------------------------
162  // if the user has provided both function pointers and objects only the pointer
163  // will be used, so catch that as an error
164  if (rc.solver->residual && rc.solver->residual_object)
165  libmesh_error_msg("ERROR: cannot specify both a function and object to compute the Residual!");
166 
168  libmesh_error_msg("ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
169 
170  if (rc.solver->residual != nullptr)
171  rc.solver->residual(*rc.sys.current_local_solution.get(), R, rc.sys);
172 
173  else if (rc.solver->residual_object != nullptr)
175 
176  else if (rc.solver->matvec != nullptr)
177  rc.solver->matvec (*rc.sys.current_local_solution.get(), &R, nullptr, rc.sys);
178 
179  else if (rc.solver->residual_and_jacobian_object != nullptr)
181 
182  else
183  libmesh_error_msg("Error! Unable to compute residual and/or Jacobian!");
184 
185  PetscVector<Number> X(x, rc.sys.comm());
186 
187  R.close();
189  R.close();
190 
191  return rc.ierr;
192  }
193 
194 #ifdef LIBMESH_ENABLE_DEPRECATED
195  PetscErrorCode
196  __libmesh_petsc_snes_residual (SNES snes, Vec x, Vec r, void * ctx)
197  {
198  libmesh_deprecated();
199  return libmesh_petsc_snes_residual(snes, x, r, ctx);
200  }
201 #endif
202 
203  //-----------------------------------------------------------------------------------------
204  // this function is called by PETSc to approximate the Jacobian at X via finite differences
205  PetscErrorCode
206  libmesh_petsc_snes_fd_residual (SNES snes, Vec x, Vec r, void * ctx)
207  {
209 
210  libmesh_assert(r);
211  PetscVector<Number> R(r, rc.sys.comm());
212 
213  if (rc.solver->_zero_out_residual)
214  R.zero();
215 
216  if (rc.solver->fd_residual_object != nullptr)
218 
219  else if (rc.solver->residual_object != nullptr)
221 
222  else
223  libmesh_error_msg("Error! Unable to compute residual for forming finite difference Jacobian!");
224 
225  R.close();
226  PetscVector<Number> X(x, rc.sys.comm());
228 
229  R.close();
230 
231  return rc.ierr;
232  }
233 
234 #ifdef LIBMESH_ENABLE_DEPRECATED
235  PetscErrorCode
236  __libmesh_petsc_snes_fd_residual (SNES snes, Vec x, Vec r, void * ctx)
237  {
238  libmesh_deprecated();
239  return libmesh_petsc_snes_fd_residual(snes, x, r, ctx);
240  }
241 #endif
242 
243  //----------------------------------------------------------------
244  // this function is called by PETSc to approximate Jacobian-vector
245  // products at X via finite differences
246  PetscErrorCode
247  libmesh_petsc_snes_mffd_residual (SNES snes, Vec x, Vec r, void * ctx)
248  {
250 
251  libmesh_assert(r);
252  PetscVector<Number> R(r, rc.sys.comm());
253 
254  if (rc.solver->_zero_out_residual)
255  R.zero();
256 
257  if (rc.solver->mffd_residual_object != nullptr)
259 
260  else if (rc.solver->residual_object != nullptr)
262 
263  else
264  libmesh_error_msg("Error! Unable to compute residual for forming finite differenced"
265  "Jacobian-vector products!");
266 
267  R.close();
268  PetscVector<Number> X(x, rc.sys.comm());
270 
271  R.close();
272 
273  return rc.ierr;
274  }
275 
276  //----------------------------------------------------------
277  // this function serves an interface between the petsc layer
278  // and the actual mffd residual computing routine
279  PetscErrorCode
280  libmesh_petsc_snes_mffd_interface (void * ctx, Vec x, Vec r)
281  {
282  // No way to safety-check this cast, since we got a void *...
284  static_cast<PetscNonlinearSolver<Number> *> (ctx);
285 
286  return libmesh_petsc_snes_mffd_residual(solver->snes(), x, r, ctx);
287  }
288 
289 #ifdef LIBMESH_ENABLE_DEPRECATED
290  PetscErrorCode
292  {
293  libmesh_deprecated();
295  }
296 #endif
297 
298  //---------------------------------------------------------------
299  // this function is called by PETSc to evaluate the Jacobian at X
300  PetscErrorCode
302 #if PETSC_RELEASE_LESS_THAN(3,5,0)
303  SNES snes, Vec x, Mat * jac, Mat * pc, MatStructure * msflag, void * ctx
304 #else
305  SNES snes, Vec x, Mat jac, Mat pc, void * ctx
306 #endif
307  )
308  {
309  LOG_SCOPE("jacobian()", "PetscNonlinearSolver");
310 
311  PetscErrorCode ierr=0;
312 
314 
315  // No way to safety-check this cast, since we got a void *...
317  static_cast<PetscNonlinearSolver<Number> *> (ctx);
318 
319  // Get the current iteration number from the snes object,
320  // store it in the PetscNonlinearSolver object for possible use
321  // by the user's Jacobian function.
322  {
323  PetscInt n_iterations = 0;
324  ierr = SNESGetIterationNumber(snes, &n_iterations);
325  CHKERRABORT(solver->comm().get(),ierr);
326  solver->_current_nonlinear_iteration_number = cast_int<unsigned>(n_iterations);
327  }
328 
329  NonlinearImplicitSystem & sys = solver->system();
330 #if PETSC_RELEASE_LESS_THAN(3,5,0)
331  PetscMatrix<Number> PC(*pc, sys.comm());
332  PetscMatrix<Number> Jac(*jac, sys.comm());
333 #else
334  PetscMatrix<Number> PC(pc, sys.comm());
335  PetscMatrix<Number> Jac(jac, sys.comm());
336 #endif
337  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
338  PetscVector<Number> X_global(x, sys.comm());
339 
340  // Set the dof maps
341  PC.attach_dof_map(sys.get_dof_map());
342  Jac.attach_dof_map(sys.get_dof_map());
343 
344  // Use the systems update() to get a good local version of the parallel solution
345  X_global.swap(X_sys);
346  sys.update();
347  X_global.swap(X_sys);
348 
349  // Enforce constraints (if any) exactly on the
350  // current_local_solution. This is the solution vector that is
351  // actually used in the computation of the residual below, and is
352  // not locked by debug-enabled PETSc the way that "x" is.
354 
355  if (solver->_zero_out_jacobian)
356  PC.zero();
357 
358  //-----------------------------------------------------------------------------
359  // if the user has provided both function pointers and objects only the pointer
360  // will be used, so catch that as an error
361  if (solver->jacobian && solver->jacobian_object)
362  libmesh_error_msg("ERROR: cannot specify both a function and object to compute the Jacobian!");
363 
364  if (solver->matvec && solver->residual_and_jacobian_object)
365  libmesh_error_msg("ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
366 
367  if (solver->jacobian != nullptr)
368  solver->jacobian(*sys.current_local_solution.get(), PC, sys);
369 
370  else if (solver->jacobian_object != nullptr)
371  solver->jacobian_object->jacobian(*sys.current_local_solution.get(), PC, sys);
372 
373  else if (solver->matvec != nullptr)
374  solver->matvec(*sys.current_local_solution.get(), nullptr, &PC, sys);
375 
376  else if (solver->residual_and_jacobian_object != nullptr)
377  solver->residual_and_jacobian_object->residual_and_jacobian (*sys.current_local_solution.get(), nullptr, &PC, sys);
378 
379  else
380  libmesh_error_msg("Error! Unable to compute residual and/or Jacobian!");
381 
382  PC.close();
384 
385  PC.close();
386  Jac.close();
387 #if PETSC_RELEASE_LESS_THAN(3,5,0)
388  *msflag = SAME_NONZERO_PATTERN;
389 #endif
390 
391  return ierr;
392  }
393 
394  // This function gets called by PETSc in place of the standard Petsc line searches
395  // if a linesearch object is supplied to the PetscNonlinearSolver class. It wraps
396  // the lineserach algorithm implemented on the linesearch object.
397  // * "linesearch" is an object that can be used to access the non-linear and linear solution
398  // vectors as well as the residual and SNES object
399  // * "ctx" is the PetscNonlinearSolver context
400  PetscErrorCode libmesh_petsc_linesearch_shellfunc (SNESLineSearch linesearch, void * ctx)
401  {
402  // No way to safety-check this cast, since we got a void *...
404  static_cast<PetscNonlinearSolver<Number> *> (ctx);
405 
406  solver->linesearch_object->linesearch(linesearch);
407  return 0;
408  }
409 
410 #ifdef LIBMESH_ENABLE_DEPRECATED
411  PetscErrorCode
413 #if PETSC_RELEASE_LESS_THAN(3,5,0)
414  SNES snes, Vec x, Mat * jac, Mat * pc, MatStructure * msflag, void * ctx
415 #else
416  SNES snes, Vec x, Mat jac, Mat pc, void * ctx
417 #endif
418  )
419  {
420  libmesh_deprecated();
422 #if PETSC_RELEASE_LESS_THAN(3,5,0)
423  snes, x, jac, pc, msflag, ctx
424 #else
425  snes, x, jac, pc, ctx
426 #endif
427  );
428  }
429 #endif
430 
431  // This function gets called by PETSc after the SNES linesearch is
432  // complete. We use it to exactly enforce any constraints on the
433  // solution which may have drifted during the linear solve. In the
434  // PETSc nomenclature:
435  // * "x" is the old solution vector,
436  // * "y" is the search direction (Newton step) vector,
437  // * "w" is the candidate solution vector, and
438  // the user is responsible for setting changed_y and changed_w
439  // appropriately, depending on whether or not the search
440  // direction or solution vector was changed, respectively.
442 #if PETSC_VERSION_LESS_THAN(3,3,0)
443  SNES, Vec x, Vec y, Vec w, void * context, PetscBool * changed_y, PetscBool * changed_w
444 #else
445  SNESLineSearch, Vec x, Vec y, Vec w, PetscBool * changed_y, PetscBool * changed_w, void * context
446 #endif
447  )
448  {
449  LOG_SCOPE("postcheck()", "PetscNonlinearSolver");
450 
451  PetscErrorCode ierr = 0;
452 
453  // PETSc almost certainly initializes these to false already, but
454  // it doesn't hurt to be explicit.
455  *changed_w = PETSC_FALSE;
456  *changed_y = PETSC_FALSE;
457 
458  libmesh_assert(context);
459 
460  // Cast the context to a NonlinearSolver object.
462  static_cast<PetscNonlinearSolver<Number> *> (context);
463 
464  // If the user has provided both postcheck function pointer and
465  // object, this is ambiguous, so throw an error.
466  if (solver->postcheck && solver->postcheck_object)
467  libmesh_error_msg("ERROR: cannot specify both a function and object for performing the solve postcheck!");
468 
469  // It's also possible that we don't need to do anything at all, in
470  // that case return early...
471  NonlinearImplicitSystem & sys = solver->system();
472 
473  if (!solver->postcheck && !solver->postcheck_object)
474  return ierr;
475 
476  // We definitely need to wrap at least "w"
477  PetscVector<Number> petsc_w(w, sys.comm());
478 
479  // The user sets these flags in his/her postcheck function to
480  // indicate whether they changed something.
481  bool
482  changed_search_direction = false,
483  changed_new_soln = false;
484 
485  if (solver->postcheck || solver->postcheck_object)
486  {
487  PetscVector<Number> petsc_x(x, sys.comm());
488  PetscVector<Number> petsc_y(y, sys.comm());
489 
490  if (solver->postcheck)
491  solver->postcheck(petsc_x,
492  petsc_y,
493  petsc_w,
494  changed_search_direction,
495  changed_new_soln,
496  sys);
497 
498  else if (solver->postcheck_object)
499  solver->postcheck_object->postcheck(petsc_x,
500  petsc_y,
501  petsc_w,
502  changed_search_direction,
503  changed_new_soln,
504  sys);
505  }
506 
507  // Record whether the user changed the solution or the search direction.
508  if (changed_search_direction)
509  *changed_y = PETSC_TRUE;
510 
511  if (changed_new_soln)
512  *changed_w = PETSC_TRUE;
513 
514  return ierr;
515  }
516 
517 #ifdef LIBMESH_ENABLE_DEPRECATED
519 #if PETSC_VERSION_LESS_THAN(3,3,0)
520  SNES, Vec x, Vec y, Vec w, void * context, PetscBool * changed_y, PetscBool * changed_w
521 #else
522  SNESLineSearch, Vec x, Vec y, Vec w, PetscBool * changed_y, PetscBool * changed_w, void * context
523 #endif
524  )
525  {
526  libmesh_deprecated();
528 #if PETSC_VERSION_LESS_THAN(3,3,0)
529  nullptr, x, y, w, context, changed_y, changed_w
530 #else
531  nullptr, x, y, w, changed_y, changed_w, context
532 #endif
533  );
534  }
535 #endif
536 } // end extern "C"
537 
538 
539 
540 //---------------------------------------------------------------------
541 // PetscNonlinearSolver<> methods
542 template <typename T>
544  NonlinearSolver<T>(system_in),
545  linesearch_object(nullptr),
546  _reason(SNES_CONVERGED_ITERATING/*==0*/), // Arbitrary initial value...
547  _n_linear_iterations(0),
548  _current_nonlinear_iteration_number(0),
549  _zero_out_residual(true),
550  _zero_out_jacobian(true),
551  _default_monitor(true),
552  _snesmf_reuse_base(true)
553 {
554 }
555 
556 
557 
558 template <typename T>
560 {
561  this->clear ();
562 }
563 
564 
565 
566 template <typename T>
568 {
569  if (this->initialized())
570  {
571  this->_is_initialized = false;
572 
573  PetscErrorCode ierr=0;
574 
575  ierr = LibMeshSNESDestroy(&_snes);
576  LIBMESH_CHKERR(ierr);
577 
578  // Reset the nonlinear iteration counter. This information is only relevant
579  // *during* the solve(). After the solve is completed it should return to
580  // the default value of 0.
581  _current_nonlinear_iteration_number = 0;
582  }
583 }
584 
585 
586 
587 template <typename T>
589 {
590  // Initialize the data structures if not done so already.
591  if (!this->initialized())
592  {
593  this->_is_initialized = true;
594 
595  PetscErrorCode ierr=0;
596 
597  ierr = SNESCreate(this->comm().get(),&_snes);
598  LIBMESH_CHKERR(ierr);
599 
600  if (name)
601  {
602  ierr = SNESSetOptionsPrefix(_snes, name);
603  LIBMESH_CHKERR(ierr);
604  }
605 
606 #if !PETSC_RELEASE_LESS_THAN(3,3,0)
607  // Attaching a DM to SNES.
608  DM dm;
609  ierr = DMCreate(this->comm().get(), &dm);LIBMESH_CHKERR(ierr);
610  ierr = DMSetType(dm,DMLIBMESH);LIBMESH_CHKERR(ierr);
611  ierr = DMlibMeshSetSystem(dm,this->system());LIBMESH_CHKERR(ierr);
612  if (name)
613  {
614  ierr = DMSetOptionsPrefix(dm,name); LIBMESH_CHKERR(ierr);
615  }
616  ierr = DMSetFromOptions(dm); LIBMESH_CHKERR(ierr);
617  ierr = DMSetUp(dm); LIBMESH_CHKERR(ierr);
618  ierr = SNESSetDM(this->_snes, dm); LIBMESH_CHKERR(ierr);
619  // SNES now owns the reference to dm.
620  ierr = DMDestroy(&dm); LIBMESH_CHKERR(ierr);
621 
622 #endif
623 
624  if (_default_monitor)
625  {
626  ierr = SNESMonitorSet (_snes, libmesh_petsc_snes_monitor,
627  this, PETSC_NULL);
628  LIBMESH_CHKERR(ierr);
629  }
630 
631  // If the SolverConfiguration object is provided, use it to set
632  // options during solver initialization.
633  if (this->_solver_configuration)
634  {
635  this->_solver_configuration->set_options_during_init();
636  }
637 
638 #if PETSC_VERSION_LESS_THAN(3,1,0)
639  // Cannot call SNESSetOptions before SNESSetFunction when using
640  // any matrix free options with PETSc 3.1.0+
641  ierr = SNESSetFromOptions(_snes);
642  LIBMESH_CHKERR(ierr);
643 #endif
644 
645  if (this->_preconditioner)
646  {
647  KSP ksp;
648  ierr = SNESGetKSP (_snes, &ksp);
649  LIBMESH_CHKERR(ierr);
650  PC pc;
651  ierr = KSPGetPC(ksp,&pc);
652  LIBMESH_CHKERR(ierr);
653 
654  this->_preconditioner->init();
655 
656  PCSetType(pc, PCSHELL);
657  PCShellSetContext(pc,(void *)this->_preconditioner);
658 
659  //Re-Use the shell functions from petsc_linear_solver
660  PCShellSetSetUp(pc,libmesh_petsc_preconditioner_setup);
661  PCShellSetApply(pc,libmesh_petsc_preconditioner_apply);
662  }
663  }
664 
665 
666  // Tell PETSc about our linesearch "post-check" function, but only
667  // if the user has provided one. There seem to be extra,
668  // unnecessary residual calculations if a postcheck function is
669  // attached for no reason.
670  if (this->postcheck || this->postcheck_object)
671  {
672 #if PETSC_VERSION_LESS_THAN(3,3,0)
673  PetscErrorCode ierr = SNESLineSearchSetPostCheck(_snes, libmesh_petsc_snes_postcheck, this);
674  LIBMESH_CHKERR(ierr);
675 
676 #else
677  SNESLineSearch linesearch;
678  PetscErrorCode ierr = SNESGETLINESEARCH(_snes, &linesearch);
679  LIBMESH_CHKERR(ierr);
680 
681  ierr = SNESLineSearchSetPostCheck(linesearch, libmesh_petsc_snes_postcheck, this);
682  LIBMESH_CHKERR(ierr);
683 #endif
684  }
685 }
686 
687 #if !PETSC_VERSION_LESS_THAN(3,3,0)
688 template <typename T>
689 void
691  void (*computeSubspace)(std::vector<NumericVector<Number> *> &, sys_type &),
692  MatNullSpace * msp)
693 {
694  PetscErrorCode ierr;
695  std::vector<NumericVector<Number> *> sp;
696  if (computeSubspaceObject)
697  (*computeSubspaceObject)(sp, this->system());
698  else
699  (*computeSubspace)(sp, this->system());
700 
701  *msp = PETSC_NULL;
702  if (sp.size())
703  {
704  Vec * modes;
705  PetscScalar * dots;
706  PetscInt nmodes = cast_int<PetscInt>(sp.size());
707 
708 #if PETSC_RELEASE_LESS_THAN(3,5,0)
709  ierr = PetscMalloc2(nmodes,Vec,&modes,nmodes,PetscScalar,&dots);
710 #else
711  ierr = PetscMalloc2(nmodes,&modes,nmodes,&dots);
712 #endif
713  LIBMESH_CHKERR(ierr);
714 
715  for (PetscInt i=0; i<nmodes; ++i)
716  {
717  PetscVector<T> * pv = cast_ptr<PetscVector<T> *>(sp[i]);
718  Vec v = pv->vec();
719 
720  ierr = VecDuplicate(v, modes+i);
721  LIBMESH_CHKERR(ierr);
722 
723  ierr = VecCopy(v,modes[i]);
724  LIBMESH_CHKERR(ierr);
725  }
726 
727  // Normalize.
728  ierr = VecNormalize(modes[0],PETSC_NULL);
729  LIBMESH_CHKERR(ierr);
730 
731  for (PetscInt i=1; i<nmodes; i++)
732  {
733  // Orthonormalize vec[i] against vec[0:i-1]
734  ierr = VecMDot(modes[i],i,modes,dots);
735  LIBMESH_CHKERR(ierr);
736 
737  for (PetscInt j=0; j<i; j++)
738  dots[j] *= -1.;
739 
740  ierr = VecMAXPY(modes[i],i,dots,modes);
741  LIBMESH_CHKERR(ierr);
742 
743  ierr = VecNormalize(modes[i],PETSC_NULL);
744  LIBMESH_CHKERR(ierr);
745  }
746 
747  ierr = MatNullSpaceCreate(this->comm().get(), PETSC_FALSE, nmodes, modes, msp);
748  LIBMESH_CHKERR(ierr);
749 
750  for (PetscInt i=0; i<nmodes; ++i)
751  {
752  ierr = VecDestroy(modes+i);
753  LIBMESH_CHKERR(ierr);
754  }
755 
756  ierr = PetscFree2(modes,dots);
757  LIBMESH_CHKERR(ierr);
758  }
759 }
760 #endif
761 
762 template <typename T>
763 std::pair<unsigned int, Real>
764 PetscNonlinearSolver<T>::solve (SparseMatrix<T> & pre_in, // System Preconditioning Matrix
765  NumericVector<T> & x_in, // Solution vector
766  NumericVector<T> & r_in, // Residual vector
767  const double, // Stopping tolerance
768  const unsigned int)
769 {
770  LOG_SCOPE("solve()", "PetscNonlinearSolver");
771  this->init ();
772 
773  // Make sure the data passed in are really of Petsc types
774  PetscMatrix<T> * pre = cast_ptr<PetscMatrix<T> *>(&pre_in);
775  PetscVector<T> * x = cast_ptr<PetscVector<T> *>(&x_in);
776  PetscVector<T> * r = cast_ptr<PetscVector<T> *>(&r_in);
777 
778  PetscErrorCode ierr=0;
779  PetscInt n_iterations =0;
780  // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal
781  Real final_residual_norm=0.;
782 
783  ierr = SNESSetFunction (_snes, r->vec(), libmesh_petsc_snes_residual, this);
784  LIBMESH_CHKERR(ierr);
785 
786  // Only set the jacobian function if we've been provided with something to call.
787  // This allows a user to set their own jacobian function if they want to
788  if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
789  {
790  ierr = SNESSetJacobian (_snes, pre->mat(), pre->mat(), libmesh_petsc_snes_jacobian, this);
791  LIBMESH_CHKERR(ierr);
792  }
793 
794 
795 #if !PETSC_VERSION_LESS_THAN(3,3,0)
796  // Only set the nullspace if we have a way of computing it and the result is non-empty.
797  if (this->nullspace || this->nullspace_object)
798  {
799  MatNullSpace msp;
800  this->build_mat_null_space(this->nullspace_object, this->nullspace, &msp);
801  if (msp)
802  {
803  ierr = MatSetNullSpace(pre->mat(), msp);
804  LIBMESH_CHKERR(ierr);
805  ierr = MatNullSpaceDestroy(&msp);
806  LIBMESH_CHKERR(ierr);
807  }
808  }
809 
810  // Only set the transpose nullspace if we have a way of computing it and the result is non-empty.
811  if (this->transpose_nullspace || this->transpose_nullspace_object)
812  {
813 #if PETSC_VERSION_LESS_THAN(3,6,0)
814  libmesh_warning("MatSetTransposeNullSpace is only supported for PETSc >= 3.6, transpose nullspace will be ignored.");
815 #else
816  MatNullSpace msp = PETSC_NULL;
817  this->build_mat_null_space(this->transpose_nullspace_object, this->transpose_nullspace, &msp);
818  if (msp)
819  {
820  ierr = MatSetTransposeNullSpace(pre->mat(), msp);
821  LIBMESH_CHKERR(ierr);
822  ierr = MatNullSpaceDestroy(&msp);
823  LIBMESH_CHKERR(ierr);
824  }
825 #endif
826  }
827 
828  // Only set the nearnullspace if we have a way of computing it and the result is non-empty.
829  if (this->nearnullspace || this->nearnullspace_object)
830  {
831  MatNullSpace msp = PETSC_NULL;
832  this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, &msp);
833 
834  if (msp)
835  {
836  ierr = MatSetNearNullSpace(pre->mat(), msp);
837  LIBMESH_CHKERR(ierr);
838  ierr = MatNullSpaceDestroy(&msp);
839  LIBMESH_CHKERR(ierr);
840  }
841  }
842 #endif
843 
844  // Have the Krylov subspace method use our good initial guess rather than 0
845  KSP ksp;
846  ierr = SNESGetKSP (_snes, &ksp);
847  LIBMESH_CHKERR(ierr);
848 
849  // Set the tolerances for the iterative solver. Use the user-supplied
850  // tolerance for the relative residual & leave the others at default values
851  ierr = KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT,
852  PETSC_DEFAULT, this->max_linear_iterations);
853  LIBMESH_CHKERR(ierr);
854 
855  // Set the tolerances for the non-linear solver.
856  ierr = SNESSetTolerances(_snes, this->absolute_residual_tolerance, this->relative_residual_tolerance,
857  this->relative_step_tolerance, this->max_nonlinear_iterations, this->max_function_evaluations);
858  LIBMESH_CHKERR(ierr);
859 
860  // Set the divergence tolerance for the non-linear solver
861 #if !PETSC_VERSION_LESS_THAN(3,8,0)
862  ierr = SNESSetDivergenceTolerance(_snes, this->divergence_tolerance);
863  LIBMESH_CHKERR(ierr);
864 #endif
865 
866  //Pull in command-line options
867 #if PETSC_VERSION_LESS_THAN(3,7,0)
868  KSPSetFromOptions(ksp);
869 #endif
870  SNESSetFromOptions(_snes);
871 
872  if (this->user_presolve)
873  this->user_presolve(this->system());
874 
875  //Set the preconditioning matrix
876  if (this->_preconditioner)
877  {
878  this->_preconditioner->set_matrix(pre_in);
879  this->_preconditioner->init();
880  }
881 
882  // If the SolverConfiguration object is provided, use it to override
883  // solver options.
884  if (this->_solver_configuration)
885  {
886  this->_solver_configuration->configure_solver();
887  }
888 
889  // In PETSc versions before 3.5.0, it is not possible to call
890  // SNESSetUp() before the solution and rhs vectors are initialized, as
891  // this triggers the
892  //
893  // "Solution vector cannot be right hand side vector!"
894  //
895  // error message. It is also not possible to call SNESSetSolution()
896  // in those versions of PETSc to work around the problem, since that
897  // API was removed in 3.0.0 and only restored in 3.6.0. The
898  // overzealous check was moved out of SNESSetUp in PETSc 3.5.0
899  // (petsc/petsc@154060b), so this code block should be safe to use
900  // in 3.5.0 and later.
901 #if !PETSC_VERSION_LESS_THAN(3,5,0)
902 #if !PETSC_VERSION_LESS_THAN(3,6,0)
903  ierr = SNESSetSolution(_snes, x->vec());
904  LIBMESH_CHKERR(ierr);
905 #endif
906  ierr = SNESSetUp(_snes);
907  LIBMESH_CHKERR(ierr);
908 
909  Mat J;
910  ierr = SNESGetJacobian(_snes,&J,PETSC_NULL,PETSC_NULL,PETSC_NULL);
911  LIBMESH_CHKERR(ierr);
912  ierr = MatMFFDSetFunction(J, libmesh_petsc_snes_mffd_interface, this);
913  LIBMESH_CHKERR(ierr);
914 #if !PETSC_VERSION_LESS_THAN(3, 8, 4)
915  // Resue the residual vector from SNES
916  ierr = MatSNESMFSetReuseBase(J, static_cast<PetscBool>(_snesmf_reuse_base));
917  LIBMESH_CHKERR(ierr);
918 #endif
919 #endif
920 
921 #if PETSC_VERSION_LESS_THAN(3, 3, 0)
922  if (linesearch_object)
923  libmesh_error_msg("Line search setter interface introduced in petsc version 3.3!");
924 #else
925  SNESLineSearch linesearch;
926  if (linesearch_object)
927  {
928  ierr = SNESGETLINESEARCH(_snes, &linesearch);
929  LIBMESH_CHKERR(ierr);
930  ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL);
931  LIBMESH_CHKERR(ierr);
932  ierr = SNESLineSearchShellSetUserFunc(linesearch, libmesh_petsc_linesearch_shellfunc, this);
933  LIBMESH_CHKERR(ierr);
934  }
935 #endif
936 
937  ierr = SNESSolve (_snes, PETSC_NULL, x->vec());
938  LIBMESH_CHKERR(ierr);
939 
940  ierr = SNESGetIterationNumber(_snes,&n_iterations);
941  LIBMESH_CHKERR(ierr);
942 
943  ierr = SNESGetLinearSolveIterations(_snes, &_n_linear_iterations);
944  LIBMESH_CHKERR(ierr);
945 
946  // SNESGetFunction has been around forever and should work on all
947  // versions of PETSc. This is also now the recommended approach
948  // according to the documentation for the PETSc 3.5.1 release:
949  // http://www.mcs.anl.gov/petsc/documentation/changes/35.html
950  Vec f;
951  ierr = SNESGetFunction(_snes, &f, 0, 0);
952  LIBMESH_CHKERR(ierr);
953  ierr = VecNorm(f, NORM_2, pPR(&final_residual_norm));
954  LIBMESH_CHKERR(ierr);
955 
956  // Get and store the reason for convergence
957  SNESGetConvergedReason(_snes, &_reason);
958 
959  //Based on Petsc 2.3.3 documentation all diverged reasons are negative
960  this->converged = (_reason >= 0);
961 
962  this->clear();
963 
964  // return the # of its. and the final residual norm.
965  return std::make_pair(n_iterations, final_residual_norm);
966 }
967 
968 
969 
970 template <typename T>
972 {
973 
974  libMesh::out << "Nonlinear solver convergence/divergence reason: "
975  << SNESConvergedReasons[this->get_converged_reason()] << std::endl;
976 }
977 
978 
979 
980 template <typename T>
982 {
983  PetscErrorCode ierr=0;
984 
985  if (this->initialized())
986  {
987  ierr = SNESGetConvergedReason(_snes, &_reason);
988  LIBMESH_CHKERR(ierr);
989  }
990 
991  return _reason;
992 }
993 
994 template <typename T>
996 {
997  return _n_linear_iterations;
998 }
999 
1000 
1001 //------------------------------------------------------------------
1002 // Explicit instantiations
1003 template class PetscNonlinearSolver<Number>;
1004 
1005 } // namespace libMesh
1006 
1007 
1008 
1009 #endif // #ifdef LIBMESH_HAVE_PETSC
libMesh::PetscNonlinearSolver< Number >
libMesh::NonlinearImplicitSystem::ComputeJacobian::jacobian
virtual void jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)=0
Jacobian function.
libMesh::libmesh_petsc_snes_residual
PetscErrorCode libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
Definition: petsc_nonlinear_solver.C:151
libMesh::ResidualContext
Definition: petsc_nonlinear_solver.C:49
libMesh::NonlinearSolver
This base class can be inherited from to provide interfaces to nonlinear solvers from different packa...
Definition: nonlinear_solver.h:60
libMesh::__libmesh_petsc_snes_residual
PetscErrorCode __libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
Definition: petsc_nonlinear_solver.C:196
libMesh::PetscNonlinearSolver::_zero_out_jacobian
bool _zero_out_jacobian
true to zero out jacobian before going into application level call-back, otherwise false
Definition: petsc_nonlinear_solver.h:246
libMesh::NonlinearSolver::fd_residual_object
NonlinearImplicitSystem::ComputeResidual * fd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
Definition: nonlinear_solver.h:151
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::NonlinearSolver::residual
void(* residual)(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)
Function that computes the residual R(X) of the nonlinear system at the input iterate X.
Definition: nonlinear_solver.h:137
libMesh::PetscMatrix::mat
Mat mat()
Definition: petsc_matrix.h:281
libMesh::pPR
PetscReal * pPR(T *ptr)
Definition: petsc_macro.h:186
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::libmesh_petsc_snes_fd_residual
PetscErrorCode libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
Definition: petsc_nonlinear_solver.C:206
libMesh::PetscNonlinearSolver::_current_nonlinear_iteration_number
unsigned _current_nonlinear_iteration_number
Stores the current nonlinear iteration number.
Definition: petsc_nonlinear_solver.h:236
libMesh::PetscNonlinearSolver::PetscNonlinearSolver
PetscNonlinearSolver(sys_type &system)
Constructor.
Definition: petsc_nonlinear_solver.C:543
libMesh::__libmesh_petsc_snes_monitor
PetscErrorCode __libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
Definition: petsc_nonlinear_solver.C:140
libMesh::NonlinearImplicitSystem::ComputeResidual::residual
virtual void residual(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)=0
Residual function.
libMesh::NonlinearSolver::matvec
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)
Function that computes either the residual or the Jacobian of the nonlinear system at the input ite...
Definition: nonlinear_solver.h:181
libMesh::ierr
ierr
Definition: petsc_dm_wrapper.C:72
libMesh::NonlinearImplicitSystem
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
Definition: nonlinear_implicit_system.h:54
libMesh::PetscNonlinearSolver::linesearch_object
std::unique_ptr< ComputeLineSearchObject > linesearch_object
A callable object that can be used to specify a custom line-search.
Definition: petsc_nonlinear_solver.h:207
libMesh::SparseMatrix
Generic sparse matrix.
Definition: vector_fe_ex5.C:45
libmesh_petsc_preconditioner_setup
PetscErrorCode libmesh_petsc_preconditioner_setup(void *ctx)
This function is called by PETSc to initialize the preconditioner.
Definition: petsc_linear_solver.C:49
DMlibMeshSetSystem
PETSC_EXTERN PetscErrorCode DMlibMeshSetSystem(DM, libMesh::NonlinearImplicitSystem &)
Any functional implementation of the DMlibMesh API must compose the following functions with the DM o...
Definition: petscdmlibmesh.C:34
libMesh::libmesh_petsc_snes_mffd_residual
PetscErrorCode libmesh_petsc_snes_mffd_residual(SNES snes, Vec x, Vec r, void *ctx)
Definition: petsc_nonlinear_solver.C:247
PetscBool
PetscTruth PetscBool
Definition: petsc_macro.h:73
libMesh::NumericVector< Number >
libMesh::NonlinearSolver::jacobian_object
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
Object that computes the Jacobian J(X) of the nonlinear system at the input iterate X.
Definition: nonlinear_solver.h:172
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::PetscNonlinearSolver::snes
SNES snes()
Definition: petsc_nonlinear_solver.h:132
libMesh::__libmesh_petsc_snes_mffd_interface
PetscErrorCode __libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
Definition: petsc_nonlinear_solver.C:291
libMesh::ResidualContext::ResidualContext
ResidualContext(PetscNonlinearSolver< Number > *solver_in, NonlinearImplicitSystem &sys_in, PetscErrorCode ierr_in)
Definition: petsc_nonlinear_solver.C:52
libMesh::DofMap::enforce_constraints_on_residual
void enforce_constraints_on_residual(const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
Definition: dof_map.h:2063
libMesh::libmesh_petsc_snes_jacobian
PetscErrorCode libmesh_petsc_snes_jacobian(SNES, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx)
libMesh::PetscVector::close
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
Definition: petsc_vector.h:821
libMesh::DofMap::enforce_constraints_exactly
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh.
Definition: dof_map.h:2054
libMesh::libmesh_petsc_snes_monitor
PetscErrorCode libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
Definition: petsc_nonlinear_solver.C:123
libMesh::System::current_local_solution
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1551
libMesh::libmesh_petsc_snes_jacobian
PetscErrorCode libmesh_petsc_snes_jacobian(#if PETSC_RELEASE_LESS_THAN(3, 5, 0) SNES snes, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx #else SNES snes, Vec x, Mat jac, Mat pc, void *ctx #endif)
Definition: petsc_nonlinear_solver.C:301
libMesh::libmesh_petsc_linesearch_shellfunc
PetscErrorCode libmesh_petsc_linesearch_shellfunc(SNESLineSearch linesearch, void *ctx)
Definition: petsc_nonlinear_solver.C:400
libMesh::NonlinearImplicitSystem::ComputeVectorSubspace
Callable abstract base class to be used as a callback to provide the solver with a basis for the syst...
Definition: nonlinear_implicit_system.h:147
libMesh::PetscVector
This class provides a nice interface to PETSc's Vec object.
Definition: petsc_vector.h:72
libMesh::NonlinearSolver::residual_object
NonlinearImplicitSystem::ComputeResidual * residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X.
Definition: nonlinear_solver.h:145
libMesh::__libmesh_petsc_snes_postcheck
PetscErrorCode __libmesh_petsc_snes_postcheck(#if PETSC_VERSION_LESS_THAN(3, 3, 0) SNES, Vec x, Vec y, Vec w, void *context, PetscBool *changed_y, PetscBool *changed_w #else SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context #endif)
Definition: petsc_nonlinear_solver.C:518
libMesh::PetscVector::zero
virtual void zero() override
Set all entries to zero.
Definition: petsc_vector.h:873
libMesh::ResidualContext::ierr
PetscErrorCode ierr
Definition: petsc_nonlinear_solver.C:61
libmesh_petsc_preconditioner_apply
PetscErrorCode libmesh_petsc_preconditioner_apply(void *ctx, Vec x, Vec y)
This function is called by PETSc to actually apply the preconditioner.
Definition: petsc_linear_solver.C:62
libMesh::initialized
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:265
libMesh::NonlinearSolver::residual_and_jacobian_object
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
Object that computes either the residual or the Jacobian of the nonlinear system at the input itera...
Definition: nonlinear_solver.h:193
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::ReferenceElem::get
const Elem & get(const ElemType type_in)
Definition: reference_elem.C:237
libMesh::libMeshPrivateData::_is_initialized
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:246
libMesh::libmesh_petsc_snes_residual_helper
ResidualContext libmesh_petsc_snes_residual_helper(SNES snes, Vec x, void *ctx)
Definition: petsc_nonlinear_solver.C:65
libMesh::__libmesh_petsc_snes_fd_residual
PetscErrorCode __libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
Definition: petsc_nonlinear_solver.C:236
libMesh::NonlinearSolver::jacobian
void(* jacobian)(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)
Function that computes the Jacobian J(X) of the nonlinear system at the input iterate X.
Definition: nonlinear_solver.h:164
libMesh::PetscMatrix
This class provides a nice interface to the PETSc C-based data structures for parallel,...
Definition: petsc_matrix.h:87
libMesh::NonlinearSolver::mffd_residual_object
NonlinearImplicitSystem::ComputeResidual * mffd_residual_object
Object that computes the residual R(X) of the nonlinear system at the input iterate X for the purpose...
Definition: nonlinear_solver.h:158
libMesh::ResidualContext::solver
PetscNonlinearSolver< Number > * solver
Definition: petsc_nonlinear_solver.C:59
libMesh::NonlinearSolver::postcheck
void(* postcheck)(const NumericVector< Number > &old_soln, NumericVector< Number > &search_direction, NumericVector< Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln, sys_type &S)
Function that performs a "check" on the Newton search direction and solution after each nonlinear ste...
Definition: nonlinear_solver.h:262
libMesh::__libmesh_petsc_snes_jacobian
PetscErrorCode __libmesh_petsc_snes_jacobian(SNES, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx)
libMesh::DofMap::enforce_constraints_on_jacobian
void enforce_constraints_on_jacobian(const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const
Definition: dof_map.h:2069
libMesh::ctx
void * ctx
Definition: petsc_dm_wrapper.C:71
libMesh::PetscNonlinearSolver::_zero_out_residual
bool _zero_out_residual
true to zero out residual before going into application level call-back, otherwise false
Definition: petsc_nonlinear_solver.h:241
libMesh::libmesh_petsc_snes_mffd_interface
PetscErrorCode libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
Definition: petsc_nonlinear_solver.C:280
libMesh::NonlinearImplicitSystem::ComputePostCheck::postcheck
virtual void postcheck(const NumericVector< Number > &old_soln, NumericVector< Number > &search_direction, NumericVector< Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln, sys_type &S)=0
This interface, which is inspired by PETSc's, passes the user: .) A constant reference to the "old" s...
libMesh::NonlinearSolver::postcheck_object
NonlinearImplicitSystem::ComputePostCheck * postcheck_object
A callable object that is executed after each nonlinear iteration.
Definition: nonlinear_solver.h:274
libMesh::ResidualContext::sys
NonlinearImplicitSystem & sys
Definition: petsc_nonlinear_solver.C:60
libMesh::PetscVector::vec
Vec vec()
Definition: petsc_vector.h:335
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::PetscVector::swap
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
Definition: petsc_vector.h:1194
ierr
PetscErrorCode ierr
Definition: petscdmlibmeshimpl.C:1028
libMesh::libmesh_petsc_snes_postcheck
PetscErrorCode libmesh_petsc_snes_postcheck(#if PETSC_VERSION_LESS_THAN(3, 3, 0) SNES, Vec x, Vec y, Vec w, void *context, PetscBool *changed_y, PetscBool *changed_w #else SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context #endif)
Definition: petsc_nonlinear_solver.C:441
libMesh::out
OStreamProxy out
libMesh::NonlinearSolver::system
const sys_type & system() const
Definition: nonlinear_solver.h:279
libMesh::System::update
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:408
libMesh::Quality::name
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
libMesh::NonlinearImplicitSystem::ComputeResidualandJacobian::residual_and_jacobian
virtual void residual_and_jacobian(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)=0
Residual & Jacobian function, calculated simultaneously.