Merge commit 'refs/pull/947/head' of https://github.com/OPM/opm-simulators into no_opm-parser_pointers

* https://github.com/OPM/opm-simulators:
  [bugfix] add defunct_well_names to BlackoilModelEbos.
  [bugfix] fix ownerMask for parallel FIP code.
  flow_ebos: tell the ebos in ourselves to not handle SWATINIT
  [bugfix] Make initialization work in parallel for flow_ebos.
  [bugfix] make flow_ebos work when no wells are present.
  flow_ebos: only instantiate the grid once
This commit is contained in:
Andreas Lauser
2016-12-06 19:43:47 +01:00
6 changed files with 84 additions and 28 deletions

View File

@@ -84,6 +84,9 @@ namespace Properties {
NEW_TYPE_TAG(EclFlowProblem, INHERITS_FROM(BlackOilModel, EclBaseProblem)); NEW_TYPE_TAG(EclFlowProblem, INHERITS_FROM(BlackOilModel, EclBaseProblem));
SET_BOOL_PROP(EclFlowProblem, DisableWells, true); SET_BOOL_PROP(EclFlowProblem, DisableWells, true);
SET_BOOL_PROP(EclFlowProblem, EnableDebuggingChecks, false); SET_BOOL_PROP(EclFlowProblem, EnableDebuggingChecks, false);
// SWATINIT is done by the flow part of flow_ebos. this can be removed once the legacy
// code for fluid and satfunc handling gets fully retired.
SET_BOOL_PROP(EclFlowProblem, EnableSwatinit, false); SET_BOOL_PROP(EclFlowProblem, EnableSwatinit, false);
}} }}
@@ -145,7 +148,8 @@ namespace Opm {
FIP_PV = 5, //< Pore volume FIP_PV = 5, //< Pore volume
FIP_WEIGHTED_PRESSURE = 6 FIP_WEIGHTED_PRESSURE = 6
}; };
std::array<std::vector<double>, 7> fip; static const int fipValues = FIP_WEIGHTED_PRESSURE + 1 ;
std::array<std::vector<double>, fipValues> fip;
}; };
// --------- Public methods --------- // --------- Public methods ---------
@@ -298,7 +302,7 @@ namespace Opm {
// Compute the nonlinear update. // Compute the nonlinear update.
const int nc = AutoDiffGrid::numCells(grid_); const int nc = AutoDiffGrid::numCells(grid_);
const int nw = wellModel().wells().number_of_wells; const int nw = numWells();
BVector x(nc); BVector x(nc);
BVector xw(nw); BVector xw(nw);
@@ -445,7 +449,7 @@ namespace Opm {
int sizeNonLinear() const int sizeNonLinear() const
{ {
const int nc = Opm::AutoDiffGrid::numCells(grid_); const int nc = Opm::AutoDiffGrid::numCells(grid_);
const int nw = wellModel().wells().number_of_wells; const int nw = numWells();
return numPhases() * (nc + nw); return numPhases() * (nc + nw);
} }
@@ -474,8 +478,11 @@ namespace Opm {
const auto& ebosJac = ebosSimulator_.model().linearizer().matrix(); const auto& ebosJac = ebosSimulator_.model().linearizer().matrix();
auto& ebosResid = ebosSimulator_.model().linearizer().residual(); auto& ebosResid = ebosSimulator_.model().linearizer().residual();
if( xw.size() > 0 )
{
// apply well residual to the residual. // apply well residual to the residual.
wellModel().apply(ebosResid); wellModel().apply(ebosResid);
}
// set initial guess // set initial guess
x = 0.0; x = 0.0;
@@ -495,10 +502,13 @@ namespace Opm {
istlSolver().solve( opA, x, ebosResid ); istlSolver().solve( opA, x, ebosResid );
} }
if( xw.size() > 0 )
{
// recover wells. // recover wells.
xw = 0.0; xw = 0.0;
wellModel().recoverVariable(x, xw); wellModel().recoverVariable(x, xw);
} }
}
//===================================================================== //=====================================================================
// Implementation for ISTL-matrix based operator // Implementation for ISTL-matrix based operator
@@ -1012,7 +1022,7 @@ namespace Opm {
const auto& pv = geo_.poreVolume(); const auto& pv = geo_.poreVolume();
const int maxnp = Opm::BlackoilPhases::MaxNumPhases; const int maxnp = Opm::BlackoilPhases::MaxNumPhases;
for (int i = 0; i<7; i++) { for (int i = 0; i<FIPData::fipValues; i++) {
fip_.fip[i].resize(nc,0.0); fip_.fip[i].resize(nc,0.0);
} }
@@ -1036,7 +1046,7 @@ namespace Opm {
// For a parallel run this is just a local maximum and needs to be updated later // For a parallel run this is just a local maximum and needs to be updated later
int dims = *std::max_element(fipnum.begin(), fipnum.end()); int dims = *std::max_element(fipnum.begin(), fipnum.end());
std::vector<std::vector<double>> values(dims, std::vector<double>(7,0.0)); std::vector<std::vector<double>> values(dims, std::vector<double>(FIPData::fipValues,0.0));
std::vector<double> hcpv(dims, 0.0); std::vector<double> hcpv(dims, 0.0);
std::vector<double> pres(dims, 0.0); std::vector<double> pres(dims, 0.0);
@@ -1104,11 +1114,12 @@ namespace Opm {
// mask[c] is 1 if we need to compute something in parallel // mask[c] is 1 if we need to compute something in parallel
const auto & pinfo = const auto & pinfo =
boost::any_cast<const ParallelISTLInformation&>(istlSolver().parallelInformation()); boost::any_cast<const ParallelISTLInformation&>(istlSolver().parallelInformation());
const auto& mask = pinfo.getOwnerMask(); const auto& mask = pinfo.updateOwnerMask( fipnum );
auto comm = pinfo.communicator(); auto comm = pinfo.communicator();
// Compute the global dims value and resize values accordingly. // Compute the global dims value and resize values accordingly.
dims = comm.max(dims); dims = comm.max(dims);
values.resize(dims, std::vector<double>(7,0.0)); values.resize(dims, std::vector<double>(FIPData::fipValues,0.0));
//Accumulate phases for each region //Accumulate phases for each region
for (int phase = 0; phase < maxnp; ++phase) { for (int phase = 0; phase < maxnp; ++phase) {
@@ -1246,6 +1257,8 @@ namespace Opm {
/// return true if wells are available in the reservoir /// return true if wells are available in the reservoir
bool wellsActive() const { return well_model_.wellsActive(); } bool wellsActive() const { return well_model_.wellsActive(); }
int numWells() const { return wellsActive() ? wells().number_of_wells : 0; }
/// return true if wells are available on this process /// return true if wells are available on this process
bool localWellsActive() const { return well_model_.localWellsActive(); } bool localWellsActive() const { return well_model_.localWellsActive(); }

View File

@@ -649,7 +649,8 @@ namespace Opm
FluidSystem::enableDissolvedGas(), FluidSystem::enableDissolvedGas(),
FluidSystem::enableVaporizedOil(), FluidSystem::enableVaporizedOil(),
eclState(), eclState(),
*output_writer_)); *output_writer_,
defunctWellNames()));
} }
private: private:
@@ -705,6 +706,9 @@ namespace Opm
Grid& grid() Grid& grid()
{ return ebosSimulator_->gridManager().grid(); } { return ebosSimulator_->gridManager().grid(); }
std::unordered_set<std::string> defunctWellNames() const
{ return ebosSimulator_->gridManager().defunctWellNames(); }
std::unique_ptr<EbosSimulator> ebosSimulator_; std::unique_ptr<EbosSimulator> ebosSimulator_;
int mpi_rank_ = 0; int mpi_rank_ = 0;
bool output_cout_ = false; bool output_cout_ = false;

View File

@@ -73,18 +73,42 @@ namespace Opm
class GridInit<Dune::CpGrid> class GridInit<Dune::CpGrid>
{ {
public: public:
GridInit()
{
gridSelfManaged_ = false;
}
/// Initialize from a deck and/or an eclipse state and (logical cartesian) specified pore volumes. /// Initialize from a deck and/or an eclipse state and (logical cartesian) specified pore volumes.
GridInit(const EclipseState& eclipse_state, const std::vector<double>& porv) GridInit(const EclipseState& eclipse_state, const std::vector<double>& porv)
{ {
grid_.processEclipseFormat(eclipse_state.getInputGrid(), false, false, false, porv); gridSelfManaged_ = true;
grid_ = new Dune::CpGrid;
grid_->processEclipseFormat(eclipse_state.getInputGrid(), false, false, false, porv);
} }
~GridInit()
{
if (gridSelfManaged_)
delete grid_;
}
/// Access the created grid. Note that mutable access may be required for load balancing. /// Access the created grid. Note that mutable access may be required for load balancing.
Dune::CpGrid& grid() Dune::CpGrid& grid()
{ {
return grid_; return *grid_;
} }
/// set the grid from the outside
void setGrid(Dune::CpGrid& newGrid)
{
gridSelfManaged_ = false;
grid_ = &newGrid;
}
private: private:
Dune::CpGrid grid_; Dune::CpGrid* grid_;
bool gridSelfManaged_;
}; };
#endif // HAVE_OPM_GRID #endif // HAVE_OPM_GRID

View File

@@ -100,7 +100,8 @@ public:
const bool has_disgas, const bool has_disgas,
const bool has_vapoil, const bool has_vapoil,
const EclipseState& eclState, const EclipseState& eclState,
BlackoilOutputWriterEbos& output_writer) BlackoilOutputWriterEbos& output_writer,
const std::unordered_set<std::string>& defunct_well_names)
: ebosSimulator_(ebosSimulator), : ebosSimulator_(ebosSimulator),
param_(param), param_(param),
model_param_(param), model_param_(param),
@@ -113,6 +114,7 @@ public:
has_vapoil_(has_vapoil), has_vapoil_(has_vapoil),
terminal_output_(param.getDefault("output_terminal", true)), terminal_output_(param.getDefault("output_terminal", true)),
output_writer_(output_writer), output_writer_(output_writer),
defunct_well_names_( defunct_well_names ),
is_parallel_run_( false ) is_parallel_run_( false )
{ {
DUNE_UNUSED_PARAMETER(eclState); DUNE_UNUSED_PARAMETER(eclState);
@@ -224,7 +226,8 @@ public:
props_.permeability(), props_.permeability(),
dynamic_list_econ_limited, dynamic_list_econ_limited,
is_parallel_run_, is_parallel_run_,
well_potentials ); well_potentials,
defunct_well_names_ );
const Wells* wells = wells_manager.c_wells(); const Wells* wells = wells_manager.c_wells();
WellState well_state; WellState well_state;
@@ -724,6 +727,11 @@ protected:
// output_writer // output_writer
OutputWriter& output_writer_; OutputWriter& output_writer_;
std::unique_ptr<RateConverterType> rateConverter_; std::unique_ptr<RateConverterType> rateConverter_;
// The names of wells that should be defunct
// (e.g. in a parallel run when they are handeled by
// a different process)
std::unordered_set<std::string> defunct_well_names_;
// Whether this a parallel simulation or not // Whether this a parallel simulation or not
bool is_parallel_run_; bool is_parallel_run_;

View File

@@ -92,15 +92,18 @@ enum WellVariablePositions {
, fluid_(nullptr) , fluid_(nullptr)
, active_(nullptr) , active_(nullptr)
, vfp_properties_(nullptr) , vfp_properties_(nullptr)
, well_perforation_densities_(wells_arg->well_connpos[wells_arg->number_of_wells]) , well_perforation_densities_( wells_ ? wells_arg->well_connpos[wells_arg->number_of_wells] : 0)
, well_perforation_pressure_diffs_(wells_arg->well_connpos[wells_arg->number_of_wells]) , well_perforation_pressure_diffs_( wells_ ? wells_arg->well_connpos[wells_arg->number_of_wells] : 0)
, wellVariables_(wells_arg->number_of_wells * wells_arg->number_of_phases) , wellVariables_( wells_ ? (wells_arg->number_of_wells * wells_arg->number_of_phases) : 0)
, F0_(wells_arg->number_of_wells * wells_arg->number_of_phases) , F0_(wells_ ? (wells_arg->number_of_wells * wells_arg->number_of_phases) : 0 )
{
if( wells_ )
{ {
invDuneD_.setBuildMode( Mat::row_wise ); invDuneD_.setBuildMode( Mat::row_wise );
duneC_.setBuildMode( Mat::row_wise ); duneC_.setBuildMode( Mat::row_wise );
duneB_.setBuildMode( Mat::row_wise ); duneB_.setBuildMode( Mat::row_wise );
} }
}
void init(const BlackoilPropsAdInterface* fluid_arg, void init(const BlackoilPropsAdInterface* fluid_arg,
const std::vector<bool>* active_arg, const std::vector<bool>* active_arg,
@@ -709,6 +712,10 @@ enum WellVariablePositions {
std::vector<double> residual() { std::vector<double> residual() {
if( ! wellsActive() )
{
return std::vector<double>();
}
const int np = numPhases(); const int np = numPhases();
const int nw = wells().number_of_wells; const int nw = wells().number_of_wells;