/* Copyright 2013 SINTEF ICT, Applied Mathematics. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see <http://www.gnu.org/licenses/>. */ #ifndef OPM_GEOPROPS_HEADER_INCLUDED #define OPM_GEOPROPS_HEADER_INCLUDED #include <opm/core/grid.h> #include <opm/core/pressure/tpfa/trans_tpfa.h> #include <Eigen/Eigen> namespace Opm { class DerivedGeology { public: typedef Eigen::ArrayXd Vector; /// Construct contained derived geological properties /// from grid and property information. template <class Props> DerivedGeology(const UnstructuredGrid& grid, const Props& props , const double* grav = 0) : pvol_ (grid.number_of_cells) , trans_(grid.number_of_faces) , gpot_ (Vector::Zero(grid.cell_facepos[ grid.number_of_cells ], 1)) { // Pore volume const typename Vector::Index nc = grid.number_of_cells; std::transform(grid.cell_volumes, grid.cell_volumes + nc, props.porosity(), pvol_.data(), std::multiplies<double>()); // Transmissibility Vector htrans(grid.cell_facepos[nc]); UnstructuredGrid* ug = const_cast<UnstructuredGrid*>(& grid); tpfa_htrans_compute(ug, props.permeability(), htrans.data()); tpfa_trans_compute (ug, htrans.data() , trans_.data()); // Gravity potential std::fill(gravity_, gravity_ + 3, 0.0); if (grav != 0) { const typename Vector::Index nd = grid.dimensions; for (typename Vector::Index c = 0; c < nc; ++c) { const double* const cc = & grid.cell_centroids[c*nd + 0]; const int* const p = grid.cell_facepos; for (int i = p[c]; i < p[c + 1]; ++i) { const int f = grid.cell_faces[i]; const double* const fc = & grid.face_centroids[f*nd + 0]; for (typename Vector::Index d = 0; d < nd; ++d) { gpot_[i] += grav[d] * (fc[d] - cc[d]); } } } std::copy(grav, grav + nd, gravity_); } } const Vector& poreVolume() const { return pvol_ ; } const Vector& transmissibility() const { return trans_; } const Vector& gravityPotential() const { return gpot_ ; } const double* gravity() const { return gravity_; } private: Vector pvol_ ; Vector trans_; Vector gpot_ ; double gravity_[3]; // Size 3 even if grid is 2-dim. }; } #endif // OPM_GEOPROPS_HEADER_INCLUDED