Line data Source code
1 : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : #ifndef PALACE_LINALG_GEOMETRIC_MULTIGRID_HPP
5 : #define PALACE_LINALG_GEOMETRIC_MULTIGRID_HPP
6 :
7 : #include <memory>
8 : #include <vector>
9 : #include "linalg/operator.hpp"
10 : #include "linalg/solver.hpp"
11 : #include "linalg/vector.hpp"
12 : #include "utils/iodata.hpp"
13 :
14 : namespace mfem
15 : {
16 :
17 : template <typename T>
18 : class Array;
19 :
20 : } // namespace mfem
21 :
22 : namespace palace
23 : {
24 :
25 : //
26 : // Geometric multigrid preconditioner using a given coarse solver for the provided
27 : // hierarchy of finite element spaces. Optionally can be configured to use auxiliary space
28 : // smoothing at each level.
29 : //
30 : template <typename OperType>
31 : class GeometricMultigridSolver : public Solver<OperType>
32 : {
33 : using VecType = typename Solver<OperType>::VecType;
34 :
35 : private:
36 : // Number of V-cycles per preconditioner application.
37 : const int pc_it;
38 :
39 : // Prolongation operators (not owned).
40 : std::vector<const Operator *> P;
41 :
42 : // System matrices at each multigrid level (not owned).
43 : std::vector<const OperType *> A;
44 : std::vector<const mfem::Array<int> *> dbc_tdof_lists;
45 :
46 : // Smoothers for each level. Coarse-level solver is B[0].
47 : mutable std::vector<std::unique_ptr<Solver<OperType>>> B;
48 :
49 : // Temporary vectors for preconditioner application. The type of these is dictated by the
50 : // MFEM Operator interface for multiple RHS.
51 : mutable std::vector<VecType> X, Y, R;
52 :
53 : // Enable timer contribution for Timer::KSP_COARSE_SOLVE.
54 : bool use_timer;
55 :
56 : // Internal function to perform a single V-cycle iteration.
57 : void VCycle(int l, bool initial_guess) const;
58 :
59 : public:
60 : GeometricMultigridSolver(MPI_Comm comm, std::unique_ptr<Solver<OperType>> &&coarse_solver,
61 : const std::vector<const Operator *> &P,
62 : const std::vector<const Operator *> *G, int cycle_it,
63 : int smooth_it, int cheby_order, double cheby_sf_max,
64 : double cheby_sf_min, bool cheby_4th_kind);
65 0 : GeometricMultigridSolver(const IoData &iodata, MPI_Comm comm,
66 : std::unique_ptr<Solver<OperType>> &&coarse_solver,
67 : const std::vector<const Operator *> &P,
68 : const std::vector<const Operator *> *G = nullptr)
69 : : GeometricMultigridSolver(
70 0 : comm, std::move(coarse_solver), P, G, iodata.solver.linear.mg_cycle_it,
71 0 : iodata.solver.linear.mg_smooth_it, iodata.solver.linear.mg_smooth_order,
72 0 : iodata.solver.linear.mg_smooth_sf_max, iodata.solver.linear.mg_smooth_sf_min,
73 0 : iodata.solver.linear.mg_smooth_cheby_4th)
74 : {
75 0 : }
76 :
77 : void SetOperator(const OperType &op) override;
78 :
79 : void Mult(const VecType &x, VecType &y) const override;
80 :
81 0 : void EnableTimer() { use_timer = true; }
82 : };
83 :
84 : } // namespace palace
85 :
86 : #endif // PALACE_LINALG_GEOMETRIC_MULTIGRID_HPP
|