From 776447686a030a07acb312ee46660c8c8f87a324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 18 Dec 2024 13:07:02 +0100 Subject: [PATCH] Report Connection Level Fracturing Statistics to I/O Layer Populates the new data::Connection::fract data member. --- opm/simulators/wells/PerfData.cpp | 3 ++ opm/simulators/wells/PerfData.hpp | 3 ++ opm/simulators/wells/WellState.cpp | 44 ++++++++++++++++++++++++++++++ opm/simulators/wells/WellState.hpp | 4 +++ 4 files changed, 54 insertions(+) diff --git a/opm/simulators/wells/PerfData.cpp b/opm/simulators/wells/PerfData.cpp index 66176fb359a..d8d776c82b3 100644 --- a/opm/simulators/wells/PerfData.cpp +++ b/opm/simulators/wells/PerfData.cpp @@ -83,6 +83,7 @@ PerfData PerfData::serializationTestObject() result.skin_pressure = {27.0, 28.0}; result.water_velocity = {29.0, 30.0}; result.filtrate_data = ConnFiltrateData::serializationTestObject(); + result.connFracStatistics.assign(3, ConnFracStatistics::serializationTestObject()); return result; } @@ -124,6 +125,7 @@ bool PerfData::try_assign(const PerfData& other) this->skin_pressure = other.skin_pressure; this->water_velocity = other.water_velocity; this->filtrate_data = other.filtrate_data; + this->connFracStatistics = other.connFracStatistics; return true; } @@ -152,6 +154,7 @@ bool PerfData::operator==(const PerfData& rhs) const && (this->skin_pressure == rhs.skin_pressure) && (this->water_velocity == rhs.water_velocity) && (this->filtrate_data == rhs.filtrate_data) + && (this->connFracStatistics == rhs.connFracStatistics) ; } diff --git a/opm/simulators/wells/PerfData.hpp b/opm/simulators/wells/PerfData.hpp index b6b5cb1809b..1c00251077d 100644 --- a/opm/simulators/wells/PerfData.hpp +++ b/opm/simulators/wells/PerfData.hpp @@ -21,6 +21,7 @@ #define OPM_PERFDATA_HEADER_INCLUDED #include +#include #include #include @@ -71,6 +72,7 @@ class PerfData serializer(skin_pressure); serializer(water_velocity); serializer(filtrate_data); + serializer(connFracStatistics); } bool operator==(const PerfData&) const; @@ -105,6 +107,7 @@ class PerfData std::vector water_velocity{}; ConnFiltrateData filtrate_data{}; + std::vector> connFracStatistics{}; }; } // namespace Opm diff --git a/opm/simulators/wells/WellState.cpp b/opm/simulators/wells/WellState.cpp index 7aeefd711ec..02a8129b65c 100644 --- a/opm/simulators/wells/WellState.cpp +++ b/opm/simulators/wells/WellState.cpp @@ -31,8 +31,10 @@ #include +#include #include #include +#include #include @@ -639,6 +641,11 @@ void WellState::reportConnections(std::vector& connect if (! ws.producer) { this->reportConnectionFilterCake(well_index, connections); } + + if (! perf_data.connFracStatistics.empty()) { + this->reportFractureStatistics(perf_data.connFracStatistics, + connections); + } } template @@ -1138,6 +1145,43 @@ reportConnectionFilterCake(const std::size_t well_index, } } +template +void WellState:: +reportFractureStatistics(const std::vector>& stats, + std::vector& connections) const +{ + using Quantity = typename ConnFracStatistics::Quantity; + using StatResult = data::ConnectionFracturing; + + auto connIx = 0*connections.size(); + for (auto& connection : connections) { + for (const auto& [q, result] : { + std::pair { Quantity::Pressure, &StatResult::press }, + std::pair { Quantity::FlowRate, &StatResult::rate }, + std::pair { Quantity::Width , &StatResult::width }, + }) + { + const auto& stat = stats[connIx].statistics(q); + + if (stat.sampleSize() > 0) { + auto& x = connection.fract.*result; + + x.avg = stat.mean(); + x.min = stat.min(); + x.max = stat.max(); + + if (const auto stdev = stat.stdev(); stdev.has_value()) { + x.stdev = *stdev; + } + + connection.fract.numCells = stat.sampleSize(); + } + } + + ++connIx; + } +} + template bool WellState::wellIsOwned(std::size_t well_index, [[maybe_unused]] const std::string& wellName) const diff --git a/opm/simulators/wells/WellState.hpp b/opm/simulators/wells/WellState.hpp index ed5f4674c11..b7f1a00f46c 100644 --- a/opm/simulators/wells/WellState.hpp +++ b/opm/simulators/wells/WellState.hpp @@ -55,6 +55,7 @@ namespace Opm template class ParallelWellInfo; template struct PerforationData; +template class ConnFracStatistics; class Schedule; enum class WellStatus; @@ -452,6 +453,9 @@ class WellState void reportConnectionFilterCake(const std::size_t well_index, std::vector& connections) const; + + void reportFractureStatistics(const std::vector>& stats, + std::vector& connections) const; }; } // namespace Opm