ComponentTransport.hpp
Go to the documentation of this file.
1/*
2 Copyright 2010 SINTEF ICT, Applied Mathematics.
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_COMPONENTTRANSPORT_HEADER_INCLUDED
21#define OPM_COMPONENTTRANSPORT_HEADER_INCLUDED
22
25#include <opm/core/utility/parameters/ParameterGroup.hpp>
26
27#include <array>
28#include <vector>
29#include <iostream>
30
31#include <stdlib.h>
32#include <float.h>
33#include <math.h>
34#include <limits.h>
35#include <assert.h>
36#include <stdio.h>
37
38namespace Opm
39{
40
41
42template <class Grid, class Rock, class Fluid, class Wells>
44{
45public:
49 : pgrid_(0), prock_(0), pfluid_(0), pwells_(0), ptrans_(0),
50 min_surfvol_threshold_(0.0),
51 single_step_only_(false),
52 min_vtime_(0.0)
53 {
54 }
55
56 void init(const Opm::parameter::ParameterGroup& param)
57 {
58 min_surfvol_threshold_ = param.getDefault("min_surfvol_threshold", min_surfvol_threshold_);
59 single_step_only_ = param.getDefault("single_step_only", single_step_only_);
60 min_vtime_ = param.getDefault("min_vtime", min_vtime_);
61 }
62
63 void setup(const Grid& grid,
64 const Rock& rock,
65 const Fluid& fluid,
66 const Wells& wells,
67 const std::vector<double>& face_trans,
68 const typename Grid::Vector& gravity)
69 {
70 pgrid_ = &grid;
71 prock_ = &rock;
72 pfluid_ = &fluid;
73 pwells_ = &wells;
74 ptrans_ = &face_trans;
75 gravity_ = gravity;
76 }
77
78
81 double transport(const PhaseVec& external_pressure,
82 const CompVec& external_composition,
83 const std::vector<double>& face_flux,
84 const std::vector<PhaseVec>& cell_pressure,
85 const std::vector<PhaseVec>& face_pressure,
86 const double dt,
87 const double voldisclimit,
88 std::vector<CompVec>& cell_z)
89 {
90 int num_cells = pgrid_->numCells();
91 std::vector<CompVec> comp_change;
92 std::vector<double> cell_outflux;
93 std::vector<double> cell_max_ff_deriv;
94 std::vector<double> cell_gravflux;
95 std::vector<double> cell_max_mob_deriv;
96 double cur_time = 0.0;
97 updateFluidProperties(cell_pressure, face_pressure, cell_z,
98 external_pressure, external_composition);
99// if (!volumeDiscrepancyAcceptable(voldisclimit)) {
100// return 0.0;
101// }
102 std::vector<CompVec> cell_z_start;
103 std::cout << "Transport solver target time: " << dt << std::endl;
104 std::cout << " Step Stepsize Remaining time\n";
105 int count = 0;
106 while (cur_time < dt) {
107 cell_z_start = cell_z;
108 computeChange(face_flux, comp_change, cell_outflux, cell_max_ff_deriv);
109 double min_time = 1e100;
110 for (int cell = 0; cell < num_cells; ++cell) {
111 double pvol = prock_->porosity(cell)*pgrid_->cellVolume(cell);
112 double vtime = pvol/(cell_outflux[cell]*cell_max_ff_deriv[cell]);
113 double gtime = 1e100; // No working CFL for gravity yet.
114 double max_nonzero_time = 1e100;
115 for (int comp = 0; comp < numComponents; ++comp) {
116 if (comp_change[cell][comp] < 0.0) {
117 if (cell_z[cell][comp] > min_surfvol_threshold_) {
118 max_nonzero_time = std::min(max_nonzero_time,
119 -cell_z[cell][comp]*pvol/comp_change[cell][comp]);
120 } else {
121 comp_change[cell][comp] = 0.0;
122 cell_z[cell][comp] = 0.0;
123 }
124 }
125 }
126 vtime = std::max(vtime,min_vtime_);
127 double time = std::min(std::min(vtime, gtime), max_nonzero_time);
128 min_time = std::min(time, min_time);
129 }
130 min_time *= 0.49; // Semi-random CFL factor... \TODO rigorize
131 double step_time = dt - cur_time;
132 if (min_time < step_time) {
133 step_time = min_time;
134 cur_time += min_time;
135 } else {
136 cur_time = dt;
137 }
138 // Check if remaining number of steps is excessive.
139 if ((dt - cur_time)/step_time > 10000) {
140 std::cout << "Collapsing transport stepsize detected." << std::endl;
141 return cur_time;
142 }
143 std::cout.precision(10);
144 std::cout << std::setw(6) << count++
145 << std::setw(24) << step_time
146 << std::setw(24) << dt - cur_time << std::endl;
147 std::cout.precision(16);
148 for (int cell = 0; cell < num_cells; ++cell) {
149 double pv = pgrid_->cellVolume(cell)*prock_->porosity(cell);
150 comp_change[cell] *= (step_time/pv);
151 cell_z[cell] += comp_change[cell];
152 }
153 // After changing z, we recompute fluid properties.
154 updateFluidProperties(cell_pressure, face_pressure, cell_z,
155 external_pressure, external_composition);
156 bool ok = volumeDiscrepancyAcceptable(voldisclimit);
157 if (!ok) {
158 // Roll back to last ok step.
159 cell_z = cell_z_start;
160 cur_time -= step_time;
161 return cur_time;
162 }
163 if (single_step_only_) {
164 return cur_time;
165 }
166 }
167 return dt;
168 }
169
170
171private: // Data
172 const Grid* pgrid_;
173 const Rock* prock_;
174 const Fluid* pfluid_;
175 const Wells* pwells_;
176 const std::vector<double>* ptrans_;
177 typename Grid::Vector gravity_;
178
179 struct AllTransportFluidData : public Opm::AllFluidData
180 {
181 std::vector<double> total_mobility;
182 std::vector<PhaseVec> fractional_flow;
183
184 template <class G, class R>
185 void computeNew(const G& grid,
186 const R& rock,
187 const BlackoilFluid& fluid,
188 const typename Grid::Vector gravity,
189 const std::vector<PhaseVec>& cell_pressure,
190 const std::vector<PhaseVec>& face_pressure,
191 const std::vector<CompVec>& cell_z,
192 const CompVec& bdy_z,
193 const double dt)
194 {
195 Opm::AllFluidData::computeNew(grid, rock, fluid, gravity,
196 cell_pressure, face_pressure,
197 cell_z, bdy_z, dt);
198 int num = grid.numCells();
199 total_mobility.resize(num);
200 fractional_flow.resize(num);
201#pragma omp parallel for
202 for (int i = 0; i < num; ++i) {
203 total_mobility[i] = 0.0;
204 for (int phase = 0; phase < numPhases; ++phase) {
205 total_mobility[i] += cell_data.mobility[i][phase];
206 }
207 fractional_flow[i] = cell_data.mobility[i];
208 fractional_flow[i] *= (1.0/total_mobility[i]);
209 }
210 }
211 };
212 AllTransportFluidData fluid_data_;
213 struct TransportFluidData
214 {
215 PhaseVec saturation;
216 PhaseVec mobility;
217 PhaseVec fractional_flow;
218 PhaseToCompMatrix phase_to_comp;
219 PhaseVec relperm;
220 PhaseVec viscosity;
221 };
222 TransportFluidData bdy_;
223 std::vector<int> perf_cells_;
224 std::vector<double> perf_flow_;
225 std::vector<TransportFluidData> perf_props_;
226 double min_surfvol_threshold_;
227 bool single_step_only_;
228 double min_vtime_;
229
230private: // Methods
231
232 TransportFluidData computeProps(const PhaseVec& pressure,
233 const CompVec& composition)
234 {
235 BlackoilFluid::FluidState state = pfluid_->computeState(pressure, composition);
236 TransportFluidData data;
237 data.saturation = state.saturation_;
238 data.mobility = state.mobility_;
239 double total_mobility = 0.0;
240 for (int phase = 0; phase < numPhases; ++phase) {
241 total_mobility += state.mobility_[phase];
242 }
243 data.fractional_flow = state.mobility_;
244 data.fractional_flow /= total_mobility;
245 data.phase_to_comp = state.phase_to_comp_;
246 data.relperm = state.relperm_;
247 data.viscosity = state.viscosity_;
248 return data;
249 }
250
251 void updateFluidProperties(const std::vector<PhaseVec>& cell_pressure,
252 const std::vector<PhaseVec>& face_pressure,
253 const std::vector<CompVec>& cell_z,
254 const PhaseVec& external_pressure,
255 const CompVec& external_composition)
256 {
257 // Properties in reservoir.
258 const double dummy_dt = 1.0;
259 fluid_data_.computeNew(*pgrid_, *prock_, *pfluid_, gravity_,
260 cell_pressure, face_pressure, cell_z, external_composition, dummy_dt);
261
262 // Properties on boundary. \TODO no need to ever recompute this.
263 bdy_ = computeProps(external_pressure, external_composition);
264
265 // Properties at well perforations.
266 // \TODO only need to recompute this once per pressure update.
267 // No, that is false, at production perforations the cell z is
268 // used, which may change every step.
269 perf_cells_.clear();
270 perf_flow_.clear();
271 perf_props_.clear();
272 Wells::WellReport::report()->clearAll();
273 int num_cells = pgrid_->numCells();
274 for (int cell = 0; cell < num_cells; ++cell) {
275 double flow = pwells_->wellToReservoirFlux(cell);
276 if (flow != 0.0) {
277 perf_cells_.push_back(cell);
278 perf_flow_.push_back(flow);
279 // \TODO handle capillary in perforation pressure below?
280 PhaseVec well_pressure = flow > 0.0 ? PhaseVec(pwells_->perforationPressure(cell)) : cell_pressure[cell];
281 CompVec well_mixture = flow > 0.0 ? pwells_->injectionMixture(cell) : cell_z[cell];
282 perf_props_.push_back(computeProps(well_pressure, well_mixture));
283 Wells::WellReport::report()->perfPressure.push_back(pwells_->perforationPressure(cell));
284 Wells::WellReport::report()->cellPressure.push_back(cell_pressure[cell][0]);
285 Wells::WellReport::report()->cellId.push_back(cell);
286 }
287 }
288 }
289
290
291
292
293 void cellData(int cell, TransportFluidData& tfd) const
294 {
295 tfd.saturation = fluid_data_.cell_data.saturation[cell];
296 tfd.mobility = fluid_data_.cell_data.mobility[cell];
297 tfd.fractional_flow = fluid_data_.fractional_flow[cell];
298 tfd.phase_to_comp = fluid_data_.cell_data.state_matrix[cell];
299 tfd.relperm = fluid_data_.cell_data.relperm[cell];
300 tfd.viscosity = fluid_data_.cell_data.viscosity[cell];
301 }
302
303
304
305
306 bool volumeDiscrepancyAcceptable(const double voldisclimit) const
307 {
308 double rel_voldiscr = *std::max_element(fluid_data_.relvoldiscr.begin(), fluid_data_.relvoldiscr.end());
309 if (rel_voldiscr > voldisclimit) {
310 std::cout << " Relative volume discrepancy too large: " << rel_voldiscr << std::endl;
311 return false;
312 } else {
313 return true;
314 }
315 }
316
317
318
319 void computeChange(const std::vector<double>& face_flux,
320 std::vector<CompVec>& comp_change,
321 std::vector<double>& cell_outflux,
322 std::vector<double>& cell_max_ff_deriv)
323 {
324 const int num_cells = pgrid_->numCells();
325 comp_change.clear();
326 CompVec zero(0.0);
327 comp_change.resize(num_cells, zero);
328 cell_outflux.clear();
329 cell_outflux.resize(num_cells, 0.0);
330 cell_max_ff_deriv.clear();
331 cell_max_ff_deriv.resize(num_cells, 0.0);
332 CompVec surf_dens = pfluid_->surfaceDensities();
333 const int num_faces = pgrid_->numFaces();
334 std::vector<CompVec> face_change(num_faces);
335 std::vector<double> faces_max_ff_deriv(num_faces);
336#pragma omp parallel for
337 for (int face = 0; face < num_faces; ++face) {
338 // Compute phase densities on face.
339 PhaseVec phase_dens(0.0);
340 for (int phase = 0; phase < numPhases; ++phase) {
341 const double* At = &fluid_data_.face_data.state_matrix[face][0][0]; // Already transposed since in Fortran order...
342 for (int comp = 0; comp < numPhases; ++comp) {
343 phase_dens[phase] += At[numPhases*phase + comp]*surf_dens[comp];
344 }
345 }
346 // Collect data from adjacent cells (or boundary).
347 int c[2];
348 TransportFluidData d[2];
349 for (int ix = 0; ix < 2; ++ix) {
350 c[ix] = pgrid_->faceCell(face, ix);
351 if (c[ix] >= 0) {
352 cellData(c[ix], d[ix]);
353 } else {
354 d[ix] = bdy_;
355 }
356 }
357 // Compute upwind directions.
358 int upwind_dir[numPhases] = { 0, 0, 0 };
359 PhaseVec vstar(face_flux[face]);
360 // double gravity_flux = gravity_*pgrid_->faceNormal(face)*pgrid_->faceArea(face);
361
362 typename Grid::Vector centroid_diff = c[0] >= 0 ? pgrid_->cellCentroid(c[0]) : pgrid_->faceCentroid(face);
363 centroid_diff -= c[1] >= 0 ? pgrid_->cellCentroid(c[1]) : pgrid_->faceCentroid(face);
364 double gravity_flux = gravity_*centroid_diff*ptrans_->operator[](face);
365 PhaseVec rho_star(phase_dens);
366 process_face(&(d[0].mobility[0]), &(d[1].mobility[0]),
367 &vstar[0], gravity_flux, numPhases, &rho_star[0], upwind_dir);
368
369 // Compute phase fluxes.
370 PhaseVec phase_mob;
371 double tot_mob = 0.0;
372 for (int phase = 0; phase < numPhases; ++phase) {
373 phase_mob[phase] = d[upwind_dir[phase] - 1].mobility[phase];
374 tot_mob += phase_mob[phase];
375 }
376 PhaseVec ff = phase_mob;
377 ff /= tot_mob;
378 PhaseVec phase_flux = ff;
379 phase_flux *= face_flux[face];
380 // Until we have proper bcs for transport, assume no gravity flow across bdys.
381 if (gravity_flux != 0.0 && c[0] >= 0 && c[1] >= 0) {
382 // Gravity contribution.
383 double omega = ff*phase_dens;
384 for (int phase = 0; phase < numPhases; ++phase) {
385 double gf = (phase_dens[phase] - omega)*gravity_flux;
386 phase_flux[phase] -= phase_mob[phase]*gf;
387 }
388 }
389
390 // Estimate max derivative of ff.
391 double face_max_ff_deriv = 0.0;
392 // Only using total flux upwinding for this purpose.
393 // Aim is to reproduce old results first. \TODO fix, include gravity.
394 int downwind_cell = c[upwind_dir[0]%2]; // Keep in mind that upwind_dir[] \in {1, 2}
395 if (downwind_cell >= 0) { // Only contribution on inflow and internal faces.
396 // Evaluating all functions at upwind viscosity.
397 // Added for this version.
398 PhaseVec upwind_viscosity = d[upwind_dir[0] - 1].viscosity;
399 PhaseVec upwind_sat = d[upwind_dir[0] - 1].saturation;
400 PhaseVec upwind_relperm = d[upwind_dir[0] - 1].relperm;
401 PhaseVec downwind_mob(0.0);
402 PhaseVec upwind_mob(0.0);
403 double downwind_totmob = 0.0;
404 double upwind_totmob = 0.0;
405 for (int phase = 0; phase < numPhases; ++phase) {
406 downwind_mob[phase] = fluid_data_.cell_data.relperm[downwind_cell][phase]/upwind_viscosity[phase];
407 downwind_totmob += downwind_mob[phase];
408 upwind_mob[phase] = upwind_relperm[phase]/upwind_viscosity[phase];
409 upwind_totmob += upwind_mob[phase];
410 }
411 PhaseVec downwind_ff = downwind_mob;
412 downwind_ff /= downwind_totmob;
413 PhaseVec upwind_ff = upwind_mob;
414 upwind_ff /= upwind_totmob;
415 PhaseVec ff_diff = upwind_ff;
416 ff_diff -= downwind_ff;
417 for (int phase = 0; phase < numPhases; ++phase) {
418 if (std::fabs(ff_diff[phase]) > 1e-10) {
419 if (face_flux[face] != 0.0) {
420 double ff_deriv = ff_diff[phase]/(upwind_sat[phase] - fluid_data_.cell_data.saturation[downwind_cell][phase]);
421 // assert(ff_deriv >= 0.0);
422 face_max_ff_deriv = std::max(face_max_ff_deriv, std::fabs(ff_deriv));
423 }
424 }
425 }
426 }
427 faces_max_ff_deriv[face] = face_max_ff_deriv;
428
429 // Compute z change.
430 CompVec change(0.0);
431 for (int phase = 0; phase < numPhases; ++phase) {
432 int upwind_ix = upwind_dir[phase] - 1; // Since process_face returns 1 or 2.
433 CompVec z_in_phase = d[upwind_ix].phase_to_comp[phase];
434 z_in_phase *= phase_flux[phase];
435 change += z_in_phase;
436 }
437 face_change[face] = change;
438 }
439
440 // Update output variables
441#pragma omp parallel for
442 for (int cell = 0; cell < num_cells; ++cell) {
443 const int num_local_faces = pgrid_->numCellFaces(cell);
444 for (int local = 0; local < num_local_faces; ++local) {
445 int face = pgrid_->cellFace(cell,local);
446 if (cell == pgrid_->faceCell(face, 0)) {
447 comp_change[cell] -= face_change[face];
448 if (face_flux[face] >= 0.0) {
449 cell_outflux[cell] += std::fabs(face_flux[face]);
450 }
451 } else if (cell == pgrid_->faceCell(face, 1)) {
452 comp_change[cell] += face_change[face];
453 if (face_flux[face] < 0.0) {
454 cell_outflux[cell] += std::fabs(face_flux[face]);
455 }
456 }
457 cell_max_ff_deriv[cell] = std::max(cell_max_ff_deriv[cell],
458 faces_max_ff_deriv[face]);
459 }
460 }
461
462 // Done with all faces, now deal with well perforations.
463 int num_perf = perf_cells_.size();
464 for (int perf = 0; perf < num_perf; ++perf) {
465 int cell = perf_cells_[perf];
466 double flow = perf_flow_[perf];
467 assert(flow != 0.0);
468 const TransportFluidData& fl = perf_props_[perf];
469 // For injection, phase volumes depend on fractional
470 // flow of injection perforation, for production we
471 // use the fractional flow of the producing cell.
472 PhaseVec phase_flux = flow > 0.0 ? fl.fractional_flow : fluid_data_.fractional_flow[cell];
473 phase_flux *= flow;
474 // Conversion to mass flux is given at perforation state
475 // if injector, cell state if producer (this is ensured by
476 // updateFluidProperties()).
477 CompVec change(0.0);
478 for (int phase = 0; phase < numPhases; ++phase) {
479 CompVec z_in_phase = fl.phase_to_comp[phase];
480 z_in_phase *= phase_flux[phase];
481 change += z_in_phase;
482 }
483 comp_change[cell] += change;
484 Wells::WellReport::report()->massRate.push_back(change);
485 }
486 }
487
488
489 // Arguments are:
490 // [in] cmob1, cmob2: cell mobilities for adjacent cells
491 // [in, destroyed] vstar: total velocity (equal for all phases) on input, modified on output
492 // [in] gf: gravity flux
493 // [in] np: number of phases
494 // [in, destroyed] rho: density on face
495 // [out] ix: upwind cells for each phase (1 or 2)
496 static void
497 process_face(double *cmob1, double *cmob2, double *vstar, double gf,
498 int np, double *rho, int *ix)
499 {
500 int i,j,k,a,b,c;
501 double v, r, m;
502 for (i=0; i<np; ++i) {
503
504 /* ============= */
505 /* same sign */
506
507 /* r = max(rho)*/
508 j = 0; r = DBL_MIN;
509 for(k=0; k<np; ++k) { if (rho[k] > r) { r = rho[k]; j = k; } }
510 a = !(vstar[j]<0) && !(gf<0);
511 b = !(vstar[j]>0) && !(gf>0);
512 c = a || b;
513
514 if ( !c ) {
515 rho[j] = NAN;
516 v = vstar[j] - gf;
517 if (v < 0) { ix[j] = 2; m = cmob2[j]; }
518 else { ix[j] = 1; m = cmob1[j]; }
519 for (k=0; k<np; ++k) { vstar[k] -= m *(rho[k]-r)*gf;}
520 continue;
521 }
522
523
524 /* ============= */
525 /* opposite sign */
526
527 /* r = min(rho)*/
528 j = 0; r = DBL_MAX;
529 for(k=0; k<np; ++k) { if (rho[k] < r) { r = rho[k]; j = k; } }
530
531 if ( c ) {
532 rho[j] = NAN;
533 v = vstar[j] + gf;
534 if (v < 0) { ix[j] = 2; m = cmob2[j]; }
535 else { ix[j] = 1; m = cmob1[j]; }
536 for (k=0; k<np; ++k) { vstar[k] -= m *(rho[k]-r)*gf;}
537 continue;
538 }
539 }
540 }
541
542
543
544
545 static void
546 phase_upwind_directions(int number_of_faces, int *face_cells, double *dflux, double *gflux, int np,
547 double *cmobility, double *fdensity, int *ix)
548 {
549 int k,f;
550 int c1, c2;
551 double *cmob1, *cmob2;
552 double *fden = (double*)malloc(np * sizeof *fden);
553 double *vstar = (double*)malloc(np * sizeof *vstar);
554 double gf;
555
556 for (f=0; f<number_of_faces; ++f) {
557 gf = gflux[f];
558
559 for (k=0; k<np; ++k) {
560 vstar[k] = dflux[f];
561 fden [k] = fdensity[np*f+k];
562 }
563 c1 = face_cells[2*f + 0];
564 c2 = face_cells[2*f + 1];
565 if (c1 != -1) {cmob1 = cmobility+np*c1;}
566 else {cmob1 = cmobility+np*c2;}
567 if (c2 != -1) {cmob2 = cmobility+np*c2;}
568 else {cmob2 = cmobility+np*c1;}
569 process_face(cmob1, cmob2, vstar, gf, np, fden, ix+np*f);
570
571 }
572 free(fden);
573 free(vstar);
574 }
575
576};
577
578
579} // namespace Opm
580
581
582#endif // OPM_COMPONENTTRANSPORT_HEADER_INCLUDED
Definition: BlackoilDefs.hpp:31
Dune::FieldVector< Scalar, numComponents > CompVec
Definition: BlackoilDefs.hpp:40
Dune::FieldVector< Scalar, numPhases > PhaseVec
Definition: BlackoilDefs.hpp:41
Dune::FieldMatrix< Scalar, numComponents, numPhases > PhaseToCompMatrix
Definition: BlackoilDefs.hpp:43
@ numComponents
Definition: BlackoilDefs.hpp:33
@ numPhases
Definition: BlackoilDefs.hpp:34
Definition: BlackoilFluid.hpp:42
FluidStateBlackoil FluidState
Definition: BlackoilFluid.hpp:44
Definition: ComponentTransport.hpp:44
ExplicitCompositionalTransport()
Default constructor. Does nothing.
Definition: ComponentTransport.hpp:48
void init(const Opm::parameter::ParameterGroup &param)
Definition: ComponentTransport.hpp:56
void setup(const Grid &grid, const Rock &rock, const Fluid &fluid, const Wells &wells, const std::vector< double > &face_trans, const typename Grid::Vector &gravity)
Definition: ComponentTransport.hpp:63
double transport(const PhaseVec &external_pressure, const CompVec &external_composition, const std::vector< double > &face_flux, const std::vector< PhaseVec > &cell_pressure, const std::vector< PhaseVec > &face_pressure, const double dt, const double voldisclimit, std::vector< CompVec > &cell_z)
Definition: ComponentTransport.hpp:81
A property class for porous media rock.
Definition: ImplicitTransportDefs.hpp:80
double porosity(int cell_index) const
Read-access to porosity.
Definition: Rock_impl.hpp:76
Definition: Wells.hpp:38
Dune::FieldVector< double, 3 > injectionMixture(int cell) const
Definition: Wells.hpp:141
double perforationPressure(int cell) const
Definition: Wells.hpp:130
double wellToReservoirFlux(int cell) const
Definition: Wells.hpp:136
Definition: BlackoilFluid.hpp:32
void zero(Matrix &A)
Zero-fill a.
Definition: Matrix.hpp:603
Definition: BlackoilFluid.hpp:406
void computeNew(const Grid &grid, const Rock &rock, const BlackoilFluid &fluid, const typename Grid::Vector gravity, const std::vector< PhaseVec > &cell_pressure, const std::vector< PhaseVec > &face_pressure, const std::vector< CompVec > &cell_z, const CompVec &bdy_z, const double dt)
Definition: BlackoilFluid.hpp:417
std::vector< PhaseVec > mobility
Definition: FluidStateBlackoil.hpp:84
PhaseVec saturation_
Definition: FluidStateBlackoil.hpp:42