diff --git a/opm/core/flowdiagnostics/FlowDiagnostics.cpp b/opm/core/flowdiagnostics/FlowDiagnostics.cpp index 9df570e6b..26f22206a 100644 --- a/opm/core/flowdiagnostics/FlowDiagnostics.cpp +++ b/opm/core/flowdiagnostics/FlowDiagnostics.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -163,4 +164,63 @@ namespace Opm + + + /// \brief Compute volumes associated with injector-producer pairs. + /// + /// \param[in] wells wells structure, containing NI injector wells and NP producer wells. + /// \param[in] porevol pore volume of each grid cell + /// \param[in] ftracer array of forward (injector) tracer values, NI per cell + /// \param[in] btracer array of backward (producer) tracer values, NP per cell + /// \return a vector of tuples, one tuple for each injector-producer pair, + /// where the first and second elements are well indices for the + /// injector and producer, and the third element is the pore volume + /// associated with that pair. + std::vector > + computeWellPairs(const Wells& wells, + const std::vector& porevol, + const std::vector& ftracer, + const std::vector& btracer) + { + // Identify injectors and producers. + std::vector inj; + std::vector prod; + const int nw = wells.number_of_wells; + for (int w = 0; w < nw; ++w) { + if (wells.type[w] == INJECTOR) { + inj.push_back(w); + } else { + prod.push_back(w); + } + } + + // Check sizes of input arrays. + const int nc = porevol.size(); + if (nc * inj.size() != ftracer.size()) { + OPM_THROW(std::runtime_error, "computeWellPairs(): wrong size of input array ftracer."); + } + if (nc * prod.size() != btracer.size()) { + OPM_THROW(std::runtime_error, "computeWellPairs(): wrong size of input array btracer."); + } + + // Compute associated pore volumes. + std::vector > result; + const int num_inj = inj.size(); + const int num_prod = prod.size(); + for (int inj_ix = 0; inj_ix < num_inj; ++inj_ix) { + for (int prod_ix = 0; prod_ix < num_prod; ++prod_ix) { + double assoc_porevol = 0.0; + for (int c = 0; c < nc; ++c) { + assoc_porevol += porevol[c] + * ftracer[num_inj * c + inj_ix] + * btracer[num_prod * c + prod_ix]; + } + result.push_back(std::make_tuple(inj[inj_ix], prod[prod_ix], assoc_porevol)); + } + } + return result; + } + + + } // namespace Opm diff --git a/opm/core/flowdiagnostics/FlowDiagnostics.hpp b/opm/core/flowdiagnostics/FlowDiagnostics.hpp index 96b512346..b5bb8c076 100644 --- a/opm/core/flowdiagnostics/FlowDiagnostics.hpp +++ b/opm/core/flowdiagnostics/FlowDiagnostics.hpp @@ -23,7 +23,9 @@ #include #include +#include +struct Wells; namespace Opm { @@ -79,6 +81,23 @@ namespace Opm computeSweep(const std::vector& flowcap, const std::vector& storagecap); + + /// \brief Compute volumes associated with injector-producer pairs. + /// + /// \param[in] wells wells structure, containing NI injector wells and NP producer wells. + /// \param[in] porevol pore volume of each grid cell + /// \param[in] ftracer array of forward (injector) tracer values, NI per cell + /// \param[in] btracer array of backward (producer) tracer values, NP per cell + /// \return a vector of tuples, one tuple for each injector-producer pair, + /// where the first and second elements are well indices for the + /// injector and producer, and the third element is the pore volume + /// associated with that pair. + std::vector> + computeWellPairs(const Wells& wells, + const std::vector& porevol, + const std::vector& ftracer, + const std::vector& btracer); + } // namespace Opm #endif // OPM_FLOWDIAGNOSTICS_HEADER_INCLUDED