mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
c3b4188295
commit
5ffd2bf026
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user