MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
solvers.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, 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 
18 #ifdef MFEM_USE_MPI
19 #include <mpi.h>
20 #endif
21 
22 #ifdef MFEM_USE_SUITESPARSE
23 #include "sparsemat.hpp"
24 #include <umfpack.h>
25 #include <klu.h>
26 #endif
27 
28 namespace mfem
29 {
30 
31 class BilinearForm;
32 
33 /// Abstract base class for an iterative solver monitor
35 {
36 protected:
37  /// The last IterativeSolver to which this monitor was attached.
39 
40 public:
42 
44 
45  /// Monitor the residual vector r
46  virtual void MonitorResidual(int it, double norm, const Vector &r,
47  bool final)
48  {
49  }
50 
51  /// Monitor the solution vector x
52  virtual void MonitorSolution(int it, double norm, const Vector &x,
53  bool final)
54  {
55  }
56 
57  /** @brief This method is invoked by ItertiveSolver::SetMonitor, informing
58  the monitor which IterativeSolver is using it. */
59  void SetIterativeSolver(const IterativeSolver &solver)
60  { iter_solver = &solver; }
61 };
62 
63 /// Abstract base class for iterative solver
64 class IterativeSolver : public Solver
65 {
66 #ifdef MFEM_USE_MPI
67 private:
68  int dot_prod_type; // 0 - local, 1 - global over 'comm'
69  MPI_Comm comm;
70 #endif
71 
72 protected:
73  const Operator *oper;
76 
78  double rel_tol, abs_tol;
79 
80  // stats
81  mutable int final_iter, converged;
82  mutable double final_norm;
83 
84  double Dot(const Vector &x, const Vector &y) const;
85  double Norm(const Vector &x) const { return sqrt(Dot(x, x)); }
86  void Monitor(int it, double norm, const Vector& r, const Vector& x,
87  bool final=false) const;
88 
89 public:
91 
92 #ifdef MFEM_USE_MPI
93  IterativeSolver(MPI_Comm _comm);
94 #endif
95 
96  void SetRelTol(double rtol) { rel_tol = rtol; }
97  void SetAbsTol(double atol) { abs_tol = atol; }
98  void SetMaxIter(int max_it) { max_iter = max_it; }
99  void SetPrintLevel(int print_lvl);
100 
101  int GetNumIterations() const { return final_iter; }
102  int GetConverged() const { return converged; }
103  double GetFinalNorm() const { return final_norm; }
104 
105  /// This should be called before SetOperator
106  virtual void SetPreconditioner(Solver &pr);
107 
108  /// Also calls SetOperator for the preconditioner if there is one
109  virtual void SetOperator(const Operator &op);
110 
111  /// Set the iterative solver monitor
113  { monitor = &m; m.SetIterativeSolver(*this); }
114 
115 #ifdef MFEM_USE_MPI
116  /** @brief Return the associated MPI communicator, or MPI_COMM_NULL if no
117  communicator is set. */
118  MPI_Comm GetComm() const
119  { return dot_prod_type == 0 ? MPI_COMM_NULL : comm; }
120 #endif
121 };
122 
123 
124 /// Jacobi smoothing for a given bilinear form (no matrix necessary).
125 /** Useful with tensorized, partially assembled operators. Can also be defined
126  by given diagonal vector. This is basic Jacobi iteration; for tolerances,
127  iteration control, etc. wrap with SLISolver. */
129 {
130 public:
131  /** Setup a Jacobi smoother with the diagonal of @a a obtained by calling
132  a.AssembleDiagonal(). It is assumed that the underlying operator acts as
133  the identity on entries in ess_tdof_list, corresponding to (assembled)
134  DIAG_ONE policy or ConstrainedOperator in the matrix-free setting. */
136  const Array<int> &ess_tdof_list,
137  const double damping=1.0);
138 
139  /** Application is by the *inverse* of the given vector. It is assumed that
140  the underlying operator acts as the identity on entries in ess_tdof_list,
141  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
142  the matrix-free setting. */
144  const Array<int> &ess_tdof_list,
145  const double damping=1.0);
147 
148  void Mult(const Vector &x, Vector &y) const;
149  void MultTranspose(const Vector &x, Vector &y) const { Mult(x, y); }
150  void SetOperator(const Operator &op) { oper = &op; }
151  void Setup(const Vector &diag);
152 
153 private:
154  const int N;
155  Vector dinv;
156  const double damping;
157  const Array<int> &ess_tdof_list;
158  mutable Vector residual;
159 
160  const Operator *oper;
161 };
162 
163 /// Chebyshev accelerated smoothing with given vector, no matrix necessary
164 /** Potentially useful with tensorized operators, for example. This is just a
165  very basic Chebyshev iteration, if you want tolerances, iteration control,
166  etc. wrap this with SLISolver. */
168 {
169 public:
170  /** Application is by *inverse* of the given vector. It is assumed the
171  underlying operator acts as the identity on entries in ess_tdof_list,
172  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
173  the matrix-free setting. The estimated largest eigenvalue of the
174  diagonally preconditoned operator must be provided via
175  max_eig_estimate. */
176  OperatorChebyshevSmoother(Operator* oper_, const Vector &d,
177  const Array<int>& ess_tdof_list,
178  int order, double max_eig_estimate);
179 
180  /** Application is by *inverse* of the given vector. It is assumed the
181  underlying operator acts as the identity on entries in ess_tdof_list,
182  corresponding to (assembled) DIAG_ONE policy or ConstrainedOperator in
183  the matrix-free setting. The largest eigenvalue of the diagonally
184  preconditoned operator is estimated internally via a power method. The
185  accuracy of the estimated eigenvalue may be controlled via
186  power_iterations and power_tolerance. */
187 #ifdef MFEM_USE_MPI
188  OperatorChebyshevSmoother(Operator* oper_, const Vector &d,
189  const Array<int>& ess_tdof_list,
190  int order, MPI_Comm comm = MPI_COMM_NULL, int power_iterations = 10,
191  double power_tolerance = 1e-8);
192 #else
193  OperatorChebyshevSmoother(Operator* oper_, const Vector &d,
194  const Array<int>& ess_tdof_list,
195  int order, int power_iterations = 10, double power_tolerance = 1e-8);
196 #endif
197 
199 
200  void Mult(const Vector&x, Vector &y) const;
201 
202  void MultTranspose(const Vector &x, Vector &y) const { Mult(x, y); }
203 
204  void SetOperator(const Operator &op_)
205  {
206  oper = &op_;
207  }
208 
209  void Setup();
210 
211 private:
212  const int order;
213  double max_eig_estimate;
214  const int N;
215  Vector dinv;
216  const Vector &diag;
217  Array<double> coeffs;
218  const Array<int>& ess_tdof_list;
219  mutable Vector residual;
220  mutable Vector helperVector;
221  const Operator* oper;
222 };
223 
224 
225 /// Stationary linear iteration: x <- x + B (b - A x)
227 {
228 protected:
229  mutable Vector r, z;
230 
231  void UpdateVectors();
232 
233 public:
234  SLISolver() { }
235 
236 #ifdef MFEM_USE_MPI
237  SLISolver(MPI_Comm _comm) : IterativeSolver(_comm) { }
238 #endif
239 
240  virtual void SetOperator(const Operator &op)
242 
243  virtual void Mult(const Vector &b, Vector &x) const;
244 };
245 
246 /// Stationary linear iteration. (tolerances are squared)
247 void SLI(const Operator &A, const Vector &b, Vector &x,
248  int print_iter = 0, int max_num_iter = 1000,
249  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
250 
251 /// Preconditioned stationary linear iteration. (tolerances are squared)
252 void SLI(const Operator &A, Solver &B, const Vector &b, Vector &x,
253  int print_iter = 0, int max_num_iter = 1000,
254  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
255 
256 
257 /// Conjugate gradient method
258 class CGSolver : public IterativeSolver
259 {
260 protected:
261  mutable Vector r, d, z;
262 
263  void UpdateVectors();
264 
265 public:
266  CGSolver() { }
267 
268 #ifdef MFEM_USE_MPI
269  CGSolver(MPI_Comm _comm) : IterativeSolver(_comm) { }
270 #endif
271 
272  virtual void SetOperator(const Operator &op)
274 
275  virtual void Mult(const Vector &b, Vector &x) const;
276 };
277 
278 /// Conjugate gradient method. (tolerances are squared)
279 void CG(const Operator &A, const Vector &b, Vector &x,
280  int print_iter = 0, int max_num_iter = 1000,
281  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
282 
283 /// Preconditioned conjugate gradient method. (tolerances are squared)
284 void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x,
285  int print_iter = 0, int max_num_iter = 1000,
286  double RTOLERANCE = 1e-12, double ATOLERANCE = 1e-24);
287 
288 
289 /// GMRES method
291 {
292 protected:
293  int m; // see SetKDim()
294 
295 public:
296  GMRESSolver() { m = 50; }
297 
298 #ifdef MFEM_USE_MPI
299  GMRESSolver(MPI_Comm _comm) : IterativeSolver(_comm) { m = 50; }
300 #endif
301 
302  /// Set the number of iteration to perform between restarts, default is 50.
303  void SetKDim(int dim) { m = dim; }
304 
305  virtual void Mult(const Vector &b, Vector &x) const;
306 };
307 
308 /// FGMRES method
310 {
311 protected:
312  int m;
313 
314 public:
315  FGMRESSolver() { m = 50; }
316 
317 #ifdef MFEM_USE_MPI
318  FGMRESSolver(MPI_Comm _comm) : IterativeSolver(_comm) { m = 50; }
319 #endif
320 
321  void SetKDim(int dim) { m = dim; }
322 
323  virtual void Mult(const Vector &b, Vector &x) const;
324 };
325 
326 /// GMRES method. (tolerances are squared)
327 int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M,
328  int &max_iter, int m, double &tol, double atol, int printit);
329 
330 /// GMRES method. (tolerances are squared)
331 void GMRES(const Operator &A, Solver &B, const Vector &b, Vector &x,
332  int print_iter = 0, int max_num_iter = 1000, int m = 50,
333  double rtol = 1e-12, double atol = 1e-24);
334 
335 
336 /// BiCGSTAB method
338 {
339 protected:
340  mutable Vector p, phat, s, shat, t, v, r, rtilde;
341 
342  void UpdateVectors();
343 
344 public:
346 
347 #ifdef MFEM_USE_MPI
348  BiCGSTABSolver(MPI_Comm _comm) : IterativeSolver(_comm) { }
349 #endif
350 
351  virtual void SetOperator(const Operator &op)
353 
354  virtual void Mult(const Vector &b, Vector &x) const;
355 };
356 
357 /// BiCGSTAB method. (tolerances are squared)
358 int BiCGSTAB(const Operator &A, Vector &x, const Vector &b, Solver &M,
359  int &max_iter, double &tol, double atol, int printit);
360 
361 /// BiCGSTAB method. (tolerances are squared)
362 void BiCGSTAB(const Operator &A, Solver &B, const Vector &b, Vector &x,
363  int print_iter = 0, int max_num_iter = 1000,
364  double rtol = 1e-12, double atol = 1e-24);
365 
366 
367 /// MINRES method
369 {
370 protected:
371  mutable Vector v0, v1, w0, w1, q;
372  mutable Vector u1; // used in the preconditioned version
373 
374 public:
376 
377 #ifdef MFEM_USE_MPI
378  MINRESSolver(MPI_Comm _comm) : IterativeSolver(_comm) { }
379 #endif
380 
381  virtual void SetPreconditioner(Solver &pr)
382  {
384  if (oper) { u1.SetSize(width); }
385  }
386 
387  virtual void SetOperator(const Operator &op);
388 
389  virtual void Mult(const Vector &b, Vector &x) const;
390 };
391 
392 /// MINRES method without preconditioner. (tolerances are squared)
393 void MINRES(const Operator &A, const Vector &b, Vector &x, int print_it = 0,
394  int max_it = 1000, double rtol = 1e-12, double atol = 1e-24);
395 
396 /// MINRES method with preconditioner. (tolerances are squared)
397 void MINRES(const Operator &A, Solver &B, const Vector &b, Vector &x,
398  int print_it = 0, int max_it = 1000,
399  double rtol = 1e-12, double atol = 1e-24);
400 
401 
402 /// Newton's method for solving F(x)=b for a given operator F.
403 /** The method GetGradient() must be implemented for the operator F.
404  The preconditioner is used (in non-iterative mode) to evaluate
405  the action of the inverse gradient of the operator. */
407 {
408 protected:
409  mutable Vector r, c;
410 
411 public:
413 
414 #ifdef MFEM_USE_MPI
415  NewtonSolver(MPI_Comm _comm) : IterativeSolver(_comm) { }
416 #endif
417  virtual void SetOperator(const Operator &op);
418 
419  /// Set the linear solver for inverting the Jacobian.
420  /** This method is equivalent to calling SetPreconditioner(). */
421  virtual void SetSolver(Solver &solver) { prec = &solver; }
422 
423  /// Solve the nonlinear system with right-hand side @a b.
424  /** If `b.Size() != Height()`, then @a b is assumed to be zero. */
425  virtual void Mult(const Vector &b, Vector &x) const;
426 
427  /** @brief This method can be overloaded in derived classes to implement line
428  search algorithms. */
429  /** The base class implementation (NewtonSolver) simply returns 1. A return
430  value of 0 indicates a failure, interrupting the Newton iteration. */
431  virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
432  { return 1.0; }
433 
434  /** @brief This method can be overloaded in derived classes to perform
435  computations that need knowledge of the newest Newton state. */
436  virtual void ProcessNewState(const Vector &x) const { }
437 };
438 
439 /** L-BFGS method for solving F(x)=b for a given operator F, by minimizing
440  the norm of F(x) - b. Requires only the action of the operator F. */
441 class LBFGSSolver : public NewtonSolver
442 {
443 protected:
444  int m = 10;
445 
446 public:
448 
449 #ifdef MFEM_USE_MPI
450  LBFGSSolver(MPI_Comm _comm) : NewtonSolver(_comm) { }
451 #endif
452 
453  void SetHistorySize(int dim) { m = dim; }
454 
455  /// Solve the nonlinear system with right-hand side @a b.
456  /** If `b.Size() != Height()`, then @a b is assumed to be zero. */
457  virtual void Mult(const Vector &b, Vector &x) const;
458 
459  virtual void SetPreconditioner(Solver &pr)
460  { MFEM_WARNING("L-BFGS won't use the given preconditioner."); }
461  virtual void SetSolver(Solver &solver)
462  { MFEM_WARNING("L-BFGS won't use the given solver."); }
463 };
464 
465 /** Adaptive restarted GMRES.
466  m_max and m_min(=1) are the maximal and minimal restart parameters.
467  m_step(=1) is the step to use for going from m_max and m_min.
468  cf(=0.4) is a desired convergence factor. */
469 int aGMRES(const Operator &A, Vector &x, const Vector &b,
470  const Operator &M, int &max_iter,
471  int m_max, int m_min, int m_step, double cf,
472  double &tol, double &atol, int printit);
473 
474 
475 /** Defines operators and constraints for the following optimization problem:
476  *
477  * Find x that minimizes the objective function F(x), subject to
478  * C(x) = c_e,
479  * d_lo <= D(x) <= d_hi,
480  * x_lo <= x <= x_hi.
481  *
482  * The operators F, C, D must take input of the same size (same width).
483  * Gradients of F, C, D might be needed, depending on the OptimizationSolver.
484  * When used with Hiop, gradients of C and D must be DenseMatrices.
485  * F always returns a scalar value, see CalcObjective(), CalcObjectiveGrad().
486  * C and D can have arbitrary heights.
487  * C and D can be NULL, meaning that their constraints are not used.
488  *
489  * When used in parallel, all Vectors are assumed to be true dof vectors, and
490  * the operators are expected to be defined for tdof vectors. */
492 {
493 protected:
494  /// Not owned, some can remain unused (NULL).
495  const Operator *C, *D;
496  const Vector *c_e, *d_lo, *d_hi, *x_lo, *x_hi;
497 
498 public:
499  const int input_size;
500 
501  /// In parallel, insize is the number of the local true dofs.
502  OptimizationProblem(int insize, const Operator *C_, const Operator *D_);
503 
504  /// Objective F(x). In parallel, the result should be reduced over tasks.
505  virtual double CalcObjective(const Vector &x) const = 0;
506  /// The result grad is expected to enter with the correct size.
507  virtual void CalcObjectiveGrad(const Vector &x, Vector &grad) const
508  { MFEM_ABORT("The objective gradient is not implemented."); }
509 
510  void SetEqualityConstraint(const Vector &c);
511  void SetInequalityConstraint(const Vector &dl, const Vector &dh);
512  void SetSolutionBounds(const Vector &xl, const Vector &xh);
513 
514  const Operator *GetC() const { return C; }
515  const Operator *GetD() const { return D; }
516  const Vector *GetEqualityVec() const { return c_e; }
517  const Vector *GetInequalityVec_Lo() const { return d_lo; }
518  const Vector *GetInequalityVec_Hi() const { return d_hi; }
519  const Vector *GetBoundsVec_Lo() const { return x_lo; }
520  const Vector *GetBoundsVec_Hi() const { return x_hi; }
521 
522  int GetNumConstraints() const;
523 };
524 
525 /// Abstract solver for OptimizationProblems.
527 {
528 protected:
530 
531 public:
533 #ifdef MFEM_USE_MPI
534  OptimizationSolver(MPI_Comm _comm): IterativeSolver(_comm), problem(NULL) { }
535 #endif
536  virtual ~OptimizationSolver() { }
537 
538  /** This function is virtual as solvers might need to perform some initial
539  * actions (e.g. validation) with the OptimizationProblem. */
541  { problem = &prob; }
542 
543  virtual void Mult(const Vector &xt, Vector &x) const = 0;
544 
545  virtual void SetPreconditioner(Solver &pr)
546  { MFEM_ABORT("Not meaningful for this solver."); }
547  virtual void SetOperator(const Operator &op)
548  { MFEM_ABORT("Not meaningful for this solver."); }
549 };
550 
551 /** SLBQP optimizer:
552  * (S)ingle (L)inearly Constrained with (B)ounds (Q)uadratic (P)rogram
553  *
554  * Minimize || x-x_t ||, subject to
555  * sum w_i x_i = a,
556  * x_lo <= x <= x_hi.
557  */
559 {
560 protected:
562  double a;
563 
564  /// Solve QP at fixed lambda
565  inline double solve(double l, const Vector &xt, Vector &x, int &nclip) const
566  {
567  add(xt, l, w, x);
568  if (problem == NULL) { x.median(lo,hi); }
569  else
570  {
573  }
574  nclip++;
575  if (problem == NULL) { return Dot(w, x) - a; }
576  else
577  {
578  Vector c(1);
579  // Includes parallel communication.
580  problem->GetC()->Mult(x, c);
581 
582  return c(0) - (*problem->GetEqualityVec())(0);
583  }
584  }
585 
586  inline void print_iteration(int it, double r, double l) const;
587 
588 public:
590 
591 #ifdef MFEM_USE_MPI
592  SLBQPOptimizer(MPI_Comm _comm) : OptimizationSolver(_comm) { }
593 #endif
594 
595  /** Setting an OptimizationProblem will overwrite the Vectors given by
596  * SetBounds and SetLinearConstraint. The objective function remains
597  * unchanged. */
598  virtual void SetOptimizationProblem(const OptimizationProblem &prob);
599 
600  void SetBounds(const Vector &_lo, const Vector &_hi);
601  void SetLinearConstraint(const Vector &_w, double _a);
602 
603  /** We let the target values play the role of the initial vector xt, from
604  * which the operator generates the optimal vector x. */
605  virtual void Mult(const Vector &xt, Vector &x) const;
606 };
607 
608 /** Block ILU solver:
609  * Performs a block ILU(k) approximate factorization with specified block
610  * size. Currently only k=0 is supported. This is useful as a preconditioner
611  * for DG-type discretizations, where the system matrix has a natural
612  * (elemental) block structure.
613  *
614  * In the case of DG discretizations, the block size should usually be set to
615  * either ndofs_per_element or vdim*ndofs_per_element (if the finite element
616  * space has Ordering::byVDIM). The block size must evenly divide the size of
617  * the matrix.
618  *
619  * Renumbering the blocks is also supported by specifying a reordering method.
620  * Currently greedy minimum discarded fill ordering and no reordering are
621  * supported. Renumbering the blocks can lead to a much better approximate
622  * factorization.
623  */
624 class BlockILU : public Solver
625 {
626 public:
627 
628  /// The reordering method used by the BlockILU factorization.
629  enum class Reordering
630  {
632  NONE
633  };
634 
635  /** Create an "empty" BlockILU solver. SetOperator must be called later to
636  * actually form the factorization
637  */
638  BlockILU(int block_size_,
640  int k_fill_ = 0);
641 
642  /** Create a block ILU approximate factorization for the matrix @a op.
643  * @a op should be of type either SparseMatrix or HypreParMatrix. In the
644  * case that @a op is a HypreParMatrix, the ILU factorization is performed
645  * on the diagonal blocks of the parallel decomposition.
646  */
647  BlockILU(Operator &op, int block_size_ = 1,
649  int k_fill_ = 0);
650 
651  /** Perform the block ILU factorization for the matrix @a op.
652  * As in the constructor, @a op must either be a SparseMatrix or
653  * HypreParMatrix
654  */
655  void SetOperator(const Operator &op);
656 
657  /// Solve the system `LUx = b`, where `L` and `U` are the block ILU factors.
658  void Mult(const Vector &b, Vector &x) const;
659 
660  /** Get the I array for the block CSR representation of the factorization.
661  * Similar to SparseMatrix::GetI(). Mostly used for testing.
662  */
663  int *GetBlockI() { return IB.GetData(); }
664 
665  /** Get the J array for the block CSR representation of the factorization.
666  * Similar to SparseMatrix::GetJ(). Mostly used for testing.
667  */
668  int *GetBlockJ() { return JB.GetData(); }
669 
670  /** Get the data array for the block CSR representation of the factorization.
671  * Similar to SparseMatrix::GetData(). Mostly used for testing.
672  */
673  double *GetBlockData() { return AB.Data(); }
674 
675 private:
676  /// Set up the block CSR structure corresponding to a sparse matrix @a A
677  void CreateBlockPattern(const class SparseMatrix &A);
678 
679  /// Perform the block ILU factorization
680  void Factorize();
681 
682  int block_size;
683 
684  /// Fill level for block ILU(k) factorizations. Only k=0 is supported.
685  int k_fill;
686 
687  Reordering reordering;
688 
689  /// Temporary vector used in the Mult() function.
690  mutable Vector y;
691 
692  /// Permutation and inverse permutation vectors for the block reordering.
693  Array<int> P, Pinv;
694 
695  /** Block CSR storage of the factorization. The block upper triangular part
696  * stores the U factor. The L factor implicitly has identity on the diagonal
697  * blocks, and the rest of L is given by the strictly block lower triangular
698  * part.
699  */
700  Array<int> IB, ID, JB;
701  DenseTensor AB;
702 
703  /// DB(i) stores the LU factorization of the i'th diagonal block
704  mutable DenseTensor DB;
705  /// Pivot arrays for the LU factorizations given by #DB
706  mutable Array<int> ipiv;
707 };
708 
709 
710 /// Monitor that checks whether the residual is zero at a given set of dofs.
711 /** This monitor is useful for checking if the initial guess, rhs, operator, and
712  preconditioner are properly setup for solving in the subspace with imposed
713  essential boundary conditions. */
715 {
716 protected:
717  const Array<int> *ess_dofs_list; ///< Not owned
718 
719 public:
720  ResidualBCMonitor(const Array<int> &ess_dofs_list_)
721  : ess_dofs_list(&ess_dofs_list_) { }
722 
723  void MonitorResidual(int it, double norm, const Vector &r,
724  bool final) override;
725 };
726 
727 
728 #ifdef MFEM_USE_SUITESPARSE
729 
730 /// Direct sparse solver using UMFPACK
731 class UMFPackSolver : public Solver
732 {
733 protected:
736  void *Numeric;
737  SuiteSparse_long *AI, *AJ;
738 
739  void Init();
740 
741 public:
742  double Control[UMFPACK_CONTROL];
743  mutable double Info[UMFPACK_INFO];
744 
745  /** @brief For larger matrices, if the solver fails, set the parameter @a
746  _use_long_ints = true. */
747  UMFPackSolver(bool _use_long_ints = false)
748  : use_long_ints(_use_long_ints) { Init(); }
749  /** @brief Factorize the given SparseMatrix using the defaults. For larger
750  matrices, if the solver fails, set the parameter @a _use_long_ints =
751  true. */
752  UMFPackSolver(SparseMatrix &A, bool _use_long_ints = false)
753  : use_long_ints(_use_long_ints) { Init(); SetOperator(A); }
754 
755  /** @brief Factorize the given Operator @a op which must be a SparseMatrix.
756 
757  The factorization uses the parameters set in the #Control data member.
758  @note This method calls SparseMatrix::SortColumnIndices() with @a op,
759  modifying the matrix if the column indices are not already sorted. */
760  virtual void SetOperator(const Operator &op);
761 
762  /// Set the print level field in the #Control data member.
763  void SetPrintLevel(int print_lvl) { Control[UMFPACK_PRL] = print_lvl; }
764 
765  virtual void Mult(const Vector &b, Vector &x) const;
766  virtual void MultTranspose(const Vector &b, Vector &x) const;
767 
768  virtual ~UMFPackSolver();
769 };
770 
771 /// Direct sparse solver using KLU
772 class KLUSolver : public Solver
773 {
774 protected:
776  klu_symbolic *Symbolic;
777  klu_numeric *Numeric;
778 
779  void Init();
780 
781 public:
783  : mat(0),Symbolic(0),Numeric(0)
784  { Init(); }
786  : mat(0),Symbolic(0),Numeric(0)
787  { Init(); SetOperator(A); }
788 
789  // Works on sparse matrices only; calls SparseMatrix::SortColumnIndices().
790  virtual void SetOperator(const Operator &op);
791 
792  virtual void Mult(const Vector &b, Vector &x) const;
793  virtual void MultTranspose(const Vector &b, Vector &x) const;
794 
795  virtual ~KLUSolver();
796 
797  mutable klu_common Common;
798 };
799 
800 #endif // MFEM_USE_SUITESPARSE
801 
802 }
803 
804 #endif // MFEM_SOLVERS
const Array< int > * ess_dofs_list
Not owned.
Definition: solvers.hpp:717
const Vector * GetInequalityVec_Hi() const
Definition: solvers.hpp:518
Conjugate gradient method.
Definition: solvers.hpp:258
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:2850
double Info[UMFPACK_INFO]
Definition: solvers.hpp:743
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:2618
Chebyshev accelerated smoothing with given vector, no matrix necessary.
Definition: solvers.hpp:167
SparseMatrix * mat
Definition: solvers.hpp:735
int GetNumIterations() const
Definition: solvers.hpp:101
const Operator * oper
Definition: solvers.hpp:73
MPI_Comm GetComm() const
Return the associated MPI communicator, or MPI_COMM_NULL if no communicator is set.
Definition: solvers.hpp:118
SuiteSparse_long * AI
Definition: solvers.hpp:737
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:535
void SetHistorySize(int dim)
Definition: solvers.hpp:453
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:547
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:459
void Monitor(int it, double norm, const Vector &r, const Vector &x, bool final=false) const
Definition: solvers.cpp:108
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:436
NewtonSolver(MPI_Comm _comm)
Definition: solvers.hpp:415
class IterativeSolver * iter_solver
The last IterativeSolver to which this monitor was attached.
Definition: solvers.hpp:38
T * GetData()
Returns the data.
Definition: array.hpp:98
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:160
FGMRES method.
Definition: solvers.hpp:309
int * GetBlockI()
Definition: solvers.hpp:663
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:985
Direct sparse solver using KLU.
Definition: solvers.hpp:772
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:421
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:2951
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:752
void SetOperator(const Operator &op)
Definition: solvers.cpp:2387
MINRES method.
Definition: solvers.hpp:368
const Operator * GetC() const
Definition: solvers.hpp:514
Reordering
The reordering method used by the BlockILU factorization.
Definition: solvers.hpp:629
virtual ~IterativeSolverMonitor()
Definition: solvers.hpp:43
ResidualBCMonitor(const Array< int > &ess_dofs_list_)
Definition: solvers.hpp:720
virtual double CalcObjective(const Vector &x) const =0
Objective F(x). In parallel, the result should be reduced over tasks.
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:261
virtual ~OptimizationSolver()
Definition: solvers.hpp:536
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:202
double Norm(const Vector &x) const
Definition: solvers.hpp:85
const Vector * d_hi
Definition: solvers.hpp:496
double GetFinalNorm() const
Definition: solvers.hpp:103
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:1328
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:357
void SetKDim(int dim)
Definition: solvers.hpp:321
const Vector * x_lo
Definition: solvers.hpp:496
FGMRESSolver(MPI_Comm _comm)
Definition: solvers.hpp:318
Direct sparse solver using UMFPACK.
Definition: solvers.hpp:731
const Vector * x_hi
Definition: solvers.hpp:496
UMFPackSolver(bool _use_long_ints=false)
For larger matrices, if the solver fails, set the parameter _use_long_ints = true.
Definition: solvers.hpp:747
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:798
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:1365
void SetLinearConstraint(const Vector &_w, double _a)
Definition: solvers.cpp:1991
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:381
void SetPrintLevel(int print_lvl)
Definition: solvers.cpp:70
const Vector * GetBoundsVec_Lo() const
Definition: solvers.hpp:519
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:97
double solve(double l, const Vector &xt, Vector &x, int &nclip) const
Solve QP at fixed lambda.
Definition: solvers.hpp:565
int GetNumConstraints() const
Definition: solvers.cpp:1964
OperatorChebyshevSmoother(Operator *oper_, const Vector &d, const Array< int > &ess_tdof_list, int order, double max_eig_estimate)
Definition: solvers.cpp:182
Data type sparse matrix.
Definition: sparsemat.hpp:46
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:1526
virtual ~UMFPackSolver()
Definition: solvers.cpp:2884
LBFGSSolver(MPI_Comm _comm)
Definition: solvers.hpp:450
Jacobi smoothing for a given bilinear form (no matrix necessary).
Definition: solvers.hpp:128
double b
Definition: lissajous.cpp:42
void SetMaxIter(int max_it)
Definition: solvers.hpp:98
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo &lt;= hi.
Definition: vector.cpp:471
SuiteSparse_long * AJ
Definition: solvers.hpp:737
void SetKDim(int dim)
Set the number of iteration to perform between restarts, default is 50.
Definition: solvers.hpp:303
Newton&#39;s method for solving F(x)=b for a given operator F.
Definition: solvers.hpp:406
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:720
void print_iteration(int it, double r, double l) const
Definition: solvers.cpp:1997
void Setup(const Vector &diag)
Definition: solvers.cpp:149
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:733
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.cpp:2906
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:1351
double Dot(const Vector &x, const Vector &y) const
Definition: solvers.cpp:54
int GetConverged() const
Definition: solvers.hpp:102
prob_type prob
Definition: ex25.cpp:149
BiCGSTABSolver(MPI_Comm _comm)
Definition: solvers.hpp:348
klu_symbolic * Symbolic
Definition: solvers.hpp:776
void SetIterativeSolver(const IterativeSolver &solver)
This method is invoked by ItertiveSolver::SetMonitor, informing the monitor which IterativeSolver is ...
Definition: solvers.hpp:59
const Vector * GetBoundsVec_Hi() const
Definition: solvers.hpp:520
SLBQPOptimizer(MPI_Comm _comm)
Definition: solvers.hpp:592
BlockILU(int block_size_, Reordering reordering_=Reordering::MINIMUM_DISCARDED_FILL, int k_fill_=0)
Definition: solvers.cpp:2369
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
Definition: solvers.cpp:1563
OperatorJacobiSmoother(const BilinearForm &a, const Array< int > &ess_tdof_list, const double damping=1.0)
Definition: solvers.cpp:118
CGSolver(MPI_Comm _comm)
Definition: solvers.hpp:269
void SetPrintLevel(int print_lvl)
Set the print level field in the Control data member.
Definition: solvers.hpp:763
Stationary linear iteration: x &lt;- x + B (b - A x)
Definition: solvers.hpp:226
void SetInequalityConstraint(const Vector &dl, const Vector &dh)
Definition: solvers.cpp:1946
void SetEqualityConstraint(const Vector &c)
Definition: solvers.cpp:1938
Abstract base class for an iterative solver monitor.
Definition: solvers.hpp:34
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:545
void SetOperator(const Operator &op_)
Set/update the solver for the given operator.
Definition: solvers.hpp:204
void SetAbsTol(double atol)
Definition: solvers.hpp:97
void SetRelTol(double rtol)
Definition: solvers.hpp:96
double Control[UMFPACK_CONTROL]
Definition: solvers.hpp:742
Monitor that checks whether the residual is zero at a given set of dofs.
Definition: solvers.hpp:714
Abstract base class for iterative solver.
Definition: solvers.hpp:64
virtual void Mult(const Vector &b, Vector &x) const
Solve the nonlinear system with right-hand side b.
Definition: solvers.cpp:1644
OptimizationSolver(MPI_Comm _comm)
Definition: solvers.hpp:534
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:1192
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:2937
double * GetBlockData()
Definition: solvers.hpp:673
SLISolver(MPI_Comm _comm)
Definition: solvers.hpp:237
GMRES method.
Definition: solvers.hpp:290
virtual void SetSolver(Solver &solver)
Set the linear solver for inverting the Jacobian.
Definition: solvers.hpp:461
GMRESSolver(MPI_Comm _comm)
Definition: solvers.hpp:299
const Vector * GetEqualityVec() const
Definition: solvers.hpp:516
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
Definition: solvers.cpp:1972
void SetMonitor(IterativeSolverMonitor &m)
Set the iterative solver monitor.
Definition: solvers.hpp:112
void SetBounds(const Vector &_lo, const Vector &_hi)
Definition: solvers.cpp:1985
const Operator * GetD() const
Definition: solvers.hpp:515
double a
Definition: lissajous.cpp:41
void UpdateVectors()
Definition: solvers.cpp:351
Abstract solver for OptimizationProblems.
Definition: solvers.hpp:526
A &quot;square matrix&quot; operator for the associated FE space and BLFIntegrators The sum of all the BLFInteg...
klu_common Common
Definition: solvers.hpp:797
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:431
OptimizationProblem(int insize, const Operator *C_, const Operator *D_)
In parallel, insize is the number of the local true dofs.
Definition: solvers.cpp:1928
void SetSolutionBounds(const Vector &xl, const Vector &xh)
Definition: solvers.cpp:1956
const Vector * GetInequalityVec_Lo() const
Definition: solvers.hpp:517
void Mult(const Vector &x, Vector &y) const
Operator application: y=A(x).
Definition: solvers.cpp:311
virtual void Mult(const Vector &xt, Vector &x) const =0
Operator application: y=A(x).
void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: solvers.hpp:150
int dim
Definition: ex24.cpp:53
int * GetBlockJ()
Definition: solvers.hpp:668
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:351
virtual void Mult(const Vector &xt, Vector &x) const
Definition: solvers.cpp:2004
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:149
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:272
virtual void CalcObjectiveGrad(const Vector &x, Vector &grad) const
The result grad is expected to enter with the correct size.
Definition: solvers.hpp:507
Vector data type.
Definition: vector.hpp:51
void MonitorResidual(int it, double norm, const Vector &r, bool final) override
Monitor the residual vector r.
Definition: solvers.cpp:2669
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.hpp:459
MINRESSolver(MPI_Comm _comm)
Definition: solvers.hpp:378
const Vector * d_lo
Definition: solvers.hpp:496
virtual void MonitorSolution(int it, double norm, const Vector &x, bool final)
Monitor the solution vector x.
Definition: solvers.hpp:52
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Definition: solvers.cpp:91
KLUSolver(SparseMatrix &A)
Definition: solvers.hpp:785
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:1777
virtual ~KLUSolver()
Definition: solvers.cpp:2965
double * Data()
Definition: densemat.hpp:822
void UpdateVectors()
Definition: solvers.cpp:528
BiCGSTAB method.
Definition: solvers.hpp:337
SparseMatrix * mat
Definition: solvers.hpp:775
Base class for solvers.
Definition: operator.hpp:634
const OptimizationProblem * problem
Definition: solvers.hpp:529
Abstract operator.
Definition: operator.hpp:24
const Operator * D
Definition: solvers.hpp:495
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:728
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
Definition: solvers.hpp:540
const Vector * c_e
Definition: solvers.hpp:496
IterativeSolverMonitor * monitor
Definition: solvers.hpp:75
klu_numeric * Numeric
Definition: solvers.hpp:777
virtual void MonitorResidual(int it, double norm, const Vector &r, bool final)
Monitor the residual vector r.
Definition: solvers.hpp:46
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:28
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Definition: solvers.cpp:2818
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.hpp:240
const Operator * C
Not owned, some can remain unused (NULL).
Definition: solvers.hpp:495
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:500
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:1156
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Definition: solvers.cpp:1552
virtual void SetOperator(const Operator &op)
Factorize the given Operator op which must be a SparseMatrix.
Definition: solvers.cpp:2721