mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Make the parallel reduction when applying the Wells.
The B matrix is basically a component-wise multiplication with a vector followed by a parallel reduction. We do that reduction to all ranks computing for the well to save the broadcast when applying C^T.
This commit is contained in:
parent
3996967344
commit
8ee58096ba
@ -416,6 +416,16 @@ public:
|
|||||||
int outputInterval = EWOMS_GET_PARAM(TypeTag, int, EclOutputInterval);
|
int outputInterval = EWOMS_GET_PARAM(TypeTag, int, EclOutputInterval);
|
||||||
if (outputInterval >= 0)
|
if (outputInterval >= 0)
|
||||||
schedule().restart().overrideRestartWriteInterval(outputInterval);
|
schedule().restart().overrideRestartWriteInterval(outputInterval);
|
||||||
|
|
||||||
|
// Initialize parallelWells with all local wells
|
||||||
|
const auto& schedule_wells = schedule().getWellsatEnd();
|
||||||
|
parallelWells_.reserve(schedule_wells.size());
|
||||||
|
|
||||||
|
for (const auto& well: schedule_wells)
|
||||||
|
{
|
||||||
|
parallelWells_.emplace_back(well.name(), true);
|
||||||
|
}
|
||||||
|
std::sort(parallelWells_.begin(), parallelWells_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -280,6 +280,7 @@ namespace Opm {
|
|||||||
std::vector< WellProdIndexCalculator > prod_index_calc_;
|
std::vector< WellProdIndexCalculator > prod_index_calc_;
|
||||||
|
|
||||||
std::vector< ParallelWellInfo > parallel_well_info_;
|
std::vector< ParallelWellInfo > parallel_well_info_;
|
||||||
|
std::vector< ParallelWellInfo* > local_parallel_well_info_;
|
||||||
|
|
||||||
bool wells_active_;
|
bool wells_active_;
|
||||||
|
|
||||||
@ -360,7 +361,7 @@ namespace Opm {
|
|||||||
/// \param timeStepIdx The index of the time step.
|
/// \param timeStepIdx The index of the time step.
|
||||||
/// \param[out] globalNumWells the number of wells globally.
|
/// \param[out] globalNumWells the number of wells globally.
|
||||||
std::vector< Well > getLocalNonshutWells(const int timeStepIdx,
|
std::vector< Well > getLocalNonshutWells(const int timeStepIdx,
|
||||||
int& globalNumWells) const;
|
int& globalNumWells);
|
||||||
|
|
||||||
// compute the well fluxes and assemble them in to the reservoir equations as source terms
|
// compute the well fluxes and assemble them in to the reservoir equations as source terms
|
||||||
// and in the well equations.
|
// and in the well equations.
|
||||||
|
@ -217,11 +217,23 @@ namespace Opm {
|
|||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
std::vector< Well >
|
std::vector< Well >
|
||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
getLocalNonshutWells(const int timeStepIdx, int& globalNumWells) const
|
getLocalNonshutWells(const int timeStepIdx, int& globalNumWells)
|
||||||
{
|
{
|
||||||
auto w = schedule().getWells(timeStepIdx);
|
auto w = schedule().getWells(timeStepIdx);
|
||||||
globalNumWells = w.size();
|
globalNumWells = w.size();
|
||||||
w.erase(std::remove_if(w.begin(), w.end(), is_shut_or_defunct_), w.end());
|
w.erase(std::remove_if(w.begin(), w.end(), is_shut_or_defunct_), w.end());
|
||||||
|
local_parallel_well_info_.clear();
|
||||||
|
local_parallel_well_info_.reserve(w.size());
|
||||||
|
for (const auto& well : w)
|
||||||
|
{
|
||||||
|
auto wellPair = std::make_pair(well.name(), true);
|
||||||
|
auto pwell = std::lower_bound(parallel_well_info_.begin(),
|
||||||
|
parallel_well_info_.end(),
|
||||||
|
wellPair);
|
||||||
|
assert(pwell != parallel_well_info_.end() &&
|
||||||
|
*pwell == wellPair);
|
||||||
|
local_parallel_well_info_.push_back(&(*pwell));
|
||||||
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,6 +814,7 @@ namespace Opm {
|
|||||||
const auto& perf_data = this->well_perf_data_[wellID];
|
const auto& perf_data = this->well_perf_data_[wellID];
|
||||||
|
|
||||||
return std::make_unique<WellType>(this->wells_ecl_[wellID],
|
return std::make_unique<WellType>(this->wells_ecl_[wellID],
|
||||||
|
*local_parallel_well_info_[wellID],
|
||||||
time_step,
|
time_step,
|
||||||
this->param_,
|
this->param_,
|
||||||
*this->rateConverter_,
|
*this->rateConverter_,
|
||||||
|
@ -98,7 +98,9 @@ namespace Opm
|
|||||||
// TODO: for now, we only use one type to save some implementation efforts, while improve later.
|
// TODO: for now, we only use one type to save some implementation efforts, while improve later.
|
||||||
typedef DenseAd::Evaluation<double, /*size=*/numEq + numWellEq> EvalWell;
|
typedef DenseAd::Evaluation<double, /*size=*/numEq + numWellEq> EvalWell;
|
||||||
|
|
||||||
MultisegmentWell(const Well& well, const int time_step,
|
MultisegmentWell(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
|
@ -31,7 +31,9 @@ namespace Opm
|
|||||||
|
|
||||||
template <typename TypeTag>
|
template <typename TypeTag>
|
||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
MultisegmentWell(const Well& well, const int time_step,
|
MultisegmentWell(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
@ -40,7 +42,7 @@ namespace Opm
|
|||||||
const int index_of_well,
|
const int index_of_well,
|
||||||
const int first_perf_index,
|
const int first_perf_index,
|
||||||
const std::vector<PerforationData>& perf_data)
|
const std::vector<PerforationData>& perf_data)
|
||||||
: Base(well, time_step, param, rate_converter, pvtRegionIdx, num_components, num_phases, index_of_well, first_perf_index, perf_data)
|
: Base(well, pw_info, time_step, param, rate_converter, pvtRegionIdx, num_components, num_phases, index_of_well, first_perf_index, perf_data)
|
||||||
, segment_perforations_(numberOfSegments())
|
, segment_perforations_(numberOfSegments())
|
||||||
, segment_inlets_(numberOfSegments())
|
, segment_inlets_(numberOfSegments())
|
||||||
, cell_perforation_depth_diffs_(number_of_perforations_, 0.0)
|
, cell_perforation_depth_diffs_(number_of_perforations_, 0.0)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <opm/simulators/wells/RateConverter.hpp>
|
#include <opm/simulators/wells/RateConverter.hpp>
|
||||||
#include <opm/simulators/wells/WellInterface.hpp>
|
#include <opm/simulators/wells/WellInterface.hpp>
|
||||||
#include <opm/simulators/wells/WellProdIndexCalculator.hpp>
|
#include <opm/simulators/wells/WellProdIndexCalculator.hpp>
|
||||||
|
#include <opm/simulators/wells/ParallelWellInfo.hpp>
|
||||||
|
|
||||||
#include <opm/models/blackoil/blackoilpolymermodules.hh>
|
#include <opm/models/blackoil/blackoilpolymermodules.hh>
|
||||||
#include <opm/models/blackoil/blackoilsolventmodules.hh>
|
#include <opm/models/blackoil/blackoilsolventmodules.hh>
|
||||||
@ -158,7 +159,9 @@ namespace Opm
|
|||||||
using Base::contiBrineEqIdx;
|
using Base::contiBrineEqIdx;
|
||||||
static const int contiEnergyEqIdx = Indices::contiEnergyEqIdx;
|
static const int contiEnergyEqIdx = Indices::contiEnergyEqIdx;
|
||||||
|
|
||||||
StandardWell(const Well& well, const int time_step,
|
StandardWell(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
@ -377,6 +380,9 @@ namespace Opm
|
|||||||
// diagonal matrix for the well
|
// diagonal matrix for the well
|
||||||
DiagMatWell invDuneD_;
|
DiagMatWell invDuneD_;
|
||||||
|
|
||||||
|
// Wrapper for the parallel application of B for distributed wells
|
||||||
|
wellhelpers::ParallelStandardWellB<Scalar> parallelB_;
|
||||||
|
|
||||||
// several vector used in the matrix calculation
|
// several vector used in the matrix calculation
|
||||||
mutable BVectorWell Bx_;
|
mutable BVectorWell Bx_;
|
||||||
mutable BVectorWell invDrw_;
|
mutable BVectorWell invDrw_;
|
||||||
|
@ -33,7 +33,9 @@ namespace Opm
|
|||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
StandardWell<TypeTag>::
|
StandardWell<TypeTag>::
|
||||||
StandardWell(const Well& well, const int time_step,
|
StandardWell(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
@ -42,9 +44,10 @@ namespace Opm
|
|||||||
const int index_of_well,
|
const int index_of_well,
|
||||||
const int first_perf_index,
|
const int first_perf_index,
|
||||||
const std::vector<PerforationData>& perf_data)
|
const std::vector<PerforationData>& perf_data)
|
||||||
: Base(well, time_step, param, rate_converter, pvtRegionIdx, num_components, num_phases, index_of_well, first_perf_index, perf_data)
|
: Base(well, pw_info, time_step, param, rate_converter, pvtRegionIdx, num_components, num_phases, index_of_well, first_perf_index, perf_data)
|
||||||
, perf_densities_(number_of_perforations_)
|
, perf_densities_(number_of_perforations_)
|
||||||
, perf_pressure_diffs_(number_of_perforations_)
|
, perf_pressure_diffs_(number_of_perforations_)
|
||||||
|
, parallelB_(duneB_, pw_info)
|
||||||
, F0_(numWellConservationEq)
|
, F0_(numWellConservationEq)
|
||||||
, ipr_a_(number_of_phases_)
|
, ipr_a_(number_of_phases_)
|
||||||
, ipr_b_(number_of_phases_)
|
, ipr_b_(number_of_phases_)
|
||||||
@ -657,6 +660,9 @@ namespace Opm
|
|||||||
// Update the connection
|
// Update the connection
|
||||||
connectionRates_ = connectionRates;
|
connectionRates_ = connectionRates;
|
||||||
|
|
||||||
|
// accumulate resWell_ and invDuneD_ in parallel to get effects of all perforations (might be distributed)
|
||||||
|
wellhelpers::sumDistributedWellEntries(invDuneD_[0][0], resWell_[0],
|
||||||
|
this->parallel_well_info_->communication());
|
||||||
// add vol * dF/dt + Q to the well equations;
|
// add vol * dF/dt + Q to the well equations;
|
||||||
for (int componentIdx = 0; componentIdx < numWellConservationEq; ++componentIdx) {
|
for (int componentIdx = 0; componentIdx < numWellConservationEq; ++componentIdx) {
|
||||||
// TODO: following the development in MSW, we need to convert the volume of the wellbore to be surface volume
|
// TODO: following the development in MSW, we need to convert the volume of the wellbore to be surface volume
|
||||||
@ -2475,7 +2481,8 @@ namespace Opm
|
|||||||
assert( invDrw_.size() == invDuneD_.N() );
|
assert( invDrw_.size() == invDuneD_.N() );
|
||||||
|
|
||||||
// Bx_ = duneB_ * x
|
// Bx_ = duneB_ * x
|
||||||
duneB_.mv(x, Bx_);
|
parallelB_.mv(x, Bx_);
|
||||||
|
|
||||||
// invDBx = invDuneD_ * Bx_
|
// invDBx = invDuneD_ * Bx_
|
||||||
// TODO: with this, we modified the content of the invDrw_.
|
// TODO: with this, we modified the content of the invDrw_.
|
||||||
// Is it necessary to do this to save some memory?
|
// Is it necessary to do this to save some memory?
|
||||||
@ -2574,7 +2581,7 @@ namespace Opm
|
|||||||
|
|
||||||
BVectorWell resWell = resWell_;
|
BVectorWell resWell = resWell_;
|
||||||
// resWell = resWell - B * x
|
// resWell = resWell - B * x
|
||||||
duneB_.mmv(x, resWell);
|
parallelB_.mmv(x, resWell);
|
||||||
// xw = D^-1 * resWell
|
// xw = D^-1 * resWell
|
||||||
invDuneD_.mv(resWell, xw);
|
invDuneD_.mv(resWell, xw);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2016 SINTEF ICT, Applied Mathematics.
|
Copyright 2016 SINTEF ICT, Applied Mathematics.
|
||||||
Copyright 2016 Statoil ASA.
|
Copyright 2016 Statoil ASA.
|
||||||
|
Copyright 2020 OPM-OP AS.
|
||||||
|
|
||||||
This file is part of the Open Porous Media project (OPM).
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
@ -22,6 +23,12 @@
|
|||||||
#ifndef OPM_WELLHELPERS_HEADER_INCLUDED
|
#ifndef OPM_WELLHELPERS_HEADER_INCLUDED
|
||||||
#define OPM_WELLHELPERS_HEADER_INCLUDED
|
#define OPM_WELLHELPERS_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||||
|
#include <opm/simulators/wells/ParallelWellInfo.hpp>
|
||||||
|
|
||||||
|
#include <dune/istl/bcrsmatrix.hh>
|
||||||
|
#include <dune/common/dynmatrix.hh>
|
||||||
|
#include <dune/common/parallel/mpihelper.hh>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -33,6 +40,93 @@ namespace Opm {
|
|||||||
namespace wellhelpers
|
namespace wellhelpers
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// \brief A wrapper around the B matrix for distributed wells
|
||||||
|
///
|
||||||
|
/// For standard wells the B matrix, is basically a multiplication
|
||||||
|
/// of the equation of the perforated cells followed by a reduction
|
||||||
|
/// (summation) of these to the well equations.
|
||||||
|
///
|
||||||
|
/// This class does that in the functions mv and mmv (from the DUNE
|
||||||
|
/// matrix interface.
|
||||||
|
///
|
||||||
|
/// \tparam Scalar The scalar used for the computation.
|
||||||
|
template<typename Scalar>
|
||||||
|
class ParallelStandardWellB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Block = Dune::DynamicMatrix<Scalar>;
|
||||||
|
using Matrix = Dune::BCRSMatrix<Block>;
|
||||||
|
|
||||||
|
ParallelStandardWellB(const Matrix& B, const ParallelWellInfo& pinfo)
|
||||||
|
: B_(&B), pinfo_(&pinfo)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//! y = A x
|
||||||
|
template<class X, class Y>
|
||||||
|
void mv (const X& x, Y& y) const
|
||||||
|
{
|
||||||
|
#if !defined(NDEBUG) && HAVE_MPI
|
||||||
|
// We need to make sure that all ranks are actually computing
|
||||||
|
// for the same well. Doing this by checking the name of the well.
|
||||||
|
int cstring_size = pinfo_->name().size()+1;
|
||||||
|
std::vector<int> sizes(pinfo_->communication().size());
|
||||||
|
pinfo_->communication().allgather(&cstring_size, 1, sizes.data());
|
||||||
|
std::vector<int> offsets(sizes.size()+1, 0); //last entry will be accumulated size
|
||||||
|
std::partial_sum(sizes.begin(), sizes.end(), offsets.begin() + 1);
|
||||||
|
std::vector<char> cstrings(offsets[sizes.size()]);
|
||||||
|
bool consistentWells = true;
|
||||||
|
char* send = const_cast<char*>(pinfo_->name().c_str());
|
||||||
|
pinfo_->communication().allgatherv(send, cstring_size,
|
||||||
|
cstrings.data(), sizes.data(),
|
||||||
|
offsets.data());
|
||||||
|
for(std::size_t i = 0; i < sizes.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string name(cstrings.data()+offsets[i]);
|
||||||
|
if (name != pinfo_->name())
|
||||||
|
{
|
||||||
|
if (pinfo_->communication().rank() == 0)
|
||||||
|
{
|
||||||
|
//only one process per well logs, might not be 0 of MPI_COMM_WORLD, though
|
||||||
|
std::string msg = std::string("Fatal Error: Not all ranks are computing for the same well")
|
||||||
|
+ " well should be " + pinfo_->name() + " but is "
|
||||||
|
+ name;
|
||||||
|
OpmLog::debug(msg);
|
||||||
|
}
|
||||||
|
consistentWells = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pinfo_->communication().barrier();
|
||||||
|
// As not all processes are involved here we need to use MPI_Abort and hope MPI kills them all
|
||||||
|
if (!consistentWells)
|
||||||
|
{
|
||||||
|
MPI_Abort(MPI_COMM_WORLD, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
B_->mv(x, y);
|
||||||
|
// The B matrix is basically a component-wise multiplication
|
||||||
|
// with a vector followed by a parallel reduction. We do that
|
||||||
|
// reduction to all ranks computing for the well to save the
|
||||||
|
// broadcast when applying C^T.
|
||||||
|
using YField = typename Y::block_type::value_type;
|
||||||
|
assert(y.size() == 1);
|
||||||
|
this->pinfo_->communication().allreduce<std::plus<YField>>(y[0].container().data(),
|
||||||
|
y[0].container().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
//! y = A x
|
||||||
|
template<class X, class Y>
|
||||||
|
void mmv (const X& x, Y& y) const
|
||||||
|
{
|
||||||
|
Y temp(y);
|
||||||
|
mv(x, temp); // includes parallel reduction
|
||||||
|
y -= temp;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const Matrix* B_;
|
||||||
|
const ParallelWellInfo* pinfo_;
|
||||||
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
double computeHydrostaticCorrection(const double well_ref_depth, const double vfp_ref_depth,
|
double computeHydrostaticCorrection(const double well_ref_depth, const double vfp_ref_depth,
|
||||||
const double rho, const double gravity) {
|
const double rho, const double gravity) {
|
||||||
@ -44,6 +138,38 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Sums entries of the diagonal Matrix for distributed wells
|
||||||
|
template<typename Scalar, typename Comm>
|
||||||
|
void sumDistributedWellEntries(Dune::DynamicMatrix<Scalar>& mat, Dune::DynamicVector<Scalar>& vec,
|
||||||
|
const Comm& comm)
|
||||||
|
{
|
||||||
|
// DynamicMatrix does not use one contiguous array for storing the data
|
||||||
|
// but a DynamicVector of DynamicVectors. Hence we need to copy the data
|
||||||
|
// to contiguous memory for MPI.
|
||||||
|
if (comm.size() == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<Scalar> allEntries;
|
||||||
|
allEntries.reserve(mat.N()*mat.M()+vec.size());
|
||||||
|
for(const auto& row: mat)
|
||||||
|
{
|
||||||
|
allEntries.insert(allEntries.end(), row.begin(), row.end());
|
||||||
|
}
|
||||||
|
allEntries.insert(allEntries.end(), vec.begin(), vec.end());
|
||||||
|
comm.sum(allEntries.data(), allEntries.size());
|
||||||
|
auto pos = allEntries.begin();
|
||||||
|
auto cols = mat.cols();
|
||||||
|
for(auto&& row: mat)
|
||||||
|
{
|
||||||
|
std::copy(pos, pos + cols, &(row[0]));
|
||||||
|
pos += cols;
|
||||||
|
}
|
||||||
|
assert(std::size_t(allEntries.end() - pos) == vec.size());
|
||||||
|
std::copy(pos, allEntries.end(), &(vec[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <int dim, class C2F, class FC>
|
template <int dim, class C2F, class FC>
|
||||||
std::array<double, dim>
|
std::array<double, dim>
|
||||||
|
@ -121,7 +121,9 @@ namespace Opm
|
|||||||
has_brine,
|
has_brine,
|
||||||
Indices::numPhases >;
|
Indices::numPhases >;
|
||||||
/// Constructor
|
/// Constructor
|
||||||
WellInterface(const Well& well, const int time_step,
|
WellInterface(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
@ -317,6 +319,8 @@ namespace Opm
|
|||||||
|
|
||||||
Well well_ecl_;
|
Well well_ecl_;
|
||||||
|
|
||||||
|
const ParallelWellInfo* parallel_well_info_;
|
||||||
|
|
||||||
const int current_step_;
|
const int current_step_;
|
||||||
|
|
||||||
// simulation parameters
|
// simulation parameters
|
||||||
|
@ -30,6 +30,7 @@ namespace Opm
|
|||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
WellInterface(const Well& well,
|
WellInterface(const Well& well,
|
||||||
|
const ParallelWellInfo& pw_info,
|
||||||
const int time_step,
|
const int time_step,
|
||||||
const ModelParameters& param,
|
const ModelParameters& param,
|
||||||
const RateConverterType& rate_converter,
|
const RateConverterType& rate_converter,
|
||||||
@ -40,6 +41,7 @@ namespace Opm
|
|||||||
const int first_perf_index,
|
const int first_perf_index,
|
||||||
const std::vector<PerforationData>& perf_data)
|
const std::vector<PerforationData>& perf_data)
|
||||||
: well_ecl_(well)
|
: well_ecl_(well)
|
||||||
|
, parallel_well_info_(&pw_info)
|
||||||
, current_step_(time_step)
|
, current_step_(time_step)
|
||||||
, param_(param)
|
, param_(param)
|
||||||
, rateConverter_(rate_converter)
|
, rateConverter_(rate_converter)
|
||||||
|
@ -126,8 +126,9 @@ BOOST_AUTO_TEST_CASE(TestStandardWellInput) {
|
|||||||
|
|
||||||
Opm::PerforationData dummy;
|
Opm::PerforationData dummy;
|
||||||
std::vector<Opm::PerforationData> pdata(well.getConnections().size(), dummy);
|
std::vector<Opm::PerforationData> pdata(well.getConnections().size(), dummy);
|
||||||
|
Opm::ParallelWellInfo pinfo{well.name()};
|
||||||
|
|
||||||
BOOST_CHECK_THROW( StandardWell( well, -1, param, *rateConverter, 0, 3, 3, 0, 0, pdata), std::invalid_argument);
|
BOOST_CHECK_THROW( StandardWell( well, pinfo, -1, param, *rateConverter, 0, 3, 3, 0, 0, pdata), std::invalid_argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,7 +157,8 @@ BOOST_AUTO_TEST_CASE(TestBehavoir) {
|
|||||||
std::vector<int>(10, 0)));
|
std::vector<int>(10, 0)));
|
||||||
Opm::PerforationData dummy;
|
Opm::PerforationData dummy;
|
||||||
std::vector<Opm::PerforationData> pdata(wells_ecl[w].getConnections().size(), dummy);
|
std::vector<Opm::PerforationData> pdata(wells_ecl[w].getConnections().size(), dummy);
|
||||||
wells.emplace_back(new StandardWell(wells_ecl[w], current_timestep, param, *rateConverter, 0, 3, 3, w, 0, pdata) );
|
Opm::ParallelWellInfo pinfo{wells_ecl[w].name()};
|
||||||
|
wells.emplace_back(new StandardWell(wells_ecl[w], pinfo, current_timestep, param, *rateConverter, 0, 3, 3, w, 0, pdata) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user