예제 #1
0
int main(int argc, char** argv)
try
{
    Opm::parameter::ParameterGroup param(argc, argv);
    Dune::CpGrid grid;
    grid.init(param);
    grid.setUniqueBoundaryIds(true);
    GridInterfaceEuler<Dune::CpGrid> gi(grid);
    typedef FlowBC FBC;
    std::array<FBC, 6> fcond = {{ FBC(FBC::Periodic, 1.0e5),
                                   FBC(FBC::Periodic, -1.0e5),
                                   FBC(FBC::Periodic, 0.0),
                                   FBC(FBC::Periodic, 0.0),
                                   FBC(FBC::Neumann, 0.0),
                                   FBC(FBC::Neumann, 0.0) }};
    typedef SatBC SBC;
    std::array<SBC, 6> scond = {{ SBC(SBC::Periodic, 0.0),
                                   SBC(SBC::Periodic, 0.0),
                                   SBC(SBC::Periodic, 0.0),
                                   SBC(SBC::Periodic, 0.0),
                                   SBC(SBC::Dirichlet, 0.0),
                                   SBC(SBC::Dirichlet, 0.0) }};
    BasicBoundaryConditions<true, true> bcs;
    createPeriodic(bcs, gi, fcond, scond);
    std::cout << bcs;
}
catch (const std::exception &e) {
    std::cerr << "Program threw an exception: " << e.what() << "\n";
    throw;
}
예제 #2
0
void extractInternalFaces(const Dune::CpGrid& grid,
                          Eigen::Array<int, Eigen::Dynamic, 1>& internal_faces,
                          Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor>& nbi)
{
    // Extracts the internal faces of the grid.
    // These are stored in internal_faces.
    int nf=numFaces(grid);
    int num_internal=0;
    for(int f=0; f<nf; ++f)
    {
        if(grid.faceCell(f, 0)<0 || grid.faceCell(f, 1)<0)
            continue;
        ++num_internal;
    }
    // std::cout << num_internal << " internal faces." << std::endl;
    nbi.resize(num_internal, 2);
    internal_faces.resize(num_internal);
    int fi = 0;

    for (int f = 0; f < nf; ++f) {
        if(grid.faceCell(f, 0)>=0 && grid.faceCell(f, 1)>=0) {
            internal_faces[fi] = f;
            nbi(fi,0) = grid.faceCell(f, 0);
            nbi(fi,1) = grid.faceCell(f, 1);
            ++fi;
        }
    }
}
int main(int argc, char** argv)
{
    Opm::parameter::ParameterGroup param(argc, argv);
    Dune::MPIHelper::instance(argc,argv);

    // Make a grid
    Dune::CpGrid grid;

    Opm::EclipseGridParser parser(param.get<std::string>("filename"));
    double z_tol = param.getDefault<double>("z_tolerance", 0.0);
    std::tr1::array<int,3> cartDims;
    build_grid(parser, z_tol, grid, cartDims);

    // Make the grid interface
    Opm::GridInterfaceEuler<Dune::CpGrid> g(grid);

    // Reservoir properties.
    typedef ReservoirPropertyCapillaryAnisotropicRelperm<3> RP;
    RP res_prop;
    res_prop.init(parser, grid.globalCell());

    assign_permeability<3>(res_prop, g.numberOfCells(), 0.1*Opm::unit::darcy);
    test_flowsolver<3>(g, res_prop);

#if 0
    // Make flow equation boundary conditions.
    // Pressure 1.0e5 on the left, 0.0 on the right.
    // Recall that the boundary ids range from 1 to 6 for the cartesian edges,
    // and that boundary id 0 means interiour face/intersection.
    typedef FlowBoundaryCondition BC;
    FlowBoundaryConditions flow_bcond(7);
    flow_bcond[1] = BC(BC::Dirichlet, 1.0e5);
    flow_bcond[2] = BC(BC::Dirichlet, 0.0);

    // Make transport equation boundary conditions.
    // The default one is fine (sat = 1.0 on inflow).
    SaturationBoundaryConditions sat_bcond(7);

    // No injection or production.
    SparseVector<double> injection_rates(g.numberOfCells());

    // Make a solver.
    typedef EulerUpstream<GridInterface,
                          RP,
                          SaturationBoundaryConditions> TransportSolver;
    TransportSolver transport_solver(g, res_prop, sat_bcond, injection_rates);

    // Define a flow field with constant velocity
    Dune::FieldVector<double, 3> vel(0.0);
    vel[0] = 2.0;
    vel[1] = 1.0;
    TestSolution<GridInterface> flow_solution(g, vel);
    // Solve a step.
    double time = 1.0;
    std::vector<double> sat(g.numberOfCells(), 0.0);
    Dune::FieldVector<double, 3> gravity(0.0);
    gravity[2] = -9.81;
    transport_solver.transportSolve(sat, time, gravity, flow_solution);
#endif
}
예제 #4
0
void Opm::initCPGrid(Dune::CpGrid& grid, const Opm::ParameterGroup& param) {
    std::string fileformat = param.get<std::string>("fileformat");
    if (fileformat == "sintef_legacy") {
        std::string grid_prefix = param.get<std::string>("grid_prefix");
        grid.readSintefLegacyFormat(grid_prefix);
    } else if (fileformat == "eclipse") {
        std::string filename = param.get<std::string>("filename");
        if (param.has("z_tolerance")) {
            std::cerr << "****** Warning: z_tolerance parameter is obsolete, use PINCH in deck input instead\n";
        }
        bool periodic_extension = param.getDefault<bool>("periodic_extension", false);
        bool turn_normals = param.getDefault<bool>("turn_normals", false);
        Opm::Parser parser;
        auto deck = parser.parseFile(filename);
        Opm::EclipseGrid inputGrid(deck);
        grid.processEclipseFormat(inputGrid, periodic_extension , turn_normals );
    } else if (fileformat == "cartesian") {
        std::array<int, 3> dims = {{ param.getDefault<int>("nx", 1),
                                     param.getDefault<int>("ny", 1),
                                     param.getDefault<int>("nz", 1) }};
        std::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);
    } else {
        OPM_THROW(std::runtime_error, "Unknown file format string: " << fileformat);
    }
}
 /// \brief Constructor.
 /// \param sendGrid   The grid that the data is attached to when sending.
 /// \param recvGrid   The grid that the data is attached to when receiving.
 /// \param sendState  The state where we will retieve the values to be sent.
 /// \param recvState The state where we will store the received values.
 BlackoilStateDataHandle(const Dune::CpGrid& sendGrid,
                         const Dune::CpGrid& recvGrid,
                         const BlackoilState& sendState,
                         BlackoilState& recvState)
     : sendGrid_(sendGrid), recvGrid_(recvGrid), sendState_(sendState), recvState_(recvState)
 {
     // construction does not resize surfacevol and hydroCarbonState. Do it manually.
     recvState.surfacevol().resize(recvGrid.numCells()*sendState.numPhases(),
                                   std::numeric_limits<double>::max());
     recvState.hydroCarbonState().resize(recvGrid.numCells());
 }
