20 #ifndef OPM_COMPOSITIONAL_WELL_MODEL_IMPL_HPP 21 #define OPM_COMPOSITIONAL_WELL_MODEL_IMPL_HPP 24 #ifndef OPM_COMPOSITIONAL_WELL_MODEL_HPP 26 #include <flowexperimental/comp/wells/CompWellModel.hpp> 31 #include <opm/input/eclipse/EclipseState/EclipseState.hpp> 32 #include <opm/input/eclipse/Schedule/Schedule.hpp> 33 #include <opm/input/eclipse/Schedule/Well/WellConnections.hpp> 37 template <
typename TypeTag>
38 CompWellModel<TypeTag>::CompWellModel(Simulator& simulator,
const NewtonIterationContext& )
39 : WellConnectionModule(*this, simulator.gridView().comm())
40 , simulator_(simulator)
41 , schedule_(simulator.vanguard().schedule())
42 , summary_state_(simulator.vanguard().summaryState())
43 , ecl_state_(simulator.vanguard().eclState())
44 , comm_(simulator.gridView().comm())
45 , comp_config_(ecl_state_.compositionalConfig())
46 , comp_well_states_(comp_config_)
47 , last_valid_comp_well_states_(comp_config_)
49 local_num_cells_ = simulator.gridView().size(0);
52 template <
typename TypeTag>
54 CompWellModel<TypeTag>::
55 beginReportStep(
unsigned report_step)
58 report_step_start_events_ = schedule_[report_step].wellgroup_events();
59 wells_ecl_ = schedule_.getWells(report_step);
61 constexpr
auto events_mask = ScheduleEvents::WELL_STATUS_CHANGE |
62 ScheduleEvents::REQUEST_OPEN_WELL |
63 ScheduleEvents::REQUEST_SHUT_WELL;
64 for (
const auto& well_ecl : wells_ecl_) {
65 if (!well_ecl.hasConnections()) {
69 if (!report_step_start_events_.hasEvent(well_ecl.name(), events_mask)) {
73 if (well_ecl.getStatus() == WellStatus::OPEN) {
74 well_open_times_.insert_or_assign(well_ecl.name(), simulator_.time());
75 well_close_times_.erase(well_ecl.name());
77 else if (well_ecl.getStatus() == WellStatus::SHUT) {
78 well_close_times_.insert_or_assign(well_ecl.name(), simulator_.time());
79 well_open_times_.erase(well_ecl.name());
83 initWellConnectionData();
86 last_valid_comp_well_states_.copyDynamicStateFrom(comp_well_states_);
89 template <
typename TypeTag>
91 CompWellModel<TypeTag>::
94 createWellContainer();
98 template <
typename TypeTag>
100 CompWellModel<TypeTag>::
101 restoreLastValidState()
103 comp_well_states_.copyDynamicStateFrom(last_valid_comp_well_states_);
106 template <
typename TypeTag>
108 CompWellModel<TypeTag>::
113 last_valid_comp_well_states_.copyDynamicStateFrom(comp_well_states_);
116 template <
typename TypeTag>
118 CompWellModel<TypeTag>::
121 simulator_.model().addAuxiliaryModule(
this);
124 template <
typename TypeTag>
126 CompWellModel<TypeTag>::
127 createWellContainer()
130 const auto nw = wells_ecl_.size();
131 well_container_.clear();
132 for (
auto w = 0 * nw; w < nw; ++w) {
133 const auto& well_name = wells_ecl_[w].name();
134 if (comp_well_states_.has(well_name)
135 && comp_well_states_[well_name].status == WellStatus::SHUT) {
139 well_container_.emplace_back(std::make_shared<CompWell<TypeTag>>(wells_ecl_[w], w, well_connection_data_[w]));
143 template <
typename TypeTag>
145 CompWellModel<TypeTag>::
148 for (
auto& well : well_container_) {
153 template <
typename TypeTag>
155 CompWellModel<TypeTag>::
156 initWellConnectionData()
160 well_connection_data_.resize(wells_ecl_.size());
163 for (
const auto& well : wells_ecl_) {
164 int connection_index = 0;
165 const auto& well_connections = well.getConnections();
166 auto& well_connection_data = well_connection_data_[well_index];
168 well_connection_data.reserve(well_connections.size());
169 for (
const auto& connection : well_connections) {
170 const auto active_index =
171 this->compressedIndexForInterior(connection.global_index());
173 const auto connIsOpen =
174 connection.state() == Connection::State::OPEN;
176 if (connIsOpen && (active_index >= 0)) {
177 auto& pd = well_connection_data_[well_index].emplace_back();
179 pd.cell_index = active_index;
180 pd.connection_transmissibility_factor = connection.CF();
181 pd.satnum_id = connection.satTableId();
182 pd.ecl_index = connection_index;
191 template <
typename TypeTag>
193 CompWellModel<TypeTag>::
197 const auto pressIx = []()
199 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) ) {
200 return FluidSystem::oilPhaseIdx;
202 if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) ) {
203 return FluidSystem::gasPhaseIdx;
205 assert(
false &&
"the usage of oil and gas phase is not correct");
206 return FluidSystem::gasPhaseIdx;
209 auto cell_pressure = std::vector<Scalar>(this->local_num_cells_, Scalar{0.});
210 auto cell_mole_fractions = std::vector<std::vector<Scalar>>(this->local_num_cells_,
211 std::vector<Scalar>(FluidSystem::numComponents, Scalar{0.}));
213 auto cell_temperature = std::vector<Scalar>(this->local_num_cells_, Scalar{0.});
215 auto elemCtx = ElementContext { this->simulator_ };
216 const auto& gridView = this->simulator_.vanguard().gridView();
218 OPM_BEGIN_PARALLEL_TRY_CATCH();
219 for (
const auto& elem : elements(gridView, Dune::Partitions::interior)) {
220 elemCtx.updatePrimaryStencil(elem);
221 elemCtx.updatePrimaryIntensiveQuantities(0);
223 const auto ix = elemCtx.globalSpaceIndex(0, 0);
224 const auto& fs = elemCtx.intensiveQuantities(0, 0).fluidState();
226 cell_pressure[ix] = fs.pressure(pressIx).value();
228 cell_temperature[ix] = fs.temperature(0).value();
229 for (
unsigned compIdx = 0; compIdx < FluidSystem::numComponents; ++compIdx) {
230 cell_mole_fractions[ix][compIdx] = fs.moleFraction(compIdx).value();
233 OPM_END_PARALLEL_TRY_CATCH(
"ComposotionalWellModel::initializeWellState() failed: ",
234 this->simulator_.vanguard().grid().comm());
241 this->comp_well_states_.init(this->wells_ecl_,
242 cell_pressure, cell_temperature[0], cell_mole_fractions, this->well_connection_data_,
243 this->summary_state_,
248 template <
typename TypeTag>
250 CompWellModel<TypeTag>::
251 compressedIndexForInterior(std::size_t cartesian_cell_idx)
const 253 return simulator_.vanguard().compressedIndexForInterior(cartesian_cell_idx);
256 template <
typename TypeTag>
258 CompWellModel<TypeTag>::
259 getCellsForConnections(
const Well& well)
const 261 std::vector<int> wellCells;
263 const auto& connectionSet = well.getConnections();
264 wellCells.reserve(connectionSet.size());
266 for (
const auto& connection : connectionSet)
268 int compressed_idx = compressedIndexForInterior(connection.global_index());
269 if (compressed_idx >= 0) {
270 wellCells.push_back(compressed_idx);
278 template <
typename TypeTag>
280 CompWellModel<TypeTag>::
284 const auto& grid = simulator_.vanguard().grid();
285 const auto& gridView = grid.leafGridView();
286 ElementContext elemCtx(simulator_);
287 for (
const auto& elem : elements(gridView, Dune::Partitions::interior)) {
288 elemCtx.updatePrimaryStencil(elem);
289 elemCtx.updatePrimaryIntensiveQuantities(0);
292 assemble(simulator_.timeStepSize());
295 template <
typename TypeTag>
297 CompWellModel<TypeTag>::
298 assemble(
const double dt)
300 const int iterationIdx = simulator_.problem().iterationContext().iteration();
302 if (iterationIdx == 0) {
303 this->calculateExplicitQuantities();
305 for (
auto& well : well_container_) {
306 auto& well_state = comp_well_states_[well->name()];
307 well->iterateWellEq(simulator_, dt, well_state);
313 template <
typename TypeTag>
315 CompWellModel<TypeTag>::
316 calculateExplicitQuantities()
318 for (
auto& well : well_container_) {
319 const auto& well_state = comp_well_states_[well->name()];
320 well->calculateExplicitQuantities(simulator_, well_state);
324 template <
typename TypeTag>
326 CompWellModel<TypeTag>::
327 computeTotalRatesForDof(RateVector& rate,
328 unsigned globalIdx)
const {
329 for (
const auto& well: well_container_) {
330 well->addCellRates(rate, globalIdx);
334 template<
typename TypeTag>
336 CompWellModel<TypeTag>::
337 recoverWellSolutionAndUpdateWellState(
const BVector& x)
340 for (
const auto& well : well_container_) {
341 const auto& cells = well->cells();
342 x_local_.resize(cells.size());
344 for (
size_t i = 0; i < cells.size(); ++i) {
345 x_local_[i] = x[cells[i]];
347 auto& ws = this->comp_well_states_[well->name()];
348 well->recoverWellSolutionAndUpdateWellState(x_local_, ws);
353 template <
typename TypeTag>
355 CompWellModel<TypeTag>::
356 forceShutWellByName(
const std::string& well_name,
357 double simulation_time,
360 int well_was_shut = 0;
362 if (comp_well_states_.has(well_name)) {
363 auto& well_state = comp_well_states_[well_name];
364 if (well_state.status != WellStatus::SHUT) {
365 well_state.status = WellStatus::SHUT;
366 well_close_times_.insert_or_assign(well_name, simulation_time);
367 well_open_times_.erase(well_name);
369 if (last_valid_comp_well_states_.has(well_name)) {
370 last_valid_comp_well_states_[well_name].status = WellStatus::SHUT;
373 std::erase_if(well_container_,
374 [&well_name](
const auto& well)
375 {
return well->name() == well_name; });
381 well_was_shut = comm_.max(well_was_shut);
382 return well_was_shut == 1;
385 template <
typename TypeTag>
387 CompWellModel<TypeTag>::
388 getWellConvergence()
const 390 bool converged =
true;
391 for (
const auto& well : this->well_container_) {
392 converged = converged && well->getConvergence();
397 template <
typename TypeTag>
399 CompWellModel<TypeTag>::
402 return this->comp_well_states_.report();
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45