Beispiel #1
0
    void
    PolymerInflowFromDeck::setInflowValues(Opm::DeckConstPtr deck,
                                           Opm::EclipseStateConstPtr eclipseState,
                                           size_t currentStep)
    {
        Opm::DeckKeywordConstPtr keyword = deck->getKeyword("WPOLYMER");
        
        //        Schedule schedule(deck);
        ScheduleConstPtr schedule = eclipseState->getSchedule();
        for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) {
            DeckRecordConstPtr record = keyword->getRecord(recordNr);

            const std::string& wellNamesPattern = record->getItem("WELL")->getTrimmedString(0);
            std::string wellName = record->getItem("WELL")->getTrimmedString(0);
            std::vector<WellPtr> wells = schedule->getWells(wellNamesPattern);
            for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter) {
                WellPtr well = *wellIter;
                WellInjectionProperties injection = well->getInjectionProperties(currentStep);
                if (injection.injectorType == WellInjector::WATER) {
                    WellPolymerProperties polymer = well->getPolymerProperties(currentStep);
                    wellPolymerRate_.insert(std::make_pair(wellName, polymer.m_polymerConcentration));
                } else {
                    OPM_THROW(std::logic_error, "For polymer injector you must have a water injector");
                }
            }
        }
    }
Beispiel #2
0
void
WellsManager::init(const Opm::EclipseStateConstPtr eclipseState,
                   const size_t                    timeStep,
                   int                             number_of_cells,
                   const int*                      global_cell,
                   const int*                      cart_dims,
                   int                             dimensions,
                   const C2F&                      cell_to_faces,
                   FC                              begin_face_centroids,
                   const double*                   permeability)
{
    if (dimensions != 3) {
        OPM_THROW(std::runtime_error,
                  "We cannot initialize wells from a deck unless "
                  "the corresponding grid is 3-dimensional.");
    }

    if (eclipseState->getSchedule()->numWells() == 0) {
        OPM_MESSAGE("No wells specified in Schedule section, "
                    "initializing no wells");
        return;
    }

    std::map<int,int> cartesian_to_compressed;
    setupCompressedToCartesian(global_cell, number_of_cells,
                               cartesian_to_compressed);

    // Obtain phase usage data.
    PhaseUsage pu = phaseUsageFromDeck(eclipseState);

    // These data structures will be filled in this constructor,
    // then used to initialize the Wells struct.
    std::vector<std::string> well_names;
    std::vector<WellData> well_data;


    // For easy lookup:
    std::map<std::string, int> well_names_to_index;

    ScheduleConstPtr          schedule = eclipseState->getSchedule();
    std::vector<WellConstPtr> wells    = schedule->getWells(timeStep);
    std::vector<int>          wells_on_proc;

    well_names.reserve(wells.size());
    well_data.reserve(wells.size());

    typedef GridPropertyAccess::ArrayPolicy::ExtractFromDeck<double> DoubleArray;
    typedef GridPropertyAccess::Compressed<DoubleArray, GridPropertyAccess::Tag::NTG> NTGArray;

    DoubleArray ntg_glob(eclipseState, "NTG", 1.0);
    NTGArray    ntg(ntg_glob, global_cell);

    EclipseGridConstPtr eclGrid = eclipseState->getEclipseGrid();

    // use cell thickness (dz) from eclGrid
    // dz overwrites values calculated by WellDetails::getCubeDim
    std::vector<double> dz(number_of_cells);
    {
        std::vector<int> gc = compressedToCartesian(number_of_cells, global_cell);
        for (int cell = 0; cell < number_of_cells; ++cell) {
            dz[cell] = eclGrid->getCellThicknes(gc[cell]);
        }
    }

    createWellsFromSpecs(wells, timeStep, cell_to_faces,
                         cart_dims,
                         begin_face_centroids,
                         dimensions,
                         dz,
                         well_names, well_data, well_names_to_index,
                         pu, cartesian_to_compressed, permeability, ntg,
                         wells_on_proc);

    setupWellControls(wells, timeStep, well_names, pu, wells_on_proc);

    {
        GroupTreeNodeConstPtr fieldNode =
            schedule->getGroupTree(timeStep)->getNode("FIELD");

        GroupConstPtr fieldGroup =
            schedule->getGroup(fieldNode->name());

        well_collection_.addField(fieldGroup, timeStep, pu);
        addChildGroups(fieldNode, schedule, timeStep, pu);
    }

    for (auto w = wells.begin(), e = wells.end(); w != e; ++w) {
        well_collection_.addWell(*w, timeStep, pu);
    }

    well_collection_.setWellsPointer(w_);
    well_collection_.applyGroupControls();

    setupGuideRates(wells, timeStep, well_data, well_names_to_index);

    // Debug output.
#define EXTRA_OUTPUT
#ifdef EXTRA_OUTPUT
    /*
      std::cout << "\t WELL DATA" << std::endl;
      for(int i = 0; i< num_wells; ++i) {
      std::cout << i << ": " << well_data[i].type << "  "
      << well_data[i].control << "  " << well_data[i].target
      << std::endl;
      }

      std::cout << "\n\t PERF DATA" << std::endl;
      for(int i=0; i< int(wellperf_data.size()); ++i) {
      for(int j=0; j< int(wellperf_data[i].size()); ++j) {
      std::cout << i << ": " << wellperf_data[i][j].cell << "  "
      << wellperf_data[i][j].well_index << std::endl;
      }
      }
    */
#endif
}
    void SimulatorFullyImplicitBlackoilPolymer<GridT>::
    computeRepRadiusPerfLength(const Opm::EclipseStateConstPtr eclipseState,
                               const size_t                    timeStep,
                               const GridT&                    grid,
                               std::vector<double>&            wells_rep_radius,
                               std::vector<double>&            wells_perf_length,
                               std::vector<double>&            wells_bore_diameter)
    {

        // TODO, the function does not work for parallel running
        // to be fixed later.
        int number_of_cells = Opm::UgGridHelpers::numCells(grid);
        const int* global_cell = Opm::UgGridHelpers::globalCell(grid);
        const int* cart_dims = Opm::UgGridHelpers::cartDims(grid);
        auto cell_to_faces = Opm::UgGridHelpers::cell2Faces(grid);
        auto begin_face_centroids = Opm::UgGridHelpers::beginFaceCentroids(grid);

        if (eclipseState->getSchedule()->numWells() == 0) {
            OPM_MESSAGE("No wells specified in Schedule section, "
                        "initializing no wells");
            return;
        }

        const size_t n_perf = wells_rep_radius.size();

        wells_rep_radius.clear();
        wells_perf_length.clear();
        wells_bore_diameter.clear();

        wells_rep_radius.reserve(n_perf);
        wells_perf_length.reserve(n_perf);
        wells_bore_diameter.reserve(n_perf);

        std::map<int,int> cartesian_to_compressed;

        setupCompressedToCartesian(global_cell, number_of_cells,
                                   cartesian_to_compressed);

        ScheduleConstPtr          schedule = eclipseState->getSchedule();
        std::vector<WellConstPtr> wells    = schedule->getWells(timeStep);

        int well_index = 0;

        for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) {
             WellConstPtr well = (*wellIter);

             if (well->getStatus(timeStep) == WellCommon::SHUT) {
                 continue;
             }
             {   // COMPDAT handling
                 CompletionSetConstPtr completionSet = well->getCompletions(timeStep);
                 for (size_t c=0; c<completionSet->size(); c++) {
                     CompletionConstPtr completion = completionSet->get(c);
                     if (completion->getState() == WellCompletion::OPEN) {
                         int i = completion->getI();
                         int j = completion->getJ();
                         int k = completion->getK();

                         const int* cpgdim = cart_dims;
                         int cart_grid_indx = i + cpgdim[0]*(j + cpgdim[1]*k);
                         std::map<int, int>::const_iterator cgit = cartesian_to_compressed.find(cart_grid_indx);
                         if (cgit == cartesian_to_compressed.end()) {
                             OPM_THROW(std::runtime_error, "Cell with i,j,k indices " << i << ' ' << j << ' '
                                       << k << " not found in grid (well = " << well->name() << ')');
                         }
                         int cell = cgit->second;

                         {
                             double radius = 0.5*completion->getDiameter();
                             if (radius <= 0.0) {
                                 radius = 0.5*unit::feet;
                                 OPM_MESSAGE("**** Warning: Well bore internal radius set to " << radius);
                             }

                             const std::array<double, 3> cubical =
                             WellsManagerDetail::getCubeDim<3>(cell_to_faces, begin_face_centroids, cell);

                             WellCompletion::DirectionEnum direction = completion->getDirection();

                             double re; // area equivalent radius of the grid block
                             double perf_length; // the length of the well perforation

                             switch (direction) {
                                 case Opm::WellCompletion::DirectionEnum::X:
                                     re = std::sqrt(cubical[1] * cubical[2] / M_PI);
                                     perf_length = cubical[0];
                                     break;
                                 case Opm::WellCompletion::DirectionEnum::Y:
                                     re = std::sqrt(cubical[0] * cubical[2] / M_PI);
                                     perf_length = cubical[1];
                                     break;
                                 case Opm::WellCompletion::DirectionEnum::Z:
                                     re = std::sqrt(cubical[0] * cubical[1] / M_PI);
                                     perf_length = cubical[2];
                                     break;
                                 default:
                                     OPM_THROW(std::runtime_error, " Dirtecion of well is not supported ");
                             }

                             double repR = std::sqrt(re * radius);
                             wells_rep_radius.push_back(repR);
                             wells_perf_length.push_back(perf_length);
                             wells_bore_diameter.push_back(2. * radius);
                         }
                     } else {
                         if (completion->getState() != WellCompletion::SHUT) {
                             OPM_THROW(std::runtime_error, "Completion state: " << WellCompletion::StateEnum2String( completion->getState() ) << " not handled");
                         }
                     }

                 }
            }
            well_index++;
        }
    }