https://mooseframework.inl.gov
PetscSupport.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "PetscSupport.h"
11 
12 // MOOSE includes
13 #include "MooseApp.h"
14 #include "FEProblem.h"
15 #include "DisplacedProblem.h"
16 #include "NonlinearSystem.h"
17 #include "LinearSystem.h"
18 #include "DisplacedProblem.h"
19 #include "PenetrationLocator.h"
20 #include "NearestNodeLocator.h"
21 #include "MooseTypes.h"
22 #include "MooseUtils.h"
23 #include "CommandLine.h"
24 #include "Console.h"
25 #include "MultiMooseEnum.h"
26 #include "Conversion.h"
27 #include "Executioner.h"
28 #include "MooseMesh.h"
30 #include "Convergence.h"
31 #include "ParallelParamObject.h"
32 
33 #include "libmesh/equation_systems.h"
34 #include "libmesh/linear_implicit_system.h"
35 #include "libmesh/nonlinear_implicit_system.h"
36 #include "libmesh/petsc_linear_solver.h"
37 #include "libmesh/petsc_matrix.h"
38 #include "libmesh/petsc_nonlinear_solver.h"
39 #include "libmesh/petsc_preconditioner.h"
40 #include "libmesh/petsc_vector.h"
41 #include "libmesh/sparse_matrix.h"
42 #include "libmesh/petsc_solver_exception.h"
43 #include "libmesh/simple_range.h"
44 
45 // PETSc includes
46 #include <petsc.h>
47 #include <petscsnes.h>
48 #include <petscksp.h>
49 
50 // For graph coloring
51 #include <petscmat.h>
52 #include <petscis.h>
53 #include <petscdm.h>
54 
55 // PetscDMMoose include
56 #include "PetscDMMoose.h"
57 
58 // Standard includes
59 #include <ostream>
60 #include <fstream>
61 #include <string>
62 
63 using namespace libMesh;
64 
65 void
67 {
68  PetscVector<Number> & petsc_vec = static_cast<PetscVector<Number> &>(vector);
69  LibmeshPetscCallA(vector.comm().get(), VecView(petsc_vec.vec(), 0));
70 }
71 
72 void
74 {
75  PetscMatrixBase<Number> & petsc_mat = static_cast<PetscMatrix<Number> &>(mat);
76  LibmeshPetscCallA(mat.comm().get(), MatView(petsc_mat.mat(), 0));
77 }
78 
79 void
81 {
82  PetscVector<Number> & petsc_vec =
83  static_cast<PetscVector<Number> &>(const_cast<NumericVector<Number> &>(vector));
84  LibmeshPetscCallA(vector.comm().get(), VecView(petsc_vec.vec(), 0));
85 }
86 
87 void
89 {
90  PetscMatrixBase<Number> & petsc_mat =
91  static_cast<PetscMatrix<Number> &>(const_cast<SparseMatrix<Number> &>(mat));
92  LibmeshPetscCallA(mat.comm().get(), MatView(petsc_mat.mat(), 0));
93 }
94 
95 namespace Moose
96 {
97 namespace PetscSupport
98 {
99 
100 std::string
102 {
103  switch (t)
104  {
105  case LS_BASIC:
106  return "basic";
107  case LS_DEFAULT:
108  return "default";
109  case LS_NONE:
110  return "none";
111  case LS_SHELL:
112  return "shell";
113  case LS_L2:
114  return "l2";
115  case LS_BT:
116  return "bt";
117  case LS_CP:
118  return "cp";
119  case LS_CONTACT:
120  return "contact";
121  case LS_PROJECT:
122  return "project";
123  case LS_INVALID:
124  mooseError("Invalid LineSearchType");
125  }
126  return "";
127 }
128 
129 std::string
130 stringify(const MffdType & t)
131 {
132  switch (t)
133  {
134  case MFFD_WP:
135  return "wp";
136  case MFFD_DS:
137  return "ds";
138  case MFFD_INVALID:
139  mooseError("Invalid MffdType");
140  }
141  return "";
142 }
143 
144 void
145 setSolverOptions(const SolverParams & solver_params, const MultiMooseEnum & dont_add_these_options)
146 {
147  const auto prefix_with_dash = '-' + solver_params._prefix;
148  // set PETSc options implied by a solve type
149  switch (solver_params._type)
150  {
151  case Moose::ST_PJFNK:
152  setSinglePetscOptionIfAppropriate(dont_add_these_options,
153  prefix_with_dash + "snes_mf_operator");
154  setSinglePetscOptionIfAppropriate(dont_add_these_options,
155  prefix_with_dash + "mat_mffd_type",
156  stringify(solver_params._mffd_type));
157  break;
158 
159  case Moose::ST_JFNK:
160  setSinglePetscOptionIfAppropriate(dont_add_these_options, prefix_with_dash + "snes_mf");
161  setSinglePetscOptionIfAppropriate(dont_add_these_options,
162  prefix_with_dash + "mat_mffd_type",
163  stringify(solver_params._mffd_type));
164  break;
165 
166  case Moose::ST_NEWTON:
167  break;
168 
169  case Moose::ST_FD:
170  setSinglePetscOptionIfAppropriate(dont_add_these_options, prefix_with_dash + "snes_fd");
171  break;
172 
173  case Moose::ST_LINEAR:
175  dont_add_these_options, prefix_with_dash + "snes_type", "ksponly");
176  setSinglePetscOptionIfAppropriate(dont_add_these_options,
177  prefix_with_dash + "snes_monitor_cancel");
178  break;
179  }
180 
181  Moose::LineSearchType ls_type = solver_params._line_search;
182  if (ls_type == Moose::LS_NONE)
183  ls_type = Moose::LS_BASIC;
184 
185  if (ls_type != Moose::LS_DEFAULT && ls_type != Moose::LS_CONTACT && ls_type != Moose::LS_PROJECT)
187  dont_add_these_options, prefix_with_dash + "snes_linesearch_type", stringify(ls_type));
188 }
189 
190 void
192 {
193  // commandline options always win
194  // the options from a user commandline will overwrite the existing ones if any conflicts
195  { // Get any options specified on the command-line
196  int argc;
197  char ** args;
198 
199  LibmeshPetscCallA(PETSC_COMM_WORLD, PetscGetArgs(&argc, &args));
200 #if PETSC_VERSION_LESS_THAN(3, 7, 0)
201  LibmeshPetscCallA(PETSC_COMM_WORLD, PetscOptionsInsert(&argc, &args, NULL));
202 #else
203  LibmeshPetscCallA(PETSC_COMM_WORLD,
204  PetscOptionsInsert(LIBMESH_PETSC_NULLPTR, &argc, &args, NULL));
205 #endif
206  }
207 }
208 
209 void
211 {
212  // Add any additional options specified in the input file
213  for (const auto & flag : po.flags)
214  // Need to use name method here to pass a str instead of an EnumItem because
215  // we don't care if the id attributes match
216  if (!po.dont_add_these_options.contains(flag.name()) ||
217  po.user_set_options.contains(flag.name()))
218  setSinglePetscOption(flag.rawName().c_str());
219 
220  // Add option pairs
221  for (auto & option : po.pairs)
222  if (!po.dont_add_these_options.contains(option.first) ||
223  po.user_set_options.contains(option.first))
224  setSinglePetscOption(option.first, option.second, problem);
225 
227 }
228 
229 void
231  const SolverParams & solver_params,
232  FEProblemBase * const problem)
233 {
234  PetscCallAbort(PETSC_COMM_WORLD, PetscOptionsClear(LIBMESH_PETSC_NULLPTR));
235  setSolverOptions(solver_params, po.dont_add_these_options);
236  petscSetOptionsHelper(po, problem);
237 }
238 
239 void
241  const std::vector<SolverParams> & solver_params_vec,
242  FEProblemBase * const problem)
243 {
244  PetscCallAbort(PETSC_COMM_WORLD, PetscOptionsClear(LIBMESH_PETSC_NULLPTR));
245  for (const auto & solver_params : solver_params_vec)
246  setSolverOptions(solver_params, po.dont_add_these_options);
247  petscSetOptionsHelper(po, problem);
248 }
249 
250 PetscErrorCode
252 {
254  char code[10] = {45, 45, 109, 111, 111, 115, 101};
255  const std::vector<std::string> argv = cmd_line->getArguments();
256  for (const auto & arg : argv)
257  {
258  if (arg.compare(code) == 0)
259  {
261  break;
262  }
263  }
264  PetscFunctionReturn(PETSC_SUCCESS);
265 }
266 
267 PetscErrorCode
269  PetscInt it,
270  PetscReal /*xnorm*/,
271  PetscReal /*snorm*/,
272  PetscReal /*fnorm*/,
273  SNESConvergedReason * reason,
274  void * ctx)
275 {
277  FEProblemBase & problem = *static_cast<FEProblemBase *>(ctx);
278 
279  // execute objects that may be used in convergence check
281 
282  // perform the convergence check
285  {
288  }
289  else
290  {
291  auto & convergence = problem.getConvergence(
293  status = convergence.checkConvergence(it);
294  }
295 
296  // convert convergence status to PETSc converged reason
297  switch (status)
298  {
300  *reason = SNES_CONVERGED_ITERATING;
301  break;
302 
304  *reason = SNES_CONVERGED_FNORM_ABS;
305  break;
306 
308  *reason = SNES_DIVERGED_DTOL;
309  break;
310  }
311 
312  PetscFunctionReturn(PETSC_SUCCESS);
313 }
314 
315 PetscErrorCode
317  KSP /*ksp*/, PetscInt it, PetscReal /*norm*/, KSPConvergedReason * reason, void * ctx)
318 {
320  FEProblemBase & problem = *static_cast<FEProblemBase *>(ctx);
321 
322  // execute objects that may be used in convergence check
323  // Right now, setting objects to execute on this flag would be ignored except in the
324  // linear-system-only use case.
326 
327  // perform the convergence check
329  if (problem.getFailNextSystemConvergenceCheck())
330  {
333  }
334  else
335  {
336  auto & convergence = problem.getConvergence(
337  problem.getLinearConvergenceNames()[problem.currentLinearSystem().number()]);
338  status = convergence.checkConvergence(it);
339  }
340 
341  // convert convergence status to PETSc converged reason
342  switch (status)
343  {
345  *reason = KSP_CONVERGED_ITERATING;
346  break;
347 
348  // TODO: find a KSP code that works better for this case
350  *reason = KSP_CONVERGED_RTOL_NORMAL;
351  break;
352 
354  *reason = KSP_DIVERGED_DTOL;
355  break;
356  }
357 
358  PetscFunctionReturn(PETSC_SUCCESS);
359 }
360 
361 PCSide
363 {
364  switch (pcs)
365  {
366  case Moose::PCS_LEFT:
367  return PC_LEFT;
368  case Moose::PCS_RIGHT:
369  return PC_RIGHT;
371  return PC_SYMMETRIC;
372  default:
373  mooseError("Unknown PC side requested.");
374  break;
375  }
376 }
377 
378 KSPNormType
380 {
381  switch (kspnorm)
382  {
383  case Moose::KSPN_NONE:
384  return KSP_NORM_NONE;
386  return KSP_NORM_PRECONDITIONED;
388  return KSP_NORM_UNPRECONDITIONED;
389  case Moose::KSPN_NATURAL:
390  return KSP_NORM_NATURAL;
391  case Moose::KSPN_DEFAULT:
392  return KSP_NORM_DEFAULT;
393  default:
394  mooseError("Unknown KSP norm type requested.");
395  break;
396  }
397 }
398 
399 void
401 {
402  for (const auto i : make_range(problem.numSolverSystems()))
403  {
404  SolverSystem & sys = problem.getSolverSystem(i);
405  LibmeshPetscCallA(problem.comm().get(),
406  KSPSetNormType(ksp, getPetscKSPNormType(sys.getMooseKSPNormType())));
407  }
408 }
409 
410 void
412 {
413  for (const auto i : make_range(problem.numSolverSystems()))
414  {
415  SolverSystem & sys = problem.getSolverSystem(i);
416 
417  // PETSc 3.2.x+
418  if (sys.getPCSide() != Moose::PCS_DEFAULT)
419  LibmeshPetscCallA(problem.comm().get(), KSPSetPCSide(ksp, getPetscPCSide(sys.getPCSide())));
420  }
421 }
422 
423 void
425 {
426  auto & es = problem.es();
427 
428  PetscReal rtol = es.parameters.get<Real>("linear solver tolerance");
429  PetscReal atol = es.parameters.get<Real>("linear solver absolute tolerance");
430 
431  // MOOSE defaults this to -1 for some dumb reason
432  if (atol < 0)
433  atol = 1e-50;
434 
435  PetscReal maxits = es.parameters.get<unsigned int>("linear solver maximum iterations");
436 
437  // 1e100 is because we don't use divtol currently
438  LibmeshPetscCallA(problem.comm().get(), KSPSetTolerances(ksp, rtol, atol, 1e100, maxits));
439 
440  petscSetDefaultPCSide(problem, ksp);
441 
442  petscSetDefaultKSPNormType(problem, ksp);
443 }
444 
445 void
447 {
448  // We care about both nonlinear and linear systems when setting the SNES prefix because
449  // SNESSetOptionsPrefix will also set its KSP prefix which could compete with linear system KSPs
450  for (const auto nl_index : make_range(problem.numNonlinearSystems()))
451  {
452  NonlinearSystemBase & nl = problem.getNonlinearSystemBase(nl_index);
453 
454  //
455  // prefix system matrices
456  //
457 
458  auto & lm_sys = nl.system();
459  // This check is necessary because we still have at least the system matrix lying around even
460  // when doing matrix-free, but critically even though the libmesh object(s) exist, the wrapped
461  // PETSc Mat(s) do not
462  if (problem.solverParams(nl_index)._type != Moose::ST_JFNK)
463  for (auto & [mat_name, mat] : as_range(lm_sys.matrices_begin(), lm_sys.matrices_end()))
464  {
465  libmesh_ignore(mat_name);
466  if (auto * const petsc_mat = dynamic_cast<PetscMatrixBase<Number> *>(mat.get()); petsc_mat)
467  {
468  LibmeshPetscCallA(nl.comm().get(),
469  MatSetOptionsPrefix(petsc_mat->mat(), (nl.name() + "_").c_str()));
470  // We should call this here to ensure that options from the command line are properly
471  // applied
472  LibmeshPetscCallA(nl.comm().get(), MatSetFromOptions(petsc_mat->mat()));
473  }
474  }
475 
476  //
477  // prefix SNES/KSP
478  //
479 
480  // dig out PETSc solver
481  auto * const petsc_solver = cast_ptr<PetscNonlinearSolver<Number> *>(nl.nonlinearSolver());
482  const char * snes_prefix = nullptr;
483  std::string snes_prefix_str;
484  if (nl.system().prefix_with_name())
485  {
486  snes_prefix_str = nl.system().prefix();
487  snes_prefix = snes_prefix_str.c_str();
488  }
489  SNES snes = petsc_solver->snes(snes_prefix);
490  KSP ksp;
491  LibmeshPetscCallA(nl.comm().get(), SNESGetKSP(snes, &ksp));
492 
493  LibmeshPetscCallA(nl.comm().get(), SNESSetMaxLinearSolveFailures(snes, 1000000));
494 
495  LibmeshPetscCallA(nl.comm().get(), SNESSetCheckJacobianDomainError(snes, PETSC_TRUE));
496 
497  // In 3.0.0, the context pointer must actually be used, and the
498  // final argument to KSPSetConvergenceTest() is a pointer to a
499  // routine for destroying said private data context. In this case,
500  // we use the default context provided by PETSc in addition to
501  // a few other tests.
502  {
503  LibmeshPetscCallA(
504  nl.comm().get(),
505  SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem, LIBMESH_PETSC_NULLPTR));
506  }
507 
508  petscSetKSPDefaults(problem, ksp);
509  }
510 
511  for (auto sys_index : make_range(problem.numLinearSystems()))
512  {
513  // dig out PETSc solver
514  LinearSystem & lin_sys = problem.getLinearSystem(sys_index);
515  PetscLinearSolver<Number> * petsc_solver = dynamic_cast<PetscLinearSolver<Number> *>(
517  KSP ksp = petsc_solver->ksp();
518 
519  if (problem.hasLinearConvergenceObjects())
520  LibmeshPetscCallA(
521  lin_sys.comm().get(),
522  KSPSetConvergenceTest(ksp, petscLinearConverged, &problem, LIBMESH_PETSC_NULLPTR));
523 
524  // We dont set the KSP defaults here because they seem to clash with the linear solve parameters
525  // set in FEProblemBase::solveLinearSystem
526  }
527 }
528 
529 void
531 {
532  setSolveTypeFromParams(fe_problem, params);
533  setLineSearchFromParams(fe_problem, params);
534  setMFFDTypeFromParams(fe_problem, params);
535 }
536 
537 #define checkPrefix(prefix) \
538  mooseAssert(prefix[0] == '-', \
539  "Leading prefix character must be a '-'. Current prefix is '" << prefix << "'"); \
540  mooseAssert((prefix.size() == 1) || (prefix.back() == '_'), \
541  "Terminating prefix character must be a '_'. Current prefix is '" << prefix << "'"); \
542  mooseAssert(MooseUtils::isAllLowercase(prefix), "PETSc prefixes should be all lower-case")
543 
544 void
546  const std::string & prefix,
547  const ParallelParamObject & param_object)
548 {
549  const auto & params = param_object.parameters();
550  processSingletonMooseWrappedOptions(fe_problem, params);
551 
552  // The parameters contained in the Action
553  const auto & petsc_options = params.get<MultiMooseEnum>("petsc_options");
554  const auto & petsc_pair_options =
555  params.get<MooseEnumItem, std::string>("petsc_options_iname", "petsc_options_value");
556 
557  // A reference to the PetscOptions object that contains the settings that will be used in the
558  // solve
559  auto & po = fe_problem.getPetscOptions();
560 
561  // First process the single petsc options/flags
562  addPetscFlagsToPetscOptions(petsc_options, prefix, param_object, po);
563 
564  // Then process the option-value pairs
566  petsc_pair_options, fe_problem.mesh().dimension(), prefix, param_object, po);
567 }
568 
569 void
571 {
572  // Note: Options set in the Preconditioner block will override those set in the Executioner block
573  if (params.isParamValid("solve_type") && !params.isParamValid("_use_eigen_value"))
574  {
575  // Extract the solve type
576  const std::string & solve_type = params.get<MooseEnum>("solve_type");
577  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
578  fe_problem.solverParams(i)._type = Moose::stringToEnum<Moose::SolveType>(solve_type);
579  }
580 }
581 
582 void
584 {
585  // Note: Options set in the Preconditioner block will override those set in the Executioner block
586  if (params.isParamValid("line_search"))
587  {
588  const auto & line_search = params.get<MooseEnum>("line_search");
589  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
590  if (fe_problem.solverParams(i)._line_search == Moose::LS_INVALID || line_search != "default")
591  {
592  Moose::LineSearchType enum_line_search =
593  Moose::stringToEnum<Moose::LineSearchType>(line_search);
594  fe_problem.solverParams(i)._line_search = enum_line_search;
595  if (enum_line_search == LS_CONTACT || enum_line_search == LS_PROJECT)
596  {
597  NonlinearImplicitSystem * nl_system = dynamic_cast<NonlinearImplicitSystem *>(
598  &fe_problem.getNonlinearSystemBase(i).system());
599  if (!nl_system)
600  mooseError("You've requested a line search but you must be solving an EigenProblem. "
601  "These two things are not consistent.");
602  PetscNonlinearSolver<Real> * petsc_nonlinear_solver =
603  dynamic_cast<PetscNonlinearSolver<Real> *>(nl_system->nonlinear_solver.get());
604  if (!petsc_nonlinear_solver)
605  mooseError("Currently the MOOSE line searches all use Petsc, so you "
606  "must use Petsc as your non-linear solver.");
607  petsc_nonlinear_solver->linesearch_object =
608  std::make_unique<ComputeLineSearchObjectWrapper>(fe_problem);
609  }
610  }
611  }
612 }
613 
614 void
616 {
617  if (params.isParamValid("mffd_type"))
618  {
619  const auto & mffd_type = params.get<MooseEnum>("mffd_type");
620  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
621  fe_problem.solverParams(i)._mffd_type = Moose::stringToEnum<Moose::MffdType>(mffd_type);
622  }
623 }
624 
625 template <typename T>
626 void
627 checkUserProvidedPetscOption(const T & option, const ParallelParamObject & param_object)
628 {
629  const auto & string_option = static_cast<const std::string &>(option);
630  if (string_option[0] != '-')
631  param_object.mooseError("PETSc option '", string_option, "' does not begin with '-'");
632 }
633 
634 void
636  std::string prefix,
637  const ParallelParamObject & param_object,
638  PetscOptions & po)
639 {
640  prefix.insert(prefix.begin(), '-');
641  checkPrefix(prefix);
642 
643  // Update the PETSc single flags
644  for (const auto & option : petsc_flags)
645  {
646  checkUserProvidedPetscOption(option, param_object);
647 
648  const std::string & string_option = option.name();
649 
656  if (option == "-log_summary" || option == "-log_view")
657  mooseError("The PETSc option \"-log_summary\" or \"-log_view\" can only be used on the "
658  "command line. Please "
659  "remove it from the input file");
660 
661  // Update the stored items, but do not create duplicates
662  const std::string prefixed_option = prefix + string_option.substr(1);
663  if (!po.flags.isValueSet(prefixed_option))
664  {
665  po.flags.setAdditionalValue(prefixed_option);
666  po.user_set_options.setAdditionalValue(prefixed_option);
667  }
668  }
669 }
670 
671 void
672 setConvergedReasonFlags(FEProblemBase & fe_problem, std::string prefix)
673 {
674  prefix.insert(prefix.begin(), '-');
675  checkPrefix(prefix);
676  libmesh_ignore(fe_problem); // avoid unused warnings for old PETSc
677 
678 #if !PETSC_VERSION_LESS_THAN(3, 14, 0)
679  // the boolean in these pairs denote whether the user has specified any of the reason flags in the
680  // input file
681  std::array<std::string, 2> reason_flags = {{"snes_converged_reason", "ksp_converged_reason"}};
682 
683  auto & po = fe_problem.getPetscOptions();
684 
685  for (const auto & reason_flag : reason_flags)
686  if (!po.flags.isValueSet(prefix + reason_flag) &&
687  (std::find_if(po.pairs.begin(),
688  po.pairs.end(),
689  [&reason_flag, &prefix](auto & pair)
690  { return pair.first == (prefix + reason_flag); }) == po.pairs.end()))
691  po.pairs.emplace_back(prefix + reason_flag, "::failed");
692 #endif
693 }
694 
695 void
697  const std::vector<std::pair<MooseEnumItem, std::string>> & petsc_pair_options,
698  const unsigned int mesh_dimension,
699  std::string prefix,
700  const ParallelParamObject & param_object,
701  PetscOptions & po)
702 {
703  prefix.insert(prefix.begin(), '-');
704  checkPrefix(prefix);
705 
706  // Setup the name value pairs
707  bool boomeramg_found = false;
708  bool strong_threshold_found = false;
709 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
710  bool superlu_dist_found = false;
711  bool fact_pattern_found = false;
712  bool tiny_pivot_found = false;
713 #endif
714  std::string pc_description = "";
715 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
716  // If users use HMG, we would like to set
717  bool hmg_found = false;
718  bool matptap_found = false;
719  bool hmg_strong_threshold_found = false;
720 #endif
721  std::vector<std::pair<std::string, std::string>> new_options;
722 
723  for (const auto & [option_name, option_value] : petsc_pair_options)
724  {
725  checkUserProvidedPetscOption(option_name, param_object);
726 
727  new_options.clear();
728  const std::string prefixed_option_name =
729  prefix + static_cast<const std::string &>(option_name).substr(1);
730 
731  // Do not add duplicate settings
732  if (auto it =
733  MooseUtils::findPair(po.pairs, po.pairs.begin(), prefixed_option_name, MooseUtils::Any);
734  it == po.pairs.end())
735  {
736 #if !PETSC_VERSION_LESS_THAN(3, 9, 0)
737  if (option_name == "-pc_factor_mat_solver_package")
738  new_options.emplace_back(prefix + "pc_factor_mat_solver_type", option_value);
739 #else
740  if (option_name == "-pc_factor_mat_solver_type")
741  new_options.push_back(prefix + "pc_factor_mat_solver_package", option_value);
742 #endif
743 
744  // Look for a pc description
745  if (option_name == "-pc_type" || option_name == "-sub_pc_type" ||
746  option_name == "-pc_hypre_type")
747  pc_description += option_value + ' ';
748 
749 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
750  if (option_name == "-pc_type" && option_value == "hmg")
751  hmg_found = true;
752 
753  // MPIAIJ for PETSc 3.12.0: -matptap_via
754  // MAIJ for PETSc 3.12.0: -matmaijptap_via
755  // MPIAIJ for PETSc 3.13 to 3.16: -matptap_via, -matproduct_ptap_via
756  // MAIJ for PETSc 3.13 to 3.16: -matproduct_ptap_via
757  // MPIAIJ for PETSc 3.17 and higher: -matptap_via, -mat_product_algorithm
758  // MAIJ for PETSc 3.17 and higher: -mat_product_algorithm
759 #if !PETSC_VERSION_LESS_THAN(3, 17, 0)
760  if (hmg_found && (option_name == "-matptap_via" || option_name == "-matmaijptap_via" ||
761  option_name == "-matproduct_ptap_via"))
762  new_options.emplace_back(prefix + "mat_product_algorithm", option_value);
763 #elif !PETSC_VERSION_LESS_THAN(3, 13, 0)
764  if (hmg_found && (option_name == "-matptap_via" || option_name == "-matmaijptap_via"))
765  new_options.emplace_back(prefix + "matproduct_ptap_via", option_value);
766 #else
767  if (hmg_found && (option_name == "-matproduct_ptap_via"))
768  {
769  new_options.emplace_back(prefix + "matptap_via", option_value);
770  new_options.emplace_back(prefix + "matmaijptap_via", option_value);
771  }
772 #endif
773 
774  if (option_name == "-matptap_via" || option_name == "-matmaijptap_via" ||
775  option_name == "-matproduct_ptap_via" || option_name == "-mat_product_algorithm")
776  matptap_found = true;
777 
778  // For 3D problems, we need to set this 0.7
779  if (option_name == "-hmg_inner_pc_hypre_boomeramg_strong_threshold")
780  hmg_strong_threshold_found = true;
781 #endif
782  // This special case is common enough that we'd like to handle it for the user.
783  if (option_name == "-pc_hypre_type" && option_value == "boomeramg")
784  boomeramg_found = true;
785  if (option_name == "-pc_hypre_boomeramg_strong_threshold")
786  strong_threshold_found = true;
787 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
788  if ((option_name == "-pc_factor_mat_solver_package" ||
789  option_name == "-pc_factor_mat_solver_type") &&
790  option_value == "superlu_dist")
791  superlu_dist_found = true;
792  if (option_name == "-mat_superlu_dist_fact")
793  fact_pattern_found = true;
794  if (option_name == "-mat_superlu_dist_replacetinypivot")
795  tiny_pivot_found = true;
796 #endif
797 
798  if (!new_options.empty())
799  {
800  std::copy(new_options.begin(), new_options.end(), std::back_inserter(po.pairs));
801  for (const auto & option : new_options)
802  po.user_set_options.setAdditionalValue(option.first);
803  }
804  else
805  {
806  po.pairs.push_back(std::make_pair(prefixed_option_name, option_value));
807  po.user_set_options.setAdditionalValue(prefixed_option_name);
808  }
809  }
810  else
811  {
812  do
813  {
814  it->second = option_value;
815  it = MooseUtils::findPair(po.pairs, std::next(it), prefixed_option_name, MooseUtils::Any);
816  } while (it != po.pairs.end());
817  }
818  }
819 
820  // When running a 3D mesh with boomeramg, it is almost always best to supply a strong threshold
821  // value. We will provide that for the user here if they haven't supplied it themselves.
822  if (boomeramg_found && !strong_threshold_found && mesh_dimension == 3)
823  {
824  po.pairs.emplace_back(prefix + "pc_hypre_boomeramg_strong_threshold", "0.7");
825  pc_description += "strong_threshold: 0.7 (auto)";
826  }
827 
828 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
829  if (hmg_found && !hmg_strong_threshold_found && mesh_dimension == 3)
830  {
831  po.pairs.emplace_back(prefix + "hmg_inner_pc_hypre_boomeramg_strong_threshold", "0.7");
832  pc_description += "strong_threshold: 0.7 (auto)";
833  }
834 
835  // Default PETSc PtAP takes too much memory, and it is not quite useful
836  // Let us switch to use new algorithm
837  if (hmg_found && !matptap_found)
838  {
839 #if !PETSC_VERSION_LESS_THAN(3, 17, 0)
840  po.pairs.emplace_back(prefix + "mat_product_algorithm", "allatonce");
841 #elif !PETSC_VERSION_LESS_THAN(3, 13, 0)
842  po.pairs.emplace_back(prefix + "matproduct_ptap_via", "allatonce");
843 #else
844  po.pairs.emplace_back(prefix + "matptap_via", "allatonce");
845  po.pairs.emplace_back(prefix + "matmaijptap_via", "allatonce");
846 #endif
847  }
848 #endif
849 
850 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
851  // In PETSc-3.7.{0--4}, there is a bug when using superlu_dist, and we have to use
852  // SamePattern_SameRowPerm, otherwise we use whatever we have in PETSc
853  if (superlu_dist_found && !fact_pattern_found)
854  {
855  po.pairs.emplace_back(prefix + "mat_superlu_dist_fact",
856 #if PETSC_VERSION_LESS_THAN(3, 7, 5)
857  "SamePattern_SameRowPerm");
858  pc_description += "mat_superlu_dist_fact: SamePattern_SameRowPerm ";
859 #else
860  "SamePattern");
861  pc_description += "mat_superlu_dist_fact: SamePattern ";
862 #endif
863  }
864 
865  // restore this superlu option
866  if (superlu_dist_found && !tiny_pivot_found)
867  {
868  po.pairs.emplace_back(prefix + "mat_superlu_dist_replacetinypivot", "1");
869  pc_description += " mat_superlu_dist_replacetinypivot: true ";
870  }
871 #endif
872  // Set Preconditioner description
873  if (!pc_description.empty() && prefix.size() > 1)
874  po.pc_description += "[" + prefix.substr(1, prefix.size() - 2) + "]: ";
875  po.pc_description += pc_description;
876 }
877 
878 std::set<std::string>
880 {
881  return {"default", "shell", "none", "basic", "l2", "bt", "cp"};
882 }
883 
886 {
888 
889  MooseEnum solve_type("PJFNK JFNK NEWTON FD LINEAR");
890  params.addParam<MooseEnum>("solve_type",
891  solve_type,
892  "PJFNK: Preconditioned Jacobian-Free Newton Krylov "
893  "JFNK: Jacobian-Free Newton Krylov "
894  "NEWTON: Full Newton Solve "
895  "FD: Use finite differences to compute Jacobian "
896  "LINEAR: Solving a linear problem");
897 
898  MooseEnum mffd_type("wp ds", "wp");
899  params.addParam<MooseEnum>("mffd_type",
900  mffd_type,
901  "Specifies the finite differencing type for "
902  "Jacobian-free solve types. Note that the "
903  "default is wp (for Walker and Pernice).");
904 
905  params.addParam<MultiMooseEnum>(
906  "petsc_options", getCommonPetscFlags(), "Singleton PETSc options");
907  params.addParam<MultiMooseEnum>(
908  "petsc_options_iname", getCommonPetscKeys(), "Names of PETSc name/value pairs");
909  params.addParam<std::vector<std::string>>(
910  "petsc_options_value",
911  "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\"");
912  params.addParamNamesToGroup("solve_type petsc_options petsc_options_iname petsc_options_value "
913  "mffd_type",
914  "PETSc");
915 
916  return params;
917 }
918 
921 {
922  return MultiMooseEnum(
923  "-ksp_monitor_snes_lg -snes_ksp_ew -ksp_snes_ew -snes_converged_reason "
924  "-snes_ksp -snes_linesearch_monitor -snes_mf -snes_mf_operator -snes_monitor "
925  "-snes_test_display -snes_view -snes_monitor_cancel",
926  "",
927  true);
928 }
929 
932 {
933  return MultiMooseEnum(
934  "-ksp_converged_reason -ksp_gmres_modifiedgramschmidt -ksp_monitor", "", true);
935 }
936 
939 {
940  auto options = MultiMooseEnum("-dm_moose_print_embedding -dm_view", "", true);
941  options.addValidName(getCommonKSPFlags());
942  options.addValidName(getCommonSNESFlags());
943  return options;
944 }
945 
948 {
949  return MultiMooseEnum("-snes_atol -snes_linesearch_type -snes_ls -snes_max_it -snes_rtol "
950  "-snes_divergence_tolerance -snes_type",
951  "",
952  true);
953 }
954 
957 {
958  return MultiMooseEnum("-ksp_atol -ksp_gmres_restart -ksp_max_it -ksp_pc_side -ksp_rtol "
959  "-ksp_type -sub_ksp_type",
960  "",
961  true);
962 }
965 {
966  auto options = MultiMooseEnum("-mat_fd_coloring_err -mat_fd_type -mat_mffd_type "
967  "-pc_asm_overlap -pc_factor_levels "
968  "-pc_factor_mat_ordering_type -pc_hypre_boomeramg_grid_sweeps_all "
969  "-pc_hypre_boomeramg_max_iter "
970  "-pc_hypre_boomeramg_strong_threshold -pc_hypre_type -pc_type "
971  "-sub_pc_type",
972  "",
973  true);
974  options.addValidName(getCommonKSPKeys());
975  options.addValidName(getCommonSNESKeys());
976  return options;
977 }
978 
979 bool
980 isSNESVI(FEProblemBase & fe_problem)
981 {
982  const PetscOptions & petsc = fe_problem.getPetscOptions();
983 
984  int argc;
985  char ** args;
986  LibmeshPetscCallA(fe_problem.comm().get(), PetscGetArgs(&argc, &args));
987 
988  std::vector<std::string> cml_arg;
989  for (int i = 0; i < argc; i++)
990  cml_arg.push_back(args[i]);
991 
992  if (MooseUtils::findPair(petsc.pairs, petsc.pairs.begin(), MooseUtils::Any, "vinewtonssls") ==
993  petsc.pairs.end() &&
994  MooseUtils::findPair(petsc.pairs, petsc.pairs.begin(), MooseUtils::Any, "vinewtonrsls") ==
995  petsc.pairs.end() &&
996  std::find(cml_arg.begin(), cml_arg.end(), "vinewtonssls") == cml_arg.end() &&
997  std::find(cml_arg.begin(), cml_arg.end(), "vinewtonrsls") == cml_arg.end())
998  return false;
999 
1000  return true;
1001 }
1002 
1003 void
1004 setSinglePetscOption(const std::string & name,
1005  const std::string & value /*=""*/,
1006  FEProblemBase * const problem /*=nullptr*/)
1007 {
1008  static const TIMPI::Communicator comm_world(PETSC_COMM_WORLD);
1009  const TIMPI::Communicator & comm = problem ? problem->comm() : comm_world;
1010  LibmeshPetscCallA(comm.get(),
1011  PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR,
1012  name.c_str(),
1013  value == "" ? LIBMESH_PETSC_NULLPTR : value.c_str()));
1014  const auto lower_case_name = MooseUtils::toLower(name);
1015  auto check_problem = [problem, &lower_case_name]()
1016  {
1017  if (!problem)
1018  mooseError(
1019  "Setting the option '",
1020  lower_case_name,
1021  "' requires passing a 'problem' parameter. Contact a developer of your application "
1022  "to have them update their code. If in doubt, reach out to the MOOSE team on Github "
1023  "discussions");
1024  };
1025 
1026  // Select vector type from user-passed PETSc options
1027  if (lower_case_name.find("-vec_type") != std::string::npos)
1028  {
1029  check_problem();
1030  for (auto & solver_system : problem->_solver_systems)
1031  {
1032  auto & lm_sys = solver_system->system();
1033  for (auto & [vec_name, vec] : as_range(lm_sys.vectors_begin(), lm_sys.vectors_end()))
1034  {
1035  libmesh_ignore(vec_name);
1036  auto * const petsc_vec = cast_ptr<PetscVector<Number> *>(vec.get());
1037  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1038  }
1039  // The solution vectors aren't included in the system vectors storage
1040  auto * petsc_vec = cast_ptr<PetscVector<Number> *>(lm_sys.solution.get());
1041  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1042  petsc_vec = cast_ptr<PetscVector<Number> *>(lm_sys.current_local_solution.get());
1043  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1044  }
1045  }
1046  // Select matrix type from user-passed PETSc options
1047  else if (lower_case_name.find("mat_type") != std::string::npos)
1048  {
1049  check_problem();
1050 
1051  bool found_matching_prefix = false;
1052  for (const auto i : index_range(problem->_solver_systems))
1053  {
1054  const auto & solver_sys_name = problem->_solver_sys_names[i];
1055  if (lower_case_name.find("-" + MooseUtils::toLower(solver_sys_name) + "_mat_type") ==
1056  std::string::npos)
1057  continue;
1058 
1059  if (problem->solverParams(i)._type == Moose::ST_JFNK)
1060  mooseError(
1061  "Setting option '", lower_case_name, "' is incompatible with a JFNK 'solve_type'");
1062 
1063  auto & lm_sys = problem->_solver_systems[i]->system();
1064  for (auto & [mat_name, mat] : as_range(lm_sys.matrices_begin(), lm_sys.matrices_end()))
1065  {
1066  libmesh_ignore(mat_name);
1067  if (auto * const petsc_mat = dynamic_cast<PetscMatrixBase<Number> *>(mat.get()); petsc_mat)
1068  {
1069 #ifdef DEBUG
1070  const char * mat_prefix;
1071  LibmeshPetscCallA(comm.get(), MatGetOptionsPrefix(petsc_mat->mat(), &mat_prefix));
1072  mooseAssert(strcmp(mat_prefix, (solver_sys_name + "_").c_str()) == 0,
1073  "We should have prefixed these matrices previously");
1074 #endif
1075  LibmeshPetscCallA(comm.get(), MatSetFromOptions(petsc_mat->mat()));
1076  }
1077  }
1078  found_matching_prefix = true;
1079  break;
1080  }
1081 
1082  if (!found_matching_prefix)
1083  mooseError("We did not find a matching solver system name for the petsc option '",
1084  lower_case_name,
1085  "'");
1086  }
1087 }
1088 
1089 void
1090 setSinglePetscOptionIfAppropriate(const MultiMooseEnum & dont_add_these_options,
1091  const std::string & name,
1092  const std::string & value /*=""*/,
1093  FEProblemBase * const problem /*=nullptr*/)
1094 {
1095  if (!dont_add_these_options.contains(name))
1096  setSinglePetscOption(name, value, problem);
1097 }
1098 
1099 void
1100 colorAdjacencyMatrix(PetscScalar * adjacency_matrix,
1101  unsigned int size,
1102  unsigned int colors,
1103  std::vector<unsigned int> & vertex_colors,
1104  const char * coloring_algorithm)
1105 {
1106  // Mat A will be a dense matrix from the incoming data structure
1107  Mat A;
1108  LibmeshPetscCallA(PETSC_COMM_SELF, MatCreate(PETSC_COMM_SELF, &A));
1109  LibmeshPetscCallA(PETSC_COMM_SELF, MatSetSizes(A, size, size, size, size));
1110  LibmeshPetscCallA(PETSC_COMM_SELF, MatSetType(A, MATSEQDENSE));
1111  // PETSc requires a non-const data array to populate the matrix
1112  LibmeshPetscCallA(PETSC_COMM_SELF, MatSeqDenseSetPreallocation(A, adjacency_matrix));
1113  LibmeshPetscCallA(PETSC_COMM_SELF, MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
1114  LibmeshPetscCallA(PETSC_COMM_SELF, MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
1115 
1116  // Convert A to a sparse matrix
1117 #if PETSC_VERSION_LESS_THAN(3, 7, 0)
1118  LibmeshPetscCallA(PETSC_COMM_SELF, MatConvert(A, MATAIJ, MAT_REUSE_MATRIX, &A));
1119 #else
1120  LibmeshPetscCallA(PETSC_COMM_SELF, MatConvert(A, MATAIJ, MAT_INPLACE_MATRIX, &A));
1121 #endif
1122 
1123  ISColoring iscoloring;
1124  MatColoring mc;
1125  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringCreate(A, &mc));
1126  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetType(mc, coloring_algorithm));
1127  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetMaxColors(mc, static_cast<PetscInt>(colors)));
1128 
1129  // Petsc normally colors by distance two (neighbors of neighbors), we just want one
1130  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetDistance(mc, 1));
1131  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetFromOptions(mc));
1132  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringApply(mc, &iscoloring));
1133 
1134  PetscInt nn;
1135  IS * is;
1136 #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
1137  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringGetIS(iscoloring, &nn, &is));
1138 #else
1139  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringGetIS(iscoloring, PETSC_USE_POINTER, &nn, &is));
1140 #endif
1141 
1142  if (nn > static_cast<PetscInt>(colors))
1143  throw std::runtime_error("Not able to color with designated number of colors");
1144 
1145  for (int i = 0; i < nn; i++)
1146  {
1147  PetscInt isize;
1148  const PetscInt * indices;
1149  LibmeshPetscCallA(PETSC_COMM_SELF, ISGetLocalSize(is[i], &isize));
1150  LibmeshPetscCallA(PETSC_COMM_SELF, ISGetIndices(is[i], &indices));
1151  for (int j = 0; j < isize; j++)
1152  {
1153  mooseAssert(indices[j] < static_cast<PetscInt>(vertex_colors.size()), "Index out of bounds");
1154  vertex_colors[indices[j]] = i;
1155  }
1156  LibmeshPetscCallA(PETSC_COMM_SELF, ISRestoreIndices(is[i], &indices));
1157  }
1158 
1159  LibmeshPetscCallA(PETSC_COMM_SELF, MatDestroy(&A));
1160  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringDestroy(&mc));
1161  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringDestroy(&iscoloring));
1162 }
1163 
1164 void
1165 dontAddPetscFlag(const std::string & flag, PetscOptions & petsc_options)
1166 {
1167  if (!petsc_options.dont_add_these_options.contains(flag))
1168  petsc_options.dont_add_these_options.setAdditionalValue(flag);
1169 }
1170 
1171 void
1173 {
1174  dontAddPetscFlag("-snes_converged_reason", fe_problem.getPetscOptions());
1175 }
1176 
1177 void
1179 {
1180  dontAddPetscFlag("-ksp_converged_reason", fe_problem.getPetscOptions());
1181 }
1182 
1183 void
1185 {
1186  auto & petsc_options = fe_problem.getPetscOptions();
1187  for (const auto & flag : getCommonKSPFlags().getNames())
1188  dontAddPetscFlag(flag, petsc_options);
1189  for (const auto & key : getCommonKSPKeys().getNames())
1190  dontAddPetscFlag(key, petsc_options);
1191 }
1192 
1193 void
1195 {
1196  auto & petsc_options = fe_problem.getPetscOptions();
1197  for (const auto & flag : getCommonSNESFlags().getNames())
1198  if (!petsc_options.dont_add_these_options.contains(flag))
1199  petsc_options.dont_add_these_options.setAdditionalValue(flag);
1200  for (const auto & key : getCommonSNESKeys().getNames())
1201  if (!petsc_options.dont_add_these_options.contains(key))
1202  petsc_options.dont_add_these_options.setAdditionalValue(key);
1203 }
1204 
1205 std::unique_ptr<PetscMatrix<Number>>
1207  Mat & mat,
1208  const std::string & binary_mat_file,
1209  const unsigned int mat_number_to_load)
1210 {
1211  LibmeshPetscCallA(comm.get(), MatCreate(comm.get(), &mat));
1212  PetscViewer matviewer;
1213  LibmeshPetscCallA(
1214  comm.get(),
1215  PetscViewerBinaryOpen(comm.get(), binary_mat_file.c_str(), FILE_MODE_READ, &matviewer));
1216  for (unsigned int i = 0; i < mat_number_to_load; ++i)
1217  LibmeshPetscCallA(comm.get(), MatLoad(mat, matviewer));
1218  LibmeshPetscCallA(comm.get(), PetscViewerDestroy(&matviewer));
1219 
1220  return std::make_unique<PetscMatrix<Number>>(mat, comm);
1221 }
1222 
1223 } // Namespace PetscSupport
1224 } // Namespace MOOSE
std::string name(const ElemQuality q)
MultiMooseEnum getCommonKSPKeys()
A helper function to produce a MultiMooseEnum with commonly used PETSc ksp option names (keys) ...
Definition: PetscSupport.C:956
MultiMooseEnum getCommonPetscKeys()
A helper function to produce a MultiMooseEnum with commonly used PETSc iname options (keys in key-val...
Definition: PetscSupport.C:964
void resetFailNextNonlinearConvergenceCheck()
Tell the problem that the nonlinear convergence check(s) may proceed as normal.
bool isSNESVI(FEProblemBase &fe_problem)
check if SNES type is variational inequalities (VI) solver
Definition: PetscSupport.C:980
const std::vector< ConvergenceName > & getNonlinearConvergenceNames() const
Gets the nonlinear system convergence object name(s).
Moose::PetscSupport::PetscOptions & getPetscOptions()
Retrieve a writable reference the PETSc options (used by PetscSupport)
void addPetscFlagsToPetscOptions(const MultiMooseEnum &petsc_flags, std::string prefix, const ParallelParamObject &param_object, PetscOptions &petsc_options)
Populate flags in a given PetscOptions object using a vector of input arguments.
Definition: PetscSupport.C:635
KSPNormType getPetscKSPNormType(Moose::MooseKSPNormType kspnorm)
Definition: PetscSupport.C:379
void addPetscOptionsFromCommandline()
Definition: PetscSupport.C:191
void setMFFDTypeFromParams(FEProblemBase &fe_problem, const InputParameters &params)
Sets the FE problem&#39;s matrix-free finite difference type from the input params.
Definition: PetscSupport.C:615
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
Full Newton Solve.
Definition: MooseTypes.h:847
std::string toLower(const std::string &name)
Convert supplied string to lower case.
const ExecFlagType EXEC_NONLINEAR_CONVERGENCE
Definition: Moose.C:34
static void petscSetupOutput()
Output string for setting up PETSC output.
Definition: Console.C:859
std::string _prefix
Definition: SolverParams.h:35
virtual std::size_t numNonlinearSystems() const override
std::set< std::string > getPetscValidLineSearches()
Returns the valid petsc line search options as a set of strings.
Definition: PetscSupport.C:879
Moose::LineSearchType _line_search
Definition: SolverParams.h:20
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:333
void setAdditionalValue(const std::string &names)
Insert operators Operator to insert (push_back) values into the enum.
const ExecFlagType EXEC_LINEAR_CONVERGENCE
Definition: Moose.C:32
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void addPetscPairsToPetscOptions(const std::vector< std::pair< MooseEnumItem, std::string >> &petsc_pair_options, const unsigned int mesh_dimension, std::string prefix, const ParallelParamObject &param_object, PetscOptions &petsc_options)
Populate name and value pairs in a given PetscOptions object using vectors of input arguments...
Definition: PetscSupport.C:696
void petscSetDefaults(FEProblemBase &problem)
Sets the default options for PETSc.
Definition: PetscSupport.C:446
libMesh::LinearImplicitSystem & linearImplicitSystem()
Return a reference to the stored linear implicit system.
Definition: LinearSystem.h:86
virtual MooseConvergenceStatus checkConvergence(unsigned int iter)=0
Returns convergence status.
MultiMooseEnum getCommonSNESFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc snes single options (flags) ...
Definition: PetscSupport.C:920
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:127
A struct for storing the various types of petsc options and values.
Definition: PetscSupport.h:44
MultiMooseEnum flags
Single value PETSc options (flags)
Definition: PetscSupport.h:56
PetscFunctionBegin
void setSolveTypeFromParams(FEProblemBase &fe_problem, const InputParameters &params)
Sets the FE problem&#39;s solve type from the input params.
Definition: PetscSupport.C:570
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
void petscSetDefaultKSPNormType(FEProblemBase &problem, KSP ksp)
Set norm type.
Definition: PetscSupport.C:400
std::unique_ptr< PetscMatrix< Number > > createMatrixFromFile(const libMesh::Parallel::Communicator &comm, Mat &petsc_mat, const std::string &binary_mat_file, unsigned int mat_number_to_load=1)
Create a matrix from a binary file.
Solving a linear problem.
Definition: MooseTypes.h:849
void petscSetKSPDefaults(FEProblemBase &problem, KSP ksp)
Set the default options for a KSP.
Definition: PetscSupport.C:424
std::vector< std::shared_ptr< SolverSystem > > _solver_systems
Combined container to base pointer of every solver system.
std::vector< std::pair< std::string, std::string > > pairs
PETSc key-value pairs.
Definition: PetscSupport.h:53
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver()=0
virtual LinearSolver< Number > * get_linear_solver() const override
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
MffdType
Type of the matrix-free finite-differencing parameter.
Definition: MooseTypes.h:943
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool hasLinearConvergenceObjects() const
Whether we have linear convergence objects.
InputParameters emptyInputParameters()
This class wraps provides and tracks access to command line parameters.
Definition: CommandLine.h:29
MooseKSPNormType
Norm type for converge test.
Definition: MooseTypes.h:831
Nonlinear system to be solved.
MPI_Status status
virtual const std::string & name() const
Definition: SystemBase.C:1332
PCSide getPetscPCSide(Moose::PCSideType pcs)
Definition: PetscSupport.C:362
void processSingletonMooseWrappedOptions(FEProblemBase &fe_problem, const InputParameters &params)
Process some MOOSE-wrapped PETSc options.
Definition: PetscSupport.C:530
void checkUserProvidedPetscOption(const T &option, const ParallelParamObject &param_object)
Definition: PetscSupport.C:627
void setConvergedReasonFlags(FEProblemBase &fe_problem, std::string prefix)
Set flags that will instruct the user on the reason their simulation diverged from PETSc&#39;s perspectiv...
Definition: PetscSupport.C:672
bool contains(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
std::vector< SolverSystemName > _solver_sys_names
The union of nonlinear and linear system names.
virtual void execute(const ExecFlagType &exec_type)
Convenience function for performing execution of MOOSE systems.
void dontAddCommonKSPOptions(FEProblemBase &fe_problem)
Function to ensure that common KSP options are not added to the PetscOptions storage object to be lat...
PetscErrorCode petscLinearConverged(KSP, PetscInt it, PetscReal, KSPConvergedReason *reason, void *ctx)
Definition: PetscSupport.C:316
void libmesh_ignore(const Args &...)
Use whatever we have in PETSc.
Definition: MooseTypes.h:825
PetscErrorCode petscNonlinearConverged(SNES, PetscInt it, PetscReal, PetscReal, PetscReal, SNESConvergedReason *reason, void *ctx)
Definition: PetscSupport.C:268
const T & get(std::string_view) const
MultiMooseEnum getCommonPetscFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc single options (flags) ...
Definition: PetscSupport.C:938
Moose::MffdType _mffd_type
Definition: SolverParams.h:21
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
LineSearchType
Type of the line search.
Definition: MooseTypes.h:926
virtual Convergence & getConvergence(const std::string &name, const THREAD_ID tid=0) const
Gets a Convergence object.
void MooseMatView(SparseMatrix< Number > &mat)
Definition: PetscSupport.C:73
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
Definition: MooseMesh.C:2928
std::string prefix() const
Use whatever we have in PETSc.
Definition: MooseTypes.h:837
void dontAddPetscFlag(const std::string &flag, PetscOptions &petsc_options)
Function to ensure that a particular petsc option is not added to the PetscOptions storage object to ...
std::string stringify(const MffdType &t)
Definition: PetscSupport.C:130
NonlinearSystemBase & currentNonlinearSystem()
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Jacobian-Free Newton Krylov.
Definition: MooseTypes.h:846
virtual libMesh::EquationSystems & es() override
void setSolverOptions(const SolverParams &solver_params, const MultiMooseEnum &dont_add_these_options)
Definition: PetscSupport.C:145
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
Moose::SolveType _type
Definition: SolverParams.h:19
PetscErrorCode PetscInt const PetscInt IS * is
Use finite differences to compute Jacobian.
Definition: MooseTypes.h:848
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
bool isValueSet(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1149
void petscSetOptions(const PetscOptions &po, const SolverParams &solver_params, FEProblemBase *const problem=nullptr)
A function for setting the PETSc options in PETSc from the options supplied to MOOSE.
Definition: PetscSupport.C:230
bool getFailNextSystemConvergenceCheck() const
Whether it will fail the next system convergence check(s), triggering failed step behavior...
LinearSystem & getLinearSystem(unsigned int sys_num)
Get non-constant reference to a linear system.
MooseConvergenceStatus
Status returned by calls to checkConvergence.
Definition: Convergence.h:33
auto findPair(C &container, It start_iterator, const M1 &first, const M2 &second)
Find a specific pair in a container matching on first, second or both pair components.
Definition: MooseUtils.h:1061
void setLineSearchFromParams(FEProblemBase &fe_problem, const InputParameters &params)
Sets the FE problem&#39;s line search from the input params.
Definition: PetscSupport.C:583
void dontAddCommonSNESOptions(FEProblemBase &fe_problem)
Function to ensure that common SNES options are not added to the PetscOptions storage object to be la...
unsigned int get(unsigned int i) const
Indexing operator Operator to retrieve the id of an item from the MultiMooseEnum. ...
void setSinglePetscOption(const std::string &name, const std::string &value="", FEProblemBase *const problem=nullptr)
A wrapper function for dealing with different versions of PetscOptionsSetValue.
MultiMooseEnum getCommonKSPFlags()
A helper function to produce a MultiMooseEnum with commonly used PETSc ksp single options (flags) ...
Definition: PetscSupport.C:931
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
InputParameters getPetscValidParams()
Returns the PETSc options that are common between Executioners and Preconditioners.
Definition: PetscSupport.C:885
PetscErrorCode petscSetupOutput(CommandLine *cmd_line)
Definition: PetscSupport.C:251
std::unique_ptr< ComputeLineSearchObject > linesearch_object
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
void petscSetOptionsHelper(const PetscOptions &po, FEProblemBase *const problem)
Definition: PetscSupport.C:210
means not set
Definition: MooseTypes.h:945
void dontAddNonlinearConvergedReason(FEProblemBase &fe_problem)
Function to ensure that -snes_converged_reason is not added to the PetscOptions storage object to be ...
void colorAdjacencyMatrix(PetscScalar *adjacency_matrix, unsigned int size, unsigned int colors, std::vector< unsigned int > &vertex_colors, const char *coloring_algorithm)
This method takes an adjacency matrix, and a desired number of colors and applies a graph coloring al...
bool getFailNextNonlinearConvergenceCheck() const
Whether it will skip further residual evaluations and fail the next nonlinear convergence check(s) ...
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
LinearSystem & currentLinearSystem()
Get a non-constant reference to the current linear system.
void resetFailNextSystemConvergenceCheck()
Tell the problem that the system convergence check(s) may proceed as normal.
PCSideType
Preconditioning side.
Definition: MooseTypes.h:820
SolverParams & solverParams(unsigned int solver_sys_num=0)
Get the solver parameters.
SolverSystem & getSolverSystem(unsigned int sys_num)
Get non-constant reference to a solver system.
MultiMooseEnum getCommonSNESKeys()
A helper function to produce a MultiMooseEnum with commonly used PETSc snes option names (keys) ...
Definition: PetscSupport.C:947
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
Linear system to be solved.
Definition: LinearSystem.h:35
void setSinglePetscOptionIfAppropriate(const MultiMooseEnum &dont_add_these_options, const std::string &name, const std::string &value="", FEProblemBase *const problem=nullptr)
Same as setSinglePetscOption, but does not set the option if it doesn&#39;t make sense for the current si...
void dontAddLinearConvergedReason(FEProblemBase &fe_problem)
Function to ensure that -ksp_converged_reason is not added to the PetscOptions storage object to be l...
void * ctx
Preconditioned Jacobian-Free Newton Krylov.
Definition: MooseTypes.h:845
virtual std::size_t numLinearSystems() const override
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
means not set
Definition: MooseTypes.h:928
void storePetscOptions(FEProblemBase &fe_problem, const std::string &prefix, const ParallelParamObject &param_object)
Stores the PETSc options supplied from the parameter object on the problem.
Definition: PetscSupport.C:545
std::string pc_description
Preconditioner description.
Definition: PetscSupport.h:65
static const struct MooseUtils::AnyType Any
MultiMooseEnum dont_add_these_options
Flags to explicitly not set, even if they are specified programmatically.
Definition: PetscSupport.h:59
Moose::MooseKSPNormType getMooseKSPNormType()
Get the norm in which the linear convergence is measured.
Definition: SolverSystem.h:87
void prefix_with_name(bool value)
Base class shared by both Action and MooseObject.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
void MooseVecView(NumericVector< Number > &vector)
Definition: PetscSupport.C:66
virtual std::size_t numSolverSystems() const override
MultiMooseEnum user_set_options
Options that are set by the user at the input level.
Definition: PetscSupport.h:62
auto index_range(const T &sizable)
const std::vector< std::string > & getArguments()
Definition: CommandLine.h:132
Moose::PCSideType getPCSide()
Get the current preconditioner side.
Definition: SolverSystem.h:76
void petscSetDefaultPCSide(FEProblemBase &problem, KSP ksp)
Setup which side we want to apply preconditioner.
Definition: PetscSupport.C:411
const std::vector< ConvergenceName > & getLinearConvergenceNames() const
Gets the linear convergence object name(s).
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
virtual libMesh::System & system() override
Get the reference to the libMesh system.