Esempio n. 1
0
void compare_pressure(const GI& g, const std::vector<double>& p)
{
    typedef typename GI::CellIterator CI;
    int count = 0;
    double l1err = 0.0;
    double l2err = 0.0;
    double linferr = 0.0;
    double totv = 0.0;
    for (CI c = g.cellbegin(); c != g.cellend(); ++c, ++count) {
        Vec cen = c->centroid();
        double uval = u(cen);
        double diff = uval - p[count];
        double v = c->volume();
        l1err += std::fabs(diff*v);
        l2err += diff*diff*v;
        linferr = std::max(std::fabs(diff), linferr);
        totv += v;
        // std::cout << cen[0] << ' ' << uval << ' ' << p[count] << std::endl;
    }
    l2err = std::sqrt(l2err);
    std::cout << "\n\n"
              << "\n     L1 error density: " << l1err/totv
              << "\n     L2 error density: " << l2err/totv
              << "\n     Linf error:       " << linferr << "\n\n\n";
}
Esempio n. 2
0
void assign_src(const GI& g, std::vector<double>& src)
{
    typedef typename GI::CellIterator CI;
    int count = 0;
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        src[count++] = -Lu(c->centroid())*c->volume();
    }
}
Esempio n. 3
0
 inline void EulerUpstream<GI, RP, BC>::initObj(const GI& g, const RP& r, const BC& b)
 {
     residual_computer_.initObj(g, r, b);
     porevol_.resize(g.numberOfCells());
     for (CIt c = g.cellbegin(); c != g.cellend(); ++c) {
         porevol_[c->index()] = c->volume()*r.porosity(c->index());
     }
 }
Esempio n. 4
0
void test_flowsolver(const GI& g, const RI& r, double tol, int kind)
{
    typedef typename GI::CellIterator                   CI;
    typedef typename CI::FaceIterator                   FI;
    typedef double (*SolutionFuncPtr)(const Vec&);

    //typedef Dune::BasicBoundaryConditions<true, false>  FBC;
    typedef Dune::FunctionBoundaryConditions<SolutionFuncPtr> FBC;
    typedef Dune::IncompFlowSolverHybrid<GI, RI, FBC,
        Dune::MimeticIPEvaluator> FlowSolver;

    FlowSolver solver;

    // FBC flow_bc;
    // assign_bc(g, flow_bc);
    FBC flow_bc(&u);

    typename CI::Vector gravity(0.0);

    std::cout << "========== Init pressure solver =============" << std::endl;
    Dune::time::StopWatch rolex;
    rolex.start();
    solver.init(g, r, gravity, flow_bc);
    rolex.stop();
    std::cout << "========== Time in seconds: " << rolex.secsSinceStart() << " =============" << std::endl;

    std::vector<double> src(g.numberOfCells(), 0.0);
    assign_src(g, src);
    std::vector<double> sat(g.numberOfCells(), 0.0);


    std::cout << "========== Starting pressure solve =============" << std::endl;
    rolex.start();
    solver.solve(r, sat, flow_bc, src, tol, 3, kind);
    rolex.stop();
    std::cout << "========== Time in seconds: " << rolex.secsSinceStart() << " =============" << std::endl;

    typedef typename FlowSolver::SolutionType FlowSolution;
    FlowSolution soln = solver.getSolution();

    std::vector<typename GI::Vector> cell_velocity;
    estimateCellVelocity(cell_velocity, g, solver.getSolution());
    // Dune's vtk writer wants multi-component data to be flattened.
    std::vector<double> cell_velocity_flat(&*cell_velocity.front().begin(),
                                           &*cell_velocity.back().end());
    std::vector<double> cell_pressure;
    getCellPressure(cell_pressure, g, soln);

    compare_pressure(g, cell_pressure);

    Dune::VTKWriter<typename GI::GridType::LeafGridView> vtkwriter(g.grid().leafView());
    vtkwriter.addCellData(cell_velocity_flat, "velocity", GI::GridType::dimension);
    vtkwriter.addCellData(cell_pressure, "pressure");
    vtkwriter.write("testsolution-" + boost::lexical_cast<std::string>(0),
                    Dune::VTKOptions::ascii);
}
Esempio n. 5
0
void assign_bc(const GI& g, BCS& bcs)
{
    typedef Dune::FlowBC BC;
    typedef typename GI::CellIterator CI;
    typedef typename CI::FaceIterator FI;
    int max_bid = 0;
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        for (FI f = c->facebegin(); f != c->faceend(); ++f) {
            int bid = f->boundaryId();
            if (bid > max_bid) {
                max_bid = bid;
                bcs.resize(bid + 1);
            }
            bcs.flowCond(bid) = BC(BC::Dirichlet, u(f->centroid()));
        }
    }
}
void test_flowsolver(const GI& g, const RI& r)
{
    typedef typename GI::CellIterator                              CI;
    typedef typename CI::FaceIterator                              FI;
    typedef Opm::BasicBoundaryConditions<true, false>                  FBC;
    typedef Opm::IncompFlowSolverHybrid<GI, RI, FBC,
                                         Opm::MimeticIPAnisoRelpermEvaluator> FlowSolver;

    FlowSolver solver;

    typedef Opm::FlowBC BC;
    FBC flow_bc(7);
    //flow_bc.flowCond(1) = BC(BC::Dirichlet, 1.0*Opm::unit::barsa);
    //flow_bc.flowCond(2) = BC(BC::Dirichlet, 0.0*Opm::unit::barsa);
    flow_bc.flowCond(5) = BC(BC::Dirichlet, 100.0*Opm::unit::barsa);

    typename CI::Vector gravity;
    gravity[0] = gravity[1] = 0.0;
    gravity[2] = Opm::unit::gravity;

    solver.init(g, r, gravity, flow_bc);
    // solver.printStats(std::cout);

    //solver.assembleStatic(g, r);
    //solver.printIP(std::cout);

    std::vector<double> src(g.numberOfCells(), 0.0);
    std::vector<double> sat(g.numberOfCells(), 0.0);
#if 0
    if (g.numberOfCells() > 1) {
        src[0]     = 1.0;
        src.back() = -1.0;
    }
#endif

    solver.solve(r, sat, flow_bc, src);

#if 0
    solver.printSystem("system");
    typedef typename FlowSolver::SolutionType FlowSolution;
    FlowSolution soln = solver.getSolution();
    std::cout << "Cell Pressure:\n" << std::scientific << std::setprecision(15);
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        std::cout << '\t' << soln.pressure(c) << '\n';
    }

    std::cout << "Cell (Out) Fluxes:\n";
    std::cout << "flux = [\n";
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        for (FI f = c->facebegin(); f != c->faceend(); ++f) {
            std::cout << soln.outflux(f) << ' ';
        }
        std::cout << "\b\n";
    }
    std::cout << "]\n";
