mirror of
				https://github.com/OPM/opm-simulators.git
				synced 2025-02-25 18:55:30 -06:00 
			
		
		
		
	Reduce Aquifer Data Copying
This commit switches to using 'map<>::insert_or_assign()' as the primary interface for collecting dynamic aquifer data. In turn, this activates move semantics for the substructures and reduces the number of times the data is copied. Insert_or_assign requires the key, so provide this value--i.e., the aquifer ID--as part of the AquiferInterface.
This commit is contained in:
		@@ -57,8 +57,7 @@ public:
 | 
			
		||||
                       const AquiferCT::AQUCT_data& aquct_data)
 | 
			
		||||
        : Base(aquct_data.aquiferID, connections, ebosSimulator)
 | 
			
		||||
        , aquct_data_(aquct_data)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    void endTimeStep() override
 | 
			
		||||
    {
 | 
			
		||||
@@ -73,7 +72,7 @@ public:
 | 
			
		||||
    data::AquiferData aquiferData() const
 | 
			
		||||
    {
 | 
			
		||||
        data::AquiferData data;
 | 
			
		||||
        data.aquiferID = this->aquiferID;
 | 
			
		||||
        data.aquiferID = this->aquiferID();
 | 
			
		||||
        // TODO: not sure how to get this pressure value yet
 | 
			
		||||
        data.pressure = this->pa0_;
 | 
			
		||||
        data.fluxRate = 0.;
 | 
			
		||||
 
 | 
			
		||||
@@ -71,13 +71,15 @@ public:
 | 
			
		||||
    data::AquiferData aquiferData() const
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: how to unify the two functions?
 | 
			
		||||
        data::AquiferData data;
 | 
			
		||||
        data.aquiferID = this->aquiferID;
 | 
			
		||||
        auto data = data::AquiferData{};
 | 
			
		||||
 | 
			
		||||
        data.aquiferID = this->aquiferID();
 | 
			
		||||
        data.pressure = this->aquifer_pressure_;
 | 
			
		||||
        data.fluxRate = 0.;
 | 
			
		||||
        for (const auto& q : this->Qai_) {
 | 
			
		||||
            data.fluxRate += q.value();
 | 
			
		||||
        }
 | 
			
		||||
        data.fluxRate = std::accumulate(this->Qai_.begin(), this->Qai_.end(), 0.0,
 | 
			
		||||
                                        [](const double flux, const auto& q) -> double
 | 
			
		||||
                                        {
 | 
			
		||||
                                            return flux + q.value();
 | 
			
		||||
                                        });
 | 
			
		||||
        data.volume = this->W_flux_.value();
 | 
			
		||||
        data.initPressure = this->pa0_;
 | 
			
		||||
        data.type = data::AquiferType::Fetkovich;
 | 
			
		||||
@@ -95,8 +97,10 @@ protected:
 | 
			
		||||
    void assignRestartData(const data::AquiferData& xaq) override
 | 
			
		||||
    {
 | 
			
		||||
        if (xaq.type != data::AquiferType::Fetkovich) {
 | 
			
		||||
            throw std::invalid_argument {"Analytic aquifer data for unexpected aquifer type "
 | 
			
		||||
                                         "passed to Fetkovich aquifer"};
 | 
			
		||||
            throw std::invalid_argument {
 | 
			
		||||
                "Analytic aquifer data for unexpected aquifer "
 | 
			
		||||
                "type passed to Fetkovich aquifer"
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this->aquifer_pressure_ = xaq.pressure;
 | 
			
		||||
 
 | 
			
		||||
@@ -77,13 +77,13 @@ public:
 | 
			
		||||
    AquiferInterface(int aqID,
 | 
			
		||||
                     const std::vector<Aquancon::AquancCell>& connections,
 | 
			
		||||
                     const Simulator& ebosSimulator)
 | 
			
		||||
        : aquiferID(aqID)
 | 
			
		||||
        : aquiferID_(aqID)
 | 
			
		||||
        , connections_(connections)
 | 
			
		||||
        , ebos_simulator_(ebosSimulator)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deconstructor
 | 
			
		||||
    // Destructor
 | 
			
		||||
    virtual ~AquiferInterface()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
@@ -92,7 +92,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        auto xaqPos
 | 
			
		||||
            = std::find_if(aquiferSoln.begin(), aquiferSoln.end(), [this](const data::AquiferData& xaq) -> bool {
 | 
			
		||||
                   return xaq.aquiferID == this->aquiferID;
 | 
			
		||||
                   return xaq.aquiferID == this->aquiferID();
 | 
			
		||||
              });
 | 
			
		||||
 | 
			
		||||
        if (xaqPos == aquiferSoln.end())
 | 
			
		||||
@@ -119,8 +119,8 @@ public:
 | 
			
		||||
 | 
			
		||||
            elemCtx.updatePrimaryStencil(elem);
 | 
			
		||||
 | 
			
		||||
            int cellIdx = elemCtx.globalSpaceIndex(0, 0);
 | 
			
		||||
            int idx = cellToConnectionIdx_[cellIdx];
 | 
			
		||||
            const int cellIdx = elemCtx.globalSpaceIndex(0, 0);
 | 
			
		||||
            const int idx = cellToConnectionIdx_[cellIdx];
 | 
			
		||||
            if (idx < 0)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
@@ -131,30 +131,36 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class Context>
 | 
			
		||||
    void addToSource(RateVector& rates, const Context& context, unsigned spaceIdx, unsigned timeIdx)
 | 
			
		||||
    void addToSource(RateVector& rates,
 | 
			
		||||
                     const Context& context,
 | 
			
		||||
                     const unsigned spaceIdx,
 | 
			
		||||
                     const unsigned timeIdx)
 | 
			
		||||
    {
 | 
			
		||||
        unsigned cellIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
 | 
			
		||||
        const unsigned cellIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
 | 
			
		||||
 | 
			
		||||
        int idx = cellToConnectionIdx_[cellIdx];
 | 
			
		||||
        const int idx = this->cellToConnectionIdx_[cellIdx];
 | 
			
		||||
        if (idx < 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // We are dereferencing the value of IntensiveQuantities because cachedIntensiveQuantities return a const
 | 
			
		||||
        // pointer to IntensiveQuantities of that particular cell_id
 | 
			
		||||
        const IntensiveQuantities intQuants = context.intensiveQuantities(spaceIdx, timeIdx);
 | 
			
		||||
        // This is the pressure at td + dt
 | 
			
		||||
        updateCellPressure(pressure_current_, idx, intQuants);
 | 
			
		||||
        updateCellDensity(idx, intQuants);
 | 
			
		||||
        calculateInflowRate(idx, context.simulator());
 | 
			
		||||
        rates[BlackoilIndices::conti0EqIdx + FluidSystem::waterCompIdx]
 | 
			
		||||
            += Qai_[idx] / context.dofVolume(spaceIdx, timeIdx);
 | 
			
		||||
    }
 | 
			
		||||
        // We are dereferencing the value of IntensiveQuantities because
 | 
			
		||||
        // cachedIntensiveQuantities return a const pointer to
 | 
			
		||||
        // IntensiveQuantities of that particular cell_id
 | 
			
		||||
        const auto& intQuants = context.intensiveQuantities(spaceIdx, timeIdx);
 | 
			
		||||
 | 
			
		||||
        // This is the pressure at td + dt
 | 
			
		||||
        this->updateCellPressure(this->pressure_current_, idx, intQuants);
 | 
			
		||||
        this->updateCellDensity(idx, intQuants);
 | 
			
		||||
        this->calculateInflowRate(idx, context.simulator());
 | 
			
		||||
 | 
			
		||||
        rates[BlackoilIndices::conti0EqIdx + FluidSystem::waterCompIdx]
 | 
			
		||||
            += this->Qai_[idx] / context.dofVolume(spaceIdx, timeIdx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::size_t size() const {
 | 
			
		||||
        return this->connections_.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int aquiferID() const { return this->aquiferID_; }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    inline Scalar gravity_() const
 | 
			
		||||
@@ -203,13 +209,14 @@ protected:
 | 
			
		||||
 | 
			
		||||
    virtual void endTimeStep() = 0;
 | 
			
		||||
 | 
			
		||||
    const int aquiferID;
 | 
			
		||||
    const int aquiferID_{};
 | 
			
		||||
    const std::vector<Aquancon::AquancCell> connections_;
 | 
			
		||||
    const Simulator& ebos_simulator_;
 | 
			
		||||
 | 
			
		||||
    // Grid variables
 | 
			
		||||
    std::vector<Scalar> faceArea_connected_;
 | 
			
		||||
    std::vector<int> cellToConnectionIdx_;
 | 
			
		||||
 | 
			
		||||
    // Quantities at each grid id
 | 
			
		||||
    std::vector<Scalar> cell_depth_;
 | 
			
		||||
    std::vector<Scalar> pressure_previous_;
 | 
			
		||||
@@ -218,8 +225,8 @@ protected:
 | 
			
		||||
    std::vector<Eval> rhow_;
 | 
			
		||||
    std::vector<Scalar> alphai_;
 | 
			
		||||
 | 
			
		||||
    Scalar Tc_; // Time constant
 | 
			
		||||
    Scalar pa0_; // initial aquifer pressure
 | 
			
		||||
    Scalar Tc_{}; // Time constant
 | 
			
		||||
    Scalar pa0_{}; // initial aquifer pressure
 | 
			
		||||
 | 
			
		||||
    Eval W_flux_;
 | 
			
		||||
 | 
			
		||||
@@ -345,8 +352,8 @@ protected:
 | 
			
		||||
            const auto& elem = *elemIt;
 | 
			
		||||
            elemCtx.updatePrimaryStencil(elem);
 | 
			
		||||
 | 
			
		||||
            size_t cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0);
 | 
			
		||||
            int idx = this->cellToConnectionIdx_[cellIdx];
 | 
			
		||||
            const auto cellIdx = elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0);
 | 
			
		||||
            const auto idx = this->cellToConnectionIdx_[cellIdx];
 | 
			
		||||
            if (idx < 0)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
@@ -364,10 +371,13 @@ protected:
 | 
			
		||||
 | 
			
		||||
        // We take the average of the calculated equilibrium pressures.
 | 
			
		||||
        const auto& comm = ebos_simulator_.vanguard().grid().comm();
 | 
			
		||||
 | 
			
		||||
        Scalar vals[2];
 | 
			
		||||
        vals[0] = std::accumulate(this->alphai_.begin(), this->alphai_.end(), 0.);
 | 
			
		||||
        vals[1] = std::accumulate(pw_aquifer.begin(), pw_aquifer.end(), 0.);
 | 
			
		||||
        vals[0] = std::accumulate(this->alphai_.begin(), this->alphai_.end(), 0.0);
 | 
			
		||||
        vals[1] = std::accumulate(pw_aquifer.begin(), pw_aquifer.end(), 0.0);
 | 
			
		||||
 | 
			
		||||
        comm.sum(vals, 2);
 | 
			
		||||
 | 
			
		||||
        return vals[1] / vals[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,11 @@ public:
 | 
			
		||||
        this->cumulative_flux_ = 0.;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int aquiferID() const
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int>(this->id_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    const size_t id_;
 | 
			
		||||
    const Simulator& ebos_simulator_;
 | 
			
		||||
 
 | 
			
		||||
@@ -237,23 +237,20 @@ template<typename TypeTag>
 | 
			
		||||
data::Aquifers BlackoilAquiferModel<TypeTag>::aquiferData() const {
 | 
			
		||||
    data::Aquifers data;
 | 
			
		||||
    if (this->aquiferCarterTracyActive()) {
 | 
			
		||||
        for (const auto& aqu : aquifers_CarterTracy) {
 | 
			
		||||
            data::AquiferData aqu_data = aqu.aquiferData();
 | 
			
		||||
            data[aqu_data.aquiferID] = aqu_data;
 | 
			
		||||
        for (const auto& aqu : this->aquifers_CarterTracy) {
 | 
			
		||||
            data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this->aquiferFetkovichActive()) {
 | 
			
		||||
        for (const auto& aqu : aquifers_Fetkovich) {
 | 
			
		||||
            data::AquiferData aqu_data = aqu.aquiferData();
 | 
			
		||||
            data[aqu_data.aquiferID] = aqu_data;
 | 
			
		||||
        for (const auto& aqu : this->aquifers_Fetkovich) {
 | 
			
		||||
            data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this->aquiferNumericalActive()) {
 | 
			
		||||
        for (const auto& aqu : this->aquifers_numerical) {
 | 
			
		||||
            data::AquiferData aqu_data = aqu.aquiferData();
 | 
			
		||||
            data[aqu_data.aquiferID] = aqu_data;
 | 
			
		||||
            data.insert_or_assign(aqu.aquiferID(), aqu.aquiferData());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user