opm-simulators
CompWell.hpp
1 /*
2  Copyright 2024, SINTEF Digital
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_COMP_WELL_HPP
21 #define OPM_COMP_WELL_HPP
22 
24 
25 #include <flowexperimental/comp/wells/CompWellEquations.hpp>
26 #include <flowexperimental/comp/wells/CompWellFlash.hpp>
27 #include <flowexperimental/comp/wells/CompWellInterface.hpp>
28 #include <flowexperimental/comp/wells/CompWellPrimaryVariables.hpp>
29 
30 #include <opm/simulators/wells/PerforationData.hpp>
31 
32 namespace Opm {
33 
34 template <typename TypeTag>
35 class CompWell : public CompWellInterface<TypeTag>
36 {
37 public:
46 
47  constexpr static unsigned num_comp = FluidSystem::numComponents;
48 
49  using EvalWell = typename PrimaryVariables::EvalWell;
50  using BVectorWell = typename WellEquations::BVectorWell;
51 
52  using VectorBlockType = Dune::FieldVector<Scalar, Indices::numEq>;
53  using BVector = Dune::BlockVector<VectorBlockType>;
54 
55  using SingleWellState = typename Base::SingleWellState;
56 
58 
59  template <typename T>
60  using FluidState = CompositionalFluidState<T, FluidSystem>;
61 
62  // TODO: this can be a rate converter role later
63  // currently, it has the surface densities for each phase and volume fractions for each phase
64  // it is part of the secondary variables used in the assembling of the well equations
66  {
67  static constexpr int num_phases = 2;
68  std::array<EvalWell, num_phases> surface_densities_{};
69  std::array<EvalWell, num_phases> volume_fractions_{};
70  std::array<std::array<EvalWell, num_comp>, num_phases> mass_fractions_{};
71 
72  EvalWell density() const {
73  EvalWell density = 0.;
74  for (int i = 0; i < num_phases; ++i) {
75  density += surface_densities_[i] * volume_fractions_[i];
76  }
77  return density;
78  }
79 
80  // TODO: it looks like that we can have a concept of component mass density?
81  EvalWell massFraction(int comp_idx) const {
82  EvalWell mass = 0.;
83  for (unsigned p = 0; p < num_phases; ++p) {
84  mass += surface_densities_[p] * volume_fractions_[p] * mass_fractions_[p][comp_idx];
85  }
86  return mass / density();
87  }
88  };
89 
90  CompWell(const Well& well,
91  int index_of_well,
92  const std::vector<CompConnectionData>& well_connection_data);
93 
94  void init() override;
95 
96  void calculateExplicitQuantities(const Simulator& simulator,
97  const SingleWellState& well_state) override;
98 
99  void updatePrimaryVariables(const Simulator& simulator,
100  const SingleWellState& well_state) override;
101 
102  void updateSecondaryQuantities(const Simulator& simulator);
103 
104  // TODO: control should be passed in later
105  void assembleWellEq(const Simulator& simulator,
106  const SingleWellState& well_state,
107  const double dt);
108 
109  bool iterateWellEq(const Simulator& simulator,
110  const Scalar dt,
111  SingleWellState& well_state) override;
112 
113  void solveEqAndUpdateWellState(SingleWellState& well_state);
114 
115  void apply(BVector& r) const override;
116 
117  void recoverWellSolutionAndUpdateWellState(const BVector& x,
118  SingleWellState& well_state) override;
119 
120  bool getConvergence() const override;
121 
122  void addWellContributions(SparseMatrixAdapter&) const override;
123 
124 private:
125 
126  // primary variables
127  PrimaryVariables primary_variables_;
128  WellEquations well_equations_;
129 
130  // the following varialbes are temporary and remain to be cleaned up and re-organized
131  // some are testing variables, and some are secondary variables might be kept
132  // anyway, they are very rough prototype code for testing and will be changed
133  const Scalar wellbore_volume_ {21.6*0.001};
134 
135  std::array<EvalWell, num_comp> mass_fractions_{0.};
136  EvalWell fluid_density_{0.};
137  // the original mass for each component in wellbore
138  std::array<Scalar, num_comp> component_masses_{0.};
139  // the new mass for each component in wellbore, derived from the primary variables
140  std::array<EvalWell, num_comp> new_component_masses_{0.};
141  // quantities used to calculate the quantities under the surface conditions
142  SurfaceConditons surface_conditions_;
143 
144  // following are some secondary property or variables to be used for later
145  void calculateSingleConnectionRate(const Simulator& simulator,
146  std::vector<EvalWell>& con_rates) const;
147 
148  void updateTotalMass();
149 
150  // TODO: a better name
151  void updateSurfaceQuantities(const Simulator& simulator);
152 
153  void getMobility(const Simulator& simulator,
154  const int connection_idx,
155  std::vector<EvalWell>& mob) const;
156 
157 
158  // TODO: the following assembling functions will be moved to a separate assmeble class
159  void assembleSourceTerm(const Scalar dt);
160 
161  void assembleControlEq(const SingleWellState& well_state,
162  const SummaryState& summary_state);
163 
164  void assembleControlEqProd(const SingleWellState& well_state,
165  const Well::ProductionControls& prod_controls,
166  EvalWell& control_eq) const;
167 
168  void assembleControlEqInj(const SingleWellState& well_state,
169  const Well::InjectionControls& inj_controls,
170  EvalWell& control_eq) const;
171 
172  void updatePrimaryVariablesNewton(const BVectorWell& dwells);
173 
174  // with passing in the SurfaceCondition, we should be able to do this in the primary variable class
175  void updateWellStateFromPrimaryVariables(SingleWellState& well_state) const;
176 
177  void updateWellState(const BVectorWell& dwells,
178  SingleWellState& well_state);
179 
180  void updateWellControl(const SummaryState& summary_state,
181  SingleWellState& well_state) const;
182 
183  template <typename T>
184  void
185  updateSurfaceCondition_(const StandardCond& surface_cond, FluidState<T>& fluid_state);
186 
187  template <typename T>
188  void
189  flashFluidState_(FluidState<T>& fluid_state);
190 };
191 
192 } // end of namespace Opm
193 
194 #include "CompWell_impl.hpp"
195 
196 #endif // OPM_COMPOSITIONAL_WELL_MODEL_HPP
Definition: CompWellInterface.hpp:33
Definition: CompWellPrimaryVariables.hpp:32
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
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: CompWell.hpp:35
Static data associated with a well perforation.
Definition: BlackoilWellModelRestart.hpp:41
The Opm property system, traits with inheritance.
Definition: CompWellPrimaryVariables.hpp:35
Definition: CompWell.hpp:65