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 #if PETSC_VERSION_LESS_THAN(3, 24, 0)
351  *reason = KSP_CONVERGED_RTOL_NORMAL;
352 #else
353  *reason = KSP_CONVERGED_RTOL_NORMAL_EQUATIONS;
354 #endif
355  break;
356 
358  *reason = KSP_DIVERGED_DTOL;
359  break;
360  }
361 
362  PetscFunctionReturn(PETSC_SUCCESS);
363 }
364 
365 PCSide
367 {
368  switch (pcs)
369  {
370  case Moose::PCS_LEFT:
371  return PC_LEFT;
372  case Moose::PCS_RIGHT:
373  return PC_RIGHT;
375  return PC_SYMMETRIC;
376  default:
377  mooseError("Unknown PC side requested.");
378  break;
379  }
380 }
381 
382 KSPNormType
384 {
385  switch (kspnorm)
386  {
387  case Moose::KSPN_NONE:
388  return KSP_NORM_NONE;
390  return KSP_NORM_PRECONDITIONED;
392  return KSP_NORM_UNPRECONDITIONED;
393  case Moose::KSPN_NATURAL:
394  return KSP_NORM_NATURAL;
395  case Moose::KSPN_DEFAULT:
396  return KSP_NORM_DEFAULT;
397  default:
398  mooseError("Unknown KSP norm type requested.");
399  break;
400  }
401 }
402 
403 void
405 {
406  for (const auto i : make_range(problem.numSolverSystems()))
407  {
408  SolverSystem & sys = problem.getSolverSystem(i);
409  LibmeshPetscCallA(problem.comm().get(),
410  KSPSetNormType(ksp, getPetscKSPNormType(sys.getMooseKSPNormType())));
411  }
412 }
413 
414 void
416 {
417  for (const auto i : make_range(problem.numSolverSystems()))
418  {
419  SolverSystem & sys = problem.getSolverSystem(i);
420 
421  // PETSc 3.2.x+
422  if (sys.getPCSide() != Moose::PCS_DEFAULT)
423  LibmeshPetscCallA(problem.comm().get(), KSPSetPCSide(ksp, getPetscPCSide(sys.getPCSide())));
424  }
425 }
426 
427 void
429 {
430  auto & es = problem.es();
431 
432  PetscReal rtol = es.parameters.get<Real>("linear solver tolerance");
433  PetscReal atol = es.parameters.get<Real>("linear solver absolute tolerance");
434 
435  // MOOSE defaults this to -1 for some dumb reason
436  if (atol < 0)
437  atol = 1e-50;
438 
439  PetscReal maxits = es.parameters.get<unsigned int>("linear solver maximum iterations");
440 
441  // 1e100 is because we don't use divtol currently
442  LibmeshPetscCallA(problem.comm().get(), KSPSetTolerances(ksp, rtol, atol, 1e100, maxits));
443 
444  petscSetDefaultPCSide(problem, ksp);
445 
446  petscSetDefaultKSPNormType(problem, ksp);
447 }
448 
449 void
451 {
452  // We care about both nonlinear and linear systems when setting the SNES prefix because
453  // SNESSetOptionsPrefix will also set its KSP prefix which could compete with linear system KSPs
454  for (const auto nl_index : make_range(problem.numNonlinearSystems()))
455  {
456  NonlinearSystemBase & nl = problem.getNonlinearSystemBase(nl_index);
457 
458  //
459  // prefix system matrices
460  //
461 
462  auto & lm_sys = nl.system();
463  // This check is necessary because we still have at least the system matrix lying around even
464  // when doing matrix-free, but critically even though the libmesh object(s) exist, the wrapped
465  // PETSc Mat(s) do not
466  if (problem.solverParams(nl_index)._type != Moose::ST_JFNK)
467  for (auto & [mat_name, mat] : as_range(lm_sys.matrices_begin(), lm_sys.matrices_end()))
468  {
469  libmesh_ignore(mat_name);
470  if (auto * const petsc_mat = dynamic_cast<PetscMatrixBase<Number> *>(mat.get()); petsc_mat)
471  {
472  LibmeshPetscCallA(nl.comm().get(),
473  MatSetOptionsPrefix(petsc_mat->mat(), (nl.name() + "_").c_str()));
474  // We should call this here to ensure that options from the command line are properly
475  // applied
476  LibmeshPetscCallA(nl.comm().get(), MatSetFromOptions(petsc_mat->mat()));
477  }
478  }
479 
480  //
481  // prefix SNES/KSP
482  //
483 
484  // dig out PETSc solver
485  auto * const petsc_solver = cast_ptr<PetscNonlinearSolver<Number> *>(nl.nonlinearSolver());
486  const char * snes_prefix = nullptr;
487  std::string snes_prefix_str;
488  if (nl.system().prefix_with_name())
489  {
490  snes_prefix_str = nl.system().prefix();
491  snes_prefix = snes_prefix_str.c_str();
492  }
493  SNES snes = petsc_solver->snes(snes_prefix);
494  KSP ksp;
495  LibmeshPetscCallA(nl.comm().get(), SNESGetKSP(snes, &ksp));
496 
497  LibmeshPetscCallA(nl.comm().get(), SNESSetMaxLinearSolveFailures(snes, 1000000));
498 
499  LibmeshPetscCallA(nl.comm().get(), SNESSetCheckJacobianDomainError(snes, PETSC_TRUE));
500 
501  // In 3.0.0, the context pointer must actually be used, and the
502  // final argument to KSPSetConvergenceTest() is a pointer to a
503  // routine for destroying said private data context. In this case,
504  // we use the default context provided by PETSc in addition to
505  // a few other tests.
506  {
507  LibmeshPetscCallA(
508  nl.comm().get(),
509  SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem, LIBMESH_PETSC_NULLPTR));
510  }
511 
512  petscSetKSPDefaults(problem, ksp);
513  }
514 
515  for (auto sys_index : make_range(problem.numLinearSystems()))
516  {
517  // dig out PETSc solver
518  LinearSystem & lin_sys = problem.getLinearSystem(sys_index);
519  PetscLinearSolver<Number> * petsc_solver = dynamic_cast<PetscLinearSolver<Number> *>(
521  KSP ksp = petsc_solver->ksp();
522 
523  if (problem.hasLinearConvergenceObjects())
524  LibmeshPetscCallA(
525  lin_sys.comm().get(),
526  KSPSetConvergenceTest(ksp, petscLinearConverged, &problem, LIBMESH_PETSC_NULLPTR));
527 
528  // We dont set the KSP defaults here because they seem to clash with the linear solve parameters
529  // set in FEProblemBase::solveLinearSystem
530  }
531 }
532 
533 void
535 {
536  setSolveTypeFromParams(fe_problem, params);
537  setLineSearchFromParams(fe_problem, params);
538  setMFFDTypeFromParams(fe_problem, params);
539 }
540 
541 #define checkPrefix(prefix) \
542  mooseAssert(prefix[0] == '-', \
543  "Leading prefix character must be a '-'. Current prefix is '" << prefix << "'"); \
544  mooseAssert((prefix.size() == 1) || (prefix.back() == '_'), \
545  "Terminating prefix character must be a '_'. Current prefix is '" << prefix << "'"); \
546  mooseAssert(MooseUtils::isAllLowercase(prefix), "PETSc prefixes should be all lower-case")
547 
548 void
550  const std::string & prefix,
551  const ParallelParamObject & param_object)
552 {
553  const auto & params = param_object.parameters();
554  processSingletonMooseWrappedOptions(fe_problem, params);
555 
556  // The parameters contained in the Action
557  const auto & petsc_options = params.get<MultiMooseEnum>("petsc_options");
558  const auto & petsc_pair_options =
559  params.get<MooseEnumItem, std::string>("petsc_options_iname", "petsc_options_value");
560 
561  // A reference to the PetscOptions object that contains the settings that will be used in the
562  // solve
563  auto & po = fe_problem.getPetscOptions();
564 
565  // First process the single petsc options/flags
566  addPetscFlagsToPetscOptions(petsc_options, prefix, param_object, po);
567 
568  // Then process the option-value pairs
570  petsc_pair_options, fe_problem.mesh().dimension(), prefix, param_object, po);
571 }
572 
573 void
575 {
576  // Note: Options set in the Preconditioner block will override those set in the Executioner block
577  if (params.isParamValid("solve_type") && !params.isParamValid("_use_eigen_value"))
578  {
579  // Extract the solve type
580  const std::string & solve_type = params.get<MooseEnum>("solve_type");
581  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
582  fe_problem.solverParams(i)._type = Moose::stringToEnum<Moose::SolveType>(solve_type);
583  }
584 }
585 
586 void
588 {
589  // Note: Options set in the Preconditioner block will override those set in the Executioner block
590  if (params.isParamValid("line_search"))
591  {
592  const auto & line_search = params.get<MooseEnum>("line_search");
593  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
594  if (fe_problem.solverParams(i)._line_search == Moose::LS_INVALID || line_search != "default")
595  {
596  Moose::LineSearchType enum_line_search =
597  Moose::stringToEnum<Moose::LineSearchType>(line_search);
598  fe_problem.solverParams(i)._line_search = enum_line_search;
599  if (enum_line_search == LS_CONTACT || enum_line_search == LS_PROJECT)
600  {
601  NonlinearImplicitSystem * nl_system = dynamic_cast<NonlinearImplicitSystem *>(
602  &fe_problem.getNonlinearSystemBase(i).system());
603  if (!nl_system)
604  mooseError("You've requested a line search but you must be solving an EigenProblem. "
605  "These two things are not consistent.");
606  PetscNonlinearSolver<Real> * petsc_nonlinear_solver =
607  dynamic_cast<PetscNonlinearSolver<Real> *>(nl_system->nonlinear_solver.get());
608  if (!petsc_nonlinear_solver)
609  mooseError("Currently the MOOSE line searches all use Petsc, so you "
610  "must use Petsc as your non-linear solver.");
611  petsc_nonlinear_solver->linesearch_object =
612  std::make_unique<ComputeLineSearchObjectWrapper>(fe_problem);
613  }
614  }
615  }
616 }
617 
618 void
620 {
621  if (params.isParamValid("mffd_type"))
622  {
623  const auto & mffd_type = params.get<MooseEnum>("mffd_type");
624  for (const auto i : make_range(fe_problem.numNonlinearSystems()))
625  fe_problem.solverParams(i)._mffd_type = Moose::stringToEnum<Moose::MffdType>(mffd_type);
626  }
627 }
628 
629 template <typename T>
630 void
631 checkUserProvidedPetscOption(const T & option, const ParallelParamObject & param_object)
632 {
633  const auto & string_option = static_cast<const std::string &>(option);
634  if (string_option[0] != '-')
635  param_object.mooseError("PETSc option '", string_option, "' does not begin with '-'");
636 }
637 
638 void
640  std::string prefix,
641  const ParallelParamObject & param_object,
642  PetscOptions & po)
643 {
644  prefix.insert(prefix.begin(), '-');
645  checkPrefix(prefix);
646 
647  // Update the PETSc single flags
648  for (const auto & option : petsc_flags)
649  {
650  checkUserProvidedPetscOption(option, param_object);
651 
652  const std::string & string_option = option.name();
653 
660  if (option == "-log_summary" || option == "-log_view")
661  mooseError("The PETSc option \"-log_summary\" or \"-log_view\" can only be used on the "
662  "command line. Please "
663  "remove it from the input file");
664 
665  // Update the stored items, but do not create duplicates
666  const std::string prefixed_option = prefix + string_option.substr(1);
667  if (!po.flags.isValueSet(prefixed_option))
668  {
669  po.flags.setAdditionalValue(prefixed_option);
670  po.user_set_options.setAdditionalValue(prefixed_option);
671  }
672  }
673 }
674 
675 void
676 setConvergedReasonFlags(FEProblemBase & fe_problem, std::string prefix)
677 {
678  prefix.insert(prefix.begin(), '-');
679  checkPrefix(prefix);
680  libmesh_ignore(fe_problem); // avoid unused warnings for old PETSc
681 
682 #if !PETSC_VERSION_LESS_THAN(3, 14, 0)
683  // the boolean in these pairs denote whether the user has specified any of the reason flags in the
684  // input file
685  std::array<std::string, 2> reason_flags = {{"snes_converged_reason", "ksp_converged_reason"}};
686 
687  auto & po = fe_problem.getPetscOptions();
688 
689  for (const auto & reason_flag : reason_flags)
690  if (!po.flags.isValueSet(prefix + reason_flag) &&
691  (std::find_if(po.pairs.begin(),
692  po.pairs.end(),
693  [&reason_flag, &prefix](auto & pair)
694  { return pair.first == (prefix + reason_flag); }) == po.pairs.end()))
695  po.pairs.emplace_back(prefix + reason_flag, "::failed");
696 #endif
697 }
698 
699 void
701  const std::vector<std::pair<MooseEnumItem, std::string>> & petsc_pair_options,
702  const unsigned int mesh_dimension,
703  std::string prefix,
704  const ParallelParamObject & param_object,
705  PetscOptions & po)
706 {
707  prefix.insert(prefix.begin(), '-');
708  checkPrefix(prefix);
709 
710  // Setup the name value pairs
711  bool boomeramg_found = false;
712  bool strong_threshold_found = false;
713 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
714  bool superlu_dist_found = false;
715  bool fact_pattern_found = false;
716  bool tiny_pivot_found = false;
717 #endif
718  std::string pc_description = "";
719 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
720  // If users use HMG, we would like to set
721  bool hmg_found = false;
722  bool matptap_found = false;
723  bool hmg_strong_threshold_found = false;
724 #endif
725  std::vector<std::pair<std::string, std::string>> new_options;
726 
727  for (const auto & [option_name, option_value] : petsc_pair_options)
728  {
729  checkUserProvidedPetscOption(option_name, param_object);
730 
731  new_options.clear();
732  const std::string prefixed_option_name =
733  prefix + static_cast<const std::string &>(option_name).substr(1);
734 
735  // Do not add duplicate settings
736  if (auto it =
737  MooseUtils::findPair(po.pairs, po.pairs.begin(), prefixed_option_name, MooseUtils::Any);
738  it == po.pairs.end())
739  {
740 #if !PETSC_VERSION_LESS_THAN(3, 9, 0)
741  if (option_name == "-pc_factor_mat_solver_package")
742  new_options.emplace_back(prefix + "pc_factor_mat_solver_type", option_value);
743 #else
744  if (option_name == "-pc_factor_mat_solver_type")
745  new_options.push_back(prefix + "pc_factor_mat_solver_package", option_value);
746 #endif
747 
748  // Look for a pc description
749  if (option_name == "-pc_type" || option_name == "-sub_pc_type" ||
750  option_name == "-pc_hypre_type")
751  pc_description += option_value + ' ';
752 
753 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
754  if (option_name == "-pc_type" && option_value == "hmg")
755  hmg_found = true;
756 
757  // MPIAIJ for PETSc 3.12.0: -matptap_via
758  // MAIJ for PETSc 3.12.0: -matmaijptap_via
759  // MPIAIJ for PETSc 3.13 to 3.16: -matptap_via, -matproduct_ptap_via
760  // MAIJ for PETSc 3.13 to 3.16: -matproduct_ptap_via
761  // MPIAIJ for PETSc 3.17 and higher: -matptap_via, -mat_product_algorithm
762  // MAIJ for PETSc 3.17 and higher: -mat_product_algorithm
763 #if !PETSC_VERSION_LESS_THAN(3, 17, 0)
764  if (hmg_found && (option_name == "-matptap_via" || option_name == "-matmaijptap_via" ||
765  option_name == "-matproduct_ptap_via"))
766  new_options.emplace_back(prefix + "mat_product_algorithm", option_value);
767 #elif !PETSC_VERSION_LESS_THAN(3, 13, 0)
768  if (hmg_found && (option_name == "-matptap_via" || option_name == "-matmaijptap_via"))
769  new_options.emplace_back(prefix + "matproduct_ptap_via", option_value);
770 #else
771  if (hmg_found && (option_name == "-matproduct_ptap_via"))
772  {
773  new_options.emplace_back(prefix + "matptap_via", option_value);
774  new_options.emplace_back(prefix + "matmaijptap_via", option_value);
775  }
776 #endif
777 
778  if (option_name == "-matptap_via" || option_name == "-matmaijptap_via" ||
779  option_name == "-matproduct_ptap_via" || option_name == "-mat_product_algorithm")
780  matptap_found = true;
781 
782  // For 3D problems, we need to set this 0.7
783  if (option_name == "-hmg_inner_pc_hypre_boomeramg_strong_threshold")
784  hmg_strong_threshold_found = true;
785 #endif
786  // This special case is common enough that we'd like to handle it for the user.
787  if (option_name == "-pc_hypre_type" && option_value == "boomeramg")
788  boomeramg_found = true;
789  if (option_name == "-pc_hypre_boomeramg_strong_threshold")
790  strong_threshold_found = true;
791 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
792  if ((option_name == "-pc_factor_mat_solver_package" ||
793  option_name == "-pc_factor_mat_solver_type") &&
794  option_value == "superlu_dist")
795  superlu_dist_found = true;
796  if (option_name == "-mat_superlu_dist_fact")
797  fact_pattern_found = true;
798  if (option_name == "-mat_superlu_dist_replacetinypivot")
799  tiny_pivot_found = true;
800 #endif
801 
802  if (!new_options.empty())
803  {
804  std::copy(new_options.begin(), new_options.end(), std::back_inserter(po.pairs));
805  for (const auto & option : new_options)
806  po.user_set_options.setAdditionalValue(option.first);
807  }
808  else
809  {
810  po.pairs.push_back(std::make_pair(prefixed_option_name, option_value));
811  po.user_set_options.setAdditionalValue(prefixed_option_name);
812  }
813  }
814  else
815  {
816  do
817  {
818  it->second = option_value;
819  it = MooseUtils::findPair(po.pairs, std::next(it), prefixed_option_name, MooseUtils::Any);
820  } while (it != po.pairs.end());
821  }
822  }
823 
824  // When running a 3D mesh with boomeramg, it is almost always best to supply a strong threshold
825  // value. We will provide that for the user here if they haven't supplied it themselves.
826  if (boomeramg_found && !strong_threshold_found && mesh_dimension == 3)
827  {
828  po.pairs.emplace_back(prefix + "pc_hypre_boomeramg_strong_threshold", "0.7");
829  pc_description += "strong_threshold: 0.7 (auto)";
830  }
831 
832 #if !PETSC_VERSION_LESS_THAN(3, 12, 0)
833  if (hmg_found && !hmg_strong_threshold_found && mesh_dimension == 3)
834  {
835  po.pairs.emplace_back(prefix + "hmg_inner_pc_hypre_boomeramg_strong_threshold", "0.7");
836  pc_description += "strong_threshold: 0.7 (auto)";
837  }
838 
839  // Default PETSc PtAP takes too much memory, and it is not quite useful
840  // Let us switch to use new algorithm
841  if (hmg_found && !matptap_found)
842  {
843 #if !PETSC_VERSION_LESS_THAN(3, 17, 0)
844  po.pairs.emplace_back(prefix + "mat_product_algorithm", "allatonce");
845 #elif !PETSC_VERSION_LESS_THAN(3, 13, 0)
846  po.pairs.emplace_back(prefix + "matproduct_ptap_via", "allatonce");
847 #else
848  po.pairs.emplace_back(prefix + "matptap_via", "allatonce");
849  po.pairs.emplace_back(prefix + "matmaijptap_via", "allatonce");
850 #endif
851  }
852 #endif
853 
854 #if !PETSC_VERSION_LESS_THAN(3, 7, 0)
855  // In PETSc-3.7.{0--4}, there is a bug when using superlu_dist, and we have to use
856  // SamePattern_SameRowPerm, otherwise we use whatever we have in PETSc
857  if (superlu_dist_found && !fact_pattern_found)
858  {
859  po.pairs.emplace_back(prefix + "mat_superlu_dist_fact",
860 #if PETSC_VERSION_LESS_THAN(3, 7, 5)
861  "SamePattern_SameRowPerm");
862  pc_description += "mat_superlu_dist_fact: SamePattern_SameRowPerm ";
863 #else
864  "SamePattern");
865  pc_description += "mat_superlu_dist_fact: SamePattern ";
866 #endif
867  }
868 
869  // restore this superlu option
870  if (superlu_dist_found && !tiny_pivot_found)
871  {
872  po.pairs.emplace_back(prefix + "mat_superlu_dist_replacetinypivot", "1");
873  pc_description += " mat_superlu_dist_replacetinypivot: true ";
874  }
875 #endif
876  // Set Preconditioner description
877  if (!pc_description.empty() && prefix.size() > 1)
878  po.pc_description += "[" + prefix.substr(1, prefix.size() - 2) + "]: ";
879  po.pc_description += pc_description;
880 }
881 
882 std::set<std::string>
884 {
885  return {"default", "shell", "none", "basic", "l2", "bt", "cp"};
886 }
887 
890 {
892 
893  MooseEnum solve_type("PJFNK JFNK NEWTON FD LINEAR");
894  params.addParam<MooseEnum>("solve_type",
895  solve_type,
896  "PJFNK: Preconditioned Jacobian-Free Newton Krylov "
897  "JFNK: Jacobian-Free Newton Krylov "
898  "NEWTON: Full Newton Solve "
899  "FD: Use finite differences to compute Jacobian "
900  "LINEAR: Solving a linear problem");
901 
902  MooseEnum mffd_type("wp ds", "wp");
903  params.addParam<MooseEnum>("mffd_type",
904  mffd_type,
905  "Specifies the finite differencing type for "
906  "Jacobian-free solve types. Note that the "
907  "default is wp (for Walker and Pernice).");
908 
909  params.addParam<MultiMooseEnum>(
910  "petsc_options", getCommonPetscFlags(), "Singleton PETSc options");
911  params.addParam<MultiMooseEnum>(
912  "petsc_options_iname", getCommonPetscKeys(), "Names of PETSc name/value pairs");
913  params.addParam<std::vector<std::string>>(
914  "petsc_options_value",
915  "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\"");
916  params.addParamNamesToGroup("solve_type petsc_options petsc_options_iname petsc_options_value "
917  "mffd_type",
918  "PETSc");
919 
920  return params;
921 }
922 
925 {
926  return MultiMooseEnum(
927  "-ksp_monitor_snes_lg -snes_ksp_ew -ksp_snes_ew -snes_converged_reason "
928  "-snes_ksp -snes_linesearch_monitor -snes_mf -snes_mf_operator -snes_monitor "
929  "-snes_test_display -snes_view -snes_monitor_cancel",
930  "",
931  true);
932 }
933 
936 {
937  return MultiMooseEnum(
938  "-ksp_converged_reason -ksp_gmres_modifiedgramschmidt -ksp_monitor", "", true);
939 }
940 
943 {
944  auto options = MultiMooseEnum("-dm_moose_print_embedding -dm_view", "", true);
945  options.addValidName(getCommonKSPFlags());
946  options.addValidName(getCommonSNESFlags());
947  return options;
948 }
949 
952 {
953  return MultiMooseEnum("-snes_atol -snes_linesearch_type -snes_ls -snes_max_it -snes_rtol "
954  "-snes_divergence_tolerance -snes_type",
955  "",
956  true);
957 }
958 
961 {
962  return MultiMooseEnum("-ksp_atol -ksp_gmres_restart -ksp_max_it -ksp_pc_side -ksp_rtol "
963  "-ksp_type -sub_ksp_type",
964  "",
965  true);
966 }
969 {
970  auto options = MultiMooseEnum("-mat_fd_coloring_err -mat_fd_type -mat_mffd_type "
971  "-pc_asm_overlap -pc_factor_levels "
972  "-pc_factor_mat_ordering_type -pc_hypre_boomeramg_grid_sweeps_all "
973  "-pc_hypre_boomeramg_max_iter "
974  "-pc_hypre_boomeramg_strong_threshold -pc_hypre_type -pc_type "
975  "-sub_pc_type",
976  "",
977  true);
978  options.addValidName(getCommonKSPKeys());
979  options.addValidName(getCommonSNESKeys());
980  return options;
981 }
982 
983 bool
984 isSNESVI(FEProblemBase & fe_problem)
985 {
986  const PetscOptions & petsc = fe_problem.getPetscOptions();
987 
988  int argc;
989  char ** args;
990  LibmeshPetscCallA(fe_problem.comm().get(), PetscGetArgs(&argc, &args));
991 
992  std::vector<std::string> cml_arg;
993  for (int i = 0; i < argc; i++)
994  cml_arg.push_back(args[i]);
995 
996  if (MooseUtils::findPair(petsc.pairs, petsc.pairs.begin(), MooseUtils::Any, "vinewtonssls") ==
997  petsc.pairs.end() &&
998  MooseUtils::findPair(petsc.pairs, petsc.pairs.begin(), MooseUtils::Any, "vinewtonrsls") ==
999  petsc.pairs.end() &&
1000  std::find(cml_arg.begin(), cml_arg.end(), "vinewtonssls") == cml_arg.end() &&
1001  std::find(cml_arg.begin(), cml_arg.end(), "vinewtonrsls") == cml_arg.end())
1002  return false;
1003 
1004  return true;
1005 }
1006 
1007 void
1008 setSinglePetscOption(const std::string & name,
1009  const std::string & value /*=""*/,
1010  FEProblemBase * const problem /*=nullptr*/)
1011 {
1012  static const TIMPI::Communicator comm_world(PETSC_COMM_WORLD);
1013  const TIMPI::Communicator & comm = problem ? problem->comm() : comm_world;
1014  LibmeshPetscCallA(comm.get(),
1015  PetscOptionsSetValue(LIBMESH_PETSC_NULLPTR,
1016  name.c_str(),
1017  value == "" ? LIBMESH_PETSC_NULLPTR : value.c_str()));
1018  const auto lower_case_name = MooseUtils::toLower(name);
1019  auto check_problem = [problem, &lower_case_name]()
1020  {
1021  if (!problem)
1022  mooseError(
1023  "Setting the option '",
1024  lower_case_name,
1025  "' requires passing a 'problem' parameter. Contact a developer of your application "
1026  "to have them update their code. If in doubt, reach out to the MOOSE team on Github "
1027  "discussions");
1028  };
1029 
1030  // Select vector type from user-passed PETSc options
1031  if (lower_case_name.find("-vec_type") != std::string::npos)
1032  {
1033  check_problem();
1034  for (auto & solver_system : problem->_solver_systems)
1035  {
1036  auto & lm_sys = solver_system->system();
1037  for (auto & [vec_name, vec] : as_range(lm_sys.vectors_begin(), lm_sys.vectors_end()))
1038  {
1039  libmesh_ignore(vec_name);
1040  auto * const petsc_vec = cast_ptr<PetscVector<Number> *>(vec.get());
1041  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1042  }
1043  // The solution vectors aren't included in the system vectors storage
1044  auto * petsc_vec = cast_ptr<PetscVector<Number> *>(lm_sys.solution.get());
1045  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1046  petsc_vec = cast_ptr<PetscVector<Number> *>(lm_sys.current_local_solution.get());
1047  LibmeshPetscCallA(comm.get(), VecSetFromOptions(petsc_vec->vec()));
1048  }
1049  }
1050  // Select matrix type from user-passed PETSc options
1051  else if (lower_case_name.find("mat_type") != std::string::npos)
1052  {
1053  check_problem();
1054 
1055  bool found_matching_prefix = false;
1056  for (const auto i : index_range(problem->_solver_systems))
1057  {
1058  const auto & solver_sys_name = problem->_solver_sys_names[i];
1059  if (lower_case_name.find("-" + MooseUtils::toLower(solver_sys_name) + "_mat_type") ==
1060  std::string::npos)
1061  continue;
1062 
1063  if (problem->solverParams(i)._type == Moose::ST_JFNK)
1064  mooseError(
1065  "Setting option '", lower_case_name, "' is incompatible with a JFNK 'solve_type'");
1066 
1067  auto & lm_sys = problem->_solver_systems[i]->system();
1068  for (auto & [mat_name, mat] : as_range(lm_sys.matrices_begin(), lm_sys.matrices_end()))
1069  {
1070  libmesh_ignore(mat_name);
1071  if (auto * const petsc_mat = dynamic_cast<PetscMatrixBase<Number> *>(mat.get()); petsc_mat)
1072  {
1073 #ifdef DEBUG
1074  const char * mat_prefix;
1075  LibmeshPetscCallA(comm.get(), MatGetOptionsPrefix(petsc_mat->mat(), &mat_prefix));
1076  mooseAssert(strcmp(mat_prefix, (solver_sys_name + "_").c_str()) == 0,
1077  "We should have prefixed these matrices previously");
1078 #endif
1079  LibmeshPetscCallA(comm.get(), MatSetFromOptions(petsc_mat->mat()));
1080  }
1081  }
1082  found_matching_prefix = true;
1083  break;
1084  }
1085 
1086  if (!found_matching_prefix)
1087  mooseError("We did not find a matching solver system name for the petsc option '",
1088  lower_case_name,
1089  "'");
1090  }
1091 }
1092 
1093 void
1094 setSinglePetscOptionIfAppropriate(const MultiMooseEnum & dont_add_these_options,
1095  const std::string & name,
1096  const std::string & value /*=""*/,
1097  FEProblemBase * const problem /*=nullptr*/)
1098 {
1099  if (!dont_add_these_options.contains(name))
1100  setSinglePetscOption(name, value, problem);
1101 }
1102 
1103 void
1104 colorAdjacencyMatrix(PetscScalar * adjacency_matrix,
1105  unsigned int size,
1106  unsigned int colors,
1107  std::vector<unsigned int> & vertex_colors,
1108  const char * coloring_algorithm)
1109 {
1110  // Mat A will be a dense matrix from the incoming data structure
1111  Mat A;
1112  LibmeshPetscCallA(PETSC_COMM_SELF, MatCreate(PETSC_COMM_SELF, &A));
1113  LibmeshPetscCallA(PETSC_COMM_SELF, MatSetSizes(A, size, size, size, size));
1114  LibmeshPetscCallA(PETSC_COMM_SELF, MatSetType(A, MATSEQDENSE));
1115  // PETSc requires a non-const data array to populate the matrix
1116  LibmeshPetscCallA(PETSC_COMM_SELF, MatSeqDenseSetPreallocation(A, adjacency_matrix));
1117  LibmeshPetscCallA(PETSC_COMM_SELF, MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
1118  LibmeshPetscCallA(PETSC_COMM_SELF, MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
1119 
1120  // Convert A to a sparse matrix
1121 #if PETSC_VERSION_LESS_THAN(3, 7, 0)
1122  LibmeshPetscCallA(PETSC_COMM_SELF, MatConvert(A, MATAIJ, MAT_REUSE_MATRIX, &A));
1123 #else
1124  LibmeshPetscCallA(PETSC_COMM_SELF, MatConvert(A, MATAIJ, MAT_INPLACE_MATRIX, &A));
1125 #endif
1126 
1127  ISColoring iscoloring;
1128  MatColoring mc;
1129  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringCreate(A, &mc));
1130  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetType(mc, coloring_algorithm));
1131  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetMaxColors(mc, static_cast<PetscInt>(colors)));
1132 
1133  // Petsc normally colors by distance two (neighbors of neighbors), we just want one
1134  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetDistance(mc, 1));
1135  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringSetFromOptions(mc));
1136  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringApply(mc, &iscoloring));
1137 
1138  PetscInt nn;
1139  IS * is;
1140 #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
1141  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringGetIS(iscoloring, &nn, &is));
1142 #else
1143  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringGetIS(iscoloring, PETSC_USE_POINTER, &nn, &is));
1144 #endif
1145 
1146  if (nn > static_cast<PetscInt>(colors))
1147  throw std::runtime_error("Not able to color with designated number of colors");
1148 
1149  for (int i = 0; i < nn; i++)
1150  {
1151  PetscInt isize;
1152  const PetscInt * indices;
1153  LibmeshPetscCallA(PETSC_COMM_SELF, ISGetLocalSize(is[i], &isize));
1154  LibmeshPetscCallA(PETSC_COMM_SELF, ISGetIndices(is[i], &indices));
1155  for (int j = 0; j < isize; j++)
1156  {
1157  mooseAssert(indices[j] < static_cast<PetscInt>(vertex_colors.size()), "Index out of bounds");
1158  vertex_colors[indices[j]] = i;
1159  }
1160  LibmeshPetscCallA(PETSC_COMM_SELF, ISRestoreIndices(is[i], &indices));
1161  }
1162 
1163  LibmeshPetscCallA(PETSC_COMM_SELF, MatDestroy(&A));
1164  LibmeshPetscCallA(PETSC_COMM_SELF, MatColoringDestroy(&mc));
1165  LibmeshPetscCallA(PETSC_COMM_SELF, ISColoringDestroy(&iscoloring));
1166 }
1167 
1168 void
1169 dontAddPetscFlag(const std::string & flag, PetscOptions & petsc_options)
1170 {
1171  if (!petsc_options.dont_add_these_options.contains(flag))
1172  petsc_options.dont_add_these_options.setAdditionalValue(flag);
1173 }
1174 
1175 void
1177 {
1178  dontAddPetscFlag("-snes_converged_reason", fe_problem.getPetscOptions());
1179 }
1180 
1181 void
1183 {
1184  dontAddPetscFlag("-ksp_converged_reason", fe_problem.getPetscOptions());
1185 }
1186 
1187 void
1189 {
1190  auto & petsc_options = fe_problem.getPetscOptions();
1191  for (const auto & flag : getCommonKSPFlags().getNames())
1192  dontAddPetscFlag(flag, petsc_options);
1193  for (const auto & key : getCommonKSPKeys().getNames())
1194  dontAddPetscFlag(key, petsc_options);
1195 }
1196 
1197 void
1199 {
1200  auto & petsc_options = fe_problem.getPetscOptions();
1201  for (const auto & flag : getCommonSNESFlags().getNames())
1202  if (!petsc_options.dont_add_these_options.contains(flag))
1203  petsc_options.dont_add_these_options.setAdditionalValue(flag);
1204  for (const auto & key : getCommonSNESKeys().getNames())
1205  if (!petsc_options.dont_add_these_options.contains(key))
1206  petsc_options.dont_add_these_options.setAdditionalValue(key);
1207 }
1208 
1209 std::unique_ptr<PetscMatrix<Number>>
1211  Mat & mat,
1212  const std::string & binary_mat_file,
1213  const unsigned int mat_number_to_load)
1214 {
1215  LibmeshPetscCallA(comm.get(), MatCreate(comm.get(), &mat));
1216  PetscViewer matviewer;
1217  LibmeshPetscCallA(
1218  comm.get(),
1219  PetscViewerBinaryOpen(comm.get(), binary_mat_file.c_str(), FILE_MODE_READ, &matviewer));
1220  for (unsigned int i = 0; i < mat_number_to_load; ++i)
1221  LibmeshPetscCallA(comm.get(), MatLoad(mat, matviewer));
1222  LibmeshPetscCallA(comm.get(), PetscViewerDestroy(&matviewer));
1223 
1224  return std::make_unique<PetscMatrix<Number>>(mat, comm);
1225 }
1226 
1227 } // Namespace PetscSupport
1228 } // 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:960
MultiMooseEnum getCommonPetscKeys()
A helper function to produce a MultiMooseEnum with commonly used PETSc iname options (keys in key-val...
Definition: PetscSupport.C:968
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:984
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:639
KSPNormType getPetscKSPNormType(Moose::MooseKSPNormType kspnorm)
Definition: PetscSupport.C:383
void addPetscOptionsFromCommandline()
Definition: PetscSupport.C:191
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:30
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:619
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
Full Newton Solve.
Definition: MooseTypes.h:847
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:883
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:323
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:700
void petscSetDefaults(FEProblemBase &problem)
Sets the default options for PETSc.
Definition: PetscSupport.C:450
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:924
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
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:574
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:404
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:428
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:1340
PCSide getPetscPCSide(Moose::PCSideType pcs)
Definition: PetscSupport.C:366
void processSingletonMooseWrappedOptions(FEProblemBase &fe_problem, const InputParameters &params)
Process some MOOSE-wrapped PETSc options.
Definition: PetscSupport.C:534
void checkUserProvidedPetscOption(const T &option, const ParallelParamObject &param_object)
Definition: PetscSupport.C:631
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:676
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:942
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:2968
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:1157
std::string toLower(std::string name)
Convert supplied string to lower case.
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:1039
void setLineSearchFromParams(FEProblemBase &fe_problem, const InputParameters &params)
Sets the FE problem&#39;s line search from the input params.
Definition: PetscSupport.C:587
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:935
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:889
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:271
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:951
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:549
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:415
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.