WIP in storing the filtration_particle_volume in BlackoilWellModelGeneric

instead of PerfData to handle the situation that well can be SHUT and
OPEN again.
This commit is contained in:
Kai Bao 2023-06-30 14:53:19 +02:00
parent 274c431492
commit cb74d26e85
7 changed files with 33 additions and 25 deletions

View File

@ -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) { void BlackoilWellModelGeneric::updateInjMult(DeferredLogger& deferred_logger) {
for (const auto& well : this->well_container_generic_) { for (const auto& well : this->well_container_generic_) {
if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) { if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) {

View File

@ -376,6 +376,8 @@ protected:
void updateInjMult(DeferredLogger& deferred_logger); void updateInjMult(DeferredLogger& deferred_logger);
void updateFiltrationParticleVolume(const double dt, const size_t water_index);
// create the well container // create the well container
virtual void createWellContainer(const int time_step) = 0; virtual void createWellContainer(const int time_step) = 0;
virtual void initWellContainer(const int reportStepIdx) = 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 // previous injection multiplier, it is used in the injection multiplier calculation for WINJMULT keyword
std::unordered_map<std::string, std::vector<double>> prev_inj_multipliers_; std::unordered_map<std::string, std::vector<double>> prev_inj_multipliers_;
// the volume of the filtration particles during water injection
std::unordered_map<std::string, std::vector<double>> filtration_particle_volume_;
/* /*
The various wellState members should be accessed and modified The various wellState members should be accessed and modified
through the accessor functions wellState(), prevWellState(), through the accessor functions wellState(), prevWellState(),

View File

@ -312,9 +312,11 @@ namespace Opm {
for (auto& well : well_container_) { for (auto& well : well_container_) {
if (well->isInjector()) { if (well->isInjector()) {
const auto& ws = this->wellState().well(well->indexOfWell()); const auto it = this->filtration_particle_volume_.find(well->name());
const auto& filtration_particle_volume = ws.perf_data.filtration_particle_volume; if (it != this->filtration_particle_volume_.end()) {
well->updateInjFCMult(filtration_particle_volume); const auto& filtration_particle_volume = it->second;
well->updateInjFCMult(filtration_particle_volume);
}
} }
} }
@ -480,10 +482,10 @@ namespace Opm {
if (getPropValue<TypeTag, Properties::EnablePolymerMW>() && well->isInjector()) { if (getPropValue<TypeTag, Properties::EnablePolymerMW>() && well->isInjector()) {
well->updateWaterThroughput(dt, this->wellState()); well->updateWaterThroughput(dt, this->wellState());
} }
}
if (well->isInjector() && Indices::waterEnabled) { if (Indices::waterEnabled) {
well->updateFiltrationParticleVolume(dt, FluidSystem::waterPhaseIdx, this->wellState()); this->updateFiltrationParticleVolume(dt, FluidSystem::waterPhaseIdx);
}
} }
// at the end of the time step, updating the inj_multiplier saved in WellState for later use // at the end of the time step, updating the inj_multiplier saved in WellState for later use

View File

@ -46,7 +46,6 @@ PerfData::PerfData(std::size_t num_perf, double pressure_first_connection_, bool
this->water_throughput.resize(num_perf); this->water_throughput.resize(num_perf);
this->skin_pressure.resize(num_perf); this->skin_pressure.resize(num_perf);
this->water_velocity.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->water_throughput = other.water_throughput;
this->skin_pressure = other.skin_pressure; this->skin_pressure = other.skin_pressure;
this->water_velocity = other.water_velocity; this->water_velocity = other.water_velocity;
this->filtration_particle_volume = other.filtration_particle_volume;
this->prod_index = other.prod_index; this->prod_index = other.prod_index;
this->micp_rates = other.micp_rates; this->micp_rates = other.micp_rates;
return true; return true;

View File

@ -84,18 +84,6 @@ public:
std::vector<double> water_throughput; std::vector<double> water_throughput;
std::vector<double> skin_pressure; std::vector<double> skin_pressure;
std::vector<double> water_velocity; std::vector<double> 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<double> water_injection_volume;
std::vector<double> filtration_particle_volume;
}; };
} // namespace Opm } // namespace Opm

View File

@ -719,7 +719,8 @@ checkNegativeWellPotentials(std::vector<double>& well_potentials,
} }
void WellInterfaceGeneric:: 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<double>& filtration_particle_volume) const
{ {
if (!this->isInjector()) { if (!this->isInjector()) {
return; 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 // it is currently used for the filter cake modeling related to formation damage study
auto& ws = well_state.well(this->index_of_well_); auto& ws = well_state.well(this->index_of_well_);
const auto& connection_rates = ws.perf_data.phase_rates; 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(); const size_t np = well_state.numPhases();
for (int perf = 0; perf < this->number_of_perforations_; ++perf) { for (int perf = 0; perf < this->number_of_perforations_; ++perf) {

View File

@ -189,7 +189,8 @@ public:
double getInjMult(const int perf, const double bhp, const double perf_pres) const; 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 // 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<double>& filtration_particle_volume) const;
// update the multiplier for well transmissbility due to cake filteration // update the multiplier for well transmissbility due to cake filteration
void updateInjFCMult(const std::vector<double>& filtration_particle_volume); void updateInjFCMult(const std::vector<double>& filtration_particle_volume);
@ -376,7 +377,7 @@ protected:
std::vector<double> prev_inj_multiplier_; std::vector<double> prev_inj_multiplier_;
// the multiplier due to injection filtration cake // the multiplier due to injection filtration cake
mutable std::vector<double> inj_fc_multiplier_; std::vector<double> inj_fc_multiplier_;
double well_efficiency_factor_; double well_efficiency_factor_;
const VFPProperties* vfp_properties_; const VFPProperties* vfp_properties_;