From cb74d26e856d934ef7bc6147401b29523df2ce17 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Fri, 30 Jun 2023 14:53:19 +0200 Subject: [PATCH] WIP in storing the filtration_particle_volume in BlackoilWellModelGeneric instead of PerfData to handle the situation that well can be SHUT and OPEN again. --- opm/simulators/wells/BlackoilWellModelGeneric.cpp | 15 +++++++++++++++ opm/simulators/wells/BlackoilWellModelGeneric.hpp | 5 +++++ opm/simulators/wells/BlackoilWellModel_impl.hpp | 14 ++++++++------ opm/simulators/wells/PerfData.cpp | 2 -- opm/simulators/wells/PerfData.hpp | 12 ------------ opm/simulators/wells/WellInterfaceGeneric.cpp | 5 ++--- opm/simulators/wells/WellInterfaceGeneric.hpp | 5 +++-- 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index faf22ca47..f3d8b0535 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -1421,6 +1421,21 @@ void BlackoilWellModelGeneric::initInjMult() { } } + +void BlackoilWellModelGeneric::updateFiltrationParticleVolume(const double dt, const size_t water_index) { + for (auto& well : this->well_container_generic_) { + if (well->isInjector() && well->wellEcl().getFilterConc() > 0.) { + auto &values = this->filtration_particle_volume_[well->name()]; + const auto& ws = this->wellState().well(well->indexOfWell()); + if (values.empty()) { + values.assign(ws.perf_data.size(), 0.); // initializing to be zero + } + well->updateFiltrationParticleVolume(dt, water_index, this->wellState(), values); + } + } + +} + void BlackoilWellModelGeneric::updateInjMult(DeferredLogger& deferred_logger) { for (const auto& well : this->well_container_generic_) { if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) { diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.hpp b/opm/simulators/wells/BlackoilWellModelGeneric.hpp index 8f500f52c..10dd608db 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.hpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.hpp @@ -376,6 +376,8 @@ protected: void updateInjMult(DeferredLogger& deferred_logger); + void updateFiltrationParticleVolume(const double dt, const size_t water_index); + // create the well container virtual void createWellContainer(const int time_step) = 0; virtual void initWellContainer(const int reportStepIdx) = 0; @@ -438,6 +440,9 @@ protected: // previous injection multiplier, it is used in the injection multiplier calculation for WINJMULT keyword std::unordered_map> prev_inj_multipliers_; + // the volume of the filtration particles during water injection + std::unordered_map> filtration_particle_volume_; + /* The various wellState members should be accessed and modified through the accessor functions wellState(), prevWellState(), diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index 1f241ac80..5fd92dca5 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -312,9 +312,11 @@ namespace Opm { for (auto& well : well_container_) { if (well->isInjector()) { - const auto& ws = this->wellState().well(well->indexOfWell()); - const auto& filtration_particle_volume = ws.perf_data.filtration_particle_volume; - well->updateInjFCMult(filtration_particle_volume); + const auto it = this->filtration_particle_volume_.find(well->name()); + if (it != this->filtration_particle_volume_.end()) { + const auto& filtration_particle_volume = it->second; + well->updateInjFCMult(filtration_particle_volume); + } } } @@ -480,10 +482,10 @@ namespace Opm { if (getPropValue() && well->isInjector()) { well->updateWaterThroughput(dt, this->wellState()); } + } - if (well->isInjector() && Indices::waterEnabled) { - well->updateFiltrationParticleVolume(dt, FluidSystem::waterPhaseIdx, this->wellState()); - } + if (Indices::waterEnabled) { + this->updateFiltrationParticleVolume(dt, FluidSystem::waterPhaseIdx); } // at the end of the time step, updating the inj_multiplier saved in WellState for later use diff --git a/opm/simulators/wells/PerfData.cpp b/opm/simulators/wells/PerfData.cpp index e1cbcccf1..4c6f04527 100644 --- a/opm/simulators/wells/PerfData.cpp +++ b/opm/simulators/wells/PerfData.cpp @@ -46,7 +46,6 @@ PerfData::PerfData(std::size_t num_perf, double pressure_first_connection_, bool this->water_throughput.resize(num_perf); this->skin_pressure.resize(num_perf); this->water_velocity.resize(num_perf); - this->filtration_particle_volume.resize(num_perf); } } @@ -98,7 +97,6 @@ bool PerfData::try_assign(const PerfData& other) { this->water_throughput = other.water_throughput; this->skin_pressure = other.skin_pressure; this->water_velocity = other.water_velocity; - this->filtration_particle_volume = other.filtration_particle_volume; this->prod_index = other.prod_index; this->micp_rates = other.micp_rates; return true; diff --git a/opm/simulators/wells/PerfData.hpp b/opm/simulators/wells/PerfData.hpp index ae9e19d53..6eda2c357 100644 --- a/opm/simulators/wells/PerfData.hpp +++ b/opm/simulators/wells/PerfData.hpp @@ -84,18 +84,6 @@ public: std::vector water_throughput; std::vector skin_pressure; std::vector water_velocity; - - // This is the accumulated water injection volume - // At the moment, it will only be used for the filtration cake modeling - // TODO: it might be problematic to handle the well open and shut, connection open and shut, since the - // information in PerfData will disappear if the well is SHUT - // TODO: if the injection concentration change, only the water injection volume will not be enough to - // calculate the formation of the filter cake. - // TODO: will change to track the volume of the solid formed during the injection - // because the injection concentration may vary during the simulation, we track the solid particle volume - // instead of tracking the water injection volume - // std::vector water_injection_volume; - std::vector filtration_particle_volume; }; } // namespace Opm diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index affc69ac5..b15c2e006 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -719,7 +719,8 @@ checkNegativeWellPotentials(std::vector& well_potentials, } void WellInterfaceGeneric:: -updateFiltrationParticleVolume(const double dt, const size_t water_index, WellState& well_state) const +updateFiltrationParticleVolume(const double dt, const size_t water_index, + const WellState& well_state, std::vector& filtration_particle_volume) const { if (!this->isInjector()) { return; @@ -738,8 +739,6 @@ updateFiltrationParticleVolume(const double dt, const size_t water_index, WellSt // it is currently used for the filter cake modeling related to formation damage study auto& ws = well_state.well(this->index_of_well_); const auto& connection_rates = ws.perf_data.phase_rates; - // per connection - auto& filtration_particle_volume = ws.perf_data.filtration_particle_volume; const size_t np = well_state.numPhases(); for (int perf = 0; perf < this->number_of_perforations_; ++perf) { diff --git a/opm/simulators/wells/WellInterfaceGeneric.hpp b/opm/simulators/wells/WellInterfaceGeneric.hpp index 5a89b8021..b4ea2dcf9 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.hpp +++ b/opm/simulators/wells/WellInterfaceGeneric.hpp @@ -189,7 +189,8 @@ public: double getInjMult(const int perf, const double bhp, const double perf_pres) const; // update the water injection volume, it will be used for calculation related to cake filtration due to injection activity - void updateFiltrationParticleVolume(const double dt, const size_t water_index, WellState& well_state) const; + void updateFiltrationParticleVolume(const double dt, const size_t water_index, + const WellState& well_state, std::vector& filtration_particle_volume) const; // update the multiplier for well transmissbility due to cake filteration void updateInjFCMult(const std::vector& filtration_particle_volume); @@ -376,7 +377,7 @@ protected: std::vector prev_inj_multiplier_; // the multiplier due to injection filtration cake - mutable std::vector inj_fc_multiplier_; + std::vector inj_fc_multiplier_; double well_efficiency_factor_; const VFPProperties* vfp_properties_;