Merge pull request #10 from atgeirr/master

Improvements in grid creation and compressible solvers.
This commit is contained in:
Bård Skaflestad 2012-08-10 01:34:44 -07:00
commit 3d45ca3512
19 changed files with 472 additions and 367 deletions

View File

@ -81,9 +81,7 @@ main(int argc, char** argv)
// Grid init
grid.reset(new GridManager(*deck));
// Rock and fluid init
const int* gc = grid->c_grid()->global_cell;
std::vector<int> global_cell(gc, gc + grid->c_grid()->number_of_cells);
props.reset(new IncompPropertiesFromDeck(*deck, global_cell));
props.reset(new IncompPropertiesFromDeck(*deck, *grid->c_grid()));
// check_well_controls = param.getDefault("check_well_controls", false);
// max_well_control_iterations = param.getDefault("max_well_control_iterations", 10);
// Rock compressibility.

View File

@ -178,9 +178,7 @@ main(int argc, char** argv)
// Grid init
grid.reset(new Opm::GridManager(deck));
// Rock and fluid init
const int* gc = grid->c_grid()->global_cell;
std::vector<int> global_cell(gc, gc + grid->c_grid()->number_of_cells);
props.reset(new Opm::BlackoilPropertiesFromDeck(deck, global_cell));
props.reset(new Opm::BlackoilPropertiesFromDeck(deck, *grid->c_grid()));
// Wells init.
wells.reset(new Opm::WellsManager(deck, *grid->c_grid(), props->permeability()));
check_well_controls = param.getDefault("check_well_controls", false);
@ -423,8 +421,10 @@ main(int argc, char** argv)
std::cout << "Making " << num_transport_substeps << " transport substeps." << std::endl;
}
for (int tr_substep = 0; tr_substep < num_transport_substeps; ++tr_substep) {
// Note that for now we do not handle rock compressibility,
// although the transport solver should be able to.
reorder_model.solve(&state.faceflux()[0], &state.pressure()[0], &state.surfacevol()[0],
&porevol[0], &reorder_src[0], stepsize, state.saturation());
&porevol[0], &porevol[0], &reorder_src[0], stepsize, state.saturation());
// Opm::computeInjectedProduced(*props, state.saturation(), reorder_src, stepsize, injected, produced);
if (use_segregation_split) {
THROW("Segregation not implemented yet.");

View File

@ -309,9 +309,7 @@ main(int argc, char** argv)
// Grid init
grid.reset(new Opm::GridManager(deck));
// Rock and fluid init
const int* gc = grid->c_grid()->global_cell;
std::vector<int> global_cell(gc, gc + grid->c_grid()->number_of_cells);
props.reset(new Opm::IncompPropertiesFromDeck(deck, global_cell));
props.reset(new Opm::IncompPropertiesFromDeck(deck, *grid->c_grid()));
// Wells init.
wells.reset(new Opm::WellsManager(deck, *grid->c_grid(), props->permeability()));
check_well_controls = param.getDefault("check_well_controls", false);

View File

@ -38,10 +38,8 @@ int main(int argc, char** argv)
// Finally handle the wells
WellsManager wells(parser, *grid.c_grid(), NULL);
std::vector<int> global_cells(grid.c_grid()->global_cell, grid.c_grid()->global_cell + grid.c_grid()->number_of_cells);
double gravity[3] = {0.0, 0.0, parameters.getDefault<double>("gravity", 0.0)};
IncompPropertiesFromDeck incomp_properties(parser, global_cells);
IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid());
RockCompressibility rock_comp(parser);

View File

