void TransportSolverCompressibleTwophaseReorder::initGravity(const double* grav)
{
    // Set up transmissibilities.
    std::vector<double> htrans(grid_.cell_facepos[grid_.number_of_cells]);
    const int nf = grid_.number_of_faces;
    trans_.resize(nf);
    gravflux_.resize(nf);
    tpfa_htrans_compute(const_cast<UnstructuredGrid*>(&grid_), props_.permeability(), &htrans[0]);
    tpfa_trans_compute(const_cast<UnstructuredGrid*>(&grid_), &htrans[0], &trans_[0]);

    // Remember gravity vector.
    gravity_ = grav;
}
 /// Construct solver.
 /// \param[in] grid          A 2d or 3d grid.
 /// \param[in] props         Rock and fluid properties.
 /// \param[in] linsolver     Linear solver to use.
 /// \param[in] residual_tol  Solution accepted if inf-norm of residual is smaller.
 /// \param[in] change_tol    Solution accepted if inf-norm of change in pressure is smaller.
 /// \param[in] maxiter       Maximum acceptable number of iterations.
 /// \param[in] gravity       Gravity vector. If non-null, the array should
 ///                          have D elements.
 /// \param[in] wells         The wells argument. Will be used in solution,
 ///                          is ignored if NULL.
 ///                          Note: this class observes the well object, and
 ///                                makes the assumption that the well topology
 ///                                and completions does not change during the
 ///                                run. However, controls (only) are allowed
 ///                                to change.
 CompressibleTpfa::CompressibleTpfa(const UnstructuredGrid& grid,
                                    const BlackoilPropertiesInterface& props,
                                    const RockCompressibility* rock_comp_props,
                                    const LinearSolverInterface& linsolver,
                                    const double residual_tol,
                                    const double change_tol,
                                    const int maxiter,
                                    const double* gravity,
                                    const struct Wells* wells)
     : grid_(grid),
       props_(props),
       rock_comp_props_(rock_comp_props),
       linsolver_(linsolver),
       residual_tol_(residual_tol),
       change_tol_(change_tol),
       maxiter_(maxiter),
       gravity_(gravity),
       wells_(wells),
       htrans_(grid.cell_facepos[ grid.number_of_cells ]),
       trans_ (grid.number_of_faces),
       allcells_(grid.number_of_cells),
       singular_(false)
 {
     if (wells_ && (wells_->number_of_phases != props.numPhases())) {
         OPM_THROW(std::runtime_error, "Inconsistent number of phases specified (wells vs. props): "
               << wells_->number_of_phases << " != " << props.numPhases());
     }
     const int num_dofs = grid.number_of_cells + (wells ? wells->number_of_wells : 0);
     pressure_increment_.resize(num_dofs);
     UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
     tpfa_htrans_compute(gg, props.permeability(), &htrans_[0]);
     tpfa_trans_compute(gg, &htrans_[0], &trans_[0]);
     // If we have rock compressibility, pore volumes are updated
     // in the compute*() methods, otherwise they are constant and
     // hence may be computed here.
     if (rock_comp_props_ == NULL || !rock_comp_props_->isActive()) {
         computePorevolume(grid_, props.porosity(), porevol_);
     }
     for (int c = 0; c < grid.number_of_cells; ++c) {
         allcells_[c] = c;
     }
     cfs_tpfa_res_wells w;
     w.W = const_cast<struct Wells*>(wells_);
     w.data = NULL;
     h_ = cfs_tpfa_res_construct(gg, &w, props.numPhases());
 }
    void init(const Grid& grid, const double* perm, const double* porosity, const typename Grid::Vector& gravity)
    {
        // Build C grid structure.
        grid_.init(grid);

        // Initialize data.
        int num_phases = 3;
        well_t* w = 0;
        if (wells_.number_of_wells != 0) {
            w = &wells_;
        }
        data_ = cfs_tpfa_construct(grid_.c_grid(), w, num_phases);
        if (!data_) {
            throw std::runtime_error("Failed to initialize cfs_tpfa solver.");
        }

        // Compute half-transmissibilities
        int num_cells = grid.numCells();
        int ngconn  = grid_.c_grid()->cell_facepos[num_cells];
        ncf_.resize(num_cells);
        for (int cell = 0; cell < num_cells; ++cell) {
            int num_local_faces = grid.numCellFaces(cell);
            ncf_[cell] = num_local_faces;
        }
        htrans_.resize(ngconn);
        tpfa_htrans_compute(grid_.c_grid(), perm, &htrans_[0]);

        // Compute transmissibilities.
        trans_.resize(grid_.numFaces());
        tpfa_trans_compute(grid_.c_grid(), &htrans_[0], &trans_[0]);

        // Compute pore volumes.
        porevol_.resize(num_cells);
        for (int i = 0; i < num_cells; ++i) {
            porevol_[i] = porosity[i]*grid.cellVolume(i);
        }

        // Set gravity.
        if (Grid::dimension != 3) {
            throw std::logic_error("Only 3 dimensions supported currently.");
        }
        std::copy(gravity.begin(), gravity.end(), gravity_);

        state_ = Initialized;
    }
Exemple #4
0
        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_);
            }
        }
 void TransportSolverTwophaseReorder::initGravity(const double* grav)
 {
     // Set up gravflux_ = T_ij g (rho_w - rho_o) (z_i - z_j)
     std::vector<double> htrans(grid_.cell_facepos[grid_.number_of_cells]);
     const int nf = grid_.number_of_faces;
     const int dim = grid_.dimensions;
     gravflux_.resize(nf);
     tpfa_htrans_compute(const_cast<UnstructuredGrid*>(&grid_), props_.permeability(), &htrans[0]);
     tpfa_trans_compute(const_cast<UnstructuredGrid*>(&grid_), &htrans[0], &gravflux_[0]);
     const double delta_rho = props_.density()[0] - props_.density()[1];
     for (int f = 0; f < nf; ++f) {
         const int* c = &grid_.face_cells[2*f];
         double gdz = 0.0;
         if (c[0] != -1 && c[1] != -1) {
             for (int d = 0; d < dim; ++d) {
                 gdz += grav[d]*(grid_.cell_centroids[dim*c[0] + d] - grid_.cell_centroids[dim*c[1] + d]);
             }
         }
         gravflux_[f] *= delta_rho*gdz;
     }
 }