WellConnectionAuxiliaryModule.hpp
Go to the documentation of this file.
1/*
2 Copyright 2017 Dr. Blatt - HPC-Simulation-Software & Services
3 Copyright 2017 Statoil ASA.
4
5 This file is part of the Open Porous Media project (OPM).
6
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_WELLCONNECTIONAUXILIARYMODULE_HEADER_INCLUDED
22#define OPM_WELLCONNECTIONAUXILIARYMODULE_HEADER_INCLUDED
23
25
27
30
31#if HAVE_MPI
33#endif
34
35namespace Opm {
36
37template<class TypeTag, class Model>
39{
43
44public:
45 using NeighborSet = typename
46 ::Opm::BaseAuxiliaryModule<TypeTag>::NeighborSet;
47
49
51 : model_(model)
52 , lin_comm_(std::move(comm))
53 {
54 }
55
56 unsigned numDofs() const override
57 {
58 // No extra dofs are inserted for wells.
59 return 0;
60 }
61
62 void addNeighbors(std::vector<NeighborSet>& neighbors) const override
63 {
64 if (!model_.addMatrixContributions()) {
65 return;
66 }
67
68 // Create cartesian to compressed mapping
69 const auto& schedule_wells = model_.schedule().getWellsatEnd();
70 auto possibleFutureConnections = model_.schedule().getPossibleFutureConnections();
71
72#if HAVE_MPI
73 // Communicate Map to other processes, since it is only available on rank 0
74 Parallel::MpiSerializer ser(lin_comm_);
75 ser.broadcast(Parallel::RootRank{0}, possibleFutureConnections);
76#endif
77 // initialize the additional cell connections introduced by wells.
78 for (const auto& well : schedule_wells)
79 {
80 std::vector<int> wellCells = model_.getCellsForConnections(well);
81 // Now add the cells of the possible future connections
82 const auto possibleFutureConnectionSetIt = possibleFutureConnections.find(well.name());
83 if (possibleFutureConnectionSetIt != possibleFutureConnections.end()) {
84 for (const auto& global_index : possibleFutureConnectionSetIt->second) {
85 int compressed_idx = model_.compressedIndexForInterior(global_index);
86 if (compressed_idx >= 0) { // Ignore connections in inactive/remote cells.
87 wellCells.push_back(compressed_idx);
88 }
89 }
90 }
91 for (int cellIdx : wellCells) {
92 neighbors[cellIdx].insert(wellCells.begin(),
93 wellCells.end());
94 }
95 }
96 }
97
98 void applyInitial() override
99 {}
100
101 void linearize(SparseMatrixAdapter& jacobian, GlobalEqVector& res) override
102 {
104 for (const auto& well : model_) {
105 this->linearizeSingleWell(jacobian, res, well);
106 }
107 OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::linearize failed: ", lin_comm_);
108 }
109
110 void postSolve(GlobalEqVector& deltaX) override
111 {
112 model_.recoverWellSolutionAndUpdateWellState(deltaX);
113 }
114
115 void linearizeDomain(const Domain& domain,
116 SparseMatrixAdapter& jacobian,
117 GlobalEqVector& res)
118 {
119 OPM_TIMEBLOCK(wellLinearizeDomain);
120 // Note: no point in trying to do a parallel gathering
121 // try/catch here, as this function is not called in
122 // parallel but for each individual domain of each rank.
123 for (const auto& well : model_) {
124 if (model_.well_domain().at(well->name()) == domain.index) {
125 this->linearizeSingleWell(jacobian, res, well);
126 }
127 }
128 }
129
130 void postSolveDomain(const GlobalEqVector& deltaX, const Domain& domain)
131 {
132 model_.recoverWellSolutionAndUpdateWellStateDomain(deltaX, domain.index);
133 }
134
135 template <class Restarter>
136 void deserialize(Restarter& /* res */)
137 {
138 // TODO (?)
139 }
140
145 template <class Restarter>
146 void serialize(Restarter& /* res*/)
147 {
148 // TODO (?)
149 }
150
151private:
152 template<class WellType>
153 void linearizeSingleWell(SparseMatrixAdapter& jacobian,
154 GlobalEqVector& res,
155 const WellType& well)
156 {
157 if (model_.addMatrixContributions()) {
158 well->addWellContributions(jacobian);
159 }
160
161 const auto& cells = well->cells();
162 linearize_res_local_.resize(cells.size());
163
164 for (size_t i = 0; i < cells.size(); ++i) {
165 linearize_res_local_[i] = res[cells[i]];
166 }
167
168 well->apply(linearize_res_local_);
169
170 for (size_t i = 0; i < cells.size(); ++i) {
171 res[cells[i]] = linearize_res_local_[i];
172 }
173 }
174
175 Model& model_;
176 GlobalEqVector linearize_res_local_{};
177 Parallel::Communication lin_comm_;
178};
179
180} // end namespace OPM
181#endif
#define OPM_END_PARALLEL_TRY_CATCH(prefix, comm)
Catch exception and throw in a parallel try-catch clause.
Definition: DeferredLoggingErrorHelpers.hpp:192
#define OPM_BEGIN_PARALLEL_TRY_CATCH()
Macro to setup the try of a parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:158
Base class for specifying auxiliary equations.
Definition: baseauxiliarymodule.hh:56
std::set< unsigned > NeighborSet
Definition: baseauxiliarymodule.hh:63
Class for serializing and broadcasting data using MPI.
Definition: MPISerializer.hpp:38
void broadcast(RootRank rootrank, Args &&... args)
Definition: MPISerializer.hpp:47
Definition: WellConnectionAuxiliaryModule.hpp:39
WellConnectionAuxiliaryModule(Model &model, Parallel::Communication comm)
Definition: WellConnectionAuxiliaryModule.hpp:50
unsigned numDofs() const override
Returns the number of additional degrees of freedom required for the auxiliary module.
Definition: WellConnectionAuxiliaryModule.hpp:56
void linearize(SparseMatrixAdapter &jacobian, GlobalEqVector &res) override
Linearize the auxiliary equation.
Definition: WellConnectionAuxiliaryModule.hpp:101
void serialize(Restarter &)
This method writes the complete state of the well to the harddisk.
Definition: WellConnectionAuxiliaryModule.hpp:146
void addNeighbors(std::vector< NeighborSet > &neighbors) const override
Specify the additional neighboring correlations caused by the auxiliary module.
Definition: WellConnectionAuxiliaryModule.hpp:62
void linearizeDomain(const Domain &domain, SparseMatrixAdapter &jacobian, GlobalEqVector &res)
Definition: WellConnectionAuxiliaryModule.hpp:115
void postSolveDomain(const GlobalEqVector &deltaX, const Domain &domain)
Definition: WellConnectionAuxiliaryModule.hpp:130
void postSolve(GlobalEqVector &deltaX) override
This method is called after the linear solver has been called but before the solution is updated for ...
Definition: WellConnectionAuxiliaryModule.hpp:110
void applyInitial() override
Set the initial condition of the auxiliary module in the solution vector.
Definition: WellConnectionAuxiliaryModule.hpp:98
void deserialize(Restarter &)
Definition: WellConnectionAuxiliaryModule.hpp:136
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilboundaryratevector.hh:39
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
Avoid mistakes in calls to broadcast() by wrapping the root argument in an explicit type.
Definition: MPISerializer.hpp:33
int index
Definition: SubDomain.hpp:64
Definition: SubDomain.hpp:85