MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
filteredsolver.cpp
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#include "filteredsolver.hpp"
13#include "sparsemat.hpp"
14#ifdef MFEM_USE_PETSC
15#include "petsc.hpp"
16#endif
17
18namespace mfem
19{
20
21std::unique_ptr<const Operator> FilteredSolver::GetPtAP(const Operator *Aop,
22 const Operator *Pop) const
23{
24#ifdef MFEM_USE_MPI
25 const HypreParMatrix * Ah = dynamic_cast<const HypreParMatrix*>(Aop);
26 const HypreParMatrix * Ph = dynamic_cast<const HypreParMatrix*>(Pop);
27 if (Ah && Ph) { return std::unique_ptr<const Operator>(RAP(Ah, Ph)); }
28#endif
29#ifdef MFEM_USE_PETSC
30 PetscParMatrix* Ap = const_cast<PetscParMatrix*>(
31 dynamic_cast<const PetscParMatrix*>(Aop));
32 PetscParMatrix* Pp = const_cast<PetscParMatrix*>(
33 dynamic_cast<const PetscParMatrix*>(Pop));
34 if (Ap && Pp) { return std::unique_ptr<const Operator>(RAP(Ap, Pp)); }
35#endif
36 const SparseMatrix * Asp = dynamic_cast<const SparseMatrix*>(Aop);
37 const SparseMatrix * Psp = dynamic_cast<const SparseMatrix*>(Pop);
38 if (Asp && Psp) { return std::unique_ptr<const Operator>(RAP(*Asp, *Psp)); }
39
40 return std::unique_ptr<const Operator>(new RAPOperator(*Pop, *Aop, *Pop));
41}
42
44{
45 MFEM_VERIFY(A, "Operator not set");
46 MFEM_VERIFY(P, "Transfer operator not set");
47 MFEM_VERIFY(B, "Solver is not set.");
48 MFEM_VERIFY(S, "Filtered space solver is not set.");
49
50 z.SetSize(height);
51 z.UseDevice(true);
52 r.SetSize(height);
53 r.UseDevice(true);
54 xf.SetSize(P->Width());
55 xf.UseDevice(true);
56 rf.SetSize(P->Width());
57 rf.UseDevice(true);
58}
59
60void FilteredSolver::MakeSolver() const
61{
62 if (solver_set) { return; }
63
65
66 // Original space solver
67 B->SetOperator(*A);
68
69 // Filtered space operator
70 PtAP = GetPtAP(A, P);
71
72 // Filtered space solver
74
75 solver_set = true;
76}
77
79{
80 A = &op;
81 height = op.Height();
82 width = op.Width();
83 solver_set = false;
84}
85
87{
88 B = &B_;
89 solver_set = false;
90}
91
93{
94 P = &P_;
95 solver_set = false;
96}
97
99{
100 S = &S_;
101 solver_set = false;
102}
103
104void FilteredSolver::Mult(const Vector &b, Vector &x) const
105{
106 MFEM_VERIFY(b.Size() == x.Size(), "Inconsistent b and x size");
107 MakeSolver();
108
109 x = 0.0;
110 r = b;
111
112 // z = B x
113 B->Mult(b, z);
114 // x = x + z
115 x+=z;
116
117 // r = b - A x = r - A z
118 A->AddMult(z, r, -1.0);
119
120 // rf = Páµ€ r
121 P->MultTranspose(r, rf);
122
123 // xf = S rf
124 S->Mult(rf, xf);
125
126 // z = P xf
127 P->Mult(xf, z);
128
129 // x = x + z
130 x+=z;
131
132 // r = b - A x = r - A z
133 A->AddMult(z, r, -1.0);
134
135 // z = B r
136 B->Mult(r, z);
137 x+=z;
138}
139
140#ifdef MFEM_USE_MPI
141
143{
144 auto Ah = dynamic_cast<const HypreParMatrix*>(&A_);
145 MFEM_VERIFY(Ah, "AMGFSolver::SetOperator: HypreParMatrix expected.");
147}
148
153
154#endif
155
156} // namespace mfem
void SetFilteredSubspaceTransferOperator(const HypreParMatrix &Pop)
Set the parallel transfer operator P for the filtered subspace.
virtual void SetOperator(const Operator &A) override
Set the system operator A.
std::unique_ptr< const Operator > PtAP
Projected operator.
void Mult(const Vector &x, Vector &y) const override
Apply the filtered solver.
const Operator * P
Transfer operator (not owned).
virtual void SetOperator(const Operator &A) override
Set the system operator A.
void SetFilteredSubspaceTransferOperator(const Operator &P)
Set the transfer operator P from filtered subspace to the full space.
Solver * B
Base solver (not owned).
Solver * S
Subspace solver (not owned).
void InitVectors() const
Initialize work vectors.
void SetFilteredSubspaceSolver(Solver &S)
Set a solver S that operates on the filtered subspace operator .
const Operator * A
System operator (not owned).
virtual void SetSolver(Solver &B)
Set the solver B that operates on the full space.
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:419
Abstract operator.
Definition operator.hpp:25
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:28
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
int height
Dimension of the output / number of rows in the matrix.
Definition operator.hpp:27
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:72
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition operator.hpp:100
virtual void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const
Operator application: y+=A(x) (default) or y+=a*A(x).
Definition operator.cpp:51
Base class for solvers.
Definition operator.hpp:792
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
Definition vector.hpp:145
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
real_t b
Definition lissajous.cpp:42
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)