Let computeNewtonIncrement() eliminate well equations.

In its current state, we still don't do CPR, but eliminate the well equations,
solve the resulting system and finally recover the eliminated well unknowns.
This commit is contained in:
Atgeirr Flø Rasmussen 2014-05-13 15:02:11 +02:00
parent c60a080a73
commit b73367deda

View File

@ -82,17 +82,34 @@ namespace Opm
NewtonIterationBlackoilCPR::SolutionVector NewtonIterationBlackoilCPR::SolutionVector
NewtonIterationBlackoilCPR::computeNewtonIncrement(const LinearisedBlackoilResidual& residual) const NewtonIterationBlackoilCPR::computeNewtonIncrement(const LinearisedBlackoilResidual& residual) const
{ {
typedef LinearisedBlackoilResidual::ADB ADB; // Build the vector of equations.
const int np = residual.material_balance_eq.size(); const int np = residual.material_balance_eq.size();
ADB mass_res = residual.material_balance_eq[0]; std::vector<ADB> eqs;
for (int phase = 1; phase < np; ++phase) { eqs.reserve(np + 2);
mass_res = vertcat(mass_res, residual.material_balance_eq[phase]); for (int phase = 0; phase < np; ++phase) {
eqs.push_back(residual.material_balance_eq[phase]);
} }
const ADB well_res = vertcat(residual.well_flux_eq, residual.well_eq); eqs.push_back(residual.well_flux_eq);
const ADB total_residual = collapseJacs(vertcat(mass_res, well_res)); eqs.push_back(residual.well_eq);
// Eliminate the well-related unknowns, and corresponding equations.
std::vector<ADB> elim_eqs;
elim_eqs.reserve(2);
elim_eqs.push_back(eqs[np]);
eqs = eliminateVariable(eqs, np); // Eliminate well flux unknowns.
elim_eqs.push_back(eqs[np]);
eqs = eliminateVariable(eqs, np); // Eliminate well bhp unknowns.
assert(int(eqs.size()) == np);
// Combine in single block.
ADB total_residual = eqs[0];
for (int phase = 1; phase < np; ++phase) {
total_residual = vertcat(total_residual, eqs[phase]);
}
total_residual = collapseJacs(total_residual);
// Solve reduced system.
const Eigen::SparseMatrix<double, Eigen::RowMajor> matr = total_residual.derivative()[0]; const Eigen::SparseMatrix<double, Eigen::RowMajor> matr = total_residual.derivative()[0];
SolutionVector dx(SolutionVector::Zero(total_residual.size())); SolutionVector dx(SolutionVector::Zero(total_residual.size()));
Opm::LinearSolverInterface::LinearSolverReport rep Opm::LinearSolverInterface::LinearSolverReport rep
= linsolver_full_->solve(matr.rows(), matr.nonZeros(), = linsolver_full_->solve(matr.rows(), matr.nonZeros(),
@ -103,6 +120,11 @@ namespace Opm
"FullyImplicitBlackoilSolver::solveJacobianSystem(): " "FullyImplicitBlackoilSolver::solveJacobianSystem(): "
"Linear solver convergence failure."); "Linear solver convergence failure.");
} }
// Compute full solution using the eliminated equations.
// Recovery in inverse order of elimination.
dx = recoverVariable(elim_eqs[1], dx, np);
dx = recoverVariable(elim_eqs[0], dx, np);
return dx; return dx;
} }