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