mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
when encountering a multisegment well
we create a multisegment well instead of treating all the wells as StandardWell. Making it compile.
This commit is contained in:
parent
d694a72b53
commit
16ecbddefb
@ -36,6 +36,8 @@ namespace Opm
|
||||
|
||||
// TODO: the WellState does not have any information related to segments
|
||||
using typename Base::WellState;
|
||||
using typename Base::Simulator;
|
||||
using typename Base::ModelParameters;
|
||||
|
||||
// TODO: for now, not considering the polymer, solvent and so on to simplify the development process.
|
||||
// TODO: should I begin with the old primary variable or the new fraction based variable systems?
|
||||
@ -157,6 +159,7 @@ namespace Opm
|
||||
|
||||
using Base::well_ecl_;
|
||||
using Base::number_of_perforations_; // TODO: can use well_ecl_?
|
||||
using Base::current_step_;
|
||||
|
||||
using Base::well_cells_; // TODO: are the perforation orders same with StandardWell or Wells?
|
||||
using Base::well_index_;
|
||||
@ -173,6 +176,8 @@ namespace Opm
|
||||
// As the current temporary solution, the grid cell related to a segment determined by the
|
||||
// first perforation cell related to the segment.
|
||||
// when no perforation is related to the segment, use it outlet segment's cell.
|
||||
|
||||
// TODO: it can be a source of error
|
||||
std::vector<int> segment_cell_;
|
||||
|
||||
// the completions that is related to each segment
|
||||
@ -181,7 +186,11 @@ namespace Opm
|
||||
// the order of the completions in wells.
|
||||
// it is for convinience reason. we can just calcuate the inforation for segment once then using it for all the perofrations
|
||||
// belonging to this segment
|
||||
std::vector<std::vector<int>> segment_perforations_;
|
||||
std::vector<std::vector<int> > segment_perforations_;
|
||||
|
||||
// the inlet segments for each segment. It is for convinience and efficiency reason
|
||||
// the original segment structure is defined as a gathering tree structure based on outlet_segment
|
||||
std::vector<std::vector<int> > segment_inlets_;
|
||||
|
||||
// Things are easy to get from SegmentSet
|
||||
// segment_volume_, segment_cross_area_, segment_length_(total length), segment_depth_
|
||||
@ -206,7 +215,7 @@ namespace Opm
|
||||
mutable BVector scaleAddRes_;
|
||||
|
||||
// residuals of the well equations
|
||||
BVectorWell resWell_;
|
||||
mutable BVectorWell resWell_;
|
||||
|
||||
// the values for the primary varibles
|
||||
// based on different solutioin strategies, the wells can have different primary variables
|
||||
@ -217,6 +226,8 @@ namespace Opm
|
||||
// the Evaluation for the well primary variables, which contain derivativles and are used in AD calculation
|
||||
mutable std::vector<std::array<EvalWell, numWellEq> > primary_variables_evaluation_;
|
||||
|
||||
void initMatrixAndVectors(const int num_cells) const;
|
||||
|
||||
// protected functions
|
||||
// EvalWell getBhp(); this one should be something similar to getSegmentPressure();
|
||||
// EvalWell getQs(); this one should be something similar to getSegmentRates()
|
||||
|
@ -27,7 +27,10 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
MultisegmentWell<TypeTag>::
|
||||
MultisegmentWell(const Well* well, const int time_step, const Wells* wells)
|
||||
:Basse(well, time_step, wells)
|
||||
: Base(well, time_step, wells)
|
||||
, segment_cell_(numberOfSegments())
|
||||
, segment_perforations_(numberOfSegments())
|
||||
, segment_inlets_(numberOfSegments())
|
||||
{
|
||||
// TODO: to see what information we need to process here later.
|
||||
// const auto& completion_set = well->getCompletions(time_step);
|
||||
@ -61,6 +64,10 @@ namespace Opm
|
||||
// For the last case, should we update the depth with the depth_arg? For the
|
||||
// future, it can be a source of wrong result with Multisegment well.
|
||||
// An indicator from the opm-parser should indicate what kind of depth we should use here.
|
||||
|
||||
// \Note: we do not update the depth here. And it looks like for now, we only have the option to use
|
||||
// specified perforation depth
|
||||
initMatrixAndVectors(num_cells);
|
||||
}
|
||||
|
||||
|
||||
@ -81,9 +88,9 @@ namespace Opm
|
||||
// B D] x_well] res_well]
|
||||
|
||||
// the number of the nnz should be numSegment() + numberOfOutlet()
|
||||
invDuneD_.setSize(numSegment(), numSegment(), 100000);
|
||||
duneB_.setSize(numSegment(), num_cells, number_of_perforations_);
|
||||
duneC_.setSize(numSegment(), num_cells, number_of_perforations_);
|
||||
invDuneD_.setSize(numberOfSegments(), numberOfSegments(), 100000);
|
||||
duneB_.setSize(numberOfSegments(), num_cells, number_of_perforations_);
|
||||
duneC_.setSize(numberOfSegments(), num_cells, number_of_perforations_);
|
||||
|
||||
// we need to add the off diagonal ones
|
||||
for (auto row=invDuneD_.createbegin(), end = invDuneD_.createend(); row!=end; ++row) {
|
||||
@ -93,8 +100,8 @@ namespace Opm
|
||||
|
||||
for (auto row = duneC_.createbegin(), end = duneC_.createend(); row!=end; ++row) {
|
||||
// the number of the row corresponds to the segment number now.
|
||||
for (int perf = 0 ; perf < ]; ++perf) { // the segments hold some perforations
|
||||
const int cell_idx = wells().well_cells[perf];
|
||||
for (int perf = 0 ; perf < number_of_perforations_; ++perf) { // the segments hold some perforations
|
||||
const int cell_idx = well_cells_[perf];
|
||||
row.insert(cell_idx);
|
||||
}
|
||||
}
|
||||
@ -102,16 +109,16 @@ namespace Opm
|
||||
// make the B^T matrix
|
||||
for (auto row = duneB_.createbegin(), end = duneB_.createend(); row!=end; ++row) {
|
||||
// the number of the row corresponds to the segment number now.
|
||||
for (int perf = wells().well_connpos[row.index()] ; perf < wells().well_connpos[row.index()+1]; ++perf) {
|
||||
const int cell_idx = wells().well_cells[perf];
|
||||
for (int perf = 0; perf < number_of_perforations_; ++perf) {
|
||||
const int cell_idx = well_cells_[perf];
|
||||
row.insert(cell_idx);
|
||||
}
|
||||
}
|
||||
|
||||
resWell_.resize( nw );
|
||||
resWell_.resize( numberOfSegments() );
|
||||
|
||||
// resize temporary class variables
|
||||
Cx_.resize( duneC_.N() );
|
||||
Bx_.resize( duneC_.N() );
|
||||
invDrw_.resize( invDuneD_.N() );
|
||||
}
|
||||
|
||||
@ -124,7 +131,7 @@ namespace Opm
|
||||
MultisegmentWell<TypeTag>::
|
||||
initPrimaryVariablesEvaluation() const
|
||||
{
|
||||
for (int seg = 0; seg < numSegment(); ++seg) {
|
||||
for (int seg = 0; seg < numberOfSegments(); ++seg) {
|
||||
for (int eq_idx = 0; eq_idx < numWellEq; ++eq_idx) {
|
||||
primary_variables_evaluation_[seg][eq_idx] = 0.0;
|
||||
primary_variables_evaluation_[seg][eq_idx].setValue(primary_variables_[seg][eq_idx]);
|
||||
@ -186,6 +193,8 @@ namespace Opm
|
||||
const ModelParameters& param) const
|
||||
{
|
||||
// TODO: it will be very similar
|
||||
ConvergenceReport report;
|
||||
return report;
|
||||
}
|
||||
|
||||
|
||||
@ -222,7 +231,7 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
void apply(const BVector& x, BVector& Ax) const
|
||||
apply(const BVector& x, BVector& Ax) const
|
||||
{
|
||||
|
||||
|
||||
@ -309,7 +318,7 @@ namespace Opm
|
||||
MultisegmentWell<TypeTag>::
|
||||
segmentSet() const
|
||||
{
|
||||
return well_ecl_->getSegmentSet(time_step);
|
||||
return well_ecl_->getSegmentSet(current_step_);
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <opm/autodiff/RateConverter.hpp>
|
||||
#include <opm/autodiff/WellInterface.hpp>
|
||||
#include <opm/autodiff/StandardWell.hpp>
|
||||
#include <opm/autodiff/MultisegmentWell.hpp>
|
||||
#include<dune/common/fmatrix.hh>
|
||||
#include<dune/istl/bcrsmatrix.hh>
|
||||
#include<dune/istl/matrixmatrix.hh>
|
||||
|
@ -146,13 +146,12 @@ namespace Opm {
|
||||
}
|
||||
|
||||
const Well* well_ecl = wells_ecl[index_well];
|
||||
// TODO: stopping throwing when encoutnering MS wells for now.
|
||||
/* if (well_ecl->isMultiSegment(time_step)) {
|
||||
OPM_THROW(Opm::NumericalProblem, "Not handling Multisegment Wells for now");
|
||||
} */
|
||||
|
||||
// Basically, we are handling all the wells as StandardWell for the moment
|
||||
well_container.emplace_back(new StandardWell<TypeTag>(well_ecl, time_step, wells) );
|
||||
if ( !well_ecl->isMultiSegment(time_step) ) {
|
||||
well_container.emplace_back(new StandardWell<TypeTag>(well_ecl, time_step, wells) );
|
||||
} else {
|
||||
well_container.emplace_back(new MultisegmentWell<TypeTag>(well_ecl, time_step, wells) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return well_container;
|
||||
|
Loading…
Reference in New Issue
Block a user