opm-simulators
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 
50 namespace Opm::detail {
51 
53 template<class TypeTag>
54 struct Extractor
55 {
58  using FluidState = typename IntensiveQuantities::FluidState;
60  static constexpr int numPhases = FluidSystem::numPhases;
61 
64  {
65  Scalar somax{};
66  Scalar swmax{};
67  Scalar swmin{};
68  Scalar sgmax{};
69  Scalar shmax{};
70  Scalar somin{};
71  };
72 
74  struct Context
75  {
76  unsigned globalDofIdx;
77  unsigned pvtRegionIdx;
79  const FluidState& fs;
80  const IntensiveQuantities& intQuants;
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 
99  struct ScalarEntry
100  {
103  };
104 
106  struct PhaseEntry
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 
191 template<class TypeTag>
193 {
195  using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
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;
210  const IntensiveQuantities& intQuants;
211  const ElementContext& elemCtx;
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 
225  struct ScalarEntry
226  {
228  std::variant<std::string_view, std::vector<std::string_view>> kw;
229 
232  };
233 
234  struct PhaseEntry
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
ScalarFunc extract
Extraction function to call.
Definition: OutputExtractor.hpp:256
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
Descriptor for extractors.
Definition: OutputExtractor.hpp:113
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
Wrapping struct holding types used for element-level data extraction.
Definition: OutputExtractor.hpp:54
bool condition
Additional condition for enabling extractor.
Definition: OutputExtractor.hpp:116
PhaseFunc extract
Associated extraction lambda.
Definition: OutputExtractor.hpp:241
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:80
Definition: OutputExtractor.hpp:234
Defines the common properties required by the porous medium multi-phase models.
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition: OutputExtractor.hpp:215
static void process(const std::vector< Exec > &blockExtractors, const Context &ectx)
Process a list of block extractors.
Definition: OutputExtractor.hpp:382
Scalar sgmax
Max gas saturation.
Definition: OutputExtractor.hpp:68
unsigned pvtRegionIdx
pvt region for dof
Definition: OutputExtractor.hpp:77
Struct holding hysteresis parameters.
Definition: OutputExtractor.hpp:63
PhaseArray * data
Array of buffers to store data in.
Definition: OutputExtractor.hpp:108
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition: OutputExtractor.hpp:219
Definition: OutputExtractor.hpp:225
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 unsigned, const Context &)> PhaseFunc
Callback for extractors assigned to a phase buffer Returns value to store in buffer for requested pha...
Definition: OutputExtractor.hpp:223
Declare the properties used by the infrastructure code of the finite volume discretizations.
Scalar shmax
Max something.
Definition: OutputExtractor.hpp:69
Context passed to element extractor functions.
Definition: OutputExtractor.hpp:205
std::function< Scalar(const unsigned, const Context &)> PhaseFunc
Callback for extractors assigned to a phase buffer Returns value to store in buffer for requested pha...
Definition: OutputExtractor.hpp:93
std::variant< ScalarEntry, PhaseEntry > Entry
Descriptor for extractors.
Definition: OutputExtractor.hpp:245
A scalar extractor descriptor.
Definition: OutputExtractor.hpp:99
PhaseFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:109
std::unordered_map< int, std::vector< Exec > > ExecMap
A map of extraction executors, keyed by cartesian cell index.
Definition: OutputExtractor.hpp:260
Exec(double *d, ScalarFunc &&e)
Move constructor.
Definition: OutputExtractor.hpp:251
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
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition: OutputExtractor.hpp:85
std::variant< AssignFunc, ScalarEntry, PhaseEntry > data
Extractor.
Definition: OutputExtractor.hpp:115
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:76
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:79
std::vector< Scalar > ScalarBuffer
A scalar buffer.
Definition: OutputExtractor.hpp:95
Scalar swmax
Max water saturation.
Definition: OutputExtractor.hpp:66
static void process(const Context &ectx, const std::vector< Entry > &extractors)
Process the given extractor entries.
Definition: OutputExtractor.hpp:158
Scalar somin
Min oil saturation.
Definition: OutputExtractor.hpp:70
Wrapping struct holding types used for block-level data extraction.
Definition: OutputExtractor.hpp:192
ScalarBuffer * data
Buffer to store data in.
Definition: OutputExtractor.hpp:101
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition: OutputExtractor.hpp:89
The Opm property system, traits with inheritance.
static std::vector< Entry > removeInactive(std::array< Entry, size > &input)
Obtain vector of active extractors from an array of extractors.
Definition: OutputExtractor.hpp:121
Context passed to extractor functions.
Definition: OutputExtractor.hpp:74
ScalarFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:102
Scalar swmin
Min water saturation.
Definition: OutputExtractor.hpp:67
double * data
Where to store output data.
Definition: OutputExtractor.hpp:255
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:209
std::array< ScalarBuffer, numPhases > PhaseArray
An array of buffers, one for each phase.
Definition: OutputExtractor.hpp:96
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:207
Scalar somax
Max oil saturation.
Definition: OutputExtractor.hpp:65
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
int episodeIndex
Current report step.
Definition: OutputExtractor.hpp:78
A phase buffer extractor descriptor.
Definition: OutputExtractor.hpp:106
Descriptor for extractor execution.
Definition: OutputExtractor.hpp:248
Defines a type tags and some fundamental properties all models.
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
const HysteresisParams & hParams
Hysteresis parameters for cell.
Definition: OutputExtractor.hpp:81
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:210
std::unordered_map< int, std::unordered_map< int, std::vector< Exec > >> LgrExecMap
A two-level map of extraction executors for cells inside an LGR, keyed by (grid level, level-local linearised Cartesian cell index).
Definition: OutputExtractor.hpp:399
ScalarFunc extract
Associated extraction lamda.
Definition: OutputExtractor.hpp:231