OutputExtractor.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
27#ifndef OPM_OUTPUT_EXTRACTORS_HPP
28#define OPM_OUTPUT_EXTRACTORS_HPP
29
30#include <opm/common/OpmLog/OpmLog.hpp>
31#include <opm/common/utility/Visitor.hpp>
32
33#include <opm/material/common/Valgrind.hpp>
34
39
40#include <algorithm>
41#include <array>
42#include <optional>
43#include <unordered_map>
44#include <set>
45#include <variant>
46#include <vector>
47
48#include <fmt/format.h>
49
50namespace Opm::detail {
51
53template<class TypeTag>
55{
58 using FluidState = typename IntensiveQuantities::FluidState;
60 static constexpr int numPhases = FluidSystem::numPhases;
61
64 {
71 };
72
74 struct Context
75 {
76 unsigned globalDofIdx;
77 unsigned pvtRegionIdx;
79 const FluidState& fs;
82 };
83
85 using AssignFunc = std::function<void(const Context&)>;
86
89 using ScalarFunc = std::function<Scalar(const Context&)>;
90
93 using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
94
95 using ScalarBuffer = std::vector<Scalar>;
96 using PhaseArray = std::array<ScalarBuffer,numPhases>;
97
100 {
103 };
104
107 {
110 };
111
113 struct Entry
114 {
115 std::variant<AssignFunc, ScalarEntry, PhaseEntry> data;
116 bool condition = true;
117 };
118
120 template<std::size_t size>
121 static std::vector<Entry> removeInactive(std::array<Entry,size>& input)
122 {
123 // Setup active extractors
124 std::vector<Entry> filtered_extractors;
125 filtered_extractors.reserve(input.size());
126 std::copy_if(std::move_iterator(input.begin()),
127 std::move_iterator(input.end()),
128 std::back_inserter(filtered_extractors),
129 [](const Entry& e)
130 {
131 if (!e.condition) {
132 return false;
133 }
134 return std::visit(VisitorOverloadSet{
135 [](const AssignFunc&)
136 {
137 return true;
138 },
139 [](const ScalarEntry& v)
140 {
141 return !v.data->empty();
142 },
143 [](const PhaseEntry& v)
144 {
145 return std::ranges::any_of(*v.data,
146 [](const auto& ve)
147 { return !ve.empty(); });
148 }
149 }, e.data);
150 });
151
152 return filtered_extractors;
153 }
154
158 static void process(const Context& ectx,
159 const std::vector<Entry>& extractors)
160 {
161 std::ranges::for_each(extractors,
162 [&ectx](const auto& entry)
163 {
164 std::visit(VisitorOverloadSet{
165 [&ectx](const ScalarEntry& v)
166 {
167 auto& array = *v.data;
168 array[ectx.globalDofIdx] = v.extract(ectx);
169 Valgrind::CheckDefined(array[ectx.globalDofIdx]);
170 },
171 [&ectx](const PhaseEntry& v)
172 {
173 std::ranges::for_each(*v.data,
174 [phaseIdx = 0, &ectx, &v](auto& array) mutable
175 {
176 if (!array.empty()) {
177 array[ectx.globalDofIdx] = v.extract(phaseIdx, ectx);
178 Valgrind::CheckDefined(array[ectx.globalDofIdx]);
179 }
180 ++phaseIdx;
181 });
182 },
183 [&ectx](const typename Extractor::AssignFunc& extract)
184 { extract(ectx); },
185 }, entry.data);
186 });
187 }
188};
189
191template<class TypeTag>
193{
197 using FluidState = typename IntensiveQuantities::FluidState;
199 static constexpr int numPhases = FluidSystem::numPhases;
200 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
201 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
202 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
203
205 struct Context
206 {
207 unsigned globalDofIdx;
208 unsigned dofIdx;
209 const FluidState& fs;
212 };
213
215 using AssignFunc = std::function<void(const Context&)>;
216
219 using ScalarFunc = std::function<Scalar(const Context&)>;
220
223 using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
224
226 {
228 std::variant<std::string_view, std::vector<std::string_view>> kw;
229
232 };
233
235 {
237 std::variant<std::array<std::string_view, numPhases>,
238 std::array<std::array<std::string_view, numPhases>, 2>> kw;
239
242 };
243
245 using Entry = std::variant<ScalarEntry, PhaseEntry>;
246
248 struct Exec
249 {
251 Exec(double* d, ScalarFunc&& e)
252 : data(d), extract(std::move(e))
253 {}
254
255 double* data;
257 };
258
260 using ExecMap = std::unordered_map<int, std::vector<Exec>>;
261
270 template<std::size_t size>
271 static std::optional<ScalarFunc>
272 makeExtractor(const std::string_view base_kw,
273 const std::array<Entry,size>& handlers)
274 {
275 using PhaseViewArray = std::array<std::string_view, numPhases>;
276 using StringViewVec = std::vector<std::string_view>;
277
278 unsigned phase{};
279 const auto handler_info =
280 std::ranges::find_if(
281 handlers,
282 [&base_kw, &phase](const auto& handler)
283 {
284 // Extract list of keyword names from handler
285 const auto gen_handlers =
286 std::visit(VisitorOverloadSet{
287 [](const ScalarEntry& entry)
288 {
289 return std::visit(VisitorOverloadSet{
290 [](const std::string_view& kw) -> StringViewVec
291 {
292 return {kw};
293 },
294 [](const StringViewVec& kws) -> StringViewVec
295 { return kws; }
296 }, entry.kw);
297 },
298 [](const PhaseEntry& entry)
299 {
300 return std::visit(VisitorOverloadSet{
301 [](const PhaseViewArray& data)
302 {
303 return StringViewVec{data.begin(), data.end()};
304 },
305 [](const std::array<PhaseViewArray,2>& data)
306 {
307 StringViewVec res;
308 res.reserve(2*numPhases);
309 res.insert(res.end(),
310 data[0].begin(),
311 data[0].end());
312 res.insert(res.end(),
313 data[1].begin(),
314 data[1].end());
315 return res;
316 }
317 }, entry.kw);
318 }
319 }, handler);
320
321 const auto found_handler =
322 std::ranges::find(gen_handlers, base_kw);
323 if (found_handler != gen_handlers.end()) {
324 phase = std::distance(gen_handlers.begin(), found_handler) % numPhases;
325 }
326 return found_handler != gen_handlers.end();
327 }
328 );
329
330 if (handler_info == handlers.end()) {
331 return std::nullopt;
332 }
333
334 return std::visit(VisitorOverloadSet{
335 [](const ScalarEntry& e) -> ScalarFunc
336 {
337 return e.extract;
338 },
339 [phase](const PhaseEntry& e) -> ScalarFunc
340 {
341 return [phase, extract = e.extract]
342 (const Context& ectx)
343 {
344 static constexpr auto phaseMap = std::array{
345 waterPhaseIdx,
346 oilPhaseIdx,
347 gasPhaseIdx,
348 };
349 return extract(phaseMap[phase], ectx);
350 };
351 }
352 }, *handler_info);
353 }
354
356 template<std::size_t size>
357 static ExecMap setupExecMap(std::map<std::pair<std::string, int>, double>& blockData,
358 const std::array<Entry,size>& handlers)
359 {
360 ExecMap extractors;
361
362 std::ranges::for_each(
363 blockData,
364 [&handlers, &extractors](auto& bd_info)
365 {
366 const auto& [key, cell] = bd_info.first;
367 if (auto extract = makeExtractor(std::string_view{key}, handlers)) {
368 extractors[cell - 1].emplace_back(&bd_info.second, std::move(*extract));
369 }
370 else {
371 OpmLog::warning("Unhandled output keyword",
372 fmt::format("Keyword '{}' is unhandled for output "
373 "to summary file.", key));
374 }
375 }
376 );
377
378 return extractors;
379 }
380
382 static void process(const std::vector<Exec>& blockExtractors,
383 const Context& ectx)
384 {
385 std::ranges::for_each(blockExtractors,
386 [&ectx](auto& bdata)
387 { *bdata.data = bdata.extract(ectx); });
388 }
389
397 using LgrExecMap = std::unordered_map<int,
398 std::unordered_map<int,
399 std::vector<Exec>>>;
400
410 template<std::size_t size>
411 static LgrExecMap setupLgrExecMap(std::map<std::tuple<std::string,int,int>,
412 double>& lgrBlockData,
413 const std::array<Entry,size>& handlers)
414 {
415 LgrExecMap extractors;
416
417 std::ranges::for_each(
418 lgrBlockData,
419 [&handlers, &extractors](auto& bd_info)
420 {
421 const auto& [lgr_kw, level, localCart] = bd_info.first;
422 // LB* keywords mirror the global B* names; drop the leading
423 // 'L' so the shared handler lookup sees "BPR", "BOSAT", ...
424 const auto base_kw = std::string_view{lgr_kw}.substr(1);
425 if (auto extract = makeExtractor(base_kw, handlers)) {
426 extractors[level][localCart].emplace_back(&bd_info.second, std::move(*extract));
427 }
428 else {
429 OpmLog::warning("Unhandled LGR output keyword",
430 fmt::format("Keyword '{}' (LGR mirror of '{}') is "
431 "unhandled for output to summary file.",
432 lgr_kw, base_kw));
433 }
434 }
435 );
436
437 return extractors;
438 }
439};
440
441} // namespace Opm::detail
442
443#endif // OPM_OUTPUT_EXTRACTORS_HPP
Defines a type tags and some fundamental properties all models.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Defines the common properties required by the porous medium multi-phase models.
Definition: alignedallocator.hh:32
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
The Opm property system, traits with inheritance.
Context passed to element extractor functions.
Definition: OutputExtractor.hpp:206
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:209
const ElementContext & elemCtx
Definition: OutputExtractor.hpp:211
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:210
unsigned dofIdx
Definition: OutputExtractor.hpp:208
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:207
Descriptor for extractor execution.
Definition: OutputExtractor.hpp:249
double * data
Where to store output data.
Definition: OutputExtractor.hpp:255
ScalarFunc extract
Extraction function to call.
Definition: OutputExtractor.hpp:256
Exec(double *d, ScalarFunc &&e)
Move constructor.
Definition: OutputExtractor.hpp:251
Definition: OutputExtractor.hpp:235
PhaseFunc extract
Associated extraction lambda.
Definition: OutputExtractor.hpp:241
std::variant< std::array< std::string_view, numPhases >, std::array< std::array< std::string_view, numPhases >, 2 > > kw
One or two lists of names for the keyword for each phase.
Definition: OutputExtractor.hpp:238
Definition: OutputExtractor.hpp:226
std::variant< std::string_view, std::vector< std::string_view > > kw
A single name or a list of names for the keyword.
Definition: OutputExtractor.hpp:228
ScalarFunc extract
Associated extraction lamda.
Definition: OutputExtractor.hpp:231
Wrapping struct holding types used for block-level data extraction.
Definition: OutputExtractor.hpp:193
std::unordered_map< int, std::vector< Exec > > ExecMap
A map of extraction executors, keyed by cartesian cell index.
Definition: OutputExtractor.hpp:260
GetPropType< TypeTag, Properties::ElementContext > ElementContext
Definition: OutputExtractor.hpp:194
typename IntensiveQuantities::FluidState FluidState
Definition: OutputExtractor.hpp:197
std::function< Scalar(const unsigned, const Context &)> PhaseFunc
Definition: OutputExtractor.hpp:223
GetPropType< TypeTag, Properties::FluidSystem > FluidSystem
Definition: OutputExtractor.hpp:198
std::variant< ScalarEntry, PhaseEntry > Entry
Descriptor for extractors.
Definition: OutputExtractor.hpp:245
static LgrExecMap setupLgrExecMap(std::map< std::tuple< std::string, int, int >, double > &lgrBlockData, const std::array< Entry, size > &handlers)
Setup an LGR-cell extractor executor map.
Definition: OutputExtractor.hpp:411
static ExecMap setupExecMap(std::map< std::pair< std::string, int >, double > &blockData, const std::array< Entry, size > &handlers)
Setup an extractor executor map from a map of evaluations to perform.
Definition: OutputExtractor.hpp:357
std::function< Scalar(const Context &)> ScalarFunc
Definition: OutputExtractor.hpp:219
std::unordered_map< int, std::unordered_map< int, std::vector< Exec > > > LgrExecMap
Definition: OutputExtractor.hpp:399
static std::optional< ScalarFunc > makeExtractor(const std::string_view base_kw, const std::array< Entry, size > &handlers)
Resolve a block-summary keyword to its bound extraction lambda.
Definition: OutputExtractor.hpp:272
GetPropType< TypeTag, Properties::IntensiveQuantities > IntensiveQuantities
Definition: OutputExtractor.hpp:195
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: OutputExtractor.hpp:196
static void process(const std::vector< Exec > &blockExtractors, const Context &ectx)
Process a list of block extractors.
Definition: OutputExtractor.hpp:382
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition: OutputExtractor.hpp:215
Context passed to extractor functions.
Definition: OutputExtractor.hpp:75
const HysteresisParams & hParams
Hysteresis parameters for cell.
Definition: OutputExtractor.hpp:81
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:80
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:76
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:79
int episodeIndex
Current report step.
Definition: OutputExtractor.hpp:78
unsigned pvtRegionIdx
pvt region for dof
Definition: OutputExtractor.hpp:77
Descriptor for extractors.
Definition: OutputExtractor.hpp:114
bool condition
Additional condition for enabling extractor.
Definition: OutputExtractor.hpp:116
std::variant< AssignFunc, ScalarEntry, PhaseEntry > data
Extractor.
Definition: OutputExtractor.hpp:115
Struct holding hysteresis parameters.
Definition: OutputExtractor.hpp:64
Scalar somin
Min oil saturation.
Definition: OutputExtractor.hpp:70
Scalar swmin
Min water saturation.
Definition: OutputExtractor.hpp:67
Scalar swmax
Max water saturation.
Definition: OutputExtractor.hpp:66
Scalar shmax
Max something.
Definition: OutputExtractor.hpp:69
Scalar sgmax
Max gas saturation.
Definition: OutputExtractor.hpp:68
Scalar somax
Max oil saturation.
Definition: OutputExtractor.hpp:65
A phase buffer extractor descriptor.
Definition: OutputExtractor.hpp:107
PhaseArray * data
Array of buffers to store data in.
Definition: OutputExtractor.hpp:108
PhaseFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:109
A scalar extractor descriptor.
Definition: OutputExtractor.hpp:100
ScalarBuffer * data
Buffer to store data in.
Definition: OutputExtractor.hpp:101
ScalarFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:102
Wrapping struct holding types used for element-level data extraction.
Definition: OutputExtractor.hpp:55
std::array< ScalarBuffer, numPhases > PhaseArray
An array of buffers, one for each phase.
Definition: OutputExtractor.hpp:96
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: OutputExtractor.hpp:57
std::vector< Scalar > ScalarBuffer
A scalar buffer.
Definition: OutputExtractor.hpp:95
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition: OutputExtractor.hpp:85
GetPropType< TypeTag, Properties::FluidSystem > FluidSystem
Definition: OutputExtractor.hpp:59
std::function< Scalar(const unsigned, const Context &)> PhaseFunc
Definition: OutputExtractor.hpp:93
GetPropType< TypeTag, Properties::IntensiveQuantities > IntensiveQuantities
Definition: OutputExtractor.hpp:56
std::function< Scalar(const Context &)> ScalarFunc
Definition: OutputExtractor.hpp:89
static void process(const Context &ectx, const std::vector< Entry > &extractors)
Process the given extractor entries.
Definition: OutputExtractor.hpp:158
typename IntensiveQuantities::FluidState FluidState
Definition: OutputExtractor.hpp:58
static std::vector< Entry > removeInactive(std::array< Entry, size > &input)
Obtain vector of active extractors from an array of extractors.
Definition: OutputExtractor.hpp:121
static constexpr int numPhases
Definition: OutputExtractor.hpp:60