Merge pull request #1883 from totto82/fix_inj

Upwinding for MSW
This commit is contained in:
Kai Bao 2019-06-19 12:50:16 +02:00 committed by GitHub
commit f4efd464f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -839,6 +839,15 @@ namespace Opm
// update the total rate // TODO: should we have a limitation of the total rate change?
{
primary_variables_[seg][GTotal] = old_primary_variables[seg][GTotal] - relaxation_factor * dwells[seg][GTotal];
// make sure that no injector produce and no producer inject
if (seg == 0) {
if (well_type_ == INJECTOR) {
primary_variables_[seg][GTotal] = std::max( primary_variables_[seg][GTotal], 0.0);
} else {
primary_variables_[seg][GTotal] = std::min( primary_variables_[seg][GTotal], 0.0);
}
}
}
}
@ -1394,6 +1403,13 @@ namespace Opm
// the result will contain the derivative with resepct to GTotal in segment seg,
// and the derivatives with respect to WFrac GFrac in segment seg_upwind.
// the derivative with respect to SPres should be zero.
if (seg == 0 && well_type_ == INJECTOR) {
const double* distr = well_controls_get_current_distr(well_controls_);
if (distr[ebosCompIdxToFlowCompIdx(comp_idx)] > 0)
return primary_variables_evaluation_[seg][GTotal] / scalingFactor(ebosCompIdxToFlowCompIdx(comp_idx));
return 0.0;
}
const EvalWell segment_rate = primary_variables_evaluation_[seg][GTotal] * volumeFractionScaled(seg_upwind, comp_idx);
assert(segment_rate.derivative(SPres + numEq) == 0.);
@ -1502,28 +1518,38 @@ namespace Opm
}
}
assert(number_phases_under_control > 0);
const std::vector<double> g = {1.0, 1.0, 0.01};
const double target_rate = well_controls_get_current_target(well_controls_);
// TODO: the two situations below should be able to be merged to be handled as one situation
const std::vector<double> g = {1.0, 1.0, 0.01};
if (number_phases_under_control == 1) { // single phase control
if (well_type_ == INJECTOR) {
assert(number_phases_under_control == 1);
// only support single component injection
for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.) { // under the control of this phase
control_eq = getSegmentGTotal(0) * volumeFraction(0, flowPhaseToEbosCompIdx(phase)) - g[phase] * target_rate;
control_eq = getSegmentGTotal(0) - g[phase] * target_rate;
break;
}
}
} else { // multiphase rate control
EvalWell rate_for_control(0.0);
const EvalWell G_total = getSegmentGTotal(0);
for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.) {
rate_for_control += G_total * volumeFractionScaled(0, flowPhaseToEbosCompIdx(phase));
} else {
// TODO: the two situations below should be able to be merged to be handled as one situation
if (number_phases_under_control == 1) { // single phase control
for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.) { // under the control of this phase
control_eq = getSegmentGTotal(0) * volumeFraction(0, flowPhaseToEbosCompIdx(phase)) - g[phase] * target_rate;
break;
}
}
} else { // multiphase rate control
EvalWell rate_for_control(0.0);
const EvalWell G_total = getSegmentGTotal(0);
for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.) {
rate_for_control += G_total * volumeFractionScaled(0, flowPhaseToEbosCompIdx(phase));
}
}
// TODO: maybe the following equation can be scaled a little bit for gas phase
control_eq = rate_for_control - target_rate;
}
// TODO: maybe the following equation can be scaled a little bit for gas phase
control_eq = rate_for_control - target_rate;
}
break;
}
@ -1543,8 +1569,6 @@ namespace Opm
default:
OPM_DEFLOG_THROW(std::runtime_error, "Unknown well control control types for well " << name(), deferred_logger);
}
// using control_eq to update the matrix and residuals
resWell_[0][SPres] = control_eq.value();
@ -2426,11 +2450,12 @@ namespace Opm
MultisegmentWell<TypeTag>::
updateUpwindingSegments()
{
// not considering upwinding for the injectors for now
// but we should
// and upwinding segment for top segment is itself
for (int seg = 0; seg < numberOfSegments(); ++seg) {
if ( (well_type_ == INJECTOR) || (seg == 0) ) {
// special treatment is needed for segment 0
if (seg == 0) {
// we are not supposed to have injecting producers and producing injectors
assert( ! (well_type_ == PRODUCER && primary_variables_evaluation_[seg][GTotal] > 0.) );
assert( ! (well_type_ == INJECTOR && primary_variables_evaluation_[seg][GTotal] < 0.) );
upwinding_segments_[seg] = seg;
continue;
}