// Extracts the information about the data decomposition from the grid for dune-istl
void extractParallelGridInformationToISTL(const Dune::CpGrid& grid, boost::any& anyComm)
{
    if(grid.comm().size()>1)
    {
        // this is a parallel run with distributed data.
        Dune::CpGrid& mgrid=const_cast<Dune::CpGrid&>(grid);
        Dune::CpGrid::ParallelIndexSet& idx=mgrid.getCellIndexSet();
        Dune::CpGrid::RemoteIndices& ridx=mgrid.getCellRemoteIndices();
        anyComm=boost::any(Opm::ParallelISTLInformation(Dune::stackobject_to_shared_ptr(idx),
                                                        Dune::stackobject_to_shared_ptr(ridx),
                                                        grid.comm()));
    }
}
예제 #7
0
void check_cpgrid()
//-----------------------------------------------------------------------------
{
    std::cout << '\n' << "CpGrid<" << refinement << ">\n" << std::endl;

    Dune::CpGrid grid;
    Dune::array<int   , 3> dims;
    std::fill(dims.begin(), dims.end(), 1 << refinement);
    Dune::array<double, 3> cell_sz;
    std::fill(cell_sz.begin(), cell_sz.end(), 1.0 / (1 << refinement));

    grid.createCartesian(dims, cell_sz);

    // Test the interface
    Dune::GridInterfaceEuler<Dune::CpGrid> gie(grid);
    test_evaluator<3>(gie);
#if 0
    test_flowsolver<3>(gie);
#endif
}
예제 #8
0
 inline void setupGridAndPropsEclipse(Opm::DeckConstPtr deck,
                                      bool periodic_extension,
                                      bool turn_normals,
                                      bool clip_z,
                                      bool unique_bids,
                                      double perm_threshold,
                                      const std::string& rock_list,
                                      bool use_jfunction_scaling,
                                      double sigma,
                                      double theta,
                                      Dune::CpGrid& grid,
                                      ResProp<3>& res_prop)
 {
     grid.processEclipseFormat(deck, periodic_extension, turn_normals, clip_z);
     const std::string* rl_ptr = (rock_list == "no_list") ? 0 : &rock_list;
     res_prop.init(deck, grid.globalCell(), perm_threshold, rl_ptr, use_jfunction_scaling, sigma, theta);
     if (unique_bids) {
         grid.setUniqueBoundaryIds(true);
     }
 }
    void outputStateVtk(const Dune::CpGrid& grid,
                        const Opm::BlackoilState& state,
                        const int step,
                        const std::string& output_dir)
    {
        // Write data in VTK format.
        std::ostringstream vtkfilename;
        std::ostringstream vtkpath;
        vtkpath << output_dir << "/vtk_files";
        vtkpath << "/output-" << std::setw(3) << std::setfill('0') << step;
        boost::filesystem::path fpath(vtkpath.str());
        try {
            create_directories(fpath);
        }
        catch (...) {
            OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath);
        }
        vtkfilename << "output-" << std::setw(3) << std::setfill('0') << step;
