int main(int argc, char** argv) { Opm::parameter::ParameterGroup param(argc, argv); CpGrid grid; grid.init(param); typedef CpGrid::LeafGridView View; View g = grid.leafView(); typedef FieldVector<double, 3> Pt; int c_local = 0; for (View::Codim<0>::Iterator c_it = g.begin<0>(); c_it != g.end<0>(); ++c_it, ++c_local) { Pt cell_centroid = c_it->geometry().center(); int f_local = 0; bool trouble = false; for (View::IntersectionIterator f_it = g.ibegin(*c_it); f_it != g.iend(*c_it); ++f_it, ++f_local) { Pt face_centroid = f_it->geometry().center(); Pt face_normal = f_it->centerUnitOuterNormal(); if (face_normal*(face_centroid - cell_centroid) < 0.0) { trouble = true; std::cout << "Encountered troublesome geometry (centroid difference dot normal is negative) " "in cell " << c_local << " local face " << f_local << std::endl; } } if (trouble) { std::cout << "Cell " << c_local << " had a total of " << f_local << " faces." << std::endl; } } }
int main(int argc, char** argv) { // Create a grid. Opm::parameter::ParameterGroup param(argc, argv); CpGrid grid; grid.init(param); }
int main(int argc, char** argv) { parameter::ParameterGroup param(argc, argv); CpGrid grid; grid.init(param); grid.setUniqueBoundaryIds(true); GridInterfaceEuler<CpGrid> gi(grid); typedef FlowBC FBC; boost::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; boost::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; }
inline void setupGridAndProps(const Opm::parameter::ParameterGroup& param, CpGrid& grid, ResProp<3>& res_prop) { // Initialize grid and reservoir properties. // Parts copied from 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); MESSAGE("Warning: We do not yet read legacy reservoir properties. Using defaults."); res_prop.init(grid.size(0)); } else 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); 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(parser, grid.globalCell(), perm_threshold, rl_ptr, use_j, sigma, theta); } else if (fileformat == "cartesian") { array<int, 3> dims = {{ param.getDefault<int>("nx", 1), param.getDefault<int>("ny", 1), param.getDefault<int>("nz", 1) }}; 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); MESSAGE("Warning: For generated cartesian grids, we use uniform reservoir properties."); res_prop.init(grid.size(0), default_poro, default_perm); } else { THROW("Unknown file format string: " << fileformat); } if (param.getDefault("use_unique_boundary_ids", false)) { grid.setUniqueBoundaryIds(true); } }
CombinedGridWellGraph::CombinedGridWellGraph(const CpGrid& grid, const Opm::EclipseStateConstPtr eclipseState, const double* transmissibilities, bool pretendEmptyGrid) : grid_(grid), eclipseState_(eclipseState), transmissibilities_(transmissibilities) { if ( pretendEmptyGrid ) { // wellsGraph not needed return; } wellsGraph_.resize(grid.numCells()); const auto& cpgdim = grid.logicalCartesianSize(); // create compressed lookup from cartesian. std::vector<Opm::WellConstPtr> wells = eclipseState->getSchedule()->getWells(); std::vector<int> cartesian_to_compressed(cpgdim[0]*cpgdim[1]*cpgdim[2], -1); int last_time_step = eclipseState->getSchedule()->getTimeMap()->size()-1; for( int i=0; i < grid.numCells(); ++i ) { cartesian_to_compressed[grid.globalCell()[i]] = i; } // We assume that we know all the wells. for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) { Opm::WellConstPtr well = (*wellIter); std::set<int> well_indices; Opm::CompletionSetConstPtr completionSet = well->getCompletions(last_time_step); for (size_t c=0; c<completionSet->size(); c++) { Opm::CompletionConstPtr completion = completionSet->get(c); int i = completion->getI(); int j = completion->getJ(); int k = completion->getK(); int cart_grid_idx = i + cpgdim[0]*(j + cpgdim[1]*k); int compressed_idx = cartesian_to_compressed[cart_grid_idx]; if ( compressed_idx >= 0 ) // Ignore completions in inactive cells. { well_indices.insert(compressed_idx); } } addCompletionSetToGraph(well_indices); } }
inline void setupGridAndPropsEclipse(const Opm::EclipseGridParser& parser, double z_tolerance, 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, CpGrid& grid, ResProp<3>& res_prop) { grid.processEclipseFormat(parser, z_tolerance, periodic_extension, turn_normals, clip_z); const std::string* rl_ptr = (rock_list == "no_list") ? 0 : &rock_list; res_prop.init(parser, grid.globalCell(), perm_threshold, rl_ptr, use_jfunction_scaling, sigma, theta); if (unique_bids) { grid.setUniqueBoundaryIds(true); } }
CombinedGridWellGraph::CombinedGridWellGraph(const CpGrid& grid, const Opm::EclipseState* eclipseState, const double* transmissibilities, bool pretendEmptyGrid) : grid_(grid), transmissibilities_(transmissibilities) { if ( pretendEmptyGrid ) { // wellsGraph not needed return; } wellsGraph_.resize(grid.numCells()); const auto& cpgdim = grid.logicalCartesianSize(); // create compressed lookup from cartesian. std::vector<int> cartesian_to_compressed(cpgdim[0]*cpgdim[1]*cpgdim[2], -1); for( int i=0; i < grid.numCells(); ++i ) { cartesian_to_compressed[grid.globalCell()[i]] = i; } well_indices_.init(*eclipseState, cpgdim, cartesian_to_compressed); std::vector<int>().swap(cartesian_to_compressed); // free memory. addCompletionSetToGraph(); }
std::vector<int> zoltanGraphPartitionGridOnRoot(const CpGrid& cpgrid, const CollectiveCommunication<MPI_Comm>& cc, int root) { int rc; float ver; struct Zoltan_Struct *zz; int changes, numGidEntries, numLidEntries, numImport, numExport; ZOLTAN_ID_PTR importGlobalGids, importLocalGids, exportGlobalGids, exportLocalGids; int *importProcs, *importToPart, *exportProcs, *exportToPart; int argc=0; char** argv; rc = Zoltan_Initialize(argc, argv, &ver); zz = Zoltan_Create(cc); if ( rc != ZOLTAN_OK ) { OPM_THROW(std::runtime_error, "Could not initialize Zoltan!"); } Zoltan_Set_Param(zz, "DEBUG_LEVEL", "0"); Zoltan_Set_Param(zz, "LB_METHOD", "GRAPH"); Zoltan_Set_Param(zz, "LB_APPROACH", "PARTITION"); Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1"); Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "1"); Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL"); Zoltan_Set_Param(zz, "DEBUG_LEVEL", "3"); Zoltan_Set_Param(zz, "CHECK_GRAPH", "2"); Zoltan_Set_Param(zz, "PHG_EDGE_SIZE_THRESHOLD", ".35"); /* 0-remove all, 1-remove none */ bool pretendEmptyGrid = cc.rank()!=root; Dune::cpgrid::setCpGridZoltanGraphFunctions(zz, cpgrid, pretendEmptyGrid); rc = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */ &changes, /* 1 if partitioning was changed, 0 otherwise */ &numGidEntries, /* Number of integers used for a global ID */ &numLidEntries, /* Number of integers used for a local ID */ &numImport, /* Number of vertices to be sent to me */ &importGlobalGids, /* Global IDs of vertices to be sent to me */ &importLocalGids, /* Local IDs of vertices to be sent to me */ &importProcs, /* Process rank for source of each incoming vertex */ &importToPart, /* New partition for each incoming vertex */ &numExport, /* Number of vertices I must send to other processes*/ &exportGlobalGids, /* Global IDs of the vertices I must send */ &exportLocalGids, /* Local IDs of the vertices I must send */ &exportProcs, /* Process to which I send each of the vertices */ &exportToPart); /* Partition to which each vertex will belong */ int size = cpgrid.numCells(); int rank = cc.rank(); std::vector<int> parts=std::vector<int>(size, rank); for ( int i=0; i < numExport; ++i ) { parts[exportLocalGids[i]] = exportProcs[i]; } cc.broadcast(&parts[0], parts.size(), root); Zoltan_LB_Free_Part(&exportGlobalGids, &exportLocalGids, &exportProcs, &exportToPart); Zoltan_LB_Free_Part(&importGlobalGids, &importLocalGids, &importProcs, &importToPart); Zoltan_Destroy(&zz); return parts; }
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; }
int main(int argc, char** argv) try { Dune::MPIHelper::instance(argc,argv); // Dummy if no MPI. CpGrid grid; if (argc != 2) { std::cout << "Usage: grdecl2vtu filename.grdecl" << std::endl; exit(1); } const char* eclipsefilename = argv[1]; #if HAVE_OPM_PARSER Opm::ParseContext parseContext; Opm::Parser parser; auto deck = parser.parseFile(eclipsefilename, parseContext); // Get logical cartesian grid dimensions. std::array<size_t, 3> dims; if (deck.hasKeyword("SPECGRID")) { const auto& specgridRecord = deck.getKeyword("SPECGRID").getRecord(0); dims[0] = specgridRecord.getItem("NX").get< int >(0); dims[1] = specgridRecord.getItem("NY").get< int >(0); dims[2] = specgridRecord.getItem("NZ").get< int >(0); } else if (deck.hasKeyword("DIMENS")) { const auto& dimensRecord = deck.getKeyword("DIMENS").getRecord(0); dims[0] = dimensRecord.getItem("NX").get< int >(0); dims[1] = dimensRecord.getItem("NY").get< int >(0); dims[2] = dimensRecord.getItem("NZ").get< int >(0); } else { OPM_THROW(std::runtime_error, "Found neither SPECGRID nor DIMENS in file. At least one is needed."); } { const int* actnum = deck.hasKeyword("ACTNUM") ? deck.getKeyword("ACTNUM").getIntData().data() : nullptr; Opm::EclipseGrid ecl_grid(deck , actnum); grid.processEclipseFormat(ecl_grid, false); } #endif VTKWriter<CpGrid::LeafGridView> vtkwriter(grid.leafGridView()); #if HAVE_OPM_PARSER const std::vector<int>& global_cell = grid.globalCell(); std::vector<double> poros; condWriteDoubleField(poros, "PORO", deck, global_cell, dims, vtkwriter); std::vector<double> permxs; condWriteDoubleField(permxs, "PERMX", deck, global_cell, dims, vtkwriter); std::vector<double> permys; condWriteDoubleField(permys, "PERMY", deck, global_cell, dims, vtkwriter); std::vector<double> permzs; condWriteDoubleField(permzs, "PERMZ", deck, global_cell, dims, vtkwriter); std::vector<double> actnums; condWriteIntegerField(actnums, "ACTNUM", deck, global_cell, dims, vtkwriter); std::vector<double> satnums; condWriteIntegerField(satnums, "SATNUM", deck, global_cell, dims, vtkwriter); std::vector<double> regnums; condWriteIntegerField(regnums, "REGNUM", deck, global_cell, dims, vtkwriter); std::vector<double> swats; condWriteDoubleField(swats, "SWAT", deck, global_cell, dims, vtkwriter); #endif // #if HAVE_OPM_PARSER std::string fname(eclipsefilename); std::string fnamebase = fname.substr(0, fname.find_last_of('.')); std::cout << "Writing to filename " << fnamebase << ".vtu" << std::endl; vtkwriter.write(fnamebase, VTK::ascii); } catch (const std::exception &e) { std::cerr << "Program threw an exception: " << e.what() << "\n"; throw; }