Allow auto creation of field properties arrays in ParallelEclipseState.

There are field properties that can usually be queried even if they
are not explicitly specified in the input
file (e.g. PVTNUM). Unfortunately, the ParallelEclipseState cannot
forsee which of these will be queried at startup and after the
loadbalancing only the master process is able to auto creates
these (easily). Hence this commit uses a fall-back if an unstored
keyword is queried. In this case we use get_global-* to auto create
the keyword and use functions of the cartesian mapper to extract the
relevant values on the process.

Of course this temporarily wastes space and we might want to resort to
a more memory savy approach later.
This commit is contained in:
Markus Blatt 2020-03-09 14:21:35 +01:00
parent f4876becfb
commit 04311f6337
3 changed files with 53 additions and 2 deletions

View File

@ -218,6 +218,8 @@ public:
#endif
cartesianIndexMapper_.reset(new CartesianIndexMapper(*grid_));
// reset cartesian index mapper for auto creation of field properties
static_cast<ParallelEclipseState&>(this->eclState()).resetCartesianMapper(cartesianIndexMapper_.get());
this->updateGridView_();
#if HAVE_MPI
if (mpiSize > 1) {

View File

@ -66,7 +66,19 @@ const std::vector<int>& ParallelFieldPropsManager::get_int(const std::string& ke
{
auto it = m_intProps.find(keyword);
if (it == m_intProps.end())
OPM_THROW(std::runtime_error, "No integer property field: " + keyword);
{
// Some of the keywords might be defaulted.
// We will let rank 0 create them and distribute them using get_global_int
auto data = get_global_int(keyword);
auto& local_data = const_cast<std::map<std::string, std::vector<int>>&>(m_intProps)[keyword];
local_data.resize(m_activeSize());
for (int i = 0; i < m_activeSize(); ++i)
{
local_data[i] = data[m_local2Global(i)];
}
return local_data;
}
return it->second;
}
@ -107,7 +119,18 @@ const std::vector<double>& ParallelFieldPropsManager::get_double(const std::stri
{
auto it = m_doubleProps.find(keyword);
if (it == m_doubleProps.end())
OPM_THROW(std::runtime_error, "No double property field: " + keyword);
{
// Some of the keywords might be defaulted.
// We will let rank 0 create them and distribute them using get_global_int
auto data = get_global_double(keyword);
auto& local_data = const_cast<std::map<std::string, std::vector<double>>&>(m_doubleProps)[keyword];
local_data.resize(m_activeSize());
for (int i = 0; i < m_activeSize(); ++i)
{
local_data[i] = data[m_local2Global(i)];
}
return local_data;
}
return it->second;
}

View File

@ -22,6 +22,8 @@
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <dune/common/parallel/mpihelper.hh>
#include <functional>
namespace Opm {
@ -83,11 +85,25 @@ public:
//! \param keyword Name of property
bool has_double(const std::string& keyword) const override;
//! \brief Resets the underlying cartesian mapper
//! \detail This has to be the cartesian mapper of the distributed grid.
//! It will be used to autocreate properties not explicitly stored.
//! \tparam T The type of the cartesian mapper
//! \param mapper The cartesian mapper of the distributed grid
template<class T>
void resetCartesianMapper(const T* mapper)
{
m_activeSize = std::bind(&T::compressedSize, mapper);
m_local2Global = std::bind(&T::cartesianIndex, mapper,
std::placeholders::_1);
}
protected:
std::map<std::string, std::vector<int>> m_intProps; //!< Map of integer properties in process-local compressed indices.
std::map<std::string, std::vector<double>> m_doubleProps; //!< Map of double properties in process-local compressed indices.
FieldPropsManager& m_manager; //!< Underlying field property manager (only used on root process).
Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> m_comm; //!< Collective communication handler.
std::function<int(void)> m_activeSize; //!< active size function of the grid
std::function<int(const int)> m_local2Global; //!< mapping from local to global cartesian indices
};
@ -152,6 +168,16 @@ public:
//! \details Can only be called on root process.
const EclipseGrid& getInputGrid() const override;
//! \brief Resets the underlying cartesian mapper
//! \detail This has to be the cartesian mapper of the distributed grid.
//! It will be used to autocreate properties not explicitly stored.
//! \tparam T The type of the cartesian mapper
//! \param mapper The cartesian mapper of the distributed grid
template<class T>
void resetCartesianMapper(const T* mapper)
{
m_fieldProps.resetCartesianMapper(mapper);
}
private:
bool m_parProps = false; //! True to use distributed properties on root process
ParallelFieldPropsManager m_fieldProps; //!< The parallel field properties