@ -22,6 +22,8 @@
#include <opm/core/grid.h>
#include <opm/core/grid/cart_grid.h>
#include <opm/core/grid/cornerpoint_grid.h>
#include <algorithm>
#include <numeric>
@ -33,35 +35,24 @@ namespace Opm
/// Construct a 3d corner-point grid from a deck.
GridManager::GridManager(const Opm::EclipseGridParser& deck)
{
// Extract data from deck.
const std::vector<double>& zcorn = deck.getFloatingPointValue("ZCORN");
const std::vector<double>& coord = deck.getFloatingPointValue("COORD");
const int* actnum = 0;
if (deck.hasField("ACTNUM")) {
actnum = &(deck.getIntegerValue("ACTNUM")[0]);
}
std::vector<int> dims;
if (deck.hasField("DIMENS")) {
dims = deck.getIntegerValue("DIMENS");
} else if (deck.hasField("SPECGRID")) {
dims = deck.getSPECGRID().dimensions;
// We accept two different ways to specify the grid.
// 1. Corner point format.
// Requires ZCORN, COORDS, DIMENS or SPECGRID, optionally ACTNUM.
// For this format, we will verify that DXV, DYV, DZV,
// DEPTHZ and TOPS are not present.
// 2. Tensor grid format.
// Requires DXV, DYV, DZV, optionally DEPTHZ or TOPS.
// For this format, we will verify that ZCORN, COORDS
// and ACTNUM are not present.
// Note that for TOPS, we only allow a uniform vector of values.
if (deck.hasField("ZCORN") && deck.hasField("COORD")) {
initFromDeckCornerpoint(deck);
} else if (deck.hasField("DXV") && deck.hasField("DYV") && deck.hasField("DZV")) {
initFromDeckTensorgrid(deck);
} else {
THROW("Deck must have either DIMENS or SPECGRID.");
}
// Collect in input struct for preprocessing.
struct grdecl grdecl;
grdecl.zcorn = &zcorn[0];
grdecl.coord = &coord[0];
grdecl.actnum = actnum;
grdecl.dims[0] = dims[0];
grdecl.dims[1] = dims[1];
grdecl.dims[2] = dims[2];
// Process grid.
ug_ = create_grid_cornerpoint(&grdecl, 0.0);
if (!ug_) {
THROW("Failed to construct grid.");
THROW("Could not initialize grid from deck. "
"Need either ZCORN + COORD or DXV + DYV + DZV keywords.");
}
}
@ -124,5 +115,94 @@ namespace Opm
// Construct corner-point grid from deck.
void GridManager::initFromDeckCornerpoint(const Opm::EclipseGridParser& deck)
{
// Extract data from deck.
const std::vector<double>& zcorn = deck.getFloatingPointValue("ZCORN");
const std::vector<double>& coord = deck.getFloatingPointValue("COORD");
const int* actnum = 0;
if (deck.hasField("ACTNUM")) {
actnum = &(deck.getIntegerValue("ACTNUM")[0]);
}
std::vector<int> dims;
if (deck.hasField("DIMENS")) {
dims = deck.getIntegerValue("DIMENS");
} else if (deck.hasField("SPECGRID")) {
dims = deck.getSPECGRID().dimensions;
} else {
THROW("Deck must have either DIMENS or SPECGRID.");
}
// Collect in input struct for preprocessing.
struct grdecl grdecl;
grdecl.zcorn = &zcorn[0];
grdecl.coord = &coord[0];
grdecl.actnum = actnum;
grdecl.dims[0] = dims[0];
grdecl.dims[1] = dims[1];
grdecl.dims[2] = dims[2];
// Process grid.
ug_ = create_grid_cornerpoint(&grdecl, 0.0);
if (!ug_) {
THROW("Failed to construct grid.");
}
}
namespace
{
std::vector<double> coordsFromDeltas(const std::vector<double>& deltas)
{
std::vector<double> coords(deltas.size() + 1);
coords[0] = 0.0;
std::partial_sum(deltas.begin(), deltas.end(), coords.begin() + 1);
return coords;
}
} // anonymous namespace
// Construct tensor grid from deck.
void GridManager::initFromDeckTensorgrid(const Opm::EclipseGridParser& deck)
{
// Extract coordinates (or offsets from top, in case of z).
const std::vector<double>& dxv = deck.getFloatingPointValue("DXV");
const std::vector<double>& dyv = deck.getFloatingPointValue("DYV");
const std::vector<double>& dzv = deck.getFloatingPointValue("DZV");
std::vector<double> x = coordsFromDeltas(dxv);
std::vector<double> y = coordsFromDeltas(dyv);
std::vector<double> z = coordsFromDeltas(dzv);
// Extract top corner depths, if available.
const double* top_depths = 0;
std::vector<double> top_depths_vec;
if (deck.hasField("DEPTHZ")) {
const std::vector<double>& depthz = deck.getFloatingPointValue("DEPTHZ");
if (depthz.size() != x.size()*y.size()) {
THROW("Incorrect size of DEPTHZ: " << depthz.size());
}
top_depths = &depthz[0];
} else if (deck.hasField("TOPS")) {
// We only support constant values for TOPS.
// It is not 100% clear how we best can deal with
// varying TOPS (stair-stepping grid, or not).
const std::vector<double>& tops = deck.getFloatingPointValue("TOPS");
if (std::count(tops.begin(), tops.end(), tops[0]) != int(tops.size())) {
THROW("We do not support nonuniform TOPS, please use ZCORN/COORDS instead.");
}
top_depths_vec.resize(x.size()*y.size(), tops[0]);
top_depths = &top_depths_vec[0];
}
// Construct grid.
ug_ = create_grid_tensor3d(dxv.size(), dyv.size(), dzv.size(),
&x[0], &y[0], &z[0], top_depths);
if (!ug_) {
THROW("Failed to construct grid.");
}
}
} // namespace Opm