#if DUNE_VERSION_NEWER(DUNE_GRID, 2, 3)
        Dune::VTKWriter<Dune::CpGrid::LeafGridView> writer(grid.leafGridView(), Dune::VTK::nonconforming);
#else
        Dune::VTKWriter<Dune::CpGrid::LeafGridView> writer(grid.leafView(), Dune::VTK::nonconforming);
#endif
        writer.addCellData(state.saturation(), "saturation", state.numPhases());
        writer.addCellData(state.pressure(), "pressure", 1);
        
        std::vector<double> cell_velocity;
        Opm::estimateCellVelocity(AutoDiffGrid::numCells(grid),
                                  AutoDiffGrid::numFaces(grid),
                                  AutoDiffGrid::beginFaceCentroids(grid),
                                  AutoDiffGrid::faceCells(grid),
                                  AutoDiffGrid::beginCellCentroids(grid),
                                  AutoDiffGrid::beginCellVolumes(grid),
                                  AutoDiffGrid::dimensions(grid),
                                  state.faceflux(), cell_velocity);
        writer.addCellData(cell_velocity, "velocity", Dune::CpGrid::dimension);
        writer.pwrite(vtkfilename.str(), vtkpath.str(), std::string("."), Dune::VTK::ascii);
    }
예제 #10
0
void build_grid(const Opm::EclipseGridParser& parser,
                const double z_tol, Dune::CpGrid& grid,
                std::tr1::array<int,3>& cartDims)
{
    Opm::EclipseGridInspector insp(parser);

    grdecl g;
    cartDims[0] = g.dims[0] = insp.gridSize()[0];
    cartDims[1] = g.dims[1] = insp.gridSize()[1];
    cartDims[2] = g.dims[2] = insp.gridSize()[2];

    g.coord = &parser.getFloatingPointValue("COORD")[0];
    g.zcorn = &parser.getFloatingPointValue("ZCORN")[0];

    if (parser.hasField("ACTNUM")) {
        g.actnum = &parser.getIntegerValue("ACTNUM")[0];
        grid.processEclipseFormat(g, z_tol, false, false);
    } else {
        std::vector<int> dflt_actnum(g.dims[0] * g.dims[1] * g.dims[2], 1);

        g.actnum = &dflt_actnum[0];
        grid.processEclipseFormat(g, z_tol, false, false);
    }
}
예제 #11
0
int numCellFaces(const Dune::CpGrid& grid)
{
    return grid.numCellFaces();    
}
예제 #12
0
    inline void setupGridAndProps(const Opm::parameter::ParameterGroup& param,
                                  Dune::CpGrid& grid,
                                  ResProp<3>& res_prop)
    {
        // Initialize grid and reservoir properties.
        // Parts copied from Dune::CpGrid::init().
        std::string fileformat = param.getDefault<std::string>("fileformat", "cartesian");
        if (fileformat == "sintef_legacy") {
            std::string grid_prefix = param.get<std::string>("grid_prefix");
            grid.readSintefLegacyFormat(grid_prefix);
            OPM_MESSAGE("Warning: We do not yet read legacy reservoir properties. Using defaults.");
            res_prop.init(grid.size(0));
        } else if (fileformat == "eclipse") {
            std::string ecl_file = param.get<std::string>("filename");

            Opm::ParseContext parseContext;
            Opm::ParserPtr parser(new Opm::Parser());
            Opm::DeckConstPtr deck(parser->parseFile(ecl_file , parseContext));
            if (param.has("z_tolerance")) {
                std::cerr << "****** Warning: z_tolerance parameter is obsolete, use PINCH in deck input instead\n";
            }
            bool periodic_extension = param.getDefault<bool>("periodic_extension", false);
            bool turn_normals = param.getDefault<bool>("turn_normals", false);
            grid.processEclipseFormat(deck, periodic_extension, turn_normals);
            // Save EGRID file in case we are writing ECL output.
            if (param.getDefault("output_ecl", false)) {
                OPM_THROW(std::runtime_error, "Saving to EGRID files is not yet implemented");
                /*
                boost::filesystem::path ecl_path(ecl_file);
                const std::vector<int>& globalCell = grid.globalCell();
                ecl_path.replace_extension(".EGRID");
                parser.saveEGRID(ecl_path.string() , (int) globalCell.size() , &globalCell[0]);
                */
            }
            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);
            std::string rock_list = param.getDefault<std::string>("rock_list", "no_list");
            std::string* rl_ptr = (rock_list == "no_list") ? 0 : &rock_list;
            bool use_j = param.getDefault("use_jfunction_scaling", useJ<ResProp<3> >());
            double sigma = 1.0;
            double theta = 0.0;
            if (use_j) {
                sigma = param.getDefault("sigma", sigma);
                theta = param.getDefault("theta", theta);
            }
            if (param.has("viscosity1") || param.has("viscosity2")) {
                double v1 = param.getDefault("viscosity1", 0.001);
                double v2 = param.getDefault("viscosity2", 0.003);
                res_prop.setViscosities(v1, v2);
            }
            res_prop.init(deck, grid.globalCell(), perm_threshold, rl_ptr,
                          use_j, sigma, theta);
        } else if (fileformat == "cartesian") {
            std::array<int, 3> dims = {{ param.getDefault<int>("nx", 1),
                                    param.getDefault<int>("ny", 1),
                                    param.getDefault<int>("nz", 1) }};
            std::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", 0.2);
            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);
            OPM_MESSAGE("Warning: For generated cartesian grids, we use uniform reservoir properties.");
            res_prop.init(grid.size(0), default_poro, default_perm);
        } else {
            OPM_THROW(std::runtime_error, "Unknown file format string: " << fileformat);
        }
        if (param.getDefault("use_unique_boundary_ids", false)) {
            grid.setUniqueBoundaryIds(true);
        }
    }
