correct the treatment of the pressure equation

the derivative of the inlet contribution should go to the correction
location in duneD_.
This commit is contained in:
Kai Bao 2017-09-15 13:42:15 +02:00
parent c3b4188295
commit 5ffd2bf026
2 changed files with 42 additions and 29 deletions

View File

@ -322,9 +322,9 @@ namespace Opm
const int perf, const int perf,
std::vector<EvalWell>& mob) const; std::vector<EvalWell>& mob) const;
EvalWell getControlEq() const; void assembleControlEq() const;
EvalWell getPressureEq(const int seg) const; void assemblePressureEq(const int seg) const;
// hytrostatic pressure loss // hytrostatic pressure loss
EvalWell getHydorPressureLoss(const int seg) const; EvalWell getHydorPressureLoss(const int seg) const;
@ -348,7 +348,7 @@ namespace Opm
// Sequential incomplete LU decomposition as the preconditioner // Sequential incomplete LU decomposition as the preconditioner
Dune::SeqILU0<MatrixType, VectorType, VectorType> preconditioner(D, 1.0); Dune::SeqILU0<MatrixType, VectorType, VectorType> preconditioner(D, 1.0);
// Preconditioned conjugate gradient solver // Preconditioned BICGSTAB solver
Dune::BiCGSTABSolver<VectorType> linsolver(linearOperator, Dune::BiCGSTABSolver<VectorType> linsolver(linearOperator,
preconditioner, preconditioner,
1.e-6, // desired residual reduction factor 1.e-6, // desired residual reduction factor

View File

@ -260,7 +260,7 @@ namespace Opm
const EvalWell inlet_rate = getSegmentRate(inlet, comp_idx); const EvalWell inlet_rate = getSegmentRate(inlet, comp_idx);
resWell_[seg][comp_idx] -= inlet_rate.value(); resWell_[seg][comp_idx] -= inlet_rate.value();
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) { for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
duneD_[seg][inlet][comp_idx][pv_idx] += -inlet_rate.derivative(pv_idx + numEq); duneD_[seg][inlet][comp_idx][pv_idx] -= inlet_rate.derivative(pv_idx + numEq);
} }
} }
} }
@ -313,18 +313,10 @@ namespace Opm
} }
// the fourth dequation, the pressure drop equation // the fourth dequation, the pressure drop equation
{ if (seg == 0) { // top segment, pressure equation is the control equation
// TODO: currently, we only handle the hydrostatic pressure difference. assembleControlEq();
// We need to add the friction pressure loss and also the acceleration pressure loss } else {
// with the acceleration pressure loss, there will be inlets flow rates (maybe alos the oulet flow) assemblePressureEq(seg);
// not sure whether to handle them implicitly or explicitly
// TODO: we can try to handle them explicitly first, if it does not work, we can handle them
// implicitly. Even explicily, we can calculate them without considering the derivative first
const EvalWell pressure_eq = getPressureEq(seg);
resWell_[seg][SPres] = pressure_eq.value();
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
duneD_[seg][seg][SPres][pv_idx] = pressure_eq.derivative(pv_idx + numEq);
}
} }
} }
} }
@ -1394,9 +1386,9 @@ namespace Opm
template<typename TypeTag> template<typename TypeTag>
typename MultisegmentWell<TypeTag>::EvalWell void
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
getControlEq() const assembleControlEq() const
{ {
EvalWell control_eq(0.0); EvalWell control_eq(0.0);
@ -1463,7 +1455,14 @@ namespace Opm
default: default:
OPM_THROW(std::runtime_error, "Unknown well control control types for well " << name()); OPM_THROW(std::runtime_error, "Unknown well control control types for well " << name());
} }
return control_eq;
// using control_eq to update the matrix and residuals
resWell_[0][SPres] = control_eq.value();
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
duneD_[0][0][SPres][pv_idx] = control_eq.derivative(pv_idx + numEq);
}
} }
@ -1471,24 +1470,38 @@ namespace Opm
template<typename TypeTag> template<typename TypeTag>
typename MultisegmentWell<TypeTag>::EvalWell void
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
getPressureEq(const int seg) const assemblePressureEq(const int seg) const
{ {
// for top segment, the well control equation will be used. // TODO: currently, we only handle the hydrostatic pressure difference.
if (seg == 0) { // for top segment, the well control equation will be used. // We need to add the friction pressure loss and also the acceleration pressure loss
return getControlEq(); // with the acceleration pressure loss, there will be inlets flow rates (maybe alos the oulet flow)
} // not sure whether to handle them implicitly or explicitly
// TODO: we can try to handle them explicitly first, if it does not work, we can handle them
assert(seg != 0); // not top segment
// for top segment, the well control equation will be used.
EvalWell pressure_equation = getSegmentPressure(seg); EvalWell pressure_equation = getSegmentPressure(seg);
const int outlet_segment_location = numberToLocation(segmentSet()[seg].outletSegment());
const EvalWell outlet_pressure = getSegmentPressure(outlet_segment_location);
pressure_equation -= outlet_pressure;
// we need to handle the pressure difference between the two segments // we need to handle the pressure difference between the two segments
// we only consider the hydrostatic pressure loss first // we only consider the hydrostatic pressure loss first
pressure_equation -= getHydorPressureLoss(seg); pressure_equation -= getHydorPressureLoss(seg);
return pressure_equation;
resWell_[seg][SPres] = pressure_equation.value();
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
duneD_[seg][seg][SPres][pv_idx] = pressure_equation.derivative(pv_idx + numEq);
}
// contribution from the outlet segment
const int outlet_segment_location = numberToLocation(segmentSet()[seg].outletSegment());
const EvalWell outlet_pressure = getSegmentPressure(outlet_segment_location);
resWell_[seg][SPres] -= outlet_pressure.value();
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
duneD_[seg][outlet_segment_location][SPres][pv_idx] = pressure_equation.derivative(pv_idx + numEq);
}
} }