Implement solveMultiCell() with Gauss-Seidel.

This commit is contained in:
Atgeirr Flø Rasmussen 2013-04-23 13:38:47 +02:00
parent f0ba716b3a
commit 643c1e7df0
2 changed files with 41 additions and 5 deletions

View File

@ -45,7 +45,8 @@ namespace Opm
limiter_method_(MinUpwindAverage), limiter_method_(MinUpwindAverage),
limiter_usage_(DuringComputations), limiter_usage_(DuringComputations),
coord_(grid.dimensions), coord_(grid.dimensions),
velocity_(grid.dimensions) velocity_(grid.dimensions),
gauss_seidel_tol_(1e-3)
{ {
const int dg_degree = param.getDefault("dg_degree", 0); const int dg_degree = param.getDefault("dg_degree", 0);
const bool use_tensorial_basis = param.getDefault("use_tensorial_basis", false); const bool use_tensorial_basis = param.getDefault("use_tensorial_basis", false);
@ -123,6 +124,10 @@ namespace Opm
basis_nb_.resize(num_basis); basis_nb_.resize(num_basis);
grad_basis_.resize(num_basis*grid_.dimensions); grad_basis_.resize(num_basis*grid_.dimensions);
velocity_interpolation_->setupFluxes(darcyflux); velocity_interpolation_->setupFluxes(darcyflux);
num_multicell_ = 0;
max_size_multicell_ = 0;
max_iter_multicell_ = 0;
num_singlesolves_ = 0;
reorderAndTransport(grid_, darcyflux); reorderAndTransport(grid_, darcyflux);
switch (limiter_usage_) { switch (limiter_usage_) {
case AsPostProcess: case AsPostProcess:
@ -137,6 +142,13 @@ namespace Opm
default: default:
THROW("Unknown limiter usage choice: " << limiter_usage_); THROW("Unknown limiter usage choice: " << limiter_usage_);
} }
if (num_multicell_ > 0) {
std::cout << num_multicell_ << " multicell blocks with max size "
<< max_size_multicell_ << " cells in upto "
<< max_iter_multicell_ << " iterations." << std::endl;
std::cout << "Average solves per cell (for all cells) was "
<< double(num_singlesolves_)/double(grid_.number_of_cells) << std::endl;
}
} }
@ -156,6 +168,7 @@ namespace Opm
const int dim = grid_.dimensions; const int dim = grid_.dimensions;
const int num_basis = basis_func_->numBasisFunc(); const int num_basis = basis_func_->numBasisFunc();
++num_singlesolves_;
std::fill(rhs_.begin(), rhs_.end(), 0.0); std::fill(rhs_.begin(), rhs_.end(), 0.0);
std::fill(jac_.begin(), jac_.end(), 0.0); std::fill(jac_.begin(), jac_.end(), 0.0);
@ -367,10 +380,27 @@ namespace Opm
void TofDiscGalReorder::solveMultiCell(const int num_cells, const int* cells) void TofDiscGalReorder::solveMultiCell(const int num_cells, const int* cells)
{ {
std::cout << "Pretending to solve multi-cell dependent equation with " << num_cells << " cells." << std::endl; ++num_multicell_;
for (int i = 0; i < num_cells; ++i) { max_size_multicell_ = std::max(max_size_multicell_, num_cells);
solveSingleCell(cells[i]); // std::cout << "Multiblock solve with " << num_cells << " cells." << std::endl;
// Using a Gauss-Seidel approach.
const int nb = basis_func_->numBasisFunc();
double max_delta = 1e100;
int num_iter = 0;
while (max_delta > gauss_seidel_tol_) {
max_delta = 0.0;
++num_iter;
for (int ci = 0; ci < num_cells; ++ci) {
const int cell = cells[ci];
const double tof_before = basis_func_->functionAverage(&tof_coeff_[nb*cell]);
solveSingleCell(cell);
const double tof_after = basis_func_->functionAverage(&tof_coeff_[nb*cell]);
max_delta = std::max(max_delta, std::fabs(tof_after - tof_before));
} }
// std::cout << "Max delta = " << max_delta << std::endl;
}
max_iter_multicell_ = std::max(max_iter_multicell_, num_iter);
} }
@ -462,7 +492,7 @@ namespace Opm
double limiter = (tof_c - min_upstream_tof)/(tof_c - min_here_tof); double limiter = (tof_c - min_upstream_tof)/(tof_c - min_here_tof);
if (tof_c < min_upstream_tof) { if (tof_c < min_upstream_tof) {
// Handle by setting a flat solution. // Handle by setting a flat solution.
std::cout << "Trouble in cell " << cell << std::endl; // std::cout << "Trouble in cell " << cell << std::endl;
limiter = 0.0; limiter = 0.0;
basis_func_->addConstant(min_upstream_tof - tof_c, tof + num_basis*cell); basis_func_->addConstant(min_upstream_tof - tof_c, tof + num_basis*cell);
} }

View File

@ -125,6 +125,12 @@ namespace Opm
mutable std::vector<double> basis_nb_; mutable std::vector<double> basis_nb_;
std::vector<double> grad_basis_; std::vector<double> grad_basis_;
std::vector<double> velocity_; std::vector<double> velocity_;
int num_singlesolves_;
// Used by solveMultiCell():
double gauss_seidel_tol_;
int num_multicell_;
int max_size_multicell_;
int max_iter_multicell_;
// Private methods // Private methods