Loading...
Searching...
No Matches
OutputExtractor.hpp
Go to the documentation of this file.
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
#ifndef OPM_OUTPUT_EXTRACTORS_HPP
#define OPM_OUTPUT_EXTRACTORS_HPP
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/utility/Visitor.hpp>
#include <opm/material/common/Valgrind.hpp>
#include <opm/models/common/multiphasebaseproperties.hh>
#include <opm/models/discretization/common/fvbaseproperties.hh>
#include <opm/models/utils/basicproperties.hh>
#include <opm/models/utils/propertysystem.hh>
#include <algorithm>
#include <array>
#include <unordered_map>
#include <set>
#include <variant>
#include <vector>
#include <fmt/format.h>
namespace Opm::detail {
template<class TypeTag>
struct Extractor
{
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidState = typename IntensiveQuantities::FluidState;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
static constexpr int numPhases = FluidSystem::numPhases;
struct HysteresisParams
{
Scalar somax{};
Scalar swmax{};
Scalar swmin{};
Scalar sgmax{};
Scalar shmax{};
Scalar somin{};
};
struct Context
{
unsigned globalDofIdx;
unsigned pvtRegionIdx;
int episodeIndex;
const FluidState& fs;
const IntensiveQuantities& intQuants;
const HysteresisParams& hParams;
};
using AssignFunc = std::function<void(const Context&)>;
using ScalarFunc = std::function<Scalar(const Context&)>;
using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
using ScalarBuffer = std::vector<Scalar>;
using PhaseArray = std::array<ScalarBuffer,numPhases>;
struct ScalarEntry
{
ScalarBuffer* data;
ScalarFunc extract;
};
struct PhaseEntry
{
PhaseArray* data;
PhaseFunc extract;
};
struct Entry
{
std::variant<AssignFunc, ScalarEntry, PhaseEntry> data;
bool condition = true;
};
template<std::size_t size>
static std::vector<Entry> removeInactive(std::array<Entry,size>& input)
{
// Setup active extractors
std::vector<Entry> filtered_extractors;
filtered_extractors.reserve(input.size());
std::copy_if(std::move_iterator(input.begin()),
std::move_iterator(input.end()),
std::back_inserter(filtered_extractors),
[](const Entry& e)
{
if (!e.condition) {
return false;
}
return std::visit(VisitorOverloadSet{
[](const AssignFunc&)
{
return true;
},
[](const ScalarEntry& v)
{
return !v.data->empty();
},
[](const PhaseEntry& v)
{
return std::any_of(v.data->begin(),
v.data->end(),
[](const auto& ve)
{ return !ve.empty(); });
}
}, e.data);
});
return filtered_extractors;
}
static void process(const Context& ectx,
const std::vector<Entry>& extractors)
{
std::for_each(extractors.begin(), extractors.end(),
[&ectx](const auto& entry)
{
std::visit(VisitorOverloadSet{
[&ectx](const ScalarEntry& v)
{
auto& array = *v.data;
array[ectx.globalDofIdx] = v.extract(ectx);
Valgrind::CheckDefined(array[ectx.globalDofIdx]);
},
[&ectx](const PhaseEntry& v)
{
std::for_each(v.data->begin(), v.data->end(),
[phaseIdx = 0, &ectx, &v](auto& array) mutable
{
if (!array.empty()) {
array[ectx.globalDofIdx] = v.extract(phaseIdx, ectx);
Valgrind::CheckDefined(array[ectx.globalDofIdx]);
}
++phaseIdx;
});
},
[&ectx](const typename Extractor::AssignFunc& extract)
{ extract(ectx); },
}, entry.data);
});
}
};
template<class TypeTag>
struct BlockExtractor
{
using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using FluidState = typename IntensiveQuantities::FluidState;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
static constexpr int numPhases = FluidSystem::numPhases;
static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
struct Context
{
unsigned globalDofIdx;
unsigned dofIdx;
const FluidState& fs;
const IntensiveQuantities& intQuants;
const ElementContext& elemCtx;
};
using AssignFunc = std::function<void(const Context&)>;
using ScalarFunc = std::function<Scalar(const Context&)>;
using PhaseFunc = std::function<Scalar(const unsigned /*phase*/, const Context&)>;
struct ScalarEntry
{
std::variant<std::string_view, std::vector<std::string_view>> kw;
ScalarFunc extract;
};
struct PhaseEntry
{
std::variant<std::array<std::string_view, numPhases>,
std::array<std::array<std::string_view, numPhases>, 2>> kw;
PhaseFunc extract;
};
using Entry = std::variant<ScalarEntry, PhaseEntry>;
struct Exec
{
Exec(double* d, ScalarFunc&& e)
: data(d), extract(std::move(e))
{}
double* data;
ScalarFunc extract;
};
using ExecMap = std::unordered_map<int, std::vector<Exec>>;
template<std::size_t size>
static ExecMap setupExecMap(std::map<std::pair<std::string, int>, double>& blockData,
const std::array<Entry,size>& handlers)
{
using PhaseViewArray = std::array<std::string_view, numPhases>;
using StringViewVec = std::vector<std::string_view>;
ExecMap extractors;
std::for_each(
blockData.begin(),
blockData.end(),
[&handlers, &extractors](auto& bd_info)
{
unsigned phase{};
const auto& [key, cell] = bd_info.first;
const auto& handler_info =
std::find_if(
handlers.begin(),
handlers.end(),
[&kw_name = bd_info.first.first, &phase](const auto& handler)
{
// Extract list of keyword names from handler
const auto gen_handlers =
std::visit(VisitorOverloadSet{
[](const ScalarEntry& entry)
{
return std::visit(VisitorOverloadSet{
[](const std::string_view& kw) -> StringViewVec
{
return {kw};
},
[](const StringViewVec& kws) -> StringViewVec
{ return kws; }
}, entry.kw);
},
[](const PhaseEntry& entry)
{
return std::visit(VisitorOverloadSet{
[](const PhaseViewArray& data)
{
return StringViewVec{data.begin(), data.end()};
},
[](const std::array<PhaseViewArray,2>& data)
{
StringViewVec res;
res.reserve(2*numPhases);
res.insert(res.end(),
data[0].begin(),
data[0].end());
res.insert(res.end(),
data[1].begin(),
data[1].end());
return res;
}
}, entry.kw);
}
}, handler);
const auto found_handler =
std::find(gen_handlers.begin(), gen_handlers.end(), kw_name);
if (found_handler != gen_handlers.end()) {
phase = std::distance(gen_handlers.begin(), found_handler) % numPhases;
}
return found_handler != gen_handlers.end();
}
);
if (handler_info != handlers.end()) {
extractors[cell - 1].emplace_back(
&bd_info.second,
std::visit(VisitorOverloadSet{
[](const ScalarEntry& e)
{
return e.extract;
},
[phase](const PhaseEntry& e) -> ScalarFunc
{
return [phase, extract = e.extract]
(const Context& ectx)
{
static constexpr auto phaseMap = std::array{
waterPhaseIdx,
oilPhaseIdx,
gasPhaseIdx,
};
return extract(phaseMap[phase], ectx);
};
}
}, *handler_info)
);
}
else {
OpmLog::warning("Unhandled output keyword",
fmt::format("Keyword '{}' is unhandled for output "
"to summary file.", key));
}
}
);
return extractors;
}
static void process(const std::vector<Exec>& blockExtractors,
const Context& ectx)
{
std::for_each(blockExtractors.begin(), blockExtractors.end(),
[&ectx](auto& bdata)
{ *bdata.data = bdata.extract(ectx); });
}
};
} // namespace Opm::detail
#endif // OPM_OUTPUT_EXTRACTORS_HPP
basicproperties.hh
Defines a type tags and some fundamental properties all models.
fvbaseproperties.hh
Declare the properties used by the infrastructure code of the finite volume discretizations.
multiphasebaseproperties.hh
Defines the common properties required by the porous medium multi-phase models.
Opm::GetPropType
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
propertysystem.hh
The Opm property system, traits with inheritance.
Opm::detail::BlockExtractor::Context
Context passed to element extractor functions.
Definition OutputExtractor.hpp:206
Opm::detail::BlockExtractor::Context::fs
const FluidState & fs
Fluid state for cell.
Definition OutputExtractor.hpp:209
Opm::detail::BlockExtractor::Context::intQuants
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition OutputExtractor.hpp:210
Opm::detail::BlockExtractor::Context::globalDofIdx
unsigned globalDofIdx
Global degree-of-freedom index.
Definition OutputExtractor.hpp:207
Opm::detail::BlockExtractor::Exec::data
double * data
Where to store output data.
Definition OutputExtractor.hpp:255
Opm::detail::BlockExtractor::Exec::extract
ScalarFunc extract
Extraction function to call.
Definition OutputExtractor.hpp:256
Opm::detail::BlockExtractor::Exec::Exec
Exec(double *d, ScalarFunc &&e)
Move constructor.
Definition OutputExtractor.hpp:251
Opm::detail::BlockExtractor::PhaseEntry
Definition OutputExtractor.hpp:235
Opm::detail::BlockExtractor::PhaseEntry::extract
PhaseFunc extract
Associated extraction lambda.
Definition OutputExtractor.hpp:241
Opm::detail::BlockExtractor::PhaseEntry::kw
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
Opm::detail::BlockExtractor::ScalarEntry
Definition OutputExtractor.hpp:226
Opm::detail::BlockExtractor::ScalarEntry::kw
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
Opm::detail::BlockExtractor::ScalarEntry::extract
ScalarFunc extract
Associated extraction lamda.
Definition OutputExtractor.hpp:231
Opm::detail::BlockExtractor
Wrapping struct holding types used for block-level data extraction.
Definition OutputExtractor.hpp:193
Opm::detail::BlockExtractor::PhaseFunc
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
Opm::detail::BlockExtractor::ExecMap
std::unordered_map< int, std::vector< Exec > > ExecMap
A map of extraction executors, keyed by cartesian cell index.
Definition OutputExtractor.hpp:260
Opm::detail::BlockExtractor::Entry
std::variant< ScalarEntry, PhaseEntry > Entry
Descriptor for extractors.
Definition OutputExtractor.hpp:245
Opm::detail::BlockExtractor::setupExecMap
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:264
Opm::detail::BlockExtractor::ScalarFunc
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition OutputExtractor.hpp:219
Opm::detail::BlockExtractor::process
static void process(const std::vector< Exec > &blockExtractors, const Context &ectx)
Process a list of block extractors.
Definition OutputExtractor.hpp:367
Opm::detail::BlockExtractor::AssignFunc
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition OutputExtractor.hpp:215
Opm::detail::Extractor::Context
Context passed to extractor functions.
Definition OutputExtractor.hpp:74
Opm::detail::Extractor::Context::hParams
const HysteresisParams & hParams
Hysteresis parameters for cell.
Definition OutputExtractor.hpp:80
Opm::detail::Extractor::Context::intQuants
const IntensiveQuantities & intQuants
Intensive quantities for cell.
Definition OutputExtractor.hpp:79
Opm::detail::Extractor::Context::globalDofIdx
unsigned globalDofIdx
Global degree-of-freedom index.
Definition OutputExtractor.hpp:75
Opm::detail::Extractor::Context::fs
const FluidState & fs
Fluid state for cell.
Definition OutputExtractor.hpp:78
Opm::detail::Extractor::Context::episodeIndex
int episodeIndex
Current report step.
Definition OutputExtractor.hpp:77
Opm::detail::Extractor::Context::pvtRegionIdx
unsigned pvtRegionIdx
pvt region for dof
Definition OutputExtractor.hpp:76
Opm::detail::Extractor::Entry
Descriptor for extractors.
Definition OutputExtractor.hpp:113
Opm::detail::Extractor::Entry::condition
bool condition
Additional condition for enabling extractor.
Definition OutputExtractor.hpp:115
Opm::detail::Extractor::Entry::data
std::variant< AssignFunc, ScalarEntry, PhaseEntry > data
Extractor.
Definition OutputExtractor.hpp:114
Opm::detail::Extractor::HysteresisParams
Struct holding hysteresis parameters.
Definition OutputExtractor.hpp:63
Opm::detail::Extractor::HysteresisParams::somin
Scalar somin
Min oil saturation.
Definition OutputExtractor.hpp:69
Opm::detail::Extractor::HysteresisParams::swmin
Scalar swmin
Min water saturation.
Definition OutputExtractor.hpp:66
Opm::detail::Extractor::HysteresisParams::swmax
Scalar swmax
Max water saturation.
Definition OutputExtractor.hpp:65
Opm::detail::Extractor::HysteresisParams::shmax
Scalar shmax
Max something.
Definition OutputExtractor.hpp:68
Opm::detail::Extractor::HysteresisParams::sgmax
Scalar sgmax
Max gas saturation.
Definition OutputExtractor.hpp:67
Opm::detail::Extractor::HysteresisParams::somax
Scalar somax
Max oil saturation.
Definition OutputExtractor.hpp:64
Opm::detail::Extractor::PhaseEntry
A phase buffer extractor descriptor.
Definition OutputExtractor.hpp:106
Opm::detail::Extractor::PhaseEntry::data
PhaseArray * data
Array of buffers to store data in.
Definition OutputExtractor.hpp:107
Opm::detail::Extractor::PhaseEntry::extract
PhaseFunc extract
Function to call for extraction.
Definition OutputExtractor.hpp:108
Opm::detail::Extractor::ScalarEntry
A scalar extractor descriptor.
Definition OutputExtractor.hpp:99
Opm::detail::Extractor::ScalarEntry::data
ScalarBuffer * data
Buffer to store data in.
Definition OutputExtractor.hpp:100
Opm::detail::Extractor::ScalarEntry::extract
ScalarFunc extract
Function to call for extraction.
Definition OutputExtractor.hpp:101
Opm::detail::Extractor
Wrapping struct holding types used for element-level data extraction.
Definition OutputExtractor.hpp:54
Opm::detail::Extractor::PhaseArray
std::array< ScalarBuffer, numPhases > PhaseArray
An array of buffers, one for each phase.
Definition OutputExtractor.hpp:95
Opm::detail::Extractor::ScalarBuffer
std::vector< Scalar > ScalarBuffer
A scalar buffer.
Definition OutputExtractor.hpp:94
Opm::detail::Extractor::AssignFunc
std::function< void(const Context &)> AssignFunc
Callback for extractors handling their own assignements.
Definition OutputExtractor.hpp:84
Opm::detail::Extractor::PhaseFunc
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
Opm::detail::Extractor::ScalarFunc
std::function< Scalar(const Context &)> ScalarFunc
Callback for extractors assigned to a scalar buffer Return value to store in buffer.
Definition OutputExtractor.hpp:88
Opm::detail::Extractor::process
static void process(const Context &ectx, const std::vector< Entry > &extractors)
Process the given extractor entries.
Definition OutputExtractor.hpp:158
Opm::detail::Extractor::removeInactive
static std::vector< Entry > removeInactive(std::array< Entry, size > &input)
Obtain vector of active extractors from an array of extractors.
Definition OutputExtractor.hpp:120