예제 #13
0
double cellCentroidCoordinate(const Dune::CpGrid& grid, int cell_index,
                              int coordinate)
{
    return grid.cellCentroid(cell_index)[coordinate];
}
inline
void distributeGridAndData( Dune::CpGrid& grid,
                            Opm::DeckConstPtr deck,
                            EclipseStateConstPtr eclipseState,
                            BlackoilState& state,
                            BlackoilPropsAdFromDeck& properties,
                            DerivedGeology& geology,
                            std::shared_ptr<BlackoilPropsAdFromDeck::MaterialLawManager>& material_law_manager,
                            std::vector<double>& threshold_pressures,
                            boost::any& parallelInformation,
                            const bool useLocalPerm)
{
    Dune::CpGrid global_grid ( grid );
    global_grid.switchToGlobalView();

    // distribute the grid and switch to the distributed view
    grid.loadBalance(eclipseState, geology.transmissibility().data());
    grid.switchToDistributedView();
    std::vector<int> compressedToCartesianIdx;
    Opm::createGlobalCellArray(grid, compressedToCartesianIdx);
    typedef BlackoilPropsAdFromDeck::MaterialLawManager MaterialLawManager;
    auto distributed_material_law_manager = std::make_shared<MaterialLawManager>();
    distributed_material_law_manager->initFromDeck(deck, eclipseState, compressedToCartesianIdx);
    // copy the values from the global to the local MaterialLawManager
    // We should actually communicate these to be future proof. But that is
    // really, really cumbersome for the underlying vector<shared_ptr>
    // where the classes pointed to even have more shared_ptr stored in them.
    typedef Dune::CpGrid::ParallelIndexSet IndexSet;
    const IndexSet& local_indices  = grid.getCellIndexSet();
    for ( auto index : local_indices )
    {
        distributed_material_law_manager->materialLawParamsPointerReferenceHack(index.local()) =
            material_law_manager->materialLawParamsPointerReferenceHack(index.global());

        distributed_material_law_manager->oilWaterScaledEpsInfoDrainagePointerReferenceHack(index.local()) =
            material_law_manager->oilWaterScaledEpsInfoDrainagePointerReferenceHack(index.global());
    }
    BlackoilPropsAdFromDeck distributed_props(properties,
                                              distributed_material_law_manager,
                                              grid.numCells());
    BlackoilState distributed_state(grid.numCells(), grid.numFaces(), state.numPhases());
    BlackoilStateDataHandle state_handle(global_grid, grid,
                                         state, distributed_state);
    BlackoilPropsDataHandle props_handle(properties,
                                         distributed_props);
    grid.scatterData(state_handle);
    grid.scatterData(props_handle);
    // Create a distributed Geology. Some values will be updated using communication
    // below
    DerivedGeology distributed_geology(grid,
                                       distributed_props, eclipseState,
                                       useLocalPerm, geology.gravity());
    GeologyDataHandle geo_handle(global_grid, grid,
                                 geology, distributed_geology);
    grid.scatterData(geo_handle);

    std::vector<double> distributed_pressures;

    if( !threshold_pressures.empty() ) // Might be empty if not specified
    {
        if( threshold_pressures.size() !=
            static_cast<std::size_t>(UgGridHelpers::numFaces(global_grid)) )
        {
            OPM_THROW(std::runtime_error, "NNCs not yet supported for parallel runs. "
                      << UgGridHelpers::numFaces(grid) << " faces but " <<
                      threshold_pressures.size()<<" threshold pressure values");
        }
        distributed_pressures.resize(UgGridHelpers::numFaces(grid));
        ThresholdPressureDataHandle press_handle(global_grid, grid,
                                                 threshold_pressures,
                                                 distributed_pressures);
        grid.scatterData(press_handle);
    }

    // copy states
    properties           = distributed_props;
    geology              = distributed_geology;
    state                = distributed_state;
    material_law_manager = distributed_material_law_manager;
    threshold_pressures   = distributed_pressures;
    extractParallelGridInformationToISTL(grid, parallelInformation);
}
예제 #15
0
FaceCentroidTraits<Dune::CpGrid>::ValueType
faceCentroid(const Dune::CpGrid& grid, int face_index)
{
    return grid.faceCentroid(face_index);
}
예제 #16
0
double cellVolume(const  Dune::CpGrid& grid, int cell_index)
{
    return grid.cellVolume(cell_index);
}
예제 #17
0
double faceArea(const Dune::CpGrid& grid, int face_index)
{
    return grid.faceArea(face_index);
}