00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef OPM_MULTISEGMENTWELL_HEADER_INCLUDED
00023 #define OPM_MULTISEGMENTWELL_HEADER_INCLUDED
00024
00025
00026 #include <opm/autodiff/WellInterface.hpp>
00027
00028 namespace Opm
00029 {
00030
00031 template<typename TypeTag>
00032 class MultisegmentWell: public WellInterface<TypeTag>
00033 {
00034 public:
00035 typedef WellInterface<TypeTag> Base;
00036
00037 using typename Base::WellState;
00038 using typename Base::Simulator;
00039 using typename Base::IntensiveQuantities;
00040 using typename Base::FluidSystem;
00041 using typename Base::ModelParameters;
00042 using typename Base::MaterialLaw;
00043 using typename Base::BlackoilIndices;
00044
00046 using Base::numEq;
00047
00048 using Base::has_solvent;
00049 using Base::has_polymer;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 static const bool gasoil = numEq == 2 && (BlackoilIndices::compositionSwitchIdx >= 0);
00060 static const int GTotal = 0;
00061 static const int WFrac = gasoil? -1000: 1;
00062 static const int GFrac = gasoil? 1 : 2;
00063 static const int SPres = gasoil? 2 : 3;
00064
00066 static const int numWellEq = GET_PROP_VALUE(TypeTag, EnablePolymer)? numEq : numEq + 1;
00067
00068 using typename Base::Scalar;
00069 using typename Base::ConvergenceReport;
00070
00072 using typename Base::Mat;
00073 using typename Base::BVector;
00074 using typename Base::Eval;
00075
00076
00077
00078
00079
00080
00081 typedef Dune::FieldVector<Scalar, numWellEq> VectorBlockWellType;
00082 typedef Dune::BlockVector<VectorBlockWellType> BVectorWell;
00083
00084
00085 typedef Dune::FieldMatrix<Scalar, numWellEq, numWellEq > DiagMatrixBlockWellType;
00086 typedef Dune::BCRSMatrix <DiagMatrixBlockWellType> DiagMatWell;
00087
00088
00089 typedef Dune::FieldMatrix<Scalar, numWellEq, numEq> OffDiagMatrixBlockWellType;
00090 typedef Dune::BCRSMatrix<OffDiagMatrixBlockWellType> OffDiagMatWell;
00091
00092
00093
00094
00095 typedef DenseAd::Evaluation<double, numEq + numWellEq> EvalWell;
00096
00097 MultisegmentWell(const Well* well, const int time_step, const Wells* wells, const ModelParameters& param);
00098
00099 virtual void init(const PhaseUsage* phase_usage_arg,
00100 const std::vector<bool>* active_arg,
00101 const std::vector<double>& depth_arg,
00102 const double gravity_arg,
00103 const int num_cells);
00104
00105
00106 virtual void initPrimaryVariablesEvaluation() const;
00107
00108 virtual void assembleWellEq(Simulator& ebosSimulator,
00109 const double dt,
00110 WellState& well_state,
00111 bool only_wells);
00112
00114
00115 virtual void updateWellStateWithTarget(const int current,
00116 WellState& well_state) const;
00117
00119 virtual ConvergenceReport getWellConvergence(const std::vector<double>& B_avg) const;
00120
00122 virtual void apply(const BVector& x, BVector& Ax) const;
00124 virtual void apply(BVector& r) const;
00125
00128 virtual void recoverWellSolutionAndUpdateWellState(const BVector& x,
00129 WellState& well_state) const;
00130
00132 virtual void computeWellPotentials(const Simulator& ebosSimulator,
00133 const WellState& well_state,
00134 std::vector<double>& well_potentials);
00135
00136 virtual void updatePrimaryVariables(const WellState& well_state) const;
00137
00138 virtual void solveEqAndUpdateWellState(WellState& well_state);
00139
00140 virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
00141 const WellState& well_state);
00142
00145 int numberOfSegments() const;
00146
00147 int numberOfPerforations() const;
00148
00149 protected:
00150 int number_segments_;
00151
00152
00153 WellSegment::CompPressureDropEnum compPressureDrop() const;
00154
00155 WellSegment::MultiPhaseModelEnum multiphaseModel() const;
00156
00157
00158 const SegmentSet& segmentSet() const;
00159
00160
00161 using Base::well_ecl_;
00162 using Base::number_of_perforations_;
00163 using Base::current_step_;
00164 using Base::index_of_well_;
00165 using Base::number_of_phases_;
00166
00167
00168
00169 using Base::well_cells_;
00170 using Base::param_;
00171 using Base::well_index_;
00172 using Base::well_type_;
00173 using Base::first_perf_;
00174 using Base::saturation_table_number_;
00175 using Base::well_efficiency_factor_;
00176 using Base::gravity_;
00177 using Base::well_controls_;
00178 using Base::perf_depth_;
00179
00180
00181 using Base::active;
00182 using Base::phaseUsage;
00183 using Base::name;
00184 using Base::numComponents;
00185 using Base::flowPhaseToEbosPhaseIdx;
00186 using Base::flowPhaseToEbosCompIdx;
00187 using Base::getAllowCrossFlow;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 std::vector<std::vector<int> > segment_perforations_;
00199
00200
00201 std::vector<std::vector<int> > segment_inlets_;
00202
00203
00204
00205 int segmentNumberToIndex(const int segment_number) const;
00206
00207
00208
00209 mutable OffDiagMatWell duneB_;
00210 mutable OffDiagMatWell duneC_;
00211
00212 mutable DiagMatWell duneD_;
00213
00214
00215 mutable BVectorWell resWell_;
00216
00217
00218
00219 mutable std::vector<std::array<double, numWellEq> > primary_variables_;
00220
00221
00222 mutable std::vector<std::array<EvalWell, numWellEq> > primary_variables_evaluation_;
00223
00224
00225 std::vector<double> cell_perforation_depth_diffs_;
00226
00227
00228 std::vector<double> cell_perforation_pressure_diffs_;
00229
00230
00231
00232
00233 std::vector<double> perforation_segment_depth_diffs_;
00234
00235
00236 std::vector<std::vector<double> > segment_comp_initial_;
00237
00238
00239
00240 std::vector<EvalWell> segment_densities_;
00241
00242
00243 std::vector<EvalWell> segment_viscosities_;
00244
00245
00246 std::vector<EvalWell> segment_mass_rates_;
00247
00248 std::vector<double> segment_depth_diffs_;
00249
00250 void initMatrixAndVectors(const int num_cells) const;
00251
00252
00253
00254
00255
00256
00257
00258 void recoverSolutionWell(const BVector& x, BVectorWell& xw) const;
00259
00260
00261 void updateWellState(const BVectorWell& dwells,
00262 const bool inner_iteration,
00263 WellState& well_state) const;
00264
00265
00266
00267
00268 void initSegmentRatesWithWellRates(WellState& well_state) const;
00269
00270
00271 void computeInitialComposition();
00272
00273
00274 void computePerfCellPressDiffs(const Simulator& ebosSimulator);
00275
00276
00277
00278 EvalWell volumeFraction(const int seg, const int comp_idx) const;
00279
00280
00281 EvalWell volumeFractionScaled(const int seg, const int comp_idx) const;
00282
00283
00284 EvalWell surfaceVolumeFraction(const int seg, const int comp_idx) const;
00285
00286 void computePerfRate(const IntensiveQuantities& int_quants,
00287 const std::vector<EvalWell>& mob_perfcells,
00288 const int seg,
00289 const int perf,
00290 const EvalWell& segment_pressure,
00291 const bool& allow_cf,
00292 std::vector<EvalWell>& cq_s) const;
00293
00294
00295 EvalWell extendEval(const Eval& in) const;
00296
00297
00298
00299 void computeSegmentFluidProperties(const Simulator& ebosSimulator);
00300
00301 EvalWell getSegmentPressure(const int seg) const;
00302
00303 EvalWell getSegmentRate(const int seg, const int comp_idx) const;
00304
00305 EvalWell getSegmentGTotal(const int seg) const;
00306
00307
00308 void getMobility(const Simulator& ebosSimulator,
00309 const int perf,
00310 std::vector<EvalWell>& mob) const;
00311
00312 void assembleControlEq() const;
00313
00314 void assemblePressureEq(const int seg) const;
00315
00316
00317 EvalWell getHydroPressureLoss(const int seg) const;
00318
00319
00320 EvalWell getFrictionPressureLoss(const int seg) const;
00321
00322 void handleAccelerationPressureLoss(const int seg) const;
00323
00324
00325 void processFractions(const int seg) const;
00326
00327 void updateWellStateFromPrimaryVariables(WellState& well_state) const;
00328
00329 double scalingFactor(const int comp_idx) const;
00330
00331 bool frictionalPressureLossConsidered() const;
00332
00333 bool accelerationalPressureLossConsidered() const;
00334
00335
00336 void iterateWellEquations(Simulator& ebosSimulator,
00337 const double dt,
00338 WellState& well_state);
00339
00340 void assembleWellEqWithoutIteration(Simulator& ebosSimulator,
00341 const double dt,
00342 WellState& well_state,
00343 bool only_wells);
00344 };
00345
00346 }
00347
00348 #include "MultisegmentWell_impl.hpp"
00349
00350 #endif // OPM_MULTISEGMENTWELL_HEADER_INCLUDED