mixed/SolverAdapter.hpp
Go to the documentation of this file.
1#ifndef OPM_MIXED_ADAPTER_HEADER_INCLUDED
2#define OPM_MIXED_ADAPTER_HEADER_INCLUDED
3
5
6#include <dune/istl/bcrsmatrix.hh>
7#include <dune/istl/bvector.hh>
8#include <dune/istl/schwarz.hh>
9#include <dune/istl/operators.hh>
10#include <dune/istl/solvers.hh>
11#include <dune/istl/owneroverlapcopy.hh>
12#include <dune/istl/matrixindexset.hh>
13
17
18
19namespace Dune
20{
21
27template <class Comm, class Operator, class Vector>
28class MixedBiCGSTABSolver:public InverseOperator<Vector, Vector>
29{
30 public:
31
33 using AbstractScalarProductType = Dune::ScalarProduct<Vector>;
34
35 static constexpr auto block_size = Vector::block_type::dimension;
37
47 MixedBiCGSTABSolver(Operator *op,
48 std::shared_ptr<AbstractScalarProductType> sp,
49 std::shared_ptr<AbstractPrecondType> prec,
50 const double& tol,
51 const int& maxiter,
52 const int& verbosity,
53 const Comm &comm)
54 {
55 int halo;
56 size_t nrows;
57 int nnz=0;
58
59 auto &A = op->getmat();
60 // trivially determine size of halo==0 for serial linear operators
61 if constexpr (std::is_same_v<Comm, Dune::Amg::SequentialInformation>)
62 {
63 halo = 0;
64 nrows = A.N();
65 nnz = A.nonzeroes();
66 }
67 // Determine size of halo for parallel linear operators
68 else
69 {
70 local_ = new int[A.N()];
71
72 // number of ghost cells
73 halo = getHaloCount(comm);
74
75 // number of local cells
76 nrows = A.N() - halo;
77
78 // number of nonzeros for local cells
79 int irow=0;
80 for(auto row=A.begin(); row.index() < nrows; row++)
81 {
82 nnz += local_[irow++] ? std::distance(row->begin(), row->end()) : 0;
83 }
84 }
85
86 // Access matrix data from double precision operator
87 double_data_ = &A[0][0][0][0];
88
89 //allocate mixed matrix
90 mixed_matrix_ = std::make_shared<MixedMatrixType>(nrows,nnz);
91
92 // copy sparsity pattern from double precision matrix
93 int *rows = mixed_matrix_->rowptr();
94 int *cols = mixed_matrix_->colidx();
95
96 int irow = 0;
97 int icol = 0;
98 rows[0] = 0;
99 for(auto row=A.begin(); row.index() < nrows; row++)
100 {
101 for(auto col = row->begin(); col != row->end(); ++col)
102 {
103 cols[icol++] = col.index();
104 }
105 rows[irow+1] = icol;
106 irow++;
107 }
108
109 // initialize mixed operator and scalar product depending on the linear operator type provided to the constructor
110 double_operator_ = op;
111 using MatrixType = std::remove_const_t<std::remove_reference_t<decltype(op->getmat())>>;
112
113 // serial runs with plain block-sparse matrices, i.e. Dune::MatrixAdapter
114 if constexpr (std::is_same_v<std::remove_pointer_t<Operator>, Dune::MatrixAdapter<MatrixType, Vector, Vector>>)
115 {
116 using MixedOperatorType = Dune::MatrixAdapter<MixedMatrixType, Vector, Vector>;
117 mixed_operator_ = std::make_shared<MixedOperatorType>(*mixed_matrix_);
118
119 using ScalarProductType = SeqOptmizedProduct<Vector>;
120 scalar_product_ = std::make_shared<ScalarProductType>();
121 }
122 // serial runs with separate linear operator for wells, i.e. Opm::WellModelMatrixAdapter
123 else if constexpr (std::is_same_v<std::remove_pointer_t<Operator>, Opm::WellModelMatrixAdapter<MatrixType, Vector, Vector>>)
124 {
126 using WellOperatorType = Opm::LinearOperatorExtra<Vector,Vector>;
127 const WellOperatorType &wellOper = op->getwellOper();
128 mixed_operator_ = std::make_shared<MixedOperatorType>(*mixed_matrix_, wellOper);
129
130 using ScalarProductType = SeqOptmizedProduct<Vector>;
131 scalar_product_ = std::make_shared<ScalarProductType>();
132 }
133 // parallel runs with plain block-sparse matrices and all ghost cells sorted after local cells, i.e. Opm::GhostLastMatrixAdapter
134 else if constexpr (std::is_same_v<std::remove_pointer_t<Operator>, Opm::GhostLastMatrixAdapter<MatrixType, Vector, Vector, Comm>>)
135 {
137 mixed_operator_ = std::make_shared<MixedOperatorType>(*mixed_matrix_,comm);
138
139 using ScalarProductType = GhostLastScalarProduct<Vector,Comm>;
140 scalar_product_ = std::make_shared<ScalarProductType>(comm,Dune::SolverCategory::overlapping);
141 }
142 // parallel runs with separate linear operators for wells and all ghost cells sorted after local cells, i.e. Opm::WellModelGhostLastMatrixAdapter
143 else if constexpr (std::is_same_v<std::remove_pointer_t<Operator>, Opm::WellModelGhostLastMatrixAdapter<MatrixType, Vector, Vector, true>>)
144 {
146 using WellOperatorType = Opm::LinearOperatorExtra<Vector,Vector>;
147 const WellOperatorType &wellOper = op->getwellOper();
148 mixed_operator_ = std::make_shared<MixedOperatorType>(*mixed_matrix_, wellOper, comm);
149
150 if constexpr (std::is_same_v<Comm, Dune::Amg::SequentialInformation>)
151 {
152 scalar_product_ = sp;
153 }
154 else
155 {
156 using ScalarProductType = GhostLastScalarProduct<Vector,Comm>;
157 scalar_product_ = std::make_shared<ScalarProductType>(comm,Dune::SolverCategory::overlapping);
158 }
159 }
160 // throw an exception for all other linear operator types
161 else { OPM_THROW(std::invalid_argument, "MixedBiCGSTABSolver: Unsupported linear operator type!!\n");}
162
163 //initialize bicgstab solver from Dune
164 solver_ = std::make_shared<Dune::BiCGSTABSolver<Vector>>(
165 *mixed_operator_,
166 *scalar_product_,
167 *prec,
168 tol, // desired residual reduction factor
169 maxiter, // maximum number of iterations
170 verbosity);
171
172 }
173
176 {
177 if constexpr (std::is_same_v<Comm, Dune::Amg::SequentialInformation>) return;
178 delete [] local_;
179 }
180
182 void apply(Vector &x, Vector &b, InverseOperatorResult &res) override
183 {
184 //transpose dense blocks and demote to single precision
185 mixed_matrix_->update(double_data_);
186
187 //apply bicgstab solver from Dune
188 solver_->apply(x,b,res);
189 }
190
192 void apply(Vector &x, Vector &b, double reduction, InverseOperatorResult &res) override
193 {
194 x=0;
195 b=0;
196 res.reduction = reduction;
197 OPM_THROW(std::invalid_argument, "MixedBiCGSTABSolver::apply(...) not implemented yet.");
198 }
199
201 Dune::SolverCategory::Category category() const override{return Dune::SolverCategory::overlapping;};
202
203 private:
204
208 int getHaloCount(const Comm& comm) const
209 {
210 int count = 0;
211 // Loop over index set
212 auto indexSet = comm.indexSet();
213 for (auto idx = indexSet.begin(); idx!=indexSet.end(); ++idx)
214 {
215 if (idx->local().attribute()!=1) count++; // count ghost indices
216
217 int i=idx->local().local(); // tag local indices
218 local_[i] = (idx->local().attribute()==1) ? 1 : 0;
219 }
220
221 return count;
222 }
223
224 using AbstractSolverType = Dune::InverseOperator<Vector,Vector>;
225 using AbstractOperatorType = Dune::AssembledLinearOperator<MixedMatrixType,Vector,Vector>;
226
227 Operator *double_operator_;
228 std::shared_ptr<AbstractSolverType> solver_;
229 std::shared_ptr<AbstractOperatorType> mixed_operator_;
230 std::shared_ptr<MixedMatrixType> mixed_matrix_;
231 std::shared_ptr<AbstractScalarProductType> scalar_product_;
232 double const *double_data_;
233
234 int *local_;
235};
236
237}
238
239#endif // OPM_MIXED_ADAPTER_HEADER_INCLUDED
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: FlexibleSolver_impl.hpp:394
Definition: ScalarProducts.hpp:16
Adapts BiCGSTAB to mixed precision.
Definition: mixed/SolverAdapter.hpp:29
void apply(Vector &x, Vector &b, double reduction, InverseOperatorResult &res) override
Unused variant of solver application.
Definition: mixed/SolverAdapter.hpp:192
~MixedBiCGSTABSolver()
destructor
Definition: mixed/SolverAdapter.hpp:175
static constexpr auto block_size
Definition: mixed/SolverAdapter.hpp:35
MixedBiCGSTABSolver(Operator *op, std::shared_ptr< AbstractScalarProductType > sp, std::shared_ptr< AbstractPrecondType > prec, const double &tol, const int &maxiter, const int &verbosity, const Comm &comm)
constructor
Definition: mixed/SolverAdapter.hpp:47
Dune::ScalarProduct< Vector > AbstractScalarProductType
Definition: mixed/SolverAdapter.hpp:33
Dune::SolverCategory::Category category() const override
Solver category.
Definition: mixed/SolverAdapter.hpp:201
void apply(Vector &x, Vector &b, InverseOperatorResult &res) override
Solver application.
Definition: mixed/SolverAdapter.hpp:182
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:34
Definition: ScalarProducts.hpp:126
Dune linear operator that assumes ghost rows are ordered after interior rows. Avoids some computation...
Definition: WellOperators.hpp:406
Adapter to take advantage of the fact that all matrix rows associated with ghost cells are located at...
Definition: Operators.hpp:18
Wraps c-implementation of mixed-precision matrix.
Definition: MatrixWrapper.hpp:22
Adapter to combine a matrix and another linear operator into a combined linear operator.
Definition: WellOperators.hpp:301
Adapter to combine a matrix and another linear operator into a combined linear operator.
Definition: WellOperators.hpp:225
Adapter to combine a matrix with another linear operator while taking advantage of the fact that all ...
Definition: Operators.hpp:74
Definition: fvbaseprimaryvariables.hh:161
Dune::InverseOperatorResult InverseOperatorResult
Definition: GpuBridge.hpp:32