24 template <
class Gr
idT>
28 const DerivedGeology& geo,
29 BlackoilPropsAdInterface& props,
31 const RockCompressibility* rock_comp_props,
32 NewtonIterationBlackoilInterface& linsolver,
33 const double* gravity,
34 const bool has_disgas,
35 const bool has_vapoil,
36 const bool has_polymer,
37 const bool has_plyshlog,
38 const bool has_shrate,
39 std::shared_ptr<EclipseState> eclipse_state,
40 BlackoilOutputWriter& output_writer,
41 Opm::DeckConstPtr& deck,
42 const std::vector<double>& threshold_pressures_by_face)
54 threshold_pressures_by_face)
55 , polymer_props_(polymer_props)
56 , has_polymer_(has_polymer)
57 , has_plyshlog_(has_plyshlog)
58 , has_shrate_(has_shrate)
63 template <
class Gr
idT>
66 -> std::unique_ptr<Solver>
68 typedef typename Traits::Model Model;
71 auto model = std::unique_ptr<Model>(
new Model(BaseType::model_param_,
75 BaseType::rock_comp_props_,
79 BaseType::eclipse_state_,
80 BaseType::has_disgas_,
81 BaseType::has_vapoil_,
88 BaseType::terminal_output_));
90 if (!BaseType::threshold_pressures_by_face_.empty()) {
91 model->setThresholdPressures(BaseType::threshold_pressures_by_face_);
94 return std::unique_ptr<Solver>(
new Solver(BaseType::solver_param_, std::move(model)));
100 template <
class Gr
idT>
103 WellsManager& wells_manager,
104 typename BaseType::WellState& well_state,
108 std::unique_ptr<PolymerInflowInterface> polymer_inflow_ptr;
109 if (deck_->hasKeyword(
"WPOLYMER")) {
110 if (wells_manager.c_wells() == 0) {
111 OPM_THROW(std::runtime_error,
"Cannot control polymer injection via WPOLYMER without wells.");
113 polymer_inflow_ptr.reset(
new PolymerInflowFromDeck(deck_, BaseType::eclipse_state_, *wells, Opm::UgGridHelpers::numCells(BaseType::grid_), timer.currentStepNum()));
119 std::vector<double> polymer_inflow_c(Opm::UgGridHelpers::numCells(BaseType::grid_));
121 timer.simulationTimeElapsed() + timer.currentStepLength(),
123 well_state.polymerInflow() = polymer_inflow_c;
125 computeRepRadiusPerfLength(BaseType::eclipse_state_, timer.currentStepNum(), BaseType::grid_, wells_rep_radius_, wells_perf_length_, wells_bore_diameter_);
129 template <
class Gr
idT>
132 std::map<int,int>& cartesian_to_compressed )
135 for (
int i = 0; i < number_of_cells; ++i) {
136 cartesian_to_compressed.insert(std::make_pair(global_cell[i], i));
140 for (
int i = 0; i < number_of_cells; ++i) {
141 cartesian_to_compressed.insert(std::make_pair(i, i));
148 template <
class Gr
idT>
149 void SimulatorFullyImplicitBlackoilPolymer<GridT>::
150 computeRepRadiusPerfLength(
const Opm::EclipseStateConstPtr eclipseState,
151 const size_t timeStep,
153 std::vector<double>& wells_rep_radius,
154 std::vector<double>& wells_perf_length,
155 std::vector<double>& wells_bore_diameter)
160 int number_of_cells = Opm::UgGridHelpers::numCells(grid);
161 const int* global_cell = Opm::UgGridHelpers::globalCell(grid);
162 const int* cart_dims = Opm::UgGridHelpers::cartDims(grid);
163 auto cell_to_faces = Opm::UgGridHelpers::cell2Faces(grid);
164 auto begin_face_centroids = Opm::UgGridHelpers::beginFaceCentroids(grid);
166 if (eclipseState->getSchedule()->numWells() == 0) {
167 OPM_MESSAGE(
"No wells specified in Schedule section, "
168 "initializing no wells");
172 const size_t n_perf = wells_rep_radius.size();
174 wells_rep_radius.clear();
175 wells_perf_length.clear();
176 wells_bore_diameter.clear();
178 wells_rep_radius.reserve(n_perf);
179 wells_perf_length.reserve(n_perf);
180 wells_bore_diameter.reserve(n_perf);
182 std::map<int,int> cartesian_to_compressed;
184 setupCompressedToCartesian(global_cell, number_of_cells,
185 cartesian_to_compressed);
187 ScheduleConstPtr schedule = eclipseState->getSchedule();
188 std::vector<WellConstPtr> wells = schedule->getWells(timeStep);
192 for (
auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) {
193 WellConstPtr well = (*wellIter);
195 if (well->getStatus(timeStep) == WellCommon::SHUT) {
199 CompletionSetConstPtr completionSet = well->getCompletions(timeStep);
200 for (
size_t c=0; c<completionSet->size(); c++) {
201 CompletionConstPtr completion = completionSet->get(c);
202 if (completion->getState() == WellCompletion::OPEN) {
203 int i = completion->getI();
204 int j = completion->getJ();
205 int k = completion->getK();
207 const int* cpgdim = cart_dims;
208 int cart_grid_indx = i + cpgdim[0]*(j + cpgdim[1]*k);
209 std::map<int, int>::const_iterator cgit = cartesian_to_compressed.find(cart_grid_indx);
210 if (cgit == cartesian_to_compressed.end()) {
211 OPM_THROW(std::runtime_error,
"Cell with i,j,k indices " << i <<
' ' << j <<
' '
212 << k <<
" not found in grid (well = " << well->name() <<
')');
214 int cell = cgit->second;
217 double radius = 0.5*completion->getDiameter();
219 radius = 0.5*unit::feet;
220 OPM_MESSAGE(
"**** Warning: Well bore internal radius set to " << radius);
223 const std::array<double, 3> cubical =
224 WellsManagerDetail::getCubeDim<3>(cell_to_faces, begin_face_centroids, cell);
226 WellCompletion::DirectionEnum direction = completion->getDirection();
232 case Opm::WellCompletion::DirectionEnum::X:
233 re = std::sqrt(cubical[1] * cubical[2] / M_PI);
234 perf_length = cubical[0];
236 case Opm::WellCompletion::DirectionEnum::Y:
237 re = std::sqrt(cubical[0] * cubical[2] / M_PI);
238 perf_length = cubical[1];
240 case Opm::WellCompletion::DirectionEnum::Z:
241 re = std::sqrt(cubical[0] * cubical[1] / M_PI);
242 perf_length = cubical[2];
245 OPM_THROW(std::runtime_error,
" Dirtecion of well is not supported ");
248 double repR = std::sqrt(re * radius);
249 wells_rep_radius.push_back(repR);
250 wells_perf_length.push_back(perf_length);
251 wells_bore_diameter.push_back(2. * radius);
254 if (completion->getState() != WellCompletion::SHUT) {
255 OPM_THROW(std::runtime_error,
"Completion state: " << WellCompletion::StateEnum2String( completion->getState() ) <<
" not handled");
Definition: SimulatorFullyImplicitBlackoilPolymer.hpp:82
std::unique_ptr< Solver > createSolver(const Wells *wells)
Definition: SimulatorFullyImplicitBlackoilPolymer_impl.hpp:65
Definition: CompressibleTpfaPolymer.hpp:32
void handleAdditionalWellInflow(SimulatorTimer &timer, WellsManager &wells_manager, typename BaseType::WellState &well_state, const Wells *wells)
Definition: SimulatorFullyImplicitBlackoilPolymer_impl.hpp:102
virtual void getInflowValues(const double step_start, const double step_end, std::vector< double > &poly_inflow_c) const =0
Basic polymer injection behaviour class. This class gives all injectors the same polymer concentratio...
Definition: PolymerInflow.hpp:59
SimulatorFullyImplicitBlackoilPolymer(const parameter::ParameterGroup ¶m, const GridT &grid, const DerivedGeology &geo, BlackoilPropsAdInterface &props, const PolymerPropsAd &polymer_props, const RockCompressibility *rock_comp_props, NewtonIterationBlackoilInterface &linsolver, const double *gravity, const bool disgas, const bool vapoil, const bool polymer, const bool plyshlog, const bool shrate, std::shared_ptr< EclipseState > eclipse_state, BlackoilOutputWriter &output_writer, Opm::DeckConstPtr &deck, const std::vector< double > &threshold_pressures_by_face)
Definition: SimulatorFullyImplicitBlackoilPolymer_impl.hpp:26
Polymer injection behaviour class using deck WPOLYMER. This class reads the accumulated WPOLYMER line...
Definition: PolymerInflow.hpp:88
Definition: PolymerPropsAd.hpp:32