Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions opm/simulators/flow/TemperatureModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <opm/simulators/flow/BlackoilModelParameters.hpp>
#include <opm/simulators/flow/GenericTemperatureModel.hpp>
#include <opm/simulators/linalg/findOverlapRowsAndColumns.hpp>
#include <opm/simulators/aquifers/AquiferGridUtils.hpp>

#include <algorithm>
#include <cassert>
Expand Down Expand Up @@ -217,14 +218,21 @@ class TemperatureModel : public GenericTemperatureModel<GetPropType<TypeTag, Pro
{
const int max_iter = 20;
const int min_iter = 1;
bool is_converged = false;
// solve using Newton
for (int iter = 0; iter < max_iter; ++iter) {
assembleEquations();
if (iter >= min_iter && converged(iter)) {
is_converged = true;
break;
}
solveAndUpdate();
}
if (!is_converged) {
const auto msg = fmt::format("Temperature model (TEMP): Newton did not converge after {} iterations. \n"
"The Simulator will continue to the next step with an unconverged solution.",max_iter);
OpmLog::debug(msg);
}
}

void solveAndUpdate()
Expand All @@ -248,24 +256,49 @@ class TemperatureModel : public GenericTemperatureModel<GetPropType<TypeTag, Pro

bool converged(const int iter)
{
const unsigned int numCells = simulator_.model().numTotalDof();
Scalar dt = simulator_.timeStepSize();
Scalar maxNorm = 0.0;
Scalar sumNorm = 0.0;
auto tolerance_cnv_energy = Parameters::Get<Parameters::ToleranceCnvEnergy<Scalar>>();
const auto& elemMapper = simulator_.model().elementMapper();
const IsNumericalAquiferCell isNumericalAquiferCell(simulator_.gridView().grid());
Scalar sum_pv = 0.0;
Scalar sum_pv_not_converged = 0.0;
for (const auto& elem : elements(simulator_.gridView(), Dune::Partitions::interior)) {
unsigned globI = elemMapper.index(elem);
maxNorm = max(maxNorm, std::abs(this->energyVector_[globI]));
sumNorm += std::abs(this->energyVector_[globI]);
const auto pvValue = simulator_.problem().referencePorosity(globI, /*timeIdx=*/0)
* simulator_.model().dofTotalVolume(globI);

const Scalar scaled_norm = dt * std::abs(this->energyVector_[globI])/ pvValue;
maxNorm = max(maxNorm, scaled_norm);
sumNorm += scaled_norm;
if (!isNumericalAquiferCell(elem)) {
if (scaled_norm > tolerance_cnv_energy) {
sum_pv_not_converged += pvValue;
}
sum_pv += pvValue;
}
}
maxNorm = simulator_.gridView().comm().max(maxNorm);
sumNorm = simulator_.gridView().comm().sum(sumNorm);
const int globalNumCells = simulator_.gridView().comm().sum(numCells);
sumNorm /= globalNumCells;
const auto tolerance_cnv_energy = Parameters::Get<Parameters::ToleranceCnvEnergy<Scalar>>();
const auto tolerance_energy_balance = Parameters::Get<Parameters::ToleranceEnergyBalance<Scalar>>();
if (maxNorm < tolerance_cnv_energy || sumNorm < tolerance_energy_balance) {
const auto msg = fmt::format("Temperature model (TEMP): Newton converged after {} iterations", iter);
OpmLog::debug(msg);
// Use relaxed tolerance if the fraction of unconverged cells porevolume is less than relaxed_max_pv_fraction
sum_pv_not_converged = simulator_.gridView().comm().sum(sum_pv_not_converged);
sum_pv = simulator_.gridView().comm().sum(sum_pv);
Scalar relaxed_max_pv_fraction = Parameters::Get<Parameters::RelaxedMaxPvFraction<Scalar>>();
const bool relax = (sum_pv_not_converged / sum_pv) < relaxed_max_pv_fraction;
const auto tolerance_energy_balance = relax? Parameters::Get<Parameters::ToleranceEnergyBalanceRelaxed<Scalar>>():
Parameters::Get<Parameters::ToleranceEnergyBalance<Scalar>>();
tolerance_cnv_energy = relax? Parameters::Get<Parameters::ToleranceCnvEnergyRelaxed<Scalar>>():
Parameters::Get<Parameters::ToleranceCnvEnergy<Scalar>>();

const auto msg = fmt::format("Temperature model (TEMP): Newton iter {}: "
"CNV(E): {:.1e}, EB: {:.1e}",
iter, maxNorm, sumNorm);
OpmLog::debug(msg);
if (maxNorm < tolerance_cnv_energy && sumNorm < tolerance_energy_balance) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to change tot ::debug here and maybe also below. I don't think the user would like all this information.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

const auto msg2 = fmt::format("Temperature model (TEMP): Newton converged after {} iterations"
, iter);
OpmLog::debug(msg2);
return true;
}
return false;
Expand Down