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 <unordered_map>
43 #include <set>
44 #include <variant>
45 #include <vector>
46 
47 #include <fmt/format.h>
48 
49 namespace Opm::detail {
50 
52 template<class TypeTag>
53 struct Extractor
54 {
57  using FluidState = typename IntensiveQuantities::FluidState;
59  static constexpr int numPhases = FluidSystem::numPhases;
60 
63  {
64  Scalar somax{};
65  Scalar swmax{};
66  Scalar swmin{};
67  Scalar sgmax{};
68  Scalar shmax{};
69  Scalar somin{};
70  };
71 
73  struct Context
74  {
75  unsigned globalDofIdx;
76  unsigned pvtRegionIdx;
78  const FluidState& fs;
79  const IntensiveQuantities& intQuants;
81  };
82 
84  using AssignFunc = std::function<void(const Context&)>;
85 
88  using ScalarFunc = std::function<Scalar(const Context&)>;
89 
92  using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
93 
94  using ScalarBuffer = std::vector<Scalar>;
95  using PhaseArray = std::array<ScalarBuffer,numPhases>;
96 
98  struct ScalarEntry
99  {
102  };
103 
105  struct PhaseEntry
106  {
109  };
110 
112  struct Entry
113  {
114  std::variant<AssignFunc, ScalarEntry, PhaseEntry> data;
115  bool condition = true;
116  };
117 
119  template<std::size_t size>
120  static std::vector<Entry> removeInactive(std::array<Entry,size>& input)
121  {
122  // Setup active extractors
123  std::vector<Entry> filtered_extractors;
124  filtered_extractors.reserve(input.size());
125  std::copy_if(std::move_iterator(input.begin()),
126  std::move_iterator(input.end()),
127  std::back_inserter(filtered_extractors),
128  [](const Entry& e)
129  {
130  if (!e.condition) {
131  return false;
132  }
133  return std::visit(VisitorOverloadSet{
134  [](const AssignFunc&)
135  {
136  return true;
137  },
138  [](const ScalarEntry& v)
139  {
140  return !v.data->empty();
141  },
142  [](const PhaseEntry& v)
143  {
144  return std::ranges::any_of(*v.data,
145  [](const auto& ve)
146  { return !ve.empty(); });
147  }
148  }, e.data);
149  });
150 
151  return filtered_extractors;
152  }
153 
157  static void process(const Context& ectx,
158  const std::vector<Entry>& extractors)
159  {
160  std::ranges::for_each(extractors,
161  [&ectx](const auto& entry)
162  {
163  std::visit(VisitorOverloadSet{
164  [&ectx](const ScalarEntry& v)
165  {
166  auto& array = *v.data;
167  array[ectx.globalDofIdx] = v.extract(ectx);
168  Valgrind::CheckDefined(array[ectx.globalDofIdx]);
169  },
170  [&ectx](const PhaseEntry& v)
171  {
172  std::ranges::for_each(*v.data,
173  [phaseIdx = 0, &ectx, &v](auto& array) mutable
174  {
175  if (!array.empty()) {
176  array[ectx.globalDofIdx] = v.extract(phaseIdx, ectx);
177  Valgrind::CheckDefined(array[ectx.globalDofIdx]);
178  }
179  ++phaseIdx;
180  });
181  },
182  [&ectx](const typename Extractor::AssignFunc& extract)
183  { extract(ectx); },
184  }, entry.data);
185  });
186  }
187 };
188 
190 template<class TypeTag>
192 {
194  using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
196  using FluidState = typename IntensiveQuantities::FluidState;
198  static constexpr int numPhases = FluidSystem::numPhases;
199  static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
200  static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
201  static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
202 
204  struct Context
205  {
206  unsigned globalDofIdx;
207  unsigned dofIdx;
208  const FluidState& fs;
209  const IntensiveQuantities& intQuants;
210  const ElementContext& elemCtx;
211  };
212 
214  using AssignFunc = std::function<void(const Context&)>;
215 
218  using ScalarFunc = std::function<Scalar(const Context&)>;
219 
222  using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
223 
224  struct ScalarEntry
225  {
227  std::variant<std::string_view, std::vector<std::string_view>> kw;
228 
231  };
232 
233  struct PhaseEntry
234  {
236  std::variant<std::array<std::string_view, numPhases>,
237  std::array<std::array<std::string_view, numPhases>, 2>> kw;
238 
241  };
242 
244  using Entry = std::variant<ScalarEntry, PhaseEntry>;
245 
247  struct Exec
248  {
250  Exec(double* d, ScalarFunc&& e)
251  : data(d), extract(std::move(e))
252  {}
253 
254  double* data;
256  };
257 
259  using ExecMap = std::unordered_map<int, std::vector<Exec>>;
260 
262  template<std::size_t size>
263  static ExecMap setupExecMap(std::map<std::pair<std::string, int>, double>& blockData,
264  const std::array<Entry,size>& handlers)
265  {
266  using PhaseViewArray = std::array<std::string_view, numPhases>;
267  using StringViewVec = std::vector<std::string_view>;
268 
269  ExecMap extractors;
270 
271  std::ranges::for_each(
272  blockData,
273  [&handlers, &extractors](auto& bd_info)
274  {
275  unsigned phase{};
276  const auto& [key, cell] = bd_info.first;
277  const auto& handler_info =
278  std::ranges::find_if(
279  handlers,
280  [&kw_name = bd_info.first.first, &phase](const auto& handler)
281  {
282  // Extract list of keyword names from handler
283  const auto gen_handlers =
284  std::visit(VisitorOverloadSet{
285  [](const ScalarEntry& entry)
286  {
287  return std::visit(VisitorOverloadSet{
288  [](const std::string_view& kw) -> StringViewVec
289  {
290  return {kw};
291  },
292  [](const StringViewVec& kws) -> StringViewVec
293  { return kws; }
294  }, entry.kw);
295  },
296  [](const PhaseEntry& entry)
297  {
298  return std::visit(VisitorOverloadSet{
299  [](const PhaseViewArray& data)
300  {
301  return StringViewVec{data.begin(), data.end()};
302  },
303  [](const std::array<PhaseViewArray,2>& data)
304  {
305  StringViewVec res;
306  res.reserve(2*numPhases);
307  res.insert(res.end(),
308  data[0].begin(),
309  data[0].end());
310  res.insert(res.end(),
311  data[1].begin(),
312  data[1].end());
313  return res;
314  }
315  }, entry.kw);
316  }
317  }, handler);
318 
319  const auto found_handler =
320  std::ranges::find(gen_handlers, kw_name);
321  if (found_handler != gen_handlers.end()) {
322  phase = std::distance(gen_handlers.begin(), found_handler) % numPhases;
323  }
324  return found_handler != gen_handlers.end();
325  }
326  );
327 
328  if (handler_info != handlers.end()) {
329  extractors[cell - 1].emplace_back(
330  &bd_info.second,
331  std::visit(VisitorOverloadSet{
332  [](const ScalarEntry& e)
333  {
334  return e.extract;
335  },
336  [phase](const PhaseEntry& e) -> ScalarFunc
337  {
338  return [phase, extract = e.extract]
339  (const Context& ectx)
340  {
341  static constexpr auto phaseMap = std::array{
342  waterPhaseIdx,
343  oilPhaseIdx,
344  gasPhaseIdx,
345  };
346  return extract(phaseMap[phase], ectx);
347  };
348  }
349  }, *handler_info)
350  );
351  }
352  else {
353  OpmLog::warning("Unhandled output keyword",
354  fmt::format("Keyword '{}' is unhandled for output "
355  "to summary file.", key));
356  }
357  }
358  );
359 
360  return extractors;
361  }
362 
364  static void process(const std::vector<Exec>& blockExtractors,
365  const Context& ectx)
366  {
367  std::ranges::for_each(blockExtractors,
368  [&ectx](auto& bdata)
369  { *bdata.data = bdata.extract(ectx); });
370  }
371 };
372 
373 } // namespace Opm::detail
374 
375 #endif // OPM_OUTPUT_EXTRACTORS_HPP
ScalarFunc extract
Extraction function to call.
Definition: OutputExtractor.hpp:255
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:112
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:237
Wrapping struct holding types used for element-level data extraction.
Definition: OutputExtractor.hpp:53
bool condition
Additional condition for enabling extractor.
Definition: OutputExtractor.hpp:115
PhaseFunc extract
Associated extraction lambda.
Definition: OutputExtractor.hpp:240
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:79
Definition: OutputExtractor.hpp:233
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:214
static void process(const std::vector< Exec > &blockExtractors, const Context &ectx)
Process a list of block extractors.
Definition: OutputExtractor.hpp:364
Scalar sgmax
Max gas saturation.
Definition: OutputExtractor.hpp:67
unsigned pvtRegionIdx
pvt region for dof
Definition: OutputExtractor.hpp:76
Struct holding hysteresis parameters.
Definition: OutputExtractor.hpp:62
PhaseArray * data
Array of buffers to store data in.
Definition: OutputExtractor.hpp:107
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition: OutputExtractor.hpp:218
Definition: OutputExtractor.hpp:224
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:263
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:222
Declare the properties used by the infrastructure code of the finite volume discretizations.
Scalar shmax
Max something.
Definition: OutputExtractor.hpp:68
Context passed to element extractor functions.
Definition: OutputExtractor.hpp:204
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:92
std::variant< ScalarEntry, PhaseEntry > Entry
Descriptor for extractors.
Definition: OutputExtractor.hpp:244
A scalar extractor descriptor.
Definition: OutputExtractor.hpp:98
PhaseFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:108
std::unordered_map< int, std::vector< Exec > > ExecMap
A map of extraction executors, keyed by cartesian cell index.
Definition: OutputExtractor.hpp:259
Exec(double *d, ScalarFunc &&e)
Move constructor.
Definition: OutputExtractor.hpp:250
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition: OutputExtractor.hpp:84
std::variant< AssignFunc, ScalarEntry, PhaseEntry > data
Extractor.
Definition: OutputExtractor.hpp:114
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:75
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:78
std::vector< Scalar > ScalarBuffer
A scalar buffer.
Definition: OutputExtractor.hpp:94
Scalar swmax
Max water saturation.
Definition: OutputExtractor.hpp:65
static void process(const Context &ectx, const std::vector< Entry > &extractors)
Process the given extractor entries.
Definition: OutputExtractor.hpp:157
Scalar somin
Min oil saturation.
Definition: OutputExtractor.hpp:69
Wrapping struct holding types used for block-level data extraction.
Definition: OutputExtractor.hpp:191
ScalarBuffer * data
Buffer to store data in.
Definition: OutputExtractor.hpp:100
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition: OutputExtractor.hpp:88
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:120
Context passed to extractor functions.
Definition: OutputExtractor.hpp:73
ScalarFunc extract
Function to call for extraction.
Definition: OutputExtractor.hpp:101
Scalar swmin
Min water saturation.
Definition: OutputExtractor.hpp:66
double * data
Where to store output data.
Definition: OutputExtractor.hpp:254
const FluidState & fs
Fluid state for cell.
Definition: OutputExtractor.hpp:208
std::array< ScalarBuffer, numPhases > PhaseArray
An array of buffers, one for each phase.
Definition: OutputExtractor.hpp:95
unsigned globalDofIdx
Global degree-of-freedom index.
Definition: OutputExtractor.hpp:206
Scalar somax
Max oil saturation.
Definition: OutputExtractor.hpp:64
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:227
int episodeIndex
Current report step.
Definition: OutputExtractor.hpp:77
A phase buffer extractor descriptor.
Definition: OutputExtractor.hpp:105
Descriptor for extractor execution.
Definition: OutputExtractor.hpp:247
Defines a type tags and some fundamental properties all models.
const HysteresisParams & hParams
Hysteresis parameters for cell.
Definition: OutputExtractor.hpp:80
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition: OutputExtractor.hpp:209
ScalarFunc extract
Associated extraction lamda.
Definition: OutputExtractor.hpp:230