View File

@ -33,13 +33,14 @@ namespace Opm
/// encapsulates creation and destruction of the grid.
/// The following grid types can be constructed:
/// - 3d corner-point grids (from deck input)
/// - 3d tensor grids (from deck input)
/// - 2d cartesian grids
/// - 3d cartesian grids
/// The resulting UnstructuredGrid is available through the c_grid() method.
class GridManager
{
public:
/// Construct a 3d corner-point grid from a deck.
/// Construct a 3d corner-point grid or tensor grid from a deck.
GridManager(const Opm::EclipseGridParser& deck);
/// Construct a 2d cartesian grid with cells of unit size.
@ -64,6 +65,12 @@ namespace Opm
// Disable copying and assignment.
GridManager(const GridManager& other);
GridManager& operator=(const GridManager& other);
// Construct corner-point grid from deck.
void initFromDeckCornerpoint(const Opm::EclipseGridParser& deck);
// Construct tensor grid from deck.
void initFromDeckTensorgrid(const Opm::EclipseGridParser& deck);
// The managed UnstructuredGrid.
UnstructuredGrid* ug_;
};

View File

@ -86,7 +86,7 @@ namespace EclipseKeywords
string("MULTPV"), string("PRESSURE"), string("SGAS"),
string("SWAT"), string("SOIL"), string("RS"),
string("DXV"), string("DYV"), string("DZV"),
string("DEPTHZ")
string("DEPTHZ"), string("TOPS")
};
const int num_floating_fields = sizeof(floating_fields) / sizeof(floating_fields[0]);
@ -527,7 +527,7 @@ void EclipseGridParser::convertToSI()
bool do_convert = true;
if (key == "COORD" || key == "ZCORN" ||
key == "DXV" || key == "DYV" || key == "DZV" ||
key == "DEPTHZ") {
key == "DEPTHZ" || key == "TOPS") {
unit = units_.length;
} else if (key == "PERMX" || key == "PERMY" || key == "PERMZ" ||
key == "PERMXX" || key == "PERMYY" || key == "PERMZZ" ||

View File

@ -23,11 +23,11 @@ namespace Opm
{
BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck(const EclipseGridParser& deck,
const std::vector<int>& global_cell)
const UnstructuredGrid& grid)
{
rock_.init(deck, global_cell);
rock_.init(deck, grid);
pvt_.init(deck);
satprops_.init(deck, global_cell);
satprops_.init(deck, grid);
if (pvt_.numPhases() != satprops_.numPhases()) {
THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data ("
<< pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ").");

View File

@ -27,6 +27,8 @@
#include <opm/core/fluid/SaturationPropsFromDeck.hpp>
#include <opm/core/eclipse/EclipseGridParser.hpp>
struct UnstructuredGrid;
namespace Opm
{
@ -35,12 +37,13 @@ namespace Opm
class BlackoilPropertiesFromDeck : public BlackoilPropertiesInterface
{
public:
/// Construct from deck and cell mapping.
/// \param deck eclipse input parser
/// \param global_cell mapping from cell indices (typically from a processed grid)
/// Initialize from deck and grid.
/// \param deck Deck input parser
/// \param grid Grid to which property object applies, needed for the
/// mapping from cell indices (typically from a processed grid)
/// to logical cartesian indices consistent with the deck.
BlackoilPropertiesFromDeck(const EclipseGridParser& deck,
const std::vector<int>& global_cell);
const UnstructuredGrid& grid);
/// Destructor.
virtual ~BlackoilPropertiesFromDeck();

View File

@ -27,11 +27,11 @@ namespace Opm
{
IncompPropertiesFromDeck::IncompPropertiesFromDeck(const EclipseGridParser& deck,
const std::vector<int>& global_cell)
const UnstructuredGrid& grid)
{
rock_.init(deck, global_cell);
rock_.init(deck, grid);
pvt_.init(deck);
satprops_.init(deck, global_cell);
satprops_.init(deck, grid);
if (pvt_.numPhases() != satprops_.numPhases()) {
THROW("IncompPropertiesFromDeck::IncompPropertiesFromDeck() - Inconsistent number of phases in pvt data ("
<< pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ").");

View File

@ -26,6 +26,8 @@
#include <opm/core/fluid/SaturationPropsFromDeck.hpp>
#include <opm/core/eclipse/EclipseGridParser.hpp>
struct UnstructuredGrid;
namespace Opm
{
@ -43,12 +45,13 @@ namespace Opm
class IncompPropertiesFromDeck : public IncompPropertiesInterface
{
public:
/// Construct from deck and cell mapping.
/// \param deck eclipse input parser
/// \param global_cell mapping from cell indices (typically from a processed grid)
/// Initialize from deck and grid.
/// \param deck Deck input parser
/// \param grid Grid to which property object applies, needed for the
/// mapping from cell indices (typically from a processed grid)
/// to logical cartesian indices consistent with the deck.
IncompPropertiesFromDeck(const EclipseGridParser& deck,
const std::vector<int>& global_cell);
const UnstructuredGrid& grid);
/// Destructor.
virtual ~IncompPropertiesFromDeck();

View File

@ -19,7 +19,7 @@
#include <opm/core/fluid/RockFromDeck.hpp>
#include <opm/core/grid.h>
#include <tr1/array>
namespace Opm
@ -53,28 +53,29 @@ namespace Opm
/// Initialize from deck and cell mapping.
/// \param deck Deck input parser
/// \param global_cell mapping from cell indices (typically from a processed grid)
/// \param grid grid to which property object applies, needed for the
/// mapping from cell indices (typically from a processed grid)
/// to logical cartesian indices consistent with the deck.
void RockFromDeck::init(const EclipseGridParser& deck,
const std::vector<int>& global_cell)
const UnstructuredGrid& grid)
{
assignPorosity(deck, global_cell);
permfield_valid_.assign(global_cell.size(), false);
assignPorosity(deck, grid);
permfield_valid_.assign(grid.number_of_cells, false);
const double perm_threshold = 0.0; // Maybe turn into parameter?
assignPermeability(deck, global_cell, perm_threshold);
assignPermeability(deck, grid, perm_threshold);
}
void RockFromDeck::assignPorosity(const EclipseGridParser& parser,
const std::vector<int>& global_cell)
const UnstructuredGrid& grid)
{
porosity_.assign(global_cell.size(), 1.0);
porosity_.assign(grid.number_of_cells, 1.0);
const int* gc = grid.global_cell;
if (parser.hasField("PORO")) {
const std::vector<double>& poro = parser.getFloatingPointValue("PORO");
for (int c = 0; c < int(porosity_.size()); ++c) {
porosity_[c] = poro[global_cell[c]];
const int deck_pos = (gc == NULL) ? c : gc[c];
porosity_[c] = poro[deck_pos];
}
}
}
@ -82,14 +83,16 @@ namespace Opm
void RockFromDeck::assignPermeability(const EclipseGridParser& parser,
const std::vector<int>& global_cell,
const UnstructuredGrid& grid,
double perm_threshold)
{
const int dim = 3;
const int num_global_cells = numGlobalCells(parser);
const int nc = grid.number_of_cells;
ASSERT (num_global_cells > 0);
permeability_.assign(dim * dim * global_cell.size(), 0.0);
permeability_.assign(dim * dim * nc, 0.0);
std::vector<const std::vector<double>*> tensor;
tensor.reserve(10);
@ -111,13 +114,13 @@ namespace Opm
// chosen) default value...
//
if (tensor.size() > 1) {
const int nc = global_cell.size();
const int* gc = grid.global_cell;
int off = 0;
for (int c = 0; c < nc; ++c, off += dim*dim) {
// SharedPermTensor K(dim, dim, &permeability_[off]);
int kix = 0;
const int glob = global_cell[c];
const int glob = (gc == NULL) ? c : gc[c];
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j, ++kix) {

View File

@ -24,6 +24,7 @@
#include <opm/core/eclipse/EclipseGridParser.hpp>
#include <vector>
struct UnstructuredGrid;
namespace Opm
{
@ -34,12 +35,13 @@ namespace Opm
/// Default constructor.
RockFromDeck();
/// Initialize from deck and cell mapping.
/// Initialize from deck and grid.
/// \param deck Deck input parser
/// \param global_cell mapping from cell indices (typically from a processed grid)
/// \param grid Grid to which property object applies, needed for the
/// mapping from cell indices (typically from a processed grid)
/// to logical cartesian indices consistent with the deck.
void init(const EclipseGridParser& deck,
const std::vector<int>& global_cell);
const UnstructuredGrid& grid);
/// \return D, the number of spatial dimensions. Always 3 for deck input.
int numDimensions() const
@ -69,9 +71,9 @@ namespace Opm
private:
void assignPorosity(const EclipseGridParser& parser,
const std::vector<int>& global_cell);
const UnstructuredGrid& grid);
void assignPermeability(const EclipseGridParser& parser,
const std::vector<int>& global_cell,
const UnstructuredGrid& grid,
const double perm_threshold);
std::vector<double> porosity_;

View File

@ -18,6 +18,7 @@
*/
#include <opm/core/fluid/SaturationPropsFromDeck.hpp>
#include <opm/core/grid.h>
#include <opm/core/fluid/blackoil/phaseUsageFromDeck.hpp>
#include <opm/core/utility/buildUniformMonotoneTable.hpp>
#include <opm/core/utility/ErrorMacros.hpp>
@ -33,7 +34,7 @@ namespace Opm
/// Initialize from deck.
void SaturationPropsFromDeck::init(const EclipseGridParser& deck,
const std::vector<int>& global_cell)
const UnstructuredGrid& grid)
{
phase_usage_ = phaseUsageFromDeck(deck);
@ -49,10 +50,12 @@ namespace Opm
if (deck.hasField("SATNUM")) {
const std::vector<int>& satnum = deck.getIntegerValue("SATNUM");
satfuncs_expected = *std::max_element(satnum.begin(), satnum.end());
int num_cells = global_cell.size();
const int num_cells = grid.number_of_cells;
cell_to_func_.resize(num_cells);
const int* gc = grid.global_cell;
for (int cell = 0; cell < num_cells; ++cell) {
cell_to_func_[cell] = satnum[global_cell[cell]] - 1;
const int deck_pos = (gc == NULL) ? cell : gc[cell];
cell_to_func_[cell] = satnum[deck_pos] - 1;
}
}

View File

@ -25,6 +25,8 @@
#include <opm/core/fluid/blackoil/BlackoilPhases.hpp>
#include <vector>
struct UnstructuredGrid;
namespace Opm
{
@ -34,10 +36,13 @@ namespace Opm
/// Default constructor.
SaturationPropsFromDeck();
/// Initialize from deck.
/// global_cell maps from grid cells to their original logical Cartesian indices.
/// Initialize from deck and grid.
/// \param deck Deck input parser
/// \param grid Grid to which property object applies, needed for the
/// mapping from cell indices (typically from a processed grid)
/// to logical cartesian indices consistent with the deck.
void init(const EclipseGridParser& deck,
const std::vector<int>& global_cell);
const UnstructuredGrid& grid);
/// \return P, the number of phases.
int numPhases() const;

View File

@ -341,7 +341,7 @@ namespace Opm
const double depth_diff = face_depth - grid_.cell_centroids[c[j]*dim + dim - 1];
props_.density(1, &cell_A_[np*np*c[j]], &gravcontrib[j][0]);
for (int p = 0; p < np; ++p) {
gravcontrib[j][p] *= depth_diff;
gravcontrib[j][p] *= depth_diff*grav;
}
} else {
std::fill(gravcontrib[j].begin(), gravcontrib[j].end(), 0.0);

View File

@ -76,6 +76,7 @@ namespace Opm
void TransportModelCompressibleTwophase::solve(const double* darcyflux,
const double* pressure,
const double* surfacevol0,
const double* porevolume0,
const double* porevolume,
const double* source,
const double dt,
@ -83,6 +84,7 @@ namespace Opm
{
darcyflux_ = darcyflux;
surfacevol0_ = surfacevol0;
porevolume0_ = porevolume0;
porevolume_ = porevolume;
source_ = source;
dt_ = dt;
@ -116,32 +118,33 @@ namespace Opm
// @@@ What about the source term
//
// where influx is water influx, outflux is total outflux.
// We need the formula influx = B_i sum_{j->i} b_j v_{ij} + q_w.
// outflux = B_i sum_{i->j} b_i v_{ij} - q = sum_{i->j} v_{ij} - q (as before)
// We need the formula influx = B_i sum_{j->i} b_j v_{ij} - B_i q_w.
// outflux = B_i sum_{i->j} b_i v_{ij} - B_i q = sum_{i->j} v_{ij} - B_i q
// Influxes are negative, outfluxes positive.
struct TransportModelCompressibleTwophase::Residual
{
int cell;
double s0;
double influx; // sum_j min(v_ij, 0)*f(s_j) + q_w // TODO: fix comment.
double outflux; // sum_j max(v_ij, 0) - q
double B_cell;
double z0;
double influx; // B_i sum_j b_j min(v_ij, 0)*f(s_j) - B_i q_w
double outflux; // sum_j max(v_ij, 0) - B_i q
// @@@ TODO: figure out change to rock-comp. terms with fluid compr.
// double comp_term; // q - sum_j v_ij
double comp_term; // Now: used to be: q - sum_j v_ij
double dtpv; // dt/pv(i)
const TransportModelCompressibleTwophase& tm;
explicit Residual(const TransportModelCompressibleTwophase& tmodel, int cell_index)
: tm(tmodel)
{
cell = cell_index;
s0 = tm.saturation_[cell];
const int np = tm.props_.numPhases();
const double B_cell = 1.0/tm.A_[np*np*cell + 0];
z0 = tm.surfacevol0_[np*cell + 0]; // I.e. water surface volume
B_cell = 1.0/tm.A_[np*np*cell + 0];
double src_flux = -tm.source_[cell];
bool src_is_inflow = src_flux < 0.0;
influx = src_is_inflow ? src_flux : 0.0;
outflux = !src_is_inflow ? src_flux : 0.0;
// comp_term = tm.source_[cell]; // Note: this assumes that all source flux is water.
dtpv = tm.dt_/tm.porevolume_[cell];
influx = src_is_inflow ? B_cell*src_flux : 0.0;
outflux = !src_is_inflow ? B_cell*src_flux : 0.0;
comp_term = (tm.porevolume_[cell] - tm.porevolume0_[cell])/tm.porevolume0_[cell];
dtpv = tm.dt_/tm.porevolume0_[cell];
for (int i = tm.grid_.cell_facepos[cell]; i < tm.grid_.cell_facepos[cell+1]; ++i) {
const int f = tm.grid_.cell_faces[i];
double flux;
@ -160,16 +163,15 @@ namespace Opm
const double b_face = tm.A_[np*np*other + 0];
influx += B_cell*b_face*flux*tm.fractionalflow_[other];
} else {
outflux += flux;
outflux += flux; // Because B_cell*b_face = 1 for outflow faces
}
// comp_term -= flux;
}
}
}
double operator()(double s) const
{
// return s - s0 + dtpv*(outflux*tm.fracFlow(s, cell) + influx + s*comp_term);
return s - s0 + dtpv*(outflux*tm.fracFlow(s, cell) + influx);
return s - B_cell*z0 + dtpv*(outflux*tm.fracFlow(s, cell) + influx) + s*comp_term;
}
};
@ -333,7 +335,7 @@ namespace Opm
gf[1] = gravflux[pos];
}
s0 = tm.saturation_[cell];
dtpv = tm.dt_/tm.porevolume_[cell];
dtpv = tm.dt_/tm.porevolume0_[cell];
}
double operator()(double s) const
@ -467,6 +469,7 @@ namespace Opm
void TransportModelCompressibleTwophase::solveGravity(const std::vector<std::vector<int> >& columns,
const double* pressure,
const double* porevolume0,
const double* porevolume,
const double dt,
std::vector<double>& saturation)
@ -489,6 +492,7 @@ namespace Opm
}
// Set up other variables.
porevolume0_ = porevolume0;
porevolume_ = porevolume;
dt_ = dt;
toWaterSat(saturation, saturation_);

View File

@ -47,6 +47,7 @@ namespace Opm
/// \param[in] darcyflux Array of signed face fluxes.
/// \param[in] pressure Array of cell pressures
/// \param[in] surfacevol0 Array of surface volumes at start of timestep
/// \param[in] porevolume0 Array of pore volumes at start of timestep.
/// \param[in] porevolume Array of pore volumes.
/// \param[in] source Transport source term.
/// \param[in] dt Time step.
@ -54,6 +55,7 @@ namespace Opm
void solve(const double* darcyflux,
const double* pressure,
const double* surfacevol0,
const double* porevolume0,
const double* porevolume,
const double* source,
const double dt,
@ -71,6 +73,7 @@ namespace Opm
/// \TODO: Implement this.
void solveGravity(const std::vector<std::vector<int> >& columns,
const double* pressure,
const double* porevolume0,
const double* porevolume,
const double dt,
std::vector<double>& saturation);
@ -96,6 +99,7 @@ namespace Opm
const double* darcyflux_; // one flux per grid face
const double* surfacevol0_; // one per phase per cell
const double* porevolume0_; // one volume per cell
const double* porevolume_; // one volume per cell
const double* source_; // one source per cell
double dt_;

View File

@ -24,6 +24,7 @@
#include <opm/core/eclipse/EclipseGridParser.hpp>
#include <opm/core/eclipse/EclipseGridInspector.hpp>
#include <opm/core/fluid/BlackoilPropertiesFromDeck.hpp>
#include <opm/core/grid.h>
#include <algorithm>
#include <iostream>
@ -39,14 +40,10 @@ int main(int argc, char** argv)
// Parser.
std::string ecl_file = param.get<std::string>("filename");
Opm::EclipseGridParser deck(ecl_file);
Opm::EclipseGridInspector insp(deck);
std::tr1::array<int, 3> gs = insp.gridSize();
int num_cells = gs[0]*gs[1]*gs[2];
std::vector<int> global_cell(num_cells);
for (int i = 0; i < num_cells; ++i) {
global_cell[i] = i;
}
Opm::BlackoilPropertiesFromDeck props(deck, global_cell);
UnstructuredGrid grid;
grid.number_of_cells = 1;
grid.global_cell = NULL;
Opm::BlackoilPropertiesFromDeck props(deck, grid);
const int n = 1;
double p[n] = { 150e5 };