SimulatorUtilities.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: SimulatorUtilities.hpp
4//
5// Created: Fri Aug 28 15:00:15 2009
6//
7// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8// Bård Skaflestad <bard.skaflestad@sintef.no>
9//
10// $Date$
11//
12// $Revision$
13//
14//===========================================================================
15
16/*
17 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18 Copyright 2009, 2010 Statoil ASA.
19
20 This file is part of The Open Reservoir Simulator Project (OpenRS).
21
22 OpenRS is free software: you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation, either version 3 of the License, or
25 (at your option) any later version.
26
27 OpenRS is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifndef OPENRS_SIMULATORUTILITIES_HEADER
37#define OPENRS_SIMULATORUTILITIES_HEADER
38
39
40#include <opm/common/utility/platform_dependent/disable_warnings.h>
41
42#include <dune/common/version.hh>
43#include <dune/common/fvector.hh>
44#include <dune/grid/io/file/vtk/vtkwriter.hh>
45
46#include <opm/common/utility/platform_dependent/reenable_warnings.h>
47
48#include <opm/common/ErrorMacros.hpp>
49#include <vector>
50#include <fstream>
51#include <algorithm>
52#include <iterator>
53
54namespace Opm
55{
56
57
64 template <class GridInterface, class FlowSol>
65 void estimateCellVelocity(std::vector<typename GridInterface::Vector>& cell_velocity,
66 const GridInterface& ginterf,
67 const FlowSol& flow_solution)
68 {
69 // Algorithm used is same as in halfFaceFluxToCellVelocity.hpp
70 // in the Sintef legacy c++ code.
71 cell_velocity.clear();
72 cell_velocity.resize(ginterf.numberOfCells());
73 for (typename GridInterface::CellIterator c = ginterf.cellbegin(); c != ginterf.cellend(); ++c) {
74 int numf = 0;
75 typename GridInterface::Vector cell_v(0.0);
76 typename GridInterface::CellIterator::FaceIterator f = c->facebegin();
77 for (; f != c->faceend(); ++f, ++numf) {
78 double flux = flow_solution.outflux(f);
79 typename GridInterface::Vector v = f->centroid();
80 v -= c->centroid();
81 v *= flux/c->volume();
82 cell_v += v;
83 }
84 cell_velocity[c->index()] = cell_v;//.two_norm();
85 }
86 }
87
92 template <class GridInterface>
93 void estimateCellVelocitySimpleInterface(std::vector<typename GridInterface::Vector>& cell_velocity,
94 const GridInterface& grid,
95 const std::vector<double>& face_flux)
96 {
97 // Algorithm used is same as in halfFaceFluxToCellVelocity.hpp
98 // in the Sintef legacy c++ code.
99 typedef typename GridInterface::Vector Vec;
100 cell_velocity.clear();
101 cell_velocity.resize(grid.numCells(), Vec(0.0));
102 for (int face = 0; face < grid.numFaces(); ++face) {
103 int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) };
104 Vec fc = grid.faceCentroid(face);
105 double flux = face_flux[face];
106 for (int i = 0; i < 2; ++i) {
107 if (c[i] >= 0) {
108 Vec v_contrib = fc - grid.cellCentroid(c[i]);
109 v_contrib *= flux/grid.cellVolume(c[i]);
110 cell_velocity[c[i]] += (i == 0) ? v_contrib : -v_contrib;
111 }
112 }
113 }
114 }
115
116
125 template <class GridInterface, class FlowSol>
126 void estimateCellVelocity(std::vector<typename GridInterface::Vector>& cell_velocity,
127 const GridInterface& ginterf,
128 const FlowSol& flow_solution,
129 const std::vector<int>& partition,
130 const int my_partition)
131 {
132 // Algorithm used is same as in halfFaceFluxToCellVelocity.hpp
133 // in the Sintef legacy c++ code.
134 cell_velocity.clear();
135 cell_velocity.resize(ginterf.numberOfCells());
136 for (typename GridInterface::CellIterator c = ginterf.cellbegin(); c != ginterf.cellend(); ++c) {
137 if (partition[c->index()] != my_partition) {
138 cell_velocity[c->index()] = 0.0;
139 } else {
140 int numf = 0;
141 typename GridInterface::Vector cell_v(0.0);
142 typename GridInterface::CellIterator::FaceIterator f = c->facebegin();
143 for (; f != c->faceend(); ++f, ++numf) {
144 double flux = flow_solution.outflux(f);
145 typename GridInterface::Vector v = f->centroid();
146 v -= c->centroid();
147 v *= flux/c->volume();
148 cell_v += v;
149 }
150 cell_velocity[c->index()] = cell_v;//.two_norm();
151 }
152 }
153 }
154
155
156 template <class ReservoirProperty>
157 void computePhaseVelocities(std::vector<Dune::FieldVector<double, 3> >& phase_velocity_water,
158 std::vector<Dune::FieldVector<double, 3> >& phase_velocity_oil,
159 const ReservoirProperty& res_prop,
160 const std::vector<double>& saturation,
161 const std::vector<Dune::FieldVector<double, 3> >& cell_velocity)
162 {
163 assert(saturation.size() == cell_velocity.size());
164 int num_cells = saturation.size();
165 phase_velocity_water = cell_velocity;
166 phase_velocity_oil = cell_velocity;
167 for (int i = 0; i < num_cells; ++i) {
168 double f = res_prop.fractionalFlow(i, saturation[i]);
169 phase_velocity_water[i] *= f;
170 phase_velocity_oil[i] *= (1.0 - f);
171 }
172 }
173
174
175
176
181 template <class GridInterface, class FlowSol>
182 void getCellPressure(std::vector<double>& cell_pressure,
183 const GridInterface& ginterf,
184 const FlowSol& flow_solution)
185 {
186 cell_pressure.clear();
187 cell_pressure.resize(ginterf.numberOfCells());
188 for (typename GridInterface::CellIterator c = ginterf.cellbegin(); c != ginterf.cellend(); ++c) {
189 cell_pressure[c->index()] = flow_solution.pressure(c);
190 }
191 }
192
197 template <class GridInterface, class FlowSol>
198 void getCellPressure(std::vector<double>& cell_pressure,
199 const GridInterface& ginterf,
200 const FlowSol& flow_solution,
201 const std::vector<int>& partition,
202 const int my_partition)
203 {
204 cell_pressure.clear();
205 cell_pressure.resize(ginterf.numberOfCells());
206 for (typename GridInterface::CellIterator c = ginterf.cellbegin(); c != ginterf.cellend(); ++c) {
207 if (partition[c->index()] != my_partition) {
208 cell_pressure[c->index()] = 0.0;
209 } else {
210 cell_pressure[c->index()] = flow_solution.pressure(c);
211 }
212 }
213 }
214
215
216
222 template <class ReservoirProperties>
223 void computeCapPressure(std::vector<double>& cap_pressure,
224 const ReservoirProperties& rp,
225 const std::vector<double>& sat)
226 {
227 int num_cells = sat.size();
228 cap_pressure.resize(num_cells);
229 for (int cell = 0; cell < num_cells; ++cell) {
230 cap_pressure[cell] = rp.capillaryPressure(cell, sat[cell]);
231 }
232 }
233
234
236 template <class GridInterface, class ReservoirProperties, class FlowSol>
237 void writeVtkOutput(const GridInterface& ginterf,
238 const ReservoirProperties& rp,
239 const FlowSol& flowsol,
240 const std::vector<double>& saturation,
241 const std::string& filename)
242 {
243 // Extract data in proper format.
244 typedef typename GridInterface::Vector Vec;
245 std::vector<Vec> cell_velocity;
246 estimateCellVelocity(cell_velocity, ginterf, flowsol);
247 std::array<std::vector<Vec>, 2> phase_velocities;
248 computePhaseVelocities(phase_velocities[0], phase_velocities[1], rp, saturation, cell_velocity);
249 // Dune's vtk writer wants multi-component data to be flattened.
250 std::vector<double> cell_velocity_flat(&*cell_velocity.front().begin(),
251 &*cell_velocity.back().end());
252 std::vector<double> water_velocity_flat(&*phase_velocities[0].front().begin(),
253 &*phase_velocities[0].back().end());
254 std::vector<double> oil_velocity_flat(&*phase_velocities[1].front().begin(),
255 &*phase_velocities[1].back().end());
256 std::vector<double> cell_pressure;
257 getCellPressure(cell_pressure, ginterf, flowsol);
258 std::vector<double> cap_pressure;
259 computeCapPressure(cap_pressure, rp, saturation);
260 int num_cells = saturation.size();
261// std::array<std::vector<double>, 2> phase_mobilities_;
262// phase_mobilities_[0].resize(num_cells);
263// phase_mobilities_[1].resize(num_cells);
264 std::vector<double> fractional_flow_(num_cells);
265 for (int i = 0; i < num_cells; ++i) {
266// for (int phase = 0; phase < 2; ++phase) {
267// rp.phaseMobility(phase, i, saturation[i], phase_mobilities_[phase][i]);
268// }
269 fractional_flow_[i] = rp.fractionalFlow(i, saturation[i]);
270 }
271
272 // Write data.
273 Dune::VTKWriter<typename GridInterface::GridType::LeafGridView> vtkwriter(ginterf.grid().leafGridView());
274 vtkwriter.addCellData(saturation, "saturation");
275 vtkwriter.addCellData(cell_pressure, "pressure");
276 vtkwriter.addCellData(cap_pressure, "capillary pressure");
277 vtkwriter.addCellData(fractional_flow_, "fractional flow [water]");
278// vtkwriter.addCellData(phase_mobilities_[0], "phase mobility [water]");
279// vtkwriter.addCellData(phase_mobilities_[1], "phase mobility [oil]");
280 vtkwriter.addCellData(cell_velocity_flat, "velocity", Vec::dimension);
281 vtkwriter.addCellData(water_velocity_flat, "phase velocity [water]", Vec::dimension);
282 vtkwriter.addCellData(oil_velocity_flat, "phase velocity [oil]", Vec::dimension);
283 vtkwriter.write(filename, Dune::VTK::ascii);
284 }
285
286
287 inline void writeField(const std::vector<double>& field,
288 const std::string& filename)
289 {
290 std::ofstream os(filename.c_str());
291 if (!os) {
292 OPM_THROW(std::runtime_error, "Could not open file " + filename);
293 }
294 os << field.size() << '\n';
295 std::copy(field.begin(), field.end(), std::ostream_iterator<double>(os, "\n"));
296 }
297
298} // namespace Opm
299
300
301#endif // OPENRS_SIMULATORUTILITIES_HEADER
Dune::BlockVector< Dune::FieldVector< double, 1 > > Vector
A vector holding our RHS.
Definition: matrixops.hpp:33
Definition: ImplicitAssembly.hpp:43
void computePhaseVelocities(std::vector< Dune::FieldVector< double, 3 > > &phase_velocity_water, std::vector< Dune::FieldVector< double, 3 > > &phase_velocity_oil, const ReservoirProperty &res_prop, const std::vector< double > &saturation, const std::vector< Dune::FieldVector< double, 3 > > &cell_velocity)
Definition: SimulatorUtilities.hpp:157
void writeField(const std::vector< double > &field, const std::string &filename)
Definition: SimulatorUtilities.hpp:287
void writeVtkOutput(const GridInterface &ginterf, const ReservoirProperties &rp, const FlowSol &flowsol, const std::vector< double > &saturation, const std::string &filename)
Definition: SimulatorUtilities.hpp:237
void estimateCellVelocitySimpleInterface(std::vector< typename GridInterface::Vector > &cell_velocity, const GridInterface &grid, const std::vector< double > &face_flux)
Estimates a scalar cell velocity from face fluxes.
Definition: SimulatorUtilities.hpp:93
void computeCapPressure(std::vector< double > &cap_pressure, const ReservoirProperties &rp, const std::vector< double > &sat)
Computes the capillary pressure in each cell from the cell saturations.
Definition: SimulatorUtilities.hpp:223
void estimateCellVelocity(std::vector< typename GridInterface::Vector > &cell_velocity, const GridInterface &ginterf, const FlowSol &flow_solution)
Estimates a scalar cell velocity from outgoing fluxes.
Definition: SimulatorUtilities.hpp:65
void getCellPressure(std::vector< double > &cell_pressure, const GridInterface &ginterf, const FlowSol &flow_solution)
Definition: SimulatorUtilities.hpp:182