int main()
{
    freopen("input.txt", "rt", stdin);
    int N, M;
    VectorInputOutputEdgeStructure inputOutputEdgesStructures;
    cin >> N >> M;
    inputOutputEdgesStructures.resize(M);
    for (int i = 0; i < M; i++) {
        int u, v, c;
        cin >> u >> v >> c;
        inputOutputEdgesStructures[i] =
            InputOutputEdgeStructure(u - 1, v - 1, c);
    }
    int64_t flowval;
    FlowSolver *flow = NULL;
    if (USE_DINIC)
        flow = new DinicScalingFlow(N);
    else
        flow = new PreflowPushFlow(N);
    flowval = flow->calculateFlow(inputOutputEdgesStructures, 0, N - 1);
    cout << flowval << endl;
    for (int i = 0; i < M; i++)
        cout << inputOutputEdgesStructures[i].flow << endl;
    return 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::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
}
Beispiel #3
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);
}
int main(int argc, char** argv)
{
    Opm::parameter::ParameterGroup param(argc, argv);
    Dune::MPIHelper::instance(argc,argv);

    // Make a grid and props.
    Grid grid;
    Rock rock;
    Fluid fluid;
    FlowSolver solver;

    using namespace Dune;

    // Initialization.
    std::string fileformat = param.getDefault<std::string>("fileformat", "cartesian");
    if (fileformat == "eclipse") {
        Opm::EclipseGridParser parser(param.get<std::string>("filename"));
        double z_tolerance = param.getDefault<double>("z_tolerance", 0.0);
        bool periodic_extension = param.getDefault<bool>("periodic_extension", false);
        bool turn_normals = param.getDefault<bool>("turn_normals", false);
        grid.processEclipseFormat(parser, z_tolerance, periodic_extension, turn_normals);
        double perm_threshold_md = param.getDefault("perm_threshold_md", 0.0);
        double perm_threshold = Opm::unit::convert::from(perm_threshold_md, Opm::prefix::milli*Opm::unit::darcy);
        rock.init(parser, grid.globalCell(), perm_threshold);
        fluid.init(parser);
    } else if (fileformat == "cartesian") {
        Dune::array<int, 3> dims = {{ param.getDefault<int>("nx", 1),
                                      param.getDefault<int>("ny", 1),
                                      param.getDefault<int>("nz", 1) }};
	Dune::array<double, 3> cellsz = {{ param.getDefault<double>("dx", 1.0),
                                           param.getDefault<double>("dy", 1.0),
                                           param.getDefault<double>("dz", 1.0) }};
        grid.createCartesian(dims, cellsz);
        double default_poro = param.getDefault("default_poro", 1.0);
        double default_perm_md = param.getDefault("default_perm_md", 100.0);
        double default_perm = Opm::unit::convert::from(default_perm_md, Opm::prefix::milli*Opm::unit::darcy);
        MESSAGE("Warning: For generated cartesian grids, we use uniform rock properties.");
        rock.init(grid.size(0), default_poro, default_perm);
	Opm::EclipseGridParser parser(param.get<std::string>("filename")); // Need a parser for the fluids anyway.
        fluid.init(parser);
    } else {
        THROW("Unknown file format string: " << fileformat);
    }
    solver.init(param);
    double dt = param.getDefault("dt", 1.0);

    // Run test.
    test_flowsolver<3>(grid, rock, fluid, solver, dt);
}
void test_flowsolver(const Grid& grid,
                     const Rock& rock,
                     const Fluid& fluid,
                     FlowSolver& solver,
                     const double dt)
{
    // Boundary conditions.
    typedef Dune::FlowBC BC;
    typedef Dune::BasicBoundaryConditions<true, false>  FBC;
    FBC flow_bc(7);
    flow_bc.flowCond(1) = BC(BC::Dirichlet, 300.0*Opm::unit::barsa);
    flow_bc.flowCond(2) = BC(BC::Dirichlet, 100.0*Opm::unit::barsa);

    // Gravity.
    typename Grid::Vector gravity(0.0);
//     gravity[2] = Dune::unit::gravity;

    Opm::Wells wells;

    // Flow solver setup.
    solver.setup(grid, rock, fluid, wells, gravity, flow_bc);

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

    int num_cells = grid.numCells();
    int num_faces = grid.numFaces();

    // Initial state.
    typedef typename Fluid::CompVec CompVec;
    typedef typename Fluid::PhaseVec PhaseVec;
    CompVec init_z(0.0);
    init_z[Fluid::Oil] = 1.0;
    std::vector<CompVec> z(grid.numCells(), init_z);
    MESSAGE("******* Assuming zero capillary pressures *******");
    PhaseVec init_p(100.0*Opm::unit::barsa);
    std::vector<PhaseVec> cell_pressure(grid.numCells(), init_p);
    // Rescale z values so that pore volume is filled exactly
    // (to get zero initial volume discrepancy).
    for (int cell = 0; cell < grid.numCells(); ++cell) {
        typename Fluid::FluidState state = fluid.computeState(cell_pressure[cell], z[cell]);
        double fluid_vol = state.total_phase_volume_density_;
        z[cell] *= 1.0/fluid_vol;
    }
    std::vector<PhaseVec> face_pressure(num_faces);
    for (int face = 0; face < num_faces; ++face) {
        int bid = grid.boundaryId(face);
        if (flow_bc.flowCond(bid).isDirichlet()) {
            face_pressure[face] = flow_bc.flowCond(bid).pressure();
        } else {
            int c[2] = { grid.faceCell(face, 0), grid.faceCell(face, 1) };
            face_pressure[face] = 0.0;
            int num = 0;
            for (int j = 0; j < 2; ++j) {
                if (c[j] >= 0) {
                    face_pressure[face] += cell_pressure[c[j]];
                    ++num;
                }
            }
            face_pressure[face] /= double(num);
        }
    }
    std::vector<double> face_flux, well_bhp_pressure, well_perf_pressure, well_flux;

    // Solve flow system.
    solver.solve(cell_pressure, face_pressure, z, face_flux, well_bhp_pressure, well_perf_pressure, well_flux, src, dt);

    // Output to VTK.
    std::vector<typename Grid::Vector> cell_velocity;
    estimateCellVelocitySimpleInterface(cell_velocity, grid, face_flux);
    // Dune's vtk writer wants multi-component data to be flattened.
    std::vector<double> cell_pressure_flat(&*cell_pressure.front().begin(),
                                           &*cell_pressure.back().end());
    std::vector<double> cell_velocity_flat(&*cell_velocity.front().begin(),
                                           &*cell_velocity.back().end());
    Dune::VTKWriter<typename Grid::LeafGridView> vtkwriter(grid.leafView());
    vtkwriter.addCellData(cell_pressure_flat, "pressure", Fluid::numPhases);
    vtkwriter.addCellData(cell_velocity_flat, "velocity", Grid::dimension);
    vtkwriter.write("testsolution", Dune::VTKOptions::ascii);

    // Dump data for Matlab.
    std::ofstream dump("celldump");
    dump.precision(15);
    std::vector<double> liq_press(num_cells);
    for (int cell = 0; cell < num_cells; ++cell) {
        liq_press[cell] = cell_pressure[cell][Fluid::Liquid];
    }
    std::copy(liq_press.begin(), liq_press.end(),
              std::ostream_iterator<double>(dump, " "));
    dump << '\n';
}
Beispiel #6
0
int main(int argc, char** argv)
{
    typedef Dune::GridInterfaceEuler<CpGrid>                       GI;
    typedef GI  ::CellIterator                                     CI;
    typedef CI  ::FaceIterator                                     FI;
    typedef Dune::BasicBoundaryConditions<true, false>                  BCs;
    typedef Dune::ReservoirPropertyCapillary<3>                    RI;
    typedef Dune::IncompFlowSolverHybrid<GI, RI, BCs,
        Dune::MimeticIPEvaluator> FlowSolver;

    Opm::parameter::ParameterGroup param(argc, argv);
    CpGrid grid;
    grid.init(param);
    //grid.setUniqueBoundaryIds(true);
    GridInterfaceEuler<CpGrid> g(grid);

    typedef Dune::FlowBC BC;
    BCs flow_bc(7);
#define BCDIR 4
#if BCDIR == 1
    flow_bc.flowCond(1) = BC(BC::Dirichlet, 1.0*Opm::unit::barsa);
    flow_bc.flowCond(2) = BC(BC::Dirichlet, 0.0*Opm::unit::barsa);
#elif BCDIR == 2
    flow_bc.flowCond(3) = BC(BC::Dirichlet, 1.0*Opm::unit::barsa);
    flow_bc.flowCond(4) = BC(BC::Dirichlet, 0.0*Opm::unit::barsa);
#elif BCDIR == 3
    flow_bc.flowCond(5) = BC(BC::Dirichlet, 1.0*Opm::unit::barsa);
    flow_bc.flowCond(6) = BC(BC::Dirichlet, 0.0*Opm::unit::barsa);
#elif BCDIR == 4
    flow_bc.flowCond(5) = BC(BC::Dirichlet, 1.0*Opm::unit::barsa);
#endif

    RI r;
    r.init(g.numberOfCells());

    std::vector<double> permdata;
    fill_perm(permdata);
    ASSERT (int(permdata.size()) == 3 * 60 * 220 * 85);
    Dune::SharedFortranMatrix Perm(60 * 220 * 85, 3, &permdata[0]);
    const int imin = param.get<int>("imin");
    const int jmin = param.get<int>("jmin");
    const int kmin = param.get<int>("kmin");
    for (int c = 0; c < g.numberOfCells(); ++c) {
        boost::array<int,3> ijk;
        grid.getIJK(c, ijk);
        ijk[0] += imin;  ijk[1] += jmin;  ijk[2] += kmin;
        const int gc = ijk[0] + 60*(ijk[1] + 220*ijk[2]);
        
        RI::SharedPermTensor K = r.permeabilityModifiable(c);
        K(0,0) = 0*0.1*Opm::unit::darcy + 1*Perm(gc,0);
        K(1,1) = 0*0.1*Opm::unit::darcy + 1*Perm(gc,1);
        K(2,2) = 0*0.1*Opm::unit::darcy + 1*Perm(gc,2);
    }


#if 1
    CI::Vector gravity;
    gravity[0] = gravity[1] = gravity[2] = 0.0;
#if 1
    gravity[2] = Opm::unit::gravity;
    gravity[2] = 10; //Opm::unit::gravity;
#endif
#endif

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

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

#if 0
    const int nx = param.get<int>("nx");
    const int ny = param.get<int>("ny");
    const int nz = param.get<int>("nz");
    const int
        i  = 0 + nz*(nx/2   + nx*ny/2  ),
        p1 = 0 + nz*(0      + nx*0     ),
        p2 = 0 + nz*((nx-1) + nx*0     ),
        p3 = 0 + nz*(0      + nx*(ny-1)),
        p4 = 0 + nz*((nx-1) + nx*(ny-1));

    const double bbl   = 0.159 * unit::cubic(unit::meter);
    const double irate = 1.0e4 * bbl / unit::day;
    for (int z = 0; z < nz; ++z) {
        src[i  + z] =   irate / nz;
        src[p1 + z] = -(irate / nz) / 4;
        src[p2 + z] = -(irate / nz) / 4;
        src[p3 + z] = -(irate / nz) / 4;
        src[p4 + z] = -(irate / nz) / 4;
    }
#endif

    solver.solve(r, sat, flow_bc, src, 5.0e-8, 3);
#endif

#if 1
    std::vector<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, solver.getSolution());

    Dune::VTKWriter<CpGrid::LeafGridView> vtkwriter(grid.leafView());
    vtkwriter.addCellData(cell_velocity_flat, "velocity", 3);
    vtkwriter.addCellData(cell_pressure, "pressure");
    vtkwriter.write("spe10_test_output", Dune::VTKOptions::ascii);
#endif
    return 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
}