MFEM  v4.6.0
Finite element discretization library
solvers.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_SOLVERS
13 #define MFEM_SOLVERS
14 
15 #include "../config/config.hpp"
16 #include "densemat.hpp"
17 #include "handle.hpp"
18 #include <memory>
19 
20 #ifdef MFEM_USE_MPI
21 #include <mpi.h>
22 #endif
23 
24 #ifdef MFEM_USE_SUITESPARSE
25 #include "sparsemat.hpp"
26 #include <umfpack.h>
27 #include <klu.h>
28 #endif
29 
30 namespace mfem
31 {
32 
33 class BilinearForm;
34 
35 /// Abstract base class for an iterative solver monitor
37 {
38 protected:
39  /// The last IterativeSolver to which this monitor was attached.
41 
42 public:
44 
46 
47  /// Monitor the residual vector r
48  virtual void MonitorResidual(int it, double norm, const Vector &r,
49  bool final)
50  {
51  }
52 
53  /// Monitor the solution vector x
54  virtual void MonitorSolution(int it, double norm, const Vector &x,
55  bool final)
56  {
57  }
58 
59  /** @brief This method is invoked by IterativeSolver::SetMonitor, informing
60  the monitor which IterativeSolver is using it. */
61  void SetIterativeSolver(const IterativeSolver &solver)
62  { iter_solver = &solver; }
63 };
64 
65 /// Abstract base class for iterative solver
66 class IterativeSolver : public Solver
67 {
68 public:
69  /** @brief Settings for the output behavior of the IterativeSolver.
70 
71  By default, all output is suppressed. The construction of the desired
72  print level can be achieved through a builder pattern, for example
73 
74  PrintLevel().Errors().Warnings()
75 
76  constructs the print level with only errors and warnings enabled.
77  */
78  struct PrintLevel
79  {
80  /** @brief If a fatal problem has been detected the failure will be
81  reported to @ref mfem::err. */
82  bool errors = false;
83  /** @brief If a non-fatal problem has been detected some context-specific
84  information will be reported to @ref mfem::out */
85  bool warnings = false;
86  /** @brief Detailed information about each iteration will be reported to
87  @ref mfem::out */
88  bool iterations = false;
89  /** @brief A summary of the solver process will be reported after the last
90  iteration to @ref mfem::out */
91  bool summary = false;
92  /** @brief Information about the first and last iteration will be printed
93  to @ref mfem::out */
94  bool first_and_last = false;
95 
96  /// Initializes the print level to suppress
97  PrintLevel() = default;
98 
99  /** @name Builder
100  These methods are utilized to construct PrintLevel objects through a
101  builder approach by chaining the function calls in this group. */
102  ///@{
103  PrintLevel &None() { *this = PrintLevel(); return *this; }
104  PrintLevel &Warnings() { warnings=true; return *this; }
105  PrintLevel &Errors() { errors=true; return *this; }
106  PrintLevel &Iterations() { iterations=true; return *this; }
107  PrintLevel &FirstAndLast() { first_and_last=true; return *this; }
108  PrintLevel &Summary() { summary=true; return *this; }
110  ///@}
111  };
112 
113 #ifdef MFEM_USE_MPI
114 private:
115  int dot_prod_type; // 0 - local, 1 - global over 'comm'
116  MPI_Comm comm = MPI_COMM_NULL;
117 #endif
118 
119 protected:
120  const Operator *oper;
123 
124  /// @name Reporting (protected attributes and member functions)
125  ///@{
126 
127  /** @brief (DEPRECATED) Legacy print level definition, which is left for
128  compatibility with custom iterative solvers.
129  @deprecated #print_options should be used instead. */
130  int print_level = -1;
131 
132  /** @brief Output behavior for the iterative solver.
133 
134  This primarily controls the output behavior of the iterative solvers
135  provided by this library. This member must be synchronized with
136  #print_level to ensure compatibility with custom iterative solvers. */
138 
139  /// Convert a legacy print level integer to a PrintLevel object
141 
142  /// @brief Use some heuristics to guess a legacy print level corresponding to
143  /// the given PrintLevel.
144  static int GuessLegacyPrintLevel(PrintLevel);
145  ///@}
146 
147  /// @name Convergence (protected attributes)
148  ///@{
149 
150  /// Limit for the number of iterations the solver is allowed to do
151  int max_iter;
152 
153  /// Relative tolerance.
154  double rel_tol;
155 
156  /// Absolute tolerance.
157  double abs_tol;
158 
159  ///@}
160 
161  /// @name Solver statistics (protected attributes)
162  /// Every IterativeSolver is expected to define these in its Mult() call.
163  ///@{
164 
165  mutable int final_iter = -1;
166  mutable bool converged = false;
167  mutable double initial_norm = -1.0, final_norm = -1.0;
168 
169  ///@}
170 
171  double Dot(const Vector &x, const Vector &y) const;
172  double Norm(const Vector &x) const { return sqrt(Dot(x, x)); }
173  void Monitor(int it, double norm, const Vector& r, const Vector& x,
174  bool final=false) const;
175 
176 public:
177  IterativeSolver();
178 
179 #ifdef MFEM_USE_MPI
180  IterativeSolver(MPI_Comm comm_);
181 #endif
182 
183  /** @name Convergence
184  @brief Termination criteria for the iterative solvers.
185 
186  @details While the convergence criterion is solver specific, most of the
187  provided iterative solvers use one of the following criteria
188 
189  \f$ ||r||_X \leq tol_{rel}||r_0||_X \f$,
190 
191  \f$ ||r||_X \leq tol_{abs} \f$,
192 
193  \f$ ||r||_X \leq \max\{ tol_{abs}, tol_{rel} ||r_0||_X \} \f$,
194 
195  where X denotes the space in which the norm is measured. The choice of
196  X depends on the specific iterative solver.
197  */
198  ///@{
199  void SetRelTol(double rtol) { rel_tol = rtol; }
200  void SetAbsTol(double atol) { abs_tol = atol; }
201  void SetMaxIter(int max_it) { max_iter = max_it; }
202  ///@}
203 
204  /** @name Reporting
205  These options control the internal reporting behavior into ::mfem::out
206  and ::mfem::err of the iterative solvers.
207  */
208  ///@{
209 
210  /// @brief Legacy method to set the level of verbosity of the solver output.
211  /** This is the old way to control what information will be printed to
212  ::mfem::out and ::mfem::err. The behavior for the print level for all
213  iterative solvers is:
214 
215  - -1: Suppress all outputs.
216  - 0: Print information about all detected issues (e.g. no convergence).
217  - 1: Same as level 0, but with detailed information about each
218  iteration.
219  - 2: Print detected issues and a summary when the solver terminates.
220  - 3: Same as 2, but print also the first and last iterations.
221  - >3: Custom print options which are dependent on the specific solver.
222 
223  In parallel, only rank 0 produces output.
224 
225  @note It is recommended to use @ref SetPrintLevel(PrintLevel) instead.
226 
227  @note Some derived classes, like KINSolver, redefine this method and use
228  their own set of print level constants. */
229  virtual void SetPrintLevel(int print_lvl);
230 
231  /// @brief Set the level of verbosity of the solver output.
232  /** In parallel, only rank 0 produces outputs. Errors are output to
233  ::mfem::err and all other information to ::mfem::out.
234 
235  @note Not all subclasses of IterativeSolver support all possible options.
236 
237  @note Some derived classes, like KINSolver, disable this method in favor
238  of SetPrintLevel(int).
239 
240  @sa PrintLevel for possible options.
241  */
242  virtual void SetPrintLevel(PrintLevel);
243  ///@}
244 
245  /// @name Solver statistics.
246  /// These are valid after the call to Mult().
247  ///@{
248 
249  /// Returns the number of iterations taken during the last call to Mult()
250  int GetNumIterations() const { return final_iter; }
251  /// Returns true if the last call to Mult() converged successfully.
252  bool GetConverged() const { return converged; }
253  /// @brief Returns the initial residual norm from the last call to Mult().
254  ///
255  /// This function returns the norm of the residual (or preconditioned
256  /// residual, depending on the solver), computed before the start of the
257  /// iteration.
258  double GetInitialNorm() const { return initial_norm; }
259  /// @brief Returns the final residual norm after termination of the solver
260  /// during the last call to Mult().
261  ///
262  /// This function returns the norm of the residual (or preconditioned
263  /// residual, depending on the solver), corresponding to the returned
264  /// solution.
265  double GetFinalNorm() const { return final_norm; }
266  /// @brief Returns the final residual norm after termination of the solver
267  /// during the last call to Mult(), divided by the initial residual norm.
268  /// Returns -1 if one of these norms is left undefined by the solver.
269  ///
270  /// @sa GetFinalNorm(), GetInitialNorm()
271  double GetFinalRelNorm() const
272  {
273  if (final_norm < 0.0 || initial_norm < 0.0) { return -1.0; }
274  return final_norm / initial_norm;
275  }
276 
277  ///@}
278 
279  /// This should be called before SetOperator
280  virtual void SetPreconditioner(Solver &pr);
281 
282  /// Also calls SetOperator for the preconditioner if there is one
283  virtual void SetOperator(const Operator &op) override;
284 
285  /// Set the iterative solver monitor
287  { monitor = &m; m.SetIterativeSolver(*this); }
288 
289 #ifdef MFEM_USE_MPI
290  /** @brief Return the associated MPI communicator, or MPI_COMM_NULL if no
291  communicator is set. */
292  MPI_Comm GetComm() const
293  { return dot_prod_type == 0 ? MPI_COMM_NULL : comm; }
294 #endif
295 };
296 
297 
298 /// Jacobi smoothing for a given bilinear form (no matrix necessary).
299 /** Useful with tensorized, partially assembled operators. Can also be defined
300  by given diagonal vector. This is basic Jacobi iteration; for tolerances,
301  iteration control, etc. wrap with SLISolver. */
303 {
304 public:
305  /** @brief Default constructor: the diagonal will be computed by subsequent
306  calls to SetOperator() using the Operator method AssembleDiagonal. */
307  /** In this case the array of essential tdofs will be empty. */
308  OperatorJacobiSmoother(const double damping=1.0);
309 
310  /** Setup a Jacobi smoother with the diagonal of @a a obtained by calling
311  a.AssembleDiagonal(). It is assumed that the underlying operator acts as
312  the identity on entries in ess_tdof_list, corresponding to (assembled)
313  DIAG_ONE policy or ConstrainedOperator in the matrix-free setting.
314 
315  @note For objects created with this constructor, calling SetOperator()
316  will only set the internal Operator pointer to the given new Operator
317  without any other changes to the object. This is done to preserve the
318  original behavior of this class. */
320  const Array<int> &ess_tdof_list,
321  const double damping=1.0);
322 
323  /** Application is by the *inverse* of the given vector. It is assumed that
324  the underlying operator acts as the identity on entries in ess_tdof_list,
325  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
326  the matrix-free setting.
327 
328  @note For objects created with this constructor, calling SetOperator()
329  will only set the internal Operator pointer to the given new Operator
330  without any other changes to the object. This is done to preserve the
331  original behavior of this class. */
333  const Array<int> &ess_tdof_list,
334  const double damping=1.0);
335 
337 
338  /// Replace diagonal entries with their absolute values.
339  void SetPositiveDiagonal(bool pos_diag = true) { use_abs_diag = pos_diag; }
340 
341  void Mult(const Vector &x, Vector &y) const;
342  void MultTranspose(const Vector &x, Vector &y) const { Mult(x, y); }
343 
344  /** @brief Recompute the diagonal using the method AssembleDiagonal of the
345  given new Operator, @a op. */
346  /** Note that (Par)BilinearForm operators are treated similar to the way they
347  are treated in the constructor that takes a BilinearForm parameter.
348  Specifically, this means that the OperatorJacobiSmoother will work with
349  true-dof vectors even though the size of the BilinearForm may be
350  different.
351 
352  When the new Operator, @a op, is not a (Par)BilinearForm, any previously
353  set array of essential true-dofs will be thrown away because in this case
354  any essential b.c. will be handled by the AssembleDiagonal method. */
355  void SetOperator(const Operator &op);
356 
357 private:
358  Vector dinv;
359  const double damping;
360  const Array<int> *ess_tdof_list; // not owned; may be NULL
361  mutable Vector residual;
362  /// Uses absolute values of the diagonal entries.
363  bool use_abs_diag = false;
364 
365  const Operator *oper; // not owned
366 
367  // To preserve the original behavior, some constructors set this flag to
368  // false to disallow updating the OperatorJacobiSmoother with SetOperator.
369  const bool allow_updates;
370 
371 public:
372  void Setup(const Vector &diag);
373 };
374 
375 /// Chebyshev accelerated smoothing with given vector, no matrix necessary
376 /** Potentially useful with tensorized operators, for example. This is just a
377  very basic Chebyshev iteration, if you want tolerances, iteration control,
378  etc. wrap this with SLISolver. */
380 {
381 public:
382  /** Application is by *inverse* of the given vector. It is assumed the
383  underlying operator acts as the identity on entries in ess_tdof_list,
384  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
385  the matrix-free setting. The estimated largest eigenvalue of the
386  diagonally preconditoned operator must be provided via
387  max_eig_estimate. */
388  OperatorChebyshevSmoother(const Operator &oper_, const Vector &d,
389  const Array<int>& ess_tdof_list,
390  int order, double max_eig_estimate);
391 
392  /// Deprecated: see pass-by-reference version above
393  MFEM_DEPRECATED
394  OperatorChebyshevSmoother(const Operator* oper_, const Vector &d,
395  const Array<int>& ess_tdof_list,
396  int order, double max_eig_estimate);
397 
398  /** Application is by *inverse* of the given vector. It is assumed the
399  underlying operator acts as the identity on entries in ess_tdof_list,
400  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
401  the matrix-free setting. The largest eigenvalue of the diagonally
402  preconditoned operator is estimated internally via a power method. The
403  accuracy of the estimated eigenvalue may be controlled via
404  power_iterations and power_tolerance. */
405 #ifdef MFEM_USE_MPI
406  OperatorChebyshevSmoother(const Operator &oper_, const Vector &d,
407  const Array<int>& ess_tdof_list,
408  int order, MPI_Comm comm = MPI_COMM_NULL,
409  int power_iterations = 10,
410  double power_tolerance = 1e-8);
411 
412  /// Deprecated: see pass-by-reference version above
413  MFEM_DEPRECATED
414  OperatorChebyshevSmoother(const Operator* oper_, const Vector &d,
415  const Array<int>& ess_tdof_list,
416  int order, MPI_Comm comm = MPI_COMM_NULL,
417  int power_iterations = 10,
418  double power_tolerance = 1e-8);
419 #else
420  OperatorChebyshevSmoother(const Operator &oper_, const Vector &d,
421  const Array<int>& ess_tdof_list,
422  int order, int power_iterations = 10,
423  double power_tolerance = 1e-8);
424 
425  /// Deprecated: see pass-by-reference version above
426  MFEM_DEPRECATED
427  OperatorChebyshevSmoother(const Operator* oper_, const Vector &d,
428  const Array<int>& ess_tdof_list,
429  int order, int power_iterations = 10,
430  double power_tolerance = 1e-8);
431 #endif
432 
434 
435  void Mult(const Vector &x, Vector &y) const;
436 
437  void MultTranspose(const Vector &x, Vector &y) const { Mult(x, y); }
438 
439  void SetOperator(const Operator &op_)
440  {
441  oper = &op_;
442  }
443 
444  void Setup();
445 
446 private:
447  const int order;
448  double max_eig_estimate;
449  const int N;
450  Vector dinv;
451  const Vector &diag;
452  Array<double> coeffs;
453  const Array<int>& ess_tdof_list;
454  mutable Vector residual;
455  mutable Vector helperVector;
456  const Operator* oper;
457 };
458 
459 
460 /// Stationary linear iteration: x <- x + B (b - A x)
462 {
463 protected:
464  mutable Vector r, z;
465 
466  void UpdateVectors();
467 
468 public:
469  SLISolver() { }
470 
471 #ifdef MFEM_USE_MPI
472  SLISolver(MPI_Comm comm_) : IterativeSolver(comm_) { }
473 #endif
474 
475  virtual void SetOperator(const Operator &op)
477 
478  virtual void Mult(const Vector &b, Vector &x) const;
479 };
480 
481 /// Stationary linear iteration. (tolerances are squared)
482 void SLI(const Operator &A, const Vector &b, Vector &x,
483  int print_iter = 0, int max_num_iter = 1000,
484  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
485 
486 /// Preconditioned stationary linear iteration. (tolerances are squared)
487 void SLI(const Operator &A, Solver &B, const Vector &b, Vector &x,
488  int print_iter = 0, int max_num_iter = 1000,
489  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
490 
491 
492 /// Conjugate gradient method
493 class CGSolver : public IterativeSolver
494 {
495 protected:
496  mutable Vector r, d, z;
497 
498  void UpdateVectors();
499 
500 public:
501  CGSolver() { }
502 
503 #ifdef MFEM_USE_MPI
504  CGSolver(MPI_Comm comm_) : IterativeSolver(comm_) { }
505 #endif
506 
507  virtual void SetOperator(const Operator &op)
509 
510  virtual void Mult(const Vector &b, Vector &x) const;
511 };
512 
513 /// Conjugate gradient method. (tolerances are squared)
514 void CG(const Operator &A, const Vector &b, Vector &x,
515  int print_iter = 0, int max_num_iter = 1000,
516  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
517 
518 /// Preconditioned conjugate gradient method. (tolerances are squared)
519 void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x,
520  int print_iter = 0, int max_num_iter = 1000,
521  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
522 
523 
524 /// GMRES method
526 {
527 protected:
528  int m; // see SetKDim()
529 
530 public:
531  GMRESSolver() { m = 50; }
532 
533 #ifdef MFEM_USE_MPI
534  GMRESSolver(MPI_Comm comm_) : IterativeSolver(comm_) { m = 50; }
535 #endif
536 
537  /// Set the number of iteration to perform between restarts, default is 50.
538  void SetKDim(int dim) { m = dim; }
539 
540  virtual void Mult(const Vector &b, Vector &x) const;
541 };
542 
543 /// FGMRES method
545 {
546 protected:
547  int m;
548 
549 public:
550  FGMRESSolver() { m = 50; }
551 
552 #ifdef MFEM_USE_MPI
553  FGMRESSolver(MPI_Comm comm_) : IterativeSolver(comm_) { m = 50; }
554 #endif
555 
556  void SetKDim(int dim) { m = dim; }
557 
558  virtual void Mult(const Vector &b, Vector &x) const;
559 };
560 
561 /// GMRES method. (tolerances are squared)
562 int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M,
563  int &max_iter, int m, double &tol, double atol, int printit);
564 
565 /// GMRES method. (tolerances are squared)
566 void GMRES(const Operator &A, Solver &B, const Vector &b, Vector &x,
567  int print_iter = 0, int max_num_iter = 1000, int m = 50,
568  double rtol = 1e-12, double atol = 1e-24);
569 
570 
571 /// BiCGSTAB method
573 {
574 protected:
575  mutable Vector p, phat, s, shat, t, v, r, rtilde;
576 
577  void UpdateVectors();
578 
579 public:
581 
582 #ifdef MFEM_USE_MPI
583  BiCGSTABSolver(MPI_Comm comm_) : IterativeSolver(comm_) { }
584 #endif
585 
586  virtual void SetOperator(const Operator &op)
588 
589  virtual void Mult(const Vector &b, Vector &x) const;
590 };
591 
592 /// BiCGSTAB method. (tolerances are squared)
593 int BiCGSTAB(const Operator &A, Vector &x, const Vector &b, Solver &M,
594  int &max_iter, double &tol, double atol, int printit);
595 
596 /// BiCGSTAB method. (tolerances are squared)
597 void BiCGSTAB(const Operator &A, Solver &B, const Vector &b, Vector &x,
598  int print_iter = 0, int max_num_iter = 1000,
599  double rtol = 1e-12, double atol = 1e-24);
600 
601 
602 /// MINRES method
604 {
605 protected:
606  mutable Vector v0, v1, w0, w1, q;
607  mutable Vector u1; // used in the preconditioned version
608 
609 public:
611 
612 #ifdef MFEM_USE_MPI
613  MINRESSolver(MPI_Comm comm_) : IterativeSolver(comm_) { }
614 #endif
615 
616  virtual void SetPreconditioner(Solver &pr)
617  {
619  if (oper) { u1.SetSize(width); }
620  }
621 
622  virtual void SetOperator(const Operator &op);
623 
624  virtual void Mult(const Vector &b, Vector &x) const;
625 };
626 
627 /// MINRES method without preconditioner. (tolerances are squared)
628 void MINRES(const Operator &A, const Vector &b, Vector &x, int print_it = 0,
629  int max_it = 1000, double rtol = 1e-12, double atol = 1e-24);
630 
631 /// MINRES method with preconditioner. (tolerances are squared)
632 void MINRES(const Operator &A, Solver &B, const Vector &b, Vector &x,
633  int print_it = 0, int max_it = 1000,
634  double rtol = 1e-12, double atol = 1e-24);
635 
636 
637 /// Newton's method for solving F(x)=b for a given operator F.
638 /** The method GetGradient() must be implemented for the operator F.
639  The preconditioner is used (in non-iterative mode) to evaluate
640  the action of the inverse gradient of the operator. */
642 {
643 protected:
644  mutable Vector r, c;
645  mutable Operator *grad;
646 
647  // Adaptive linear solver rtol variables
648 
649  // Method to determine rtol, 0 means the adaptive algorithm is deactivated.
650  int lin_rtol_type = 0;
651  // rtol to use in first iteration
652  double lin_rtol0;
653  // Maximum rtol
654  double lin_rtol_max;
655  // Function norm ||F(x)|| of the previous iterate
656  mutable double fnorm_last = 0.0;
657  // Linear residual norm of the previous iterate
658  mutable double lnorm_last = 0.0;
659  // Forcing term (linear residual rtol) from the previous iterate
660  mutable double eta_last = 0.0;
661  // Eisenstat-Walker factor gamma
662  double gamma;
663  // Eisenstat-Walker factor alpha
664  double alpha;
665 
666  /** @brief Method for the adaptive linear solver rtol invoked before the
667  linear solve. */
668  void AdaptiveLinRtolPreSolve(const Vector &x,
669  const int it,
670  const double fnorm) const;
671 
672  /** @brief Method for the adaptive linear solver rtol invoked after the
673  linear solve. */
674  void AdaptiveLinRtolPostSolve(const Vector &x,
675  const Vector &b,
676  const int it,
677  const double fnorm) const;
678 
679 public:
681 
682 #ifdef MFEM_USE_MPI
683  NewtonSolver(MPI_Comm comm_) : IterativeSolver(comm_) { }
684 #endif
685  virtual void SetOperator(const Operator &op);
686 
687  /// Set the linear solver for inverting the Jacobian.
688  /** This method is equivalent to calling SetPreconditioner(). */
689  virtual void SetSolver(Solver &solver) { prec = &solver; }
690 
691  /// Solve the nonlinear system with right-hand side @a b.
692  /** If `b.Size() != Height()`, then @a b is assumed to be zero. */
693  virtual void Mult(const Vector &b, Vector &x) const;
694 
695  /** @brief This method can be overloaded in derived classes to implement line
696  search algorithms. */
697  /** The base class implementation (NewtonSolver) simply returns 1. A return
698  value of 0 indicates a failure, interrupting the Newton iteration. */
699  virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
700  { return 1.0; }
701 
702  /** @brief This method can be overloaded in derived classes to perform
703  computations that need knowledge of the newest Newton state. */
704  virtual void ProcessNewState(const Vector &x) const { }
705 
706  /// Enable adaptive linear solver relative tolerance algorithm.
707  /** Compute a relative tolerance for the Krylov method after each nonlinear
708  iteration, based on the algorithm presented in [1].
709 
710  The maximum linear solver relative tolerance @a rtol_max should be < 1. For
711  @a type 1 the parameters @a alpha and @a gamma are ignored. For @a type 2
712  @a alpha has to be between 0 and 1 and @a gamma between 1 and 2.
713 
714  [1] Eisenstat, Stanley C., and Homer F. Walker. "Choosing the forcing terms
715  in an inexact Newton method."
716  */
717  void SetAdaptiveLinRtol(const int type = 2,
718  const double rtol0 = 0.5,
719  const double rtol_max = 0.9,
720  const double alpha = 0.5 * (1.0 + sqrt(5.0)),
721  const double gamma = 1.0);
722 };
723 
724 /** L-BFGS method for solving F(x)=b for a given operator F, by minimizing
725  the norm of F(x) - b. Requires only the action of the operator F. */
726 class LBFGSSolver : public NewtonSolver
727 {
728 protected:
729  int m = 10;
731 
733  {
734  for (int i = 0; i < skArray.Size(); i++)
735  {
736  delete skArray[i];
737  delete ykArray[i];
738  }
739  }
740 
742  {
744  skArray.SetSize(m);
745  ykArray.SetSize(m);
746  for (int i = 0; i < m; i++)
747  {
748  skArray[i] = new Vector(width);
749  ykArray[i] = new Vector(width);
750  skArray[i]->UseDevice(true);
751  ykArray[i]->UseDevice(true);
752  }
753  }
754 
755 public:
757 
758 #ifdef MFEM_USE_MPI
759  LBFGSSolver(MPI_Comm comm_) : NewtonSolver(comm_) { }
760 #endif
761 
762  virtual void SetOperator(const Operator &op)
763  {
766  }
767 
768  void SetHistorySize(int dim)
769  {
770  m = dim;
772  }
773 
774  /// Solve the nonlinear system with right-hand side @a b.
775  /** If `b.Size() != Height()`, then @a b is assumed to be zero. */
776  virtual void Mult(const Vector &b, Vector &x) const;
777 
778  virtual void SetPreconditioner(Solver &pr)
779  { MFEM_WARNING("L-BFGS won't use the given preconditioner."); }
780  virtual void SetSolver(Solver &solver)
781  { MFEM_WARNING("L-BFGS won't use the given solver."); }
782 
784 };
785 
786 
787 /** Adaptive restarted GMRES.
788  m_max and m_min(=1) are the maximal and minimal restart parameters.
789  m_step(=1) is the step to use for going from m_max and m_min.
790  cf(=0.4) is a desired convergence factor. */
791 int aGMRES(const Operator &A, Vector &x, const Vector &b,
792  const Operator &M, int &max_iter,
793  int m_max, int m_min, int m_step, double cf,
794  double &tol, double &atol, int printit);
795 
796 #ifdef MFEM_USE_HIOP
797 class HiopOptimizationProblem;
798 #endif
799 
800 /** Defines operators and constraints for the following optimization problem:
801  *
802  * Find x that minimizes the objective function F(x), subject to
803  * C(x) = c_e,
804  * d_lo <= D(x) <= d_hi,
805  * x_lo <= x <= x_hi.
806  *
807  * The operators F, C, D must take input of the same size (same width).
808  * Gradients of F, C, D might be needed, depending on the OptimizationSolver.
809  * When used with Hiop, gradients of C and D must be DenseMatrices.
810  * F always returns a scalar value, see CalcObjective(), CalcObjectiveGrad().
811  * C and D can have arbitrary heights.
812  * C and D can be NULL, meaning that their constraints are not used.
813  *
814  * When used in parallel, all Vectors are assumed to be true dof vectors, and
815  * the operators are expected to be defined for tdof vectors. */
817 {
818 #ifdef MFEM_USE_HIOP
820 #endif
821 
822 private:
823  /// See NewX().
824  mutable bool new_x = true;
825 
826 protected:
827  /// Not owned, some can remain unused (NULL).
828  const Operator *C, *D;
829  const Vector *c_e, *d_lo, *d_hi, *x_lo, *x_hi;
830 
831  /// Implementations of CalcObjective() and CalcObjectiveGrad() can use this
832  /// method to check if the argument Vector x has been changed after the last
833  /// call to CalcObjective() or CalcObjectiveGrad().
834  /// The result is on by default, and gets set by the OptimizationSolver.
835  bool NewX() const { return new_x; }
836 
837 public:
838  const int input_size;
839 
840  /// In parallel, insize is the number of the local true dofs.
841  OptimizationProblem(int insize, const Operator *C_, const Operator *D_);
842 
843  /// Objective F(x). In parallel, the result should be reduced over tasks.
844  virtual double CalcObjective(const Vector &x) const = 0;
845  /// The result grad is expected to enter with the correct size.
846  virtual void CalcObjectiveGrad(const Vector &x, Vector &grad) const
847  { MFEM_ABORT("The objective gradient is not implemented."); }
848 
849  void SetEqualityConstraint(const Vector &c);
850  void SetInequalityConstraint(const Vector &dl, const Vector &dh);
851  void SetSolutionBounds(const Vector &xl, const Vector &xh);
852 
853  const Operator *GetC() const { return C; }
854  const Operator *GetD() const { return D; }
855  const Vector *GetEqualityVec() const { return c_e; }
856  const Vector *GetInequalityVec_Lo() const { return d_lo; }
857  const Vector *GetInequalityVec_Hi() const { return d_hi; }
858  const Vector *GetBoundsVec_Lo() const { return x_lo; }
859  const Vector *GetBoundsVec_Hi() const { return x_hi; }
860 
861  int GetNumConstraints() const;
862 };
863 
864 /// Abstract solver for OptimizationProblems.
866 {
867 protected:
869 
870 public:
872 #ifdef MFEM_USE_MPI
873  OptimizationSolver(MPI_Comm comm_): IterativeSolver(comm_), problem(NULL) { }
874 #endif
875  virtual ~OptimizationSolver() { }
876 
877  /** This function is virtual as solvers might need to perform some initial
878  * actions (e.g. validation) with the OptimizationProblem. */
880  { problem = &prob; }
881 
882  virtual void Mult(const Vector &xt, Vector &x) const = 0;
883 
884  virtual void SetPreconditioner(Solver &pr)
885  { MFEM_ABORT("Not meaningful for this solver."); }
886  virtual void SetOperator(const Operator &op)
887  { MFEM_ABORT("Not meaningful for this solver."); }
888 };
889 
890 /** SLBQP optimizer:
891  * (S)ingle (L)inearly Constrained with (B)ounds (Q)uadratic (P)rogram
892  *
893  * Minimize || x-x_t ||, subject to
894  * sum w_i x_i = a,
895  * x_lo <= x <= x_hi.
896  */
898 {
899 protected:
901  double a;
902 
903  /// Solve QP at fixed lambda
904  inline double solve(double l, const Vector &xt, Vector &x, int &nclip) const
905  {
906  add(xt, l, w, x);
907  if (problem == NULL) { x.median(lo,hi); }
908  else
909  {
912  }
913  nclip++;
914  if (problem == NULL) { return Dot(w, x) - a; }
915  else
916  {
917  Vector c(1);
918  // Includes parallel communication.
919  problem->GetC()->Mult(x, c);
920 
921  return c(0) - (*problem->GetEqualityVec())(0);
922  }
923  }
924 
925  inline void print_iteration(int it, double r, double l) const;
926 
927 public:
929 
930 #ifdef MFEM_USE_MPI
931  SLBQPOptimizer(MPI_Comm comm_) : OptimizationSolver(comm_) { }
932 #endif
933 
934  /** Setting an OptimizationProblem will overwrite the Vectors given by
935  * SetBounds and SetLinearConstraint. The objective function remains
936  * unchanged. */
937  virtual void SetOptimizationProblem(const OptimizationProblem &prob);
938 
939  void SetBounds(const Vector &lo_, const Vector &hi_);
940  void SetLinearConstraint(const Vector &w_, double a_);
941 
942  /** We let the target values play the role of the initial vector xt, from
943  * which the operator generates the optimal vector x. */
944  virtual void Mult(const Vector &xt, Vector &x) const;
945 };
946 
947 /** Block ILU solver:
948  * Performs a block ILU(k) approximate factorization with specified block
949  * size. Currently only k=0 is supported. This is useful as a preconditioner
950  * for DG-type discretizations, where the system matrix has a natural
951  * (elemental) block structure.
952  *
953  * In the case of DG discretizations, the block size should usually be set to
954  * either ndofs_per_element or vdim*ndofs_per_element (if the finite element
955  * space has Ordering::byVDIM). The block size must evenly divide the size of
956  * the matrix.
957  *
958  * Renumbering the blocks is also supported by specifying a reordering method.
959  * Currently greedy minimum discarded fill ordering and no reordering are
960  * supported. Renumbering the blocks can lead to a much better approximate
961  * factorization.
962  */
963 class BlockILU : public Solver
964 {
965 public:
966 
967  /// The reordering method used by the BlockILU factorization.
968  enum class Reordering
969  {
971  NONE
972  };
973 
974  /** Create an "empty" BlockILU solver. SetOperator must be called later to
975  * actually form the factorization
976  */
977  BlockILU(int block_size_,
979  int k_fill_ = 0);
980 
981  /** Create a block ILU approximate factorization for the matrix @a op.
982  * @a op should be of type either SparseMatrix or HypreParMatrix. In the
983  * case that @a op is a HypreParMatrix, the ILU factorization is performed
984  * on the diagonal blocks of the parallel decomposition.
985  */
986  BlockILU(const Operator &op, int block_size_ = 1,
988  int k_fill_ = 0);
989 
990  /** Perform the block ILU factorization for the matrix @a op.
991  * As in the constructor, @a op must either be a SparseMatrix or
992  * HypreParMatrix
993  */
994  void SetOperator(const Operator &op);
995 
996  /// Solve the system `LUx = b`, where `L` and `U` are the block ILU factors.
997  void Mult(const Vector &b, Vector &x) const;
998 
999  /** Get the I array for the block CSR representation of the factorization.
1000  * Similar to SparseMatrix::GetI(). Mostly used for testing.
1001  */
1002  int *GetBlockI() { return IB.GetData(); }
1003 
1004  /** Get the J array for the block CSR representation of the factorization.
1005  * Similar to SparseMatrix::GetJ(). Mostly used for testing.
1006  */
1007  int *GetBlockJ() { return JB.GetData(); }
1008 
1009  /** Get the data array for the block CSR representation of the factorization.
1010  * Similar to SparseMatrix::GetData(). Mostly used for testing.
1011  */
1012  double *GetBlockData() { return AB.Data(); }
1013 
1014 private:
1015  /// Set up the block CSR structure corresponding to a sparse matrix @a A
1016  void CreateBlockPattern(const class SparseMatrix &A);
1017 
1018  /// Perform the block ILU factorization
1019  void Factorize();
1020 
1021  int block_size;
1022 
1023  /// Fill level for block ILU(k) factorizations. Only k=0 is supported.
1024  int k_fill;
1025 
1026  Reordering reordering;
1027 
1028  /// Temporary vector used in the Mult() function.
1029  mutable Vector y;
1030 
1031  /// Permutation and inverse permutation vectors for the block reordering.
1032  Array<int> P, Pinv;
1033 
1034  /** Block CSR storage of the factorization. The block upper triangular part
1035  * stores the U factor. The L factor implicitly has identity on the diagonal
1036  * blocks, and the rest of L is given by the strictly block lower triangular
1037  * part.
1038  */
1039  Array<int> IB, ID, JB;
1040  DenseTensor AB;
1041 
1042  /// DB(i) stores the LU factorization of the i'th diagonal block
1043  mutable DenseTensor DB;
1044  /// Pivot arrays for the LU factorizations given by #DB
1045  mutable Array<int> ipiv;
1046 };
1047 
1048 
1049 /// Monitor that checks whether the residual is zero at a given set of dofs.
1050 /** This monitor is useful for checking if the initial guess, rhs, operator, and
1051  preconditioner are properly setup for solving in the subspace with imposed
1052  essential boundary conditions. */
1054 {
1055 protected:
1056  const Array<int> *ess_dofs_list; ///< Not owned
1057 
1058 public:
1059  ResidualBCMonitor(const Array<int> &ess_dofs_list_)
1060  : ess_dofs_list(&ess_dofs_list_) { }
1061 
1062  void MonitorResidual(int it, double norm, const Vector &r,
1063  bool final) override;
1064 };
1065 
1066 
1067 #ifdef MFEM_USE_SUITESPARSE
1068 
1069 /// Direct sparse solver using UMFPACK
1070 class UMFPackSolver : public Solver
1071 {
1072 protected:
1075  void *Numeric;
1076  SuiteSparse_long *AI, *AJ;
1077 
1078  void Init();
1079 
1080 public:
1081  double Control[UMFPACK_CONTROL];
1082  mutable double Info[UMFPACK_INFO];
1083 
1084  /** @brief For larger matrices, if the solver fails, set the parameter @a
1085  use_long_ints_ = true. */
1086  UMFPackSolver(bool use_long_ints_ = false)
1087  : use_long_ints(use_long_ints_) { Init(); }
1088  /** @brief Factorize the given SparseMatrix using the defaults. For larger
1089  matrices, if the solver fails, set the parameter @a use_long_ints_ =
1090  true. */
1091  UMFPackSolver(SparseMatrix &A, bool use_long_ints_ = false)
1092  : use_long_ints(use_long_ints_) { Init(); SetOperator(A); }
1093 
1094  /** @brief Factorize the given Operator @a op which must be a SparseMatrix.
1095 
1096  The factorization uses the parameters set in the #Control data member.
1097  @note This method calls SparseMatrix::SortColumnIndices() with @a op,
1098  modifying the matrix if the column indices are not already sorted. */
1099  virtual void SetOperator(const Operator &op);
1100 
1101  /// Set the print level field in the #Control data member.
1102  void SetPrintLevel(int print_lvl) { Control[UMFPACK_PRL] = print_lvl; }
1103 
1104  virtual void Mult(const Vector &b, Vector &x) const;
1105  virtual void MultTranspose(const Vector &b, Vector &x) const;
1106 
1107  virtual ~UMFPackSolver();
1108 };
1109 
1110 /// Direct sparse solver using KLU
1111 class KLUSolver : public Solver
1112 {
1113 protected:
1115  klu_symbolic *Symbolic;
1116  klu_numeric *Numeric;
1117 
1118  void Init();
1119 
1120 public:
1122  : mat(0),Symbolic(0),Numeric(0)
1123  { Init(); }
1125  : mat(0),Symbolic(0),Numeric(0)
1126  { Init(); SetOperator(A); }
1127 
1128  // Works on sparse matrices only; calls SparseMatrix::SortColumnIndices().
1129  virtual void SetOperator(const Operator &op);
1130 
1131  virtual void Mult(const Vector &b, Vector &x) const;
1132  virtual void MultTranspose(const Vector &b, Vector &x) const;
1133 
1134  virtual ~KLUSolver();
1135 
1136  mutable klu_common Common;
1137 };
1138 
1139 #endif // MFEM_USE_SUITESPARSE
1140 
1141 /// Block diagonal solver for A, each block is inverted by direct solver
1143 {
1144  SparseMatrix& block_dof;
1145  mutable Array<int> local_dofs;
1146  mutable Vector sub_rhs;
1147  mutable Vector sub_sol;
1148  std::unique_ptr<DenseMatrixInverse[]> block_solvers;
1149 public:
1150  /// block_dof is a boolean matrix, block_dof(i, j) = 1 if j-th dof belongs to
1151  /// i-th block, block_dof(i, j) = 0 otherwise.
1152  DirectSubBlockSolver(const SparseMatrix& A, const SparseMatrix& block_dof);
1153  virtual void Mult(const Vector &x, Vector &y) const;
1154  virtual void SetOperator(const Operator &op) { }
1155 };
1156 
1157 /// Solver S such that I - A * S = (I - A * S1) * (I - A * S0).
1158 /// That is, S = S0 + S1 - S1 * A * S0.
1159 class ProductSolver : public Solver
1160 {
1161  OperatorPtr A;
1162  OperatorPtr S0;
1163  OperatorPtr S1;
1164 public:
1166  bool ownA, bool ownS0, bool ownS1)
1167  : Solver(A_->NumRows()), A(A_, ownA), S0(S0_, ownS0), S1(S1_, ownS1) { }
1168  virtual void Mult(const Vector &x, Vector &y) const;
1169  virtual void MultTranspose(const Vector &x, Vector &y) const;
1170  virtual void SetOperator(const Operator &op) { }
1171 };
1172 
1173 /// Solver wrapper which orthogonalizes the input and output vector
1174 /**
1175  * OrthoSolver wraps an existing Solver and orthogonalizes the input vector
1176  * before passing it to the Mult() method of the Solver. This is a convenience
1177  * implementation to handle e.g. a Poisson problem with pure Neumann boundary
1178  * conditions, where this procedure removes the Nullspace.
1179  */
1180 class OrthoSolver : public Solver
1181 {
1182 private:
1183 #ifdef MFEM_USE_MPI
1184  MPI_Comm mycomm;
1185  mutable HYPRE_BigInt global_size;
1186  const bool parallel;
1187 #else
1188  mutable int global_size;
1189 #endif
1190 
1191 public:
1192  OrthoSolver();
1193 #ifdef MFEM_USE_MPI
1194  OrthoSolver(MPI_Comm mycomm_);
1195 #endif
1196 
1197  /// Set the solver used by the OrthoSolver.
1198  /** The action of the OrthoSolver is given by P * s * P where P is the
1199  projection to the subspace of vectors with zero sum. Calling this method
1200  is required before calling SetOperator() or Mult(). */
1201  void SetSolver(Solver &s);
1202 
1203  /// Set the Operator that is the OrthoSolver is to invert (approximately).
1204  /** The Operator @a op is simply forwarded to the solver object given by
1205  SetSolver() which needs to be called before this method. Calling this
1206  method is optional when the solver already has an associated Operator. */
1207  virtual void SetOperator(const Operator &op);
1208 
1209  /** @brief Perform the action of the OrthoSolver: P * solver * P where P is
1210  the projection to the subspace of vectors with zero sum. */
1211  /** @note The projection P can be written as P = I - 1 1^T / (1^T 1) where
1212  I is the identity matrix and 1 is the column-vector with all components
1213  equal to 1. */
1214  void Mult(const Vector &b, Vector &x) const;
1215 
1216 private:
1217  Solver *solver = nullptr;
1218 
1219  mutable Vector b_ortho;
1220 
1221  void Orthogonalize(const Vector &v, Vector &v_ortho) const;
1222 };
1223 
1224 #ifdef MFEM_USE_MPI
1225 /** This smoother does relaxations on an auxiliary space (determined by a map
1226  from the original space to the auxiliary space provided by the user).
1227  The smoother on the auxiliary space is a HypreSmoother. Its options can be
1228  modified through GetSmoother.
1229  For example, the space can be the nullspace of div/curl, in which case the
1230  smoother can be used to construct a Hiptmair smoother. */
1231 class AuxSpaceSmoother : public Solver
1232 {
1233  OperatorPtr aux_map_;
1234  OperatorPtr aux_system_;
1235  OperatorPtr aux_smoother_;
1236  void Mult(const Vector &x, Vector &y, bool transpose) const;
1237 public:
1238  AuxSpaceSmoother(const HypreParMatrix &op, HypreParMatrix *aux_map,
1239  bool op_is_symmetric = true, bool own_aux_map = false);
1240  virtual void Mult(const Vector &x, Vector &y) const { Mult(x, y, false); }
1241  virtual void MultTranspose(const Vector &x, Vector &y) const { Mult(x, y, true); }
1242  virtual void SetOperator(const Operator &op) { }
1243  HypreSmoother& GetSmoother() { return *aux_smoother_.As<HypreSmoother>(); }
1244  using Operator::Mult;
1245 };
1246 #endif // MFEM_USE_MPI
1247 
1248 #ifdef MFEM_USE_LAPACK
1249 /** Non-negative least squares (NNLS) solver class, for computing a vector
1250  with non-negative entries approximately satisfying an under-determined
1251  linear system. */
1252 class NNLSSolver : public Solver
1253 {
1254 public:
1255  NNLSSolver();
1256 
1258 
1259  /// The operator must be a DenseMatrix.
1260  void SetOperator(const Operator &op) override;
1261 
1262  void Mult(const Vector &w, Vector &sol) const override;
1263 
1264  /**
1265  * Set verbosity. If set to 0: print nothing; if 1: just print results;
1266  * if 2: print short update on every iteration; if 3: print longer update
1267  * each iteration.
1268  */
1269  void SetVerbosity(int v) { verbosity_ = v; }
1270 
1271  void SetTolerance(double tol) { const_tol_ = tol; }
1272 
1273  /// Set the minimum number of nonzeros required for the solution.
1274  void SetMinNNZ(int min_nnz) { min_nnz_ = min_nnz; }
1275 
1276  /// Set the maximum number of nonzeros required for the solution, as an early
1277  /// termination condition.
1278  void SetMaxNNZ(int max_nnz) { max_nnz_ = max_nnz; }
1279 
1280  /// Set threshold on relative change in residual over nStallCheck_ iterations.
1282  { res_change_termination_tol_ = tol; }
1283 
1284  void SetZeroTolerance(double tol) { zero_tol_ = tol; }
1285 
1286  /// Set RHS vector constant shift, defining rhs_lb and rhs_ub in Solve().
1287  void SetRHSDelta(double d) { rhs_delta_ = d; }
1288 
1289  /// Set the maximum number of outer iterations in Solve().
1290  void SetOuterIterations(int n) { n_outer_ = n; }
1291 
1292  /// Set the maximum number of inner iterations in Solve().
1293  void SetInnerIterations(int n) { n_inner_ = n; }
1294 
1295  /// Set the number of iterations to use for stall checking.
1296  void SetStallCheck(int n) { nStallCheck_ = n; }
1297 
1298  /// Set a flag to determine whether to call NormalizeConstraints().
1299  void SetNormalize(bool n) { normalize_ = n; }
1300 
1301  /**
1302  * Enumerated types of QRresidual mode. Options are 'off': the residual is
1303  * calculated normally, 'on': the residual is calculated using the QR
1304  * method, 'hybrid': the residual is calculated normally until we experience
1305  * rounding errors, then the QR method is used. The default is 'hybrid',
1306  * which should see the best performance. Recommend using 'hybrid' or 'off'
1307  * only, since 'on' is computationally expensive.
1308  */
1309  enum class QRresidualMode {off, on, hybrid};
1310 
1311  /**
1312  * Set the residual calculation mode for the NNLS solver. See QRresidualMode
1313  * enum above for details.
1314  */
1315  void SetQRResidualMode(const QRresidualMode qr_residual_mode);
1316 
1317  /**
1318  * @brief Solve the NNLS problem. Specifically, we find a vector @a soln,
1319  * such that rhs_lb < mat*soln < rhs_ub is satisfied, where mat is the
1320  * DenseMatrix input to SetOperator().
1321  *
1322  * The method by which we find the solution is the active-set method
1323  * developed by Lawson and Hanson (1974) using lapack. To decrease rounding
1324  * errors in the case of very tight tolerances, we have the option to compute
1325  * the residual using the QR factorization of A, by res = b - Q*Q^T*b. This
1326  * residual calculation results in less rounding error, but is more
1327  * computationally expensive. To select whether to use the QR residual method
1328  * or not, see set_qrresidual_mode above.
1329  */
1330  void Solve(const Vector& rhs_lb, const Vector& rhs_ub, Vector& soln) const;
1331 
1332  /**
1333  * Normalize the constraints such that the tolerances for each constraint
1334  * (i.e. (UB - LB)/2) are equal. This seems to help the performance in most
1335  * cases.
1336  */
1337  void NormalizeConstraints(Vector& rhs_lb, Vector& rhs_ub) const;
1338 
1339 private:
1340  const DenseMatrix *mat;
1341 
1342  double const_tol_;
1343  int min_nnz_; // minimum number of nonzero entries
1344  mutable int max_nnz_; // maximum number of nonzero entries
1345  int verbosity_;
1346 
1347  /**
1348  * @brief Threshold on relative change in residual over nStallCheck_
1349  * iterations, for stall sensing.
1350  */
1351  double res_change_termination_tol_;
1352 
1353  double zero_tol_;
1354  double rhs_delta_;
1355  int n_outer_;
1356  int n_inner_;
1357  int nStallCheck_;
1358 
1359  bool normalize_;
1360 
1361  mutable bool NNLS_qrres_on_;
1362  QRresidualMode qr_residual_mode_;
1363 
1364  mutable Vector row_scaling_;
1365 };
1366 #endif // MFEM_USE_LAPACK
1367 
1368 }
1369 
1370 #endif // MFEM_SOLVERS
const Array< int > * ess_dofs_list
Not owned.
Definition: solvers.hpp:1056
MINRESSolver(MPI_Comm comm_)
Definition: solvers.hpp:613
GMRESSolver(MPI_Comm comm_)
Definition: solvers.hpp:534
Conjugate gradient method.
Definition: solvers.hpp:493
CGSolver(MPI_Comm comm_)
Definition: solvers.hpp:504
HypreSmoother & GetSmoother()
Definition: solvers.hpp:1243
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.hpp:437
double Info[UMFPACK_INFO]
Definition: solvers.hpp:1082
Chebyshev accelerated smoothing with given vector, no matrix necessary.
Definition: solvers.hpp:379
SparseMatrix * mat
Definition: solvers.hpp:1074
const Operator * oper
Definition: solvers.hpp:120
Array< Vector * > ykArray
Definition: solvers.hpp:730
void SetPositiveDiagonal(bool pos_diag=true)
Replace diagonal entries with their absolute values.
Definition: solvers.hpp:339
const Operator * GetC() const
Definition: solvers.hpp:853
SuiteSparse_long * AI
Definition: solvers.hpp:1076
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:762
double GetInitialNorm() const
Returns the initial residual norm from the last call to Mult().
Definition: solvers.hpp:258
void SetHistorySize(int dim)
Definition: solvers.hpp:768
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:886
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:517
void Mult(const Vector &w, Vector &sol) const override
Operator application: y=A(x).
Definition: solvers.cpp:3620
void SetMaxNNZ(int max_nnz)
Definition: solvers.hpp:1278
bool summary
A summary of the solver process will be reported after the last iteration to mfem::out.
Definition: solvers.hpp:91
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:475
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:303
virtual void ProcessNewState(const Vector &x) const
This method can be overloaded in derived classes to perform computations that need knowledge of the n...
Definition: solvers.hpp:704
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
Definition: solvers.cpp:2007
bool first_and_last
Information about the first and last iteration will be printed to mfem::out.
Definition: solvers.hpp:94
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:1168
const Vector * GetBoundsVec_Hi() const
Definition: solvers.hpp:859
OperatorJacobiSmoother(const double damping=1.0)
Default constructor: the diagonal will be computed by subsequent calls to SetOperator() using the Ope...
Definition: solvers.cpp:200
Pointer to an Operator of a specified type.
Definition: handle.hpp:33
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:1614
T * GetData()
Returns the data.
Definition: array.hpp:115
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:718
FGMRES method.
Definition: solvers.hpp:544
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:980
int * GetBlockI()
Definition: solvers.hpp:1002
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
void InitializeStorageVectors()
Definition: solvers.hpp:741
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:531
Direct sparse solver using KLU.
Definition: solvers.hpp:1111
bool errors
If a fatal problem has been detected the failure will be reported to mfem::err.
Definition: solvers.hpp:82
void SetQRResidualMode(const QRresidualMode qr_residual_mode)
Definition: solvers.cpp:3579
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
Definition: operator.hpp:69
void SetRHSDelta(double d)
Set RHS vector constant shift, defining rhs_lb and rhs_ub in Solve().
Definition: solvers.hpp:1287
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
virtual void SetSolver(Solver &solver)
Set the linear solver for inverting the Jacobian.
Definition: solvers.hpp:689
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:3319
void SetOperator(const Operator &op)
Definition: solvers.cpp:2765
MINRES method.
Definition: solvers.hpp:603
UMFPackSolver(SparseMatrix &A, bool use_long_ints_=false)
Factorize the given SparseMatrix using the defaults. For larger matrices, if the solver fails...
Definition: solvers.hpp:1091
Reordering
The reordering method used by the BlockILU factorization.
Definition: solvers.hpp:968
void Mult(const Vector &b, Vector &x) const
Solve the system LUx = b, where L and U are the block ILU factors.
Definition: solvers.cpp:2996
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.hpp:1240
virtual ~IterativeSolverMonitor()
Definition: solvers.hpp:45
ResidualBCMonitor(const Array< int > &ess_dofs_list_)
Definition: solvers.hpp:1059
int print_level
(DEPRECATED) Legacy print level definition, which is left for compatibility with custom iterative sol...
Definition: solvers.hpp:130
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.hpp:1170
PrintLevel()=default
Initializes the print level to suppress.
void SetResidualChangeTolerance(double tol)
Set threshold on relative change in residual over nStallCheck_ iterations.
Definition: solvers.hpp:1281
virtual double CalcObjective(const Vector &x) const =0
Objective F(x). In parallel, the result should be reduced over tasks.
SLISolver(MPI_Comm comm_)
Definition: solvers.hpp:472
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:317
virtual ~OptimizationSolver()
Definition: solvers.hpp:875
void Monitor(int it, double norm, const Vector &r, const Vector &x, bool final=false) const
Definition: solvers.cpp:190
const Vector * d_hi
Definition: solvers.hpp:829
double GetFinalNorm() const
Returns the final residual norm after termination of the solver during the last call to Mult()...
Definition: solvers.hpp:265
virtual void SetOperator(const Operator &op)
Set the Operator that is the OrthoSolver is to invert (approximately).
Definition: solvers.cpp:3442
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:3372
int BiCGSTAB(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, double &tol, double atol, int printit)
BiCGSTAB method. (tolerances are squared)
Definition: solvers.cpp:1570
void SetKDim(int dim)
Definition: solvers.hpp:556
const Vector * GetInequalityVec_Lo() const
Definition: solvers.hpp:856
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:179
const Vector * x_lo
Definition: solvers.hpp:829
double Norm(const Vector &x) const
Definition: solvers.hpp:172
Direct sparse solver using UMFPACK.
Definition: solvers.hpp:1070
Operator * grad
Definition: solvers.hpp:645
const Vector * x_hi
Definition: solvers.hpp:829
const class IterativeSolver * iter_solver
The last IterativeSolver to which this monitor was attached.
Definition: solvers.hpp:40
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:616
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
Definition: solvers.cpp:71
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.cpp:3333
void Solve(const Vector &rhs_lb, const Vector &rhs_ub, Vector &soln) const
Solve the NNLS problem. Specifically, we find a vector soln, such that rhs_lb < mat*soln < rhs_ub is ...
Definition: solvers.cpp:3668
int GetNumConstraints() const
Definition: solvers.cpp:2340
Data type sparse matrix.
Definition: sparsemat.hpp:50
double solve(double l, const Vector &xt, Vector &x, int &nclip) const
Solve QP at fixed lambda.
Definition: solvers.hpp:904
void MINRES(const Operator &A, const Vector &b, Vector &x, int print_it, int max_it, double rtol, double atol)
MINRES method without preconditioner. (tolerances are squared)
Definition: solvers.cpp:1780
virtual ~UMFPackSolver()
Definition: solvers.cpp:3266
void SetStallCheck(int n)
Set the number of iterations to use for stall checking.
Definition: solvers.hpp:1296
Jacobi smoothing for a given bilinear form (no matrix necessary).
Definition: solvers.hpp:302
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
Definition: solvers.hpp:250
double b
Definition: lissajous.cpp:42
void SetVerbosity(int v)
Definition: solvers.hpp:1269
virtual void CalcObjectiveGrad(const Vector &x, Vector &grad) const
The result grad is expected to enter with the correct size.
Definition: solvers.hpp:846
void SetMaxIter(int max_it)
Definition: solvers.hpp:201
OperatorChebyshevSmoother(const Operator &oper_, const Vector &d, const Array< int > &ess_tdof_list, int order, double max_eig_estimate)
Definition: solvers.cpp:331
void SetLinearConstraint(const Vector &w_, double a_)
Definition: solvers.cpp:2367
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo <= hi.
Definition: vector.cpp:555
void SetZeroTolerance(double tol)
Definition: solvers.hpp:1284
DirectSubBlockSolver(const SparseMatrix &A, const SparseMatrix &block_dof)
Definition: solvers.cpp:3357
SuiteSparse_long * AJ
Definition: solvers.hpp:1076
void SetKDim(int dim)
Set the number of iteration to perform between restarts, default is 50.
Definition: solvers.hpp:538
Newton&#39;s method for solving F(x)=b for a given operator F.
Definition: solvers.hpp:641
void print_iteration(int it, double r, double l) const
Definition: solvers.cpp:2373
void CG(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Conjugate gradient method. (tolerances are squared)
Definition: solvers.cpp:898
void SetNormalize(bool n)
Set a flag to determine whether to call NormalizeConstraints().
Definition: solvers.hpp:1299
void Setup(const Vector &diag)
Definition: solvers.cpp:277
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.hpp:1241
Parallel smoothers in hypre.
Definition: hypre.hpp:971
void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Preconditioned conjugate gradient method. (tolerances are squared)
Definition: solvers.cpp:913
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.cpp:3288
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:1593
const Vector * GetInequalityVec_Hi() const
Definition: solvers.hpp:857
Array< Vector * > skArray
Definition: solvers.hpp:730
prob_type prob
Definition: ex25.cpp:154
klu_symbolic * Symbolic
Definition: solvers.hpp:1115
void SetIterativeSolver(const IterativeSolver &solver)
This method is invoked by IterativeSolver::SetMonitor, informing the monitor which IterativeSolver is...
Definition: solvers.hpp:61
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.hpp:1242
BlockILU(int block_size_, Reordering reordering_=Reordering::MINIMUM_DISCARDED_FILL, int k_fill_=0)
Definition: solvers.cpp:2747
void SetPrintLevel(int print_lvl)
Set the print level field in the Control data member.
Definition: solvers.hpp:1102
void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.hpp:342
Stationary linear iteration: x <- x + B (b - A x)
Definition: solvers.hpp:461
void SetInequalityConstraint(const Vector &dl, const Vector &dh)
Definition: solvers.cpp:2322
void SetEqualityConstraint(const Vector &c)
Definition: solvers.cpp:2314
Abstract base class for an iterative solver monitor.
Definition: solvers.hpp:36
const Vector * GetBoundsVec_Lo() const
Definition: solvers.hpp:858
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:884
void SetOperator(const Operator &op_)
Set/update the solver for the given operator.
Definition: solvers.hpp:439
ProductSolver(Operator *A_, Solver *S0_, Solver *S1_, bool ownA, bool ownS0, bool ownS1)
Definition: solvers.hpp:1165
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
Definition: solvers.cpp:1819
void SetAbsTol(double atol)
Definition: solvers.hpp:200
PrintLevel print_options
Output behavior for the iterative solver.
Definition: solvers.hpp:137
void SetRelTol(double rtol)
Definition: solvers.hpp:199
double Control[UMFPACK_CONTROL]
Definition: solvers.hpp:1081
Monitor that checks whether the residual is zero at a given set of dofs.
Definition: solvers.hpp:1053
Abstract base class for iterative solver.
Definition: solvers.hpp:66
UMFPackSolver(bool use_long_ints_=false)
For larger matrices, if the solver fails, set the parameter use_long_ints_ = true.
Definition: solvers.hpp:1086
void SetInnerIterations(int n)
Set the maximum number of inner iterations in Solve().
Definition: solvers.hpp:1293
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.cpp:3229
void DeleteStorageVectors()
Definition: solvers.hpp:732
void SetAdaptiveLinRtol(const int type=2, const double rtol0=0.5, const double rtol_max=0.9, const double alpha=0.5 *(1.0+sqrt(5.0)), const double gamma=1.0)
Enable adaptive linear solver relative tolerance algorithm.
Definition: solvers.cpp:1927
bool GetConverged() const
Returns true if the last call to Mult() converged successfully.
Definition: solvers.hpp:252
int max_iter
Limit for the number of iterations the solver is allowed to do.
Definition: solvers.hpp:151
LBFGSSolver(MPI_Comm comm_)
Definition: solvers.hpp:759
HYPRE_Int HYPRE_BigInt
double * GetBlockData()
Definition: solvers.hpp:1012
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:3194
GMRES method.
Definition: solvers.hpp:525
virtual void SetSolver(Solver &solver)
Set the linear solver for inverting the Jacobian.
Definition: solvers.hpp:780
void AdaptiveLinRtolPostSolve(const Vector &x, const Vector &b, const int it, const double fnorm) const
Method for the adaptive linear solver rtol invoked after the linear solve.
Definition: solvers.cpp:1987
static int GuessLegacyPrintLevel(PrintLevel)
Use some heuristics to guess a legacy print level corresponding to the given PrintLevel.
Definition: solvers.cpp:149
FGMRESSolver(MPI_Comm comm_)
Definition: solvers.hpp:553
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
Definition: solvers.cpp:2348
void SetMonitor(IterativeSolverMonitor &m)
Set the iterative solver monitor.
Definition: solvers.hpp:286
void NormalizeConstraints(Vector &rhs_lb, Vector &rhs_ub) const
Definition: solvers.cpp:3588
double a
Definition: lissajous.cpp:41
void UpdateVectors()
Definition: solvers.cpp:525
Abstract solver for OptimizationProblems.
Definition: solvers.hpp:865
A "square matrix" operator for the associated FE space and BLFIntegrators The sum of all the BLFInteg...
Solver wrapper which orthogonalizes the input and output vector.
Definition: solvers.hpp:1180
virtual ~LBFGSSolver()
Definition: solvers.hpp:783
klu_common Common
Definition: solvers.hpp:1136
double rel_tol
Relative tolerance.
Definition: solvers.hpp:154
OptimizationProblem(int insize, const Operator *C_, const Operator *D_)
In parallel, insize is the number of the local true dofs.
Definition: solvers.cpp:2304
void SetSolutionBounds(const Vector &xl, const Vector &xh)
Definition: solvers.cpp:2332
virtual void Mult(const Vector &xt, Vector &x) const
Definition: solvers.cpp:2382
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Definition: handle.hpp:104
AuxSpaceSmoother(const HypreParMatrix &op, HypreParMatrix *aux_map, bool op_is_symmetric=true, bool own_aux_map=false)
Definition: solvers.cpp:3509
virtual void Mult(const Vector &xt, Vector &x) const =0
Operator application: y=A(x).
BiCGSTABSolver(MPI_Comm comm_)
Definition: solvers.hpp:583
void SetOperator(const Operator &op)
Recompute the diagonal using the method AssembleDiagonal of the given new Operator, op.
Definition: solvers.cpp:241
void SetMinNNZ(int min_nnz)
Set the minimum number of nonzeros required for the solution.
Definition: solvers.hpp:1274
int dim
Definition: ex24.cpp:53
SLBQPOptimizer(MPI_Comm comm_)
Definition: solvers.hpp:931
const Vector * GetEqualityVec() const
Definition: solvers.hpp:855
PrintLevel FromLegacyPrintLevel(int)
Convert a legacy print level integer to a PrintLevel object.
Definition: solvers.cpp:114
int * GetBlockJ()
Definition: solvers.hpp:1007
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:586
double Dot(const Vector &x, const Vector &y) const
Definition: solvers.cpp:55
MPI_Comm GetComm() const
Return the associated MPI communicator, or MPI_COMM_NULL if no communicator is set.
Definition: solvers.hpp:292
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:507
Vector data type.
Definition: vector.hpp:58
void SetSolver(Solver &s)
Set the solver used by the OrthoSolver.
Definition: solvers.cpp:3433
void Mult(const Vector &b, Vector &x) const
Perform the action of the OrthoSolver: P * solver * P where P is the projection to the subspace of ve...
Definition: solvers.cpp:3452
void MonitorResidual(int it, double norm, const Vector &r, bool final) override
Monitor the residual vector r.
Definition: solvers.cpp:3047
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:778
const Vector * d_lo
Definition: solvers.hpp:829
void SetTolerance(double tol)
Definition: solvers.hpp:1271
virtual void MonitorSolution(int it, double norm, const Vector &x, bool final)
Monitor the solution vector x.
Definition: solvers.hpp:54
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.cpp:173
void SetOuterIterations(int n)
Set the maximum number of outer iterations in Solve().
Definition: solvers.hpp:1290
KLUSolver(SparseMatrix &A)
Definition: solvers.hpp:1124
int aGMRES(const Operator &A, Vector &x, const Vector &b, const Operator &M, int &max_iter, int m_max, int m_min, int m_step, double cf, double &tol, double &atol, int printit)
Definition: solvers.cpp:2149
virtual ~KLUSolver()
Definition: solvers.cpp:3347
RefCoord s[3]
double * Data()
Definition: densemat.hpp:1213
void UpdateVectors()
Definition: solvers.cpp:709
BiCGSTAB method.
Definition: solvers.hpp:572
bool warnings
If a non-fatal problem has been detected some context-specific information will be reported to mfem::...
Definition: solvers.hpp:85
bool iterations
Detailed information about each iteration will be reported to mfem::out.
Definition: solvers.hpp:88
void SetOperator(const Operator &op) override
The operator must be a DenseMatrix.
Definition: solvers.cpp:3566
OptimizationSolver(MPI_Comm comm_)
Definition: solvers.hpp:873
SparseMatrix * mat
Definition: solvers.hpp:1114
Base class for solvers.
Definition: operator.hpp:682
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.hpp:1154
const OptimizationProblem * problem
Definition: solvers.hpp:868
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:1378
virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
This method can be overloaded in derived classes to implement line search algorithms.
Definition: solvers.hpp:699
Abstract operator.
Definition: operator.hpp:24
Wrapper for hypre&#39;s ParCSR matrix class.
Definition: hypre.hpp:343
Block diagonal solver for A, each block is inverted by direct solver.
Definition: solvers.hpp:1142
void SetBounds(const Vector &lo_, const Vector &hi_)
Definition: solvers.cpp:2361
virtual void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:3387
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition: solvers.cpp:3404
void AdaptiveLinRtolPreSolve(const Vector &x, const int it, const double fnorm) const
Method for the adaptive linear solver rtol invoked before the linear solve.
Definition: solvers.cpp:1940
const Operator * D
Definition: solvers.hpp:828
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:1096
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
Definition: solvers.hpp:879
NewtonSolver(MPI_Comm comm_)
Definition: solvers.hpp:683
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:485
const Operator * GetD() const
Definition: solvers.hpp:854
const Vector * c_e
Definition: solvers.hpp:829
IterativeSolverMonitor * monitor
Definition: solvers.hpp:122
klu_numeric * Numeric
Definition: solvers.hpp:1116
virtual void MonitorResidual(int it, double norm, const Vector &r, bool final)
Monitor the residual vector r.
Definition: solvers.hpp:48
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:28
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:475
Settings for the output behavior of the IterativeSolver.
Definition: solvers.hpp:78
const Operator * C
Not owned, some can remain unused (NULL).
Definition: solvers.hpp:828
double abs_tol
Absolute tolerance.
Definition: solvers.hpp:157
void SLI(const Operator &A, const Vector &b, Vector &x, int print_iter, int max_num_iter, double RTOLERANCE, double ATOLERANCE)
Stationary linear iteration. (tolerances are squared)
Definition: solvers.cpp:677
int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, int m, double &tol, double atol, int printit)
GMRES method. (tolerances are squared)
Definition: solvers.cpp:1340
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:1808
virtual void SetOperator(const Operator &op)
Factorize the given Operator op which must be a SparseMatrix.
Definition: solvers.cpp:3099
Internal class - adapts the OptimizationProblem class to HiOp&#39;s interface.
Definition: hiop.hpp:32
double GetFinalRelNorm() const
Returns the final residual norm after termination of the solver during the last call to Mult()...
Definition: solvers.hpp:271