updating AquiferConstantFlux with AQUFLUX

not recreating new instances to avoid unnecessary cost from constructor.
This commit is contained in:
Kai Bao 2023-02-15 23:21:05 +01:00
parent 6fa97874f8
commit 73dc31a7a5
5 changed files with 19 additions and 40 deletions

View File

@ -226,12 +226,6 @@ protected:
return FluidSystem::waterCompIdx; return FluidSystem::waterCompIdx;
} }
double cumulativeFlux() const
{
return Opm::getValue(this->W_flux_);
}
void initQuantities() void initQuantities()
{ {
// We reset the cumulative flux at the start of any simulation, so, W_flux = 0 // We reset the cumulative flux at the start of any simulation, so, W_flux = 0

View File

@ -37,14 +37,12 @@ public:
static constexpr int numEq = BlackoilIndices::numEq; static constexpr int numEq = BlackoilIndices::numEq;
using Eval = DenseAd::Evaluation<double, /*size=*/numEq>; using Eval = DenseAd::Evaluation<double, /*size=*/numEq>;
AquiferConstantFlux(const AquiferFlux& aquifer, AquiferConstantFlux(const SingleAquiferFlux& aquifer,
const std::vector<Aquancon::AquancCell>& connections, const std::vector<Aquancon::AquancCell>& connections,
const Simulator& ebos_simulator, const Simulator& ebos_simulator)
const double init_cumulative_flux = 0.)
: AquiferInterface<TypeTag>(aquifer.id, ebos_simulator) : AquiferInterface<TypeTag>(aquifer.id, ebos_simulator)
, connections_(connections) , connections_(connections)
, aquifer_data_(aquifer) , aquifer_data_(aquifer)
, cumulative_flux_(init_cumulative_flux)
{ {
// init_cumulative_flux is the flux volume from previoius running // init_cumulative_flux is the flux volume from previoius running
this->initializeConnections(); this->initializeConnections();
@ -53,15 +51,14 @@ public:
virtual ~AquiferConstantFlux() = default; virtual ~AquiferConstantFlux() = default;
/* void updateAquifer(const std::shared_ptr<AquiferFlux>& aquifer) { void updateAquifer(const SingleAquiferFlux& aquifer) {
aquifer_data_ = aquifer; aquifer_data_ = aquifer;
} */ }
void initFromRestart(const data::Aquifers& /* aquiferSoln */) { void initFromRestart(const data::Aquifers& /* aquiferSoln */) {
} }
void initialSolutionApplied() { void initialSolutionApplied() {
// this->initializeConnections();
} }
void beginTimeStep() { void beginTimeStep() {
@ -107,32 +104,23 @@ public:
} }
const double fw = this->aquifer_data_.flux; const double fw = this->aquifer_data_.flux;
// const double m = this->connections_[idx].influx_coeff;
this->connection_flux_[idx] = fw * this->connections_[idx].effective_facearea; this->connection_flux_[idx] = fw * this->connections_[idx].effective_facearea;
rates[BlackoilIndices::conti0EqIdx + compIdx_()] rates[BlackoilIndices::conti0EqIdx + compIdx_()]
+= this->connection_flux_[idx] / model.dofTotalVolume(cellIdx); += this->connection_flux_[idx] / model.dofTotalVolume(cellIdx);
} }
// TODO: repeated function from AquiferAnalytical
std::size_t size() const
{
return this->connections_.size();
}
private: private:
const std::vector<Aquancon::AquancCell> connections_; const std::vector<Aquancon::AquancCell> connections_;
AquiferFlux aquifer_data_; SingleAquiferFlux aquifer_data_;
std::vector<int> cellToConnectionIdx_; std::vector<int> cellToConnectionIdx_;
std::vector<Eval> connection_flux_; std::vector<Eval> connection_flux_;
double flux_rate_ {}; double flux_rate_ {};
double cumulative_flux_ = 0.; double cumulative_flux_ = 0.;
void initializeConnections() { void initializeConnections() {
this->cellToConnectionIdx_.resize(this->ebos_simulator_.gridView().size(/*codim=*/0), -1); this->cellToConnectionIdx_.resize(this->ebos_simulator_.gridView().size(/*codim=*/0), -1);
const auto& gridView = this->ebos_simulator_.vanguard().gridView(); const auto& gridView = this->ebos_simulator_.vanguard().gridView();
for (std::size_t idx = 0; idx < this->size(); ++idx) { for (std::size_t idx = 0; idx < this->connections_.size(); ++idx) {
const auto global_index = this->connections_[idx].global_index; const auto global_index = this->connections_[idx].global_index;
const int cell_index = this->ebos_simulator_.vanguard().compressedIndex(global_index); const int cell_index = this->ebos_simulator_.vanguard().compressedIndex(global_index);
auto elemIt = gridView.template begin</*codim=*/ 0>(); auto elemIt = gridView.template begin</*codim=*/ 0>();
@ -157,11 +145,6 @@ private:
return FluidSystem::waterCompIdx; return FluidSystem::waterCompIdx;
} }
double cumulativeFlux() const
{
return this->cumulative_flux_;
}
}; };
} }