#endif
}
    inline void EulerUpstreamImplicit<GI, RP, BC>::initObj(const GI& g, const RP& r, const BC& b)
    {
        //residual_computer_.initObj(g, r, b);

        mygrid_.init(g.grid());
        porevol_.resize(mygrid_.numCells());
        for (int i = 0; i < mygrid_.numCells(); ++i){
            porevol_[i]= mygrid_.cellVolume(i)*r.porosity(i);
        }
        // int numf=mygrid_.numFaces();
        int num_cells = mygrid_.numCells();
        int ngconn  = mygrid_.c_grid()->cell_facepos[num_cells];
        //std::vector<double> htrans_(ngconn);
        htrans_.resize(ngconn);
        const double* perm = &(r.permeability(0)(0,0));
        tpfa_htrans_compute(mygrid_.c_grid(), perm, &htrans_[0]);
        // int count = 0;

        myrp_= r;

        typedef typename GI::CellIterator CIt;
        typedef typename CIt::FaceIterator FIt;
        std::vector<FIt> bid_to_face;
        int maxbid = 0;
        for (CIt c = g.cellbegin(); c != g.cellend(); ++c) {
            for (FIt f = c->facebegin(); f != c->faceend(); ++f) {
                int bid = f->boundaryId();
                maxbid = std::max(maxbid, bid);
            }
        }

        bid_to_face.resize(maxbid + 1);
        std::vector<int> egf_cf(mygrid_.numFaces());
        int cix=0;
        for (CIt c = g.cellbegin(); c != g.cellend(); ++c) {
            int loc_fix=0;
            for (FIt f = c->facebegin(); f != c->faceend(); ++f) {
                if (f->boundary() && b.satCond(*f).isPeriodic()) {
                    bid_to_face[f->boundaryId()] = f;
                }
                int egf=f->index();
                int cf=mygrid_.cellFace(cix,loc_fix);
                egf_cf[egf]=cf;
                loc_fix+=1;
            }
            cix+=1;
        }

#ifndef NDEBUG
        const UnstructuredGrid& c_grid=*mygrid_.c_grid();
#endif
        int hf_ind=0;
        int bf_ind=0;
        periodic_cells_.resize(0);
        periodic_faces_.resize(0);
        periodic_hfaces_.resize(0);
        periodic_nbfaces_.resize(0);
        //cell1 = cell0;
        direclet_cells_.resize(0);
        direclet_sat_.resize(0);
        direclet_sat_.resize(0);
        direclet_hfaces_.resize(0);

        assert(periodic_cells_.size()==0);
        for (CIt c = g.cellbegin(); c != g.cellend(); ++c) {
            int cell0 = c->index();
            for (FIt f = c->facebegin(); f != c->faceend(); ++f) {
                // Neighbour face, will be changed if on a periodic boundary.
                // Compute cell[1], cell_sat[1]
                FIt nbface = f;
                if (f->boundary()) {
                    bf_ind+=1;
                    if (b.satCond(*f).isPeriodic()) {
                        nbface = bid_to_face[b.getPeriodicPartner(f->boundaryId())];
                        assert(nbface != f);
                        int cell1 = nbface->cellIndex();
                        assert(cell0 != cell1);

                        int f_ind=f->index();

                        int fn_ind=nbface->index();
                        // mapping face indices
                        f_ind=egf_cf[f_ind];
                        fn_ind=egf_cf[fn_ind];
                        assert((c_grid.face_cells[2*f_ind]==-1) || (c_grid.face_cells[2*f_ind+1]==-1));
                        assert((c_grid.face_cells[2*fn_ind]==-1) || (c_grid.face_cells[2*fn_ind+1]==-1));
                        assert((c_grid.face_cells[2*f_ind]==cell0) || (c_grid.face_cells[2*f_ind+1]==cell0));
                        assert((c_grid.face_cells[2*fn_ind]==cell1) || (c_grid.face_cells[2*fn_ind+1]==cell1));
                        periodic_cells_.push_back(cell0);
                        periodic_cells_.push_back(cell1);
                        periodic_faces_.push_back(f_ind);
                        periodic_hfaces_.push_back(hf_ind);
                        periodic_nbfaces_.push_back(fn_ind);
                    } else if (!( b.flowCond(*f).isNeumann() && b.flowCond(*f).outflux() == 0.0)) {
                        //cell1 = cell0;
                        direclet_cells_.push_back(cell0);
                        direclet_sat_.push_back(b.satCond(*f).saturation());
                        direclet_sat_.push_back(1-b.satCond(*f).saturation());//only work for 2 phases
                        direclet_hfaces_.push_back(hf_ind);
                    }
                }
                hf_ind+=1;
            }
        }

        mygrid_.makeQPeriodic(periodic_hfaces_,periodic_cells_);
        // use fractional flow instead of saturation as src
        TwophaseFluid myfluid(myrp_);
        int num_b=direclet_cells_.size();
        for(int i=0; i <num_b; ++i){
            std::array<double,2> sat = {{direclet_sat_[2*i] ,direclet_sat_[2*i+1] }};
            std::array<double,2> mob;
            std::array<double,2*2> dmob;
            myfluid.mobility(direclet_cells_[i], sat, mob, dmob);
            double fl = mob[0]/(mob[0]+mob[1]);
            direclet_sat_[2*i] = fl;
            direclet_sat_[2*i+1] = 1-fl;
        }
    }
Esempio n. 8
0
void test_flowsolver(const GI& g, const RI& r)
{
    typedef typename GI::CellIterator                   CI;
    typedef typename CI::FaceIterator                   FI;
    typedef Opm::BasicBoundaryConditions<true, false>  FBC;
    typedef Opm::IncompFlowSolverHybrid<GI, RI, FBC,
                                         Opm::MimeticIPEvaluator> FlowSolver;

    FlowSolver solver;

    typedef Opm::FlowBC BC;
    FBC flow_bc(7);

#if !USE_ALUGRID
    flow_bc.flowCond(5) = BC(BC::Dirichlet, 100.0*Opm::unit::barsa);
    flow_bc.flowCond(6) = BC(BC::Dirichlet, 0.0*Opm::unit::barsa);
#endif

    typename CI::Vector gravity(0.0);
    // gravity[2] = Dune::unit::gravity;

    solver.init(g, r, gravity, flow_bc);

    std::vector<double> src(g.numberOfCells(), 0.0);
    std::vector<double> sat(g.numberOfCells(), 0.0);
//     if (g.numberOfCells() > 1) {
//         src[0]     = 1.0;
//         src.back() = -1.0;
//     }

    solver.solve(r, sat, flow_bc, src, 5e-9, 3, 1);

#if 1
    typedef typename FlowSolver::SolutionType FlowSolution;
    FlowSolution soln = solver.getSolution();

    std::vector<typename GI::Vector> cell_velocity;
    estimateCellVelocity(cell_velocity, g, soln);
    // Dune's vtk writer wants multi-component data to be flattened.
    std::vector<double> cell_velocity_flat(&*cell_velocity.front().begin(),
                                           &*cell_velocity.back().end());
    std::vector<double> cell_pressure;
    getCellPressure(cell_pressure, g, soln);

    Dune::VTKWriter<typename GI::GridType::LeafGridView> vtkwriter(g.grid().leafView());
    vtkwriter.addCellData(cell_velocity_flat, "velocity", dim);
    vtkwriter.addCellData(cell_pressure, "pressure");
    vtkwriter.write("testsolution-" + boost::lexical_cast<std::string>(0),
                    Dune::VTKOptions::ascii);
#else    
    solver.printSystem("system");
    typedef typename FlowSolver::SolutionType FlowSolution;
    FlowSolution soln = solver.getSolution();

    std::cout << "Cell Pressure:\n" << std::scientific << std::setprecision(15);
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        std::cout << '\t' << soln.pressure(c) << '\n';
    }

    std::cout << "Cell (Out) Fluxes:\n";
    std::cout << "flux = [\n";
    for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
        for (FI f = c->facebegin(); f != c->faceend(); ++f) {
            std::cout << soln.outflux(f) << ' ';
        }
        std::cout << "\b\n";
    }
    std::cout << "]\n";
#endif
}