mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Calculate parallel averages in RateConverter.
Previously, local averages were calculated and used in the well equations. With this commit we add versions of defineState and calcAverages that take into account the parallel domain decomposition and calculate correct averages. Function calcAverages has a boolean template parameter indicating whether this is a parallel run. Additionally we introduce AverageIncrementCalculator with the same boolean template parameter. In a parallel run we check whether the cell is owned by the process and only in this case return an increment bigger than zero. In a sequential run (no MPI or just one process -> empty boost::any parameter) no overhead is introduced.
This commit is contained in:
parent
2a0051655c
commit
f8715e31e7
@ -26,6 +26,7 @@
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/utility/RegionMapping.hpp>
|
||||
#include <opm/core/linalg/ParallelIstlInformation.hpp>
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
||||
@ -37,7 +38,6 @@
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Facility for converting component rates at surface conditions to
|
||||
@ -70,6 +70,52 @@ namespace Opm {
|
||||
};
|
||||
} // Select
|
||||
|
||||
/**
|
||||
* \brief Computes the temperature, pressure, and counter increment.
|
||||
*
|
||||
* In a parallel run only cells owned contribute to the cell average.
|
||||
* \tparam is_parallel Whether this is a parallel run.
|
||||
*/
|
||||
template<bool is_parallel>
|
||||
struct AverageIncrementCalculator
|
||||
{
|
||||
/**
|
||||
* \brief Computes the temperature, pressure, and counter increment.
|
||||
* \param pressure The pressure.
|
||||
* \param temperature The temperature.
|
||||
* \param cell The current cell index.
|
||||
* \param ownership A vector indicating whether a cell is owned
|
||||
* by this process (value 1), or not (value 0).
|
||||
* \param cell The cell index.
|
||||
*/
|
||||
std::tuple<double, double, int>
|
||||
operator()(const std::vector<double>& pressure,
|
||||
const std::vector<double>& temperature,
|
||||
const std::vector<double>& ownership,
|
||||
std::size_t cell){
|
||||
if ( ownership[cell] )
|
||||
{
|
||||
return std::make_tuple(pressure[cell],
|
||||
temperature[cell], 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::make_tuple(0, 0, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct AverageIncrementCalculator<true>
|
||||
{
|
||||
std::tuple<double, double, int>
|
||||
operator()(const std::vector<double>& pressure,
|
||||
const std::vector<double>& temperature,
|
||||
const std::vector<double>&,
|
||||
std::size_t cell){
|
||||
return std::make_tuple(pressure[cell],
|
||||
temperature[cell], 1);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Provide mapping from Region IDs to user-specified collection
|
||||
* of per-region attributes.
|
||||
@ -378,14 +424,31 @@ namespace Opm {
|
||||
* reservoir voidage rate.
|
||||
*
|
||||
* \param[in] state Dynamic reservoir state.
|
||||
* \param[in] any The information and communication utilities
|
||||
* about/of the parallelization. in any parallel
|
||||
* it wraps a ParallelISTLInformation. Parameter
|
||||
* is optional.
|
||||
*/
|
||||
void
|
||||
defineState(const BlackoilState& state)
|
||||
defineState(const BlackoilState& state,
|
||||
const boost::any& info = boost::any())
|
||||
{
|
||||
calcAverages(state);
|
||||
#if HAVE_MPI
|
||||
if( info.type() == typeid(ParallelISTLInformation) )
|
||||
{
|
||||
const auto& ownership =
|
||||
boost::any_cast<const ParallelISTLInformation&>(info)
|
||||
.updateOwnerMask(state.pressure());
|
||||
calcAverages<true>(state, info, ownership);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
std::vector<double> dummyOwnership; // not actually used
|
||||
calcAverages<false>(state, info, dummyOwnership);
|
||||
}
|
||||
calcRmax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Region identifier.
|
||||
*
|
||||
@ -551,10 +614,20 @@ namespace Opm {
|
||||
* Compute average hydrocarbon pressure and temperatures in all
|
||||
* regions.
|
||||
*
|
||||
* \param[in] state Dynamic reservoir state.
|
||||
* \param[in] state Dynamic reservoir state.
|
||||
* \param[in] info The information and communication utilities
|
||||
* about/of the parallelization.
|
||||
* \param[in] ownership In a parallel run this is vector containing
|
||||
* 1 for every owned unknown, zero othercase.
|
||||
* If it is no such run then it is not used.
|
||||
* \tparam is_parallel True if the runi is parallel. In this case
|
||||
* info has to contain a ParallelISTLInformation
|
||||
* object.
|
||||
*/
|
||||
template<bool is_parallel>
|
||||
void
|
||||
calcAverages(const BlackoilState& state)
|
||||
calcAverages(const BlackoilState& state, const boost::any& info,
|
||||
const std::vector<double>& ownerShip)
|
||||
{
|
||||
const auto& press = state.pressure();
|
||||
const auto& temp = state.temperature();
|
||||
@ -567,17 +640,30 @@ namespace Opm {
|
||||
std::size_t n = 0;
|
||||
p = T = 0.0;
|
||||
for (const auto& cell : rmap_.cells(reg)) {
|
||||
p += press[ cell ];
|
||||
T += temp [ cell ];
|
||||
|
||||
n += 1;
|
||||
auto increment = Details::
|
||||
AverageIncrementCalculator<is_parallel>()(press, temp,
|
||||
ownerShip,
|
||||
cell);
|
||||
p += std::get<0>(increment);
|
||||
T += std::get<1>(increment);
|
||||
n += std::get<2>(increment);
|
||||
}
|
||||
|
||||
p /= n;
|
||||
T /= n;
|
||||
std::size_t global_n = n;
|
||||
double global_p = p;
|
||||
double global_T = T;
|
||||
#if HAVE_MPI
|
||||
if ( is_parallel )
|
||||
{
|
||||
const auto& real_info = boost::any_cast<const ParallelISTLInformation&>(info);
|
||||
global_n = real_info.communicator().sum(n);
|
||||
global_p = real_info.communicator().sum(p);
|
||||
global_T = real_info.communicator().sum(T);
|
||||
}
|
||||
#endif
|
||||
p = global_p / global_n;
|
||||
T = global_T / global_n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute maximum dissolution and evaporation ratios at
|
||||
* average hydrocarbon pressure.
|
||||
|
@ -365,12 +365,34 @@ namespace Opm
|
||||
|
||||
const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells, step, wmap);
|
||||
|
||||
const std::size_t number_resv_wells = resv_wells.size();
|
||||
std::size_t global_number_resv_wells = number_resv_wells;
|
||||
#if HAVE_MPI
|
||||
if ( solver_.parallelInformation().type() == typeid(ParallelISTLInformation) )
|
||||
{
|
||||
global_number_resv_wells = boost::any_cast<const ParallelISTLInformation&>(solver_.parallelInformation()).communicator().sum(global_number_resv_wells);
|
||||
if ( global_number_resv_wells )
|
||||
{
|
||||
// At least one process has resv wells. Therefore rate converter needs
|
||||
// to calculate averages over regions that might cross process
|
||||
// borders. This needs to be done by all processes and therefore
|
||||
// outside of the next if statement.
|
||||
rateConverter_.defineState(x, boost::any_cast<const ParallelISTLInformation&>(solver_.parallelInformation()));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if ( global_number_resv_wells )
|
||||
{
|
||||
rateConverter_.defineState(x);
|
||||
}
|
||||
}
|
||||
|
||||
if (! resv_wells.empty()) {
|
||||
const PhaseUsage& pu = props_.phaseUsage();
|
||||
const std::vector<double>::size_type np = props_.numPhases();
|
||||
|
||||
rateConverter_.defineState(x);
|
||||
|
||||
std::vector<double> distr (np);
|
||||
std::vector<double> hrates(np);
|
||||
std::vector<double> prates(np);
|
||||
|
Loading…
Reference in New Issue
Block a user