View File

@ -74,10 +74,6 @@ public:
int aquiferID() const { return this->aquiferID_; } int aquiferID() const { return this->aquiferID_; }
// TODO: in the future, we might need to save the aquifer state here
// TODO: when other aquifer types are involved
virtual double cumulativeFlux() const = 0;
protected: protected:
bool co2store_() const bool co2store_() const
{ {

View File

@ -68,15 +68,20 @@ BlackoilAquiferModel<TypeTag>::beginEpisode()
auto find = std::find_if(begin(this->aquifers), end(this->aquifers), [id](auto& v){ return v->aquiferID() == id; }); auto find = std::find_if(begin(this->aquifers), end(this->aquifers), [id](auto& v){ return v->aquiferID() == id; });
if (find == this->aquifers.end()) { if (find == this->aquifers.end()) {
// the aquifer id does not exist in BlackoilAquiferModel yet // the aquifer id does not exist in BlackoilAquiferModel yet
const auto& aquinfo = *(elem.second); const auto& aquinfo = elem.second;
auto aqf = std::make_unique<AquiferConstantFlux<TypeTag>>(aquinfo, connections.getConnections(aquinfo.id), this->simulator_); auto aqf = std::make_unique<AquiferConstantFlux<TypeTag>>(aquinfo, connections.getConnections(aquinfo.id), this->simulator_);
this->aquifers.push_back(std::move(aqf)); this->aquifers.push_back(std::move(aqf));
} else { } else {
const double prev_cumulative_flux = (*find)->cumulativeFlux(); const auto& aquinfo = elem.second;
const auto& aquinfo = *(elem.second); auto aqu = dynamic_cast<AquiferConstantFlux<TypeTag>*> (find->get());
// TODO: it should be improved to be something like to update the related information instead of creating a new one if (!aqu) {
auto aqf = std::make_unique<AquiferConstantFlux<TypeTag>>(aquinfo, connections.getConnections(aquinfo.id), this->simulator_, prev_cumulative_flux); // if the aquifers can return types easily, we might be able to give a better message with type information
*find = std::move(aqf); const auto msg = fmt::format("Aquifer {} is updated with constant flux aquifer keyword AQUFLUX at report step {},"
" while it might be specified to be a different type of aquifer before this. We do not support the conversion between"
" different types of aquifer.\n", id, report_step);
OPM_THROW(std::runtime_error, msg);
}
aqu->updateAquifer(aquinfo);
} }
} }
} }
@ -194,6 +199,7 @@ BlackoilAquiferModel<TypeTag>::init()
} }
for (const auto& [id, aq] : aquifer.aquflux()) { for (const auto& [id, aq] : aquifer.aquflux()) {
// make sure not dummy constant flux aquifers
if ( !aq.active ) continue; if ( !aq.active ) continue;
if (!connections.hasAquiferConnections(id)) { if (!connections.hasAquiferConnections(id)) {

View File

@ -268,7 +268,7 @@ namespace {
errorGuard); errorGuard);
} }
eclipseState->appendAqufluxSchedule(schedule->getAquiferFluxListEnd()); eclipseState->appendAqufluxSchedule(schedule->getAquiferFluxSchedule());
if (Opm::OpmLog::hasBackend("STDOUT_LOGGER")) { if (Opm::OpmLog::hasBackend("STDOUT_LOGGER")) {
// loggers might not be set up! // loggers might not be set up!