Improvments for solvent model

- add dss to appleyard chopping
- support for bhp injectors with solvent
- copy perfSolventRates between the time steps.
- fix bug in well access indicies when numComponents ~= numPhases
This commit is contained in:
Tor Harald Sandve
2017-05-23 15:46:11 +02:00
parent 50c1a1404a
commit 441a8895ac
3 changed files with 67 additions and 18 deletions

View File

@@ -633,6 +633,8 @@ namespace Opm {
// Appleyard chop process.
maxVal = std::max(std::abs(dsg),maxVal);
maxVal = std::max(std::abs(dss),maxVal);
double step = dsMax()/maxVal;
step = std::min(step, 1.0);

View File

@@ -1157,14 +1157,14 @@ namespace Opm {
if (pu.phase_used[BlackoilPhases::Vapour]) {
const int gaspos = pu.phase_pos[BlackoilPhases::Vapour] + perf * numComp;
const int gaspos_well = pu.phase_pos[BlackoilPhases::Vapour] + w * numComp;
const int gaspos_well = pu.phase_pos[BlackoilPhases::Vapour] + w * pu.num_phases;
if (pu.phase_used[BlackoilPhases::Liquid]) {
const int oilpos_well = pu.phase_pos[BlackoilPhases::Liquid] + w * numComp;
const int oilpos_well = pu.phase_pos[BlackoilPhases::Liquid] + w * pu.num_phases;
const double oilrate = std::abs(xw.wellRates()[oilpos_well]); //in order to handle negative rates in producers
rvmax_perf[perf] = FluidSystem::gasPvt().saturatedOilVaporizationFactor(fs.pvtRegionIndex(), temperature, p_avg);
if (oilrate > 0) {
const double gasrate = std::abs(xw.wellRates()[gaspos_well]);
const double gasrate = std::abs(xw.wellRates()[gaspos_well]) - xw.solventWellRate(w);
double rv = 0.0;
if (gasrate > 0) {
rv = oilrate / gasrate;
@@ -1184,11 +1184,11 @@ namespace Opm {
if (pu.phase_used[BlackoilPhases::Liquid]) {
const int oilpos = pu.phase_pos[BlackoilPhases::Liquid] + perf * numComp;
const int oilpos_well = pu.phase_pos[BlackoilPhases::Liquid] + w * numComp;
const int oilpos_well = pu.phase_pos[BlackoilPhases::Liquid] + w * pu.num_phases;
if (pu.phase_used[BlackoilPhases::Vapour]) {
rsmax_perf[perf] = FluidSystem::oilPvt().saturatedGasDissolutionFactor(fs.pvtRegionIndex(), temperature, p_avg);
const int gaspos_well = pu.phase_pos[BlackoilPhases::Vapour] + w * numComp;
const double gasrate = std::abs(xw.wellRates()[gaspos_well]);
const int gaspos_well = pu.phase_pos[BlackoilPhases::Vapour] + w * pu.num_phases;
const double gasrate = std::abs(xw.wellRates()[gaspos_well]) - xw.solventWellRate(w);
if (gasrate > 0) {
const double oilrate = std::abs(xw.wellRates()[oilpos_well]);
double rs = 0.0;
@@ -2149,17 +2149,24 @@ namespace Opm {
// surface rate injection control. Improvement will be required.
if (wells().type[wellIdx] == INJECTOR) {
if (has_solvent_ ) {
double comp_frac = 0.0;
if (compIdx == solventCompIdx) { // solvent
comp_frac = wells().comp_frac[np*wellIdx + pu.phase_pos[ Gas ]] * wsolvent(wellIdx);
} else if (compIdx == pu.phase_pos[ Gas ]) {
comp_frac = wells().comp_frac[np*wellIdx + compIdx] * (1.0 - wsolvent(wellIdx));
} else {
comp_frac = wells().comp_frac[np*wellIdx + compIdx];
}
if (comp_frac == 0.0) {
return qs; //zero
}
if (well_controls_get_current_type(wc) == BHP || well_controls_get_current_type(wc) == THP) {
OPM_THROW(std::runtime_error,"BHP controlled solvent injector is unsupported. Check well "
<< wells().name [wellIdx] );
}
if (compIdx == pu.phase_pos[ Gas ]) { //gas
qs.setValue(target_rate * (1.0 - wsolvent(wellIdx)));
return qs;
} else if (compIdx == solventCompIdx) { // solvent
qs.setValue(wsolvent(wellIdx) * target_rate);
return qs;
return comp_frac * wellVariables_[nw*XvarWell + wellIdx];
}
qs.setValue(comp_frac * target_rate);
return qs;
}
const double comp_frac = wells().comp_frac[np*wellIdx + compIdx];
if (comp_frac == 0.0) {

View File

@@ -67,6 +67,48 @@ namespace Opm
// call init on base class
BaseType :: init(wells, state, prevState);
const int nw = wells->number_of_wells;
if (nw == 0) {
return;
}
const int nperf = wells->well_connpos[nw];
perfRateSolvent_.clear();
perfRateSolvent_.resize(nperf, 0.0);
if(pu.has_solvent) {
// intialize wells that have been there before
// order may change so the mapping is based on the well name
if( ! prevState.wellMap().empty() )
{
typedef typename WellMapType :: const_iterator const_iterator;
const_iterator end = prevState.wellMap().end();
for (int w = 0; w < nw; ++w) {
std::string name( wells->name[ w ] );
const_iterator it = prevState.wellMap().find( name );
if( it != end )
{
const int newIndex = w;
// perfSolventRates
int oldPerf_idx = (*it).second[ 1 ];
const int num_perf_old_well = (*it).second[ 2 ];
const int num_perf_this_well = wells->well_connpos[newIndex + 1] - wells->well_connpos[newIndex];
if( num_perf_old_well == num_perf_this_well )
{
for (int perf = wells->well_connpos[ newIndex ];
perf < wells->well_connpos[ newIndex + 1]; ++perf, ++oldPerf_idx )
{
perfRateSolvent()[ perf ] = prevState.perfRateSolvent()[ oldPerf_idx ];
}
}
}
}
}
}
// TODO: the reason to keep this is to avoid getting defaulted value BHP
// some facilities needed from opm-parser or opm-core
// It is a little tricky, since sometimes before applying group control, the only
@@ -88,9 +130,7 @@ namespace Opm
if (nw == 0) {
return;
}
const int nperf = wells_->well_connpos[nw];
perfRateSolvent_.clear();
perfRateSolvent_.resize(nperf, 0.0);
const int np = wells_->number_of_phases;
const int numComp = pu.has_solvent? np+1:np;