opm-simulators
CompWellPrimaryVariables_impl.hpp
1 /*
2  Copyright 2024, 2026, 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_PRIMARY_VARIABLES_IMPL_HPP
21 #define OPM_COMP_WELL_PRIMARY_VARIABLES_IMPL_HPP
22 
23 #include <flowexperimental/comp/wells/SingleCompWellState.hpp>
24 
25 #include <algorithm>
26 
27 namespace Opm {
28 
29 template <typename FluidSystem, typename Indices>
30 void
31 CompWellPrimaryVariables<FluidSystem, Indices>::
32 update(const SingleWellState& well_state)
33 {
34  value_[QTotal] = well_state.get_total_surface_rate();
35  // the mole fractions of the first n-1 component
36  std::vector<Scalar> mole_fractions(FluidSystem::numComponents, 0.);
37  Scalar sum_mole_fraction = 0.;
38  for (int i = 0; i < FluidSystem::numComponents; ++i) {
39  mole_fractions[i] = std::max(well_state.total_molar_fractions[i], 1.e-10);
40  sum_mole_fraction += mole_fractions[i];
41  }
42  assert(sum_mole_fraction != 0.);
43  for (int i = 0; i < numWellConservationEq - 1; ++i) {
44  value_[i + 1] = mole_fractions[i] / sum_mole_fraction;
45  }
46  value_[Bhp] = well_state.bhp;
47 
48  temperature_ = well_state.temperature;
49 
50  updateEvaluation();
51 }
52 
53 template <typename FluidSystem, typename Indices>
54 void
55 CompWellPrimaryVariables<FluidSystem, Indices>::
56 updateEvaluation()
57 {
58  for (std::size_t idx = 0; idx < numWellEq; ++idx) {
59  evaluation_[idx] = 0.;
60  evaluation_[idx].setValue(value_[idx]);
61  evaluation_[idx].setDerivative(idx + numResEq, 1.);
62  }
63 }
64 
65 template <typename FluidSystem, typename Indices>
66 typename CompWellPrimaryVariables<FluidSystem, Indices>::EvalWell
67 CompWellPrimaryVariables<FluidSystem, Indices>::
68 getBhp() const
69 {
70  return evaluation_[Bhp];
71 }
72 
73 template <typename FluidSystem, typename Indices>
74 typename CompWellPrimaryVariables<FluidSystem, Indices>::EvalWell
75 CompWellPrimaryVariables<FluidSystem, Indices>::
76 getTotalRate() const
77 {
78  return evaluation_[QTotal];
79 }
80 
81 template <typename FluidSystem, typename Indices>
82 typename CompWellPrimaryVariables<FluidSystem, Indices>::EvalWell
83 CompWellPrimaryVariables<FluidSystem, Indices>::
84 extendEval(const Eval& in)
85 {
86  EvalWell out = 0.0;
87  out.setValue(in.value());
88  for(int eq_idx = 0; eq_idx < Indices::numEq;++eq_idx) {
89  out.setDerivative(eq_idx, in.derivative(eq_idx));
90  }
91  return out;
92 }
93 
94 template <typename FluidSystem, typename Indices>
95 typename CompWellPrimaryVariables<FluidSystem, Indices>::Eval
96 CompWellPrimaryVariables<FluidSystem, Indices>::
97 restrictEval(const EvalWell& in)
98 {
99  Eval out = 0.0;
100  out.setValue(in.value());
101  for(int eq_idx = 0; eq_idx < Indices::numEq;++eq_idx) {
102  out.setDerivative(eq_idx, in.derivative(eq_idx));
103  }
104  return out;
105 }
106 
107 template <typename FluidSystem, typename Indices>
108 void
109 CompWellPrimaryVariables<FluidSystem, Indices>::
110 updateNewton(const BVectorWell& dwells)
111 {
112  constexpr Scalar damping = 1.0;
113 
114  for (unsigned i = 0; i < value_.size(); ++i) {
115  value_[i] -= damping * dwells[0][i];
116  }
117  // The mole-fraction primary variables occupy indices [1, numComponents - 1]
118  // (QTotal is at 0 and Bhp at numComponents). Clamp each of them, then
119  // renormalize so the full composition - including the implicit last
120  // component - sums to one.
121  std::vector<Scalar> mole_fractions(FluidSystem::numComponents, 0.);
122  Scalar sum_mole_fraction = 0.;
123  for (int i = 0; i < FluidSystem::numComponents - 1; ++i) {
124  value_[i + 1] = std::clamp(value_[i + 1], 1.e-10, 1.);
125  mole_fractions[i] = value_[i + 1];
126  sum_mole_fraction += mole_fractions[i];
127  }
128  mole_fractions[FluidSystem::numComponents - 1] = std::max(1.0 - sum_mole_fraction, 1.e-10);
129  sum_mole_fraction += mole_fractions[FluidSystem::numComponents - 1];
130  assert(sum_mole_fraction != 0.);
131  for (int i = 0; i < FluidSystem::numComponents - 1; ++i) {
132  value_[i + 1] = mole_fractions[i] / sum_mole_fraction;
133  }
134 
135  updateEvaluation();
136 }
137 
138 template <typename FluidSystem, typename Indices>
139 template <typename T>
140 T
141 CompWellPrimaryVariables<FluidSystem, Indices>::
142 getValue_(int index) const
143 {
144  static_assert(std::is_same_v<T, Scalar> || std::is_same_v<T, EvalWell>, "Unsupported type in CompWellPrimaryVariables::getValue_");
145 
146  if constexpr (std::is_same_v<T, Scalar>) {
147  return value_[index];
148  } else {
149  return evaluation_[index];
150  }
151 }
152 
153 template <typename FluidSystem, typename Indices>
154 template <typename T>
155 typename CompWellPrimaryVariables<FluidSystem, Indices>::template FluidState<T>
156 CompWellPrimaryVariables<FluidSystem, Indices>::
157 toFluidState() const
158 {
159  static_assert(std::is_same_v<T, Scalar> || std::is_same_v<T, EvalWell>, "Unsupported type in CompWellPrimaryVariables::toFluidState");
160 
161  CompositionalFluidState<T, FluidSystem> fluid_state;
162  const auto& pressure = getValue_<T>(Bhp);
163  std::array<T, FluidSystem::numComponents> total_molar_fractions;
164  T sum = 0.;
165  for (int i = 0; i < FluidSystem::numComponents - 1; ++i) {
166  total_molar_fractions[i] = getValue_<T>(i + 1);
167  sum += total_molar_fractions[i];
168  }
169  total_molar_fractions[FluidSystem::numComponents - 1] = 1.0 - sum;
170 
171  for (int i = 0; i < FluidSystem::numComponents; ++i) {
172  if constexpr (std::is_same_v<T, EvalWell>) {
173  total_molar_fractions[i].setValue(std::max(getValue(total_molar_fractions[i]), 1.e-10));
174  } else { // Scalar
175  total_molar_fractions[i] = std::max(total_molar_fractions[i], 1.e-10);
176  }
177  fluid_state.setMoleFraction(i, total_molar_fractions[i]);
178  }
179 
180  fluid_state.setPressure(FluidSystem::oilPhaseIdx, pressure);
181  fluid_state.setPressure(FluidSystem::gasPhaseIdx, pressure);
182 
183  fluid_state.setTemperature(temperature_);
184 
185  for (int i = 0; i < FluidSystem::numComponents; ++i) {
186  fluid_state.setKvalue(i, fluid_state.wilsonK_(i));
187  }
188 
189  fluid_state.setLvalue(-1.);
190 
191  return fluid_state;
192 }
193 
194 } // end of namespace Opm
195 
196 #endif // OPM_COMP_WELL_PRIMARY_VARIABLES_IMPL_HPP
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45