opm-simulators
GpuPressureTransferPolicy.hpp
1 /*
2  Copyright 2025 Equinor ASA.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_GPU_PRESSURE_TRANSFER_POLICY_HEADER_INCLUDED
21 #define OPM_GPU_PRESSURE_TRANSFER_POLICY_HEADER_INCLUDED
22 
23 #include <opm/simulators/linalg/PropertyTree.hpp>
24 #include <opm/simulators/linalg/WellOperators.hpp>
25 #include <opm/simulators/linalg/gpuistl/GpuSparseMatrixWrapper.hpp>
26 #include <opm/simulators/linalg/gpuistl/GpuVector.hpp>
27 #include <opm/simulators/linalg/gpuistl/detail/cpr_amg_operations.hpp>
29 
30 #include <cstddef>
31 
32 namespace Opm
33 {
34 namespace Details
35 {
36  template <class Scalar>
37  using GpuPressureMatrixType = gpuistl::GpuSparseMatrixWrapper<Scalar>;
38  template <class Scalar>
39  using GpuPressureVectorType = gpuistl::GpuVector<Scalar>;
40  template <class Scalar>
41  using GpuSeqCoarseOperatorType = Dune::
42  MatrixAdapter<GpuPressureMatrixType<Scalar>, GpuPressureVectorType<Scalar>, GpuPressureVectorType<Scalar>>;
43 
44  template <class Scalar, class Comm>
45  using GpuCoarseOperatorType = GpuSeqCoarseOperatorType<Scalar>;
46 } // namespace Details
47 } // namespace Opm
48 
49 namespace Opm::gpuistl
50 {
51 template <class FineOperator, class Communication, class Scalar, bool transpose = false>
53  : public Dune::Amg::LevelTransferPolicyCpr<FineOperator, Details::GpuCoarseOperatorType<Scalar, Communication>>
54 {
55 public:
56  using CoarseOperator = typename Details::GpuCoarseOperatorType<Scalar, Communication>;
58  using ParallelInformation = Communication;
59  using FineVectorType = typename FineOperator::domain_type;
60 
61 public:
62  GpuPressureTransferPolicy(const Communication& comm,
63  const FineVectorType& weights,
64  [[maybe_unused]] const PropertyTree& prm,
65  int pressure_var_index)
66  : communication_(&const_cast<Communication&>(comm))
67  , weights_(weights)
68  , pressure_var_index_(pressure_var_index)
69  {
70  }
71 
72 
73  void createCoarseLevelSystem(const FineOperator& fineOperator) override
74  {
75  using CoarseMatrix = typename CoarseOperator::matrix_type;
76  const auto& fineLevelMatrix = fineOperator.getmat();
77  // Create coarse level matrix on GPU with block size 1 but same sparsity pattern
78  coarseLevelMatrix_ = std::make_shared<CoarseMatrix>(fineLevelMatrix.getRowIndices(),
79  fineLevelMatrix.getColumnIndices(),
80  1 // block size 1
81  );
82 
83  // Calculate entries for coarse matrix
84  calculateCoarseEntries(fineOperator);
85  coarseLevelCommunication_.reset(communication_, [](Communication*) {});
86 
87  this->lhs_.resize(coarseLevelMatrix_->N());
88  this->rhs_.resize(coarseLevelMatrix_->N());
89 
90  // Create a MatrixAdapter that wraps the matrix without copying it
91  this->operator_ = std::make_shared<CoarseOperator>(*coarseLevelMatrix_);
92  }
93 
94  void calculateCoarseEntries(const FineOperator& fineOperator) override
95  {
96  const auto& fineLevelMatrix = fineOperator.getmat();
97 
98  // Set coarse matrix to zero
99  coarseLevelMatrix_->getNonZeroValues() = 0.0;
100 
101  // Calculate coarse entries on GPU
102  detail::calculateCoarseEntries<Scalar, transpose>(fineLevelMatrix, *coarseLevelMatrix_, weights_, pressure_var_index_);
103  }
104 
105  void moveToCoarseLevel(const typename ParentType::FineRangeType& fine) override
106  {
107  // Set coarse vector to zero
108  this->rhs_ = 0;
109 
110  // Restrict vector on GPU
111  detail::restrictVector<Scalar, transpose>(fine, this->rhs_, weights_, pressure_var_index_);
112 
113  this->lhs_ = 0;
114  }
115 
116  void moveToFineLevel(typename ParentType::FineDomainType& fine) override
117  {
118  // Prolongate vector on GPU
119  detail::prolongateVector<Scalar, transpose>(this->lhs_, fine, weights_, pressure_var_index_);
120  }
121 
123  {
124  return new GpuPressureTransferPolicy(*this);
125  }
126 
127  const Communication& getCoarseLevelCommunication() const
128  {
129  return *coarseLevelCommunication_;
130  }
131 
132  std::size_t getPressureIndex() const
133  {
134  return pressure_var_index_;
135  }
136 
137 private:
138  Communication* communication_;
139  const FineVectorType& weights_;
140  const std::size_t pressure_var_index_;
141  std::shared_ptr<Communication> coarseLevelCommunication_;
142  std::shared_ptr<typename CoarseOperator::matrix_type> coarseLevelMatrix_;
143 };
144 
145 } // namespace Opm::gpuistl
146 
147 #endif // OPM_GPU_PRESSURE_TRANSFER_POLICY_HEADER_INCLUDED
std::shared_ptr< CoarseOperatorType > operator_
the coarse level linear operator.
Definition: twolevelmethodcpr.hh:148
FineOperatorType::domain_type FineDomainType
The type of the domain of the fine level operator.
Definition: twolevelmethodcpr.hh:63
void createCoarseLevelSystem(const FineOperator &fineOperator) override
Algebraically creates the coarse level system.
Definition: GpuPressureTransferPolicy.hpp:73
Definition: GpuPressureTransferPolicy.hpp:52
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
void calculateCoarseEntries(const FineOperator &fineOperator) override
???.
Definition: GpuPressureTransferPolicy.hpp:94
Algebraic twolevel methods.
Abstract base class for transfer between levels and creation of the coarse level system.
Definition: twolevelmethodcpr.hh:48
GpuPressureTransferPolicy * clone() const override
Clone the current object.
Definition: GpuPressureTransferPolicy.hpp:122
FineOperatorType::range_type FineRangeType
The type of the range of the fine level operator.
Definition: twolevelmethodcpr.hh:59
A small, fixed‑dimension MiniVector class backed by std::array that can be used in both host and CUD...
Definition: AmgxInterface.hpp:37
CoarseRangeType rhs_
The coarse level rhs.
Definition: twolevelmethodcpr.hh:144
CoarseDomainType lhs_
The coarse level lhs.
Definition: twolevelmethodcpr.hh:146
void moveToFineLevel(typename ParentType::FineDomainType &fine) override
Updates the fine level linear system after the correction of the coarse levels system.
Definition: GpuPressureTransferPolicy.hpp:116
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:38