mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
detecting the NAN and INF values during VFP calculation
and give warning messages when they happen, since they can be the culprits of the termination of simulation later. For ADB related, I did not find a good way to do the detection, so there is no warning message given.
This commit is contained in:
parent
32b00b61f8
commit
afcdbcf202
@ -365,7 +365,7 @@ spdiag(const AutoDiffBlock<double>::V& d)
|
||||
public:
|
||||
typedef AutoDiffBlock<Scalar> ADB;
|
||||
|
||||
enum CriterionForLeftElement { GreaterEqualZero, GreaterZero, Zero, NotEqualZero, LessZero, LessEqualZero, NotNaN };
|
||||
enum CriterionForLeftElement { GreaterEqualZero, GreaterZero, Zero, NotEqualZero, LessZero, LessEqualZero, NotNaN, NotNaNInf };
|
||||
|
||||
Selector(const typename ADB::V& selection_basis,
|
||||
CriterionForLeftElement crit = GreaterEqualZero)
|
||||
@ -400,6 +400,9 @@ spdiag(const AutoDiffBlock<double>::V& d)
|
||||
case NotNaN:
|
||||
chooseleft = !isnan(selection_basis[i]);
|
||||
break;
|
||||
case NotNaNInf:
|
||||
chooseleft = !isnan(selection_basis[i]) && !std::isinf(selection_basis[i]);
|
||||
break;
|
||||
default:
|
||||
OPM_THROW(std::logic_error, "No such criterion: " << crit);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#ifndef OPM_AUTODIFF_VFPHELPERS_HPP_
|
||||
#define OPM_AUTODIFF_VFPHELPERS_HPP_
|
||||
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
@ -37,19 +38,31 @@ namespace detail {
|
||||
|
||||
|
||||
/**
|
||||
* Returns zero if input value is NaN
|
||||
* Returns zero if input value is NaN of INF
|
||||
*/
|
||||
inline double zeroIfNan(const double& value) {
|
||||
return (std::isnan(value)) ? 0.0 : value;
|
||||
inline double zeroIfNanInf(const double& value) {
|
||||
const bool nan_or_inf = std::isnan(value) || std::isinf(value);
|
||||
|
||||
if (nan_or_inf) {
|
||||
OpmLog::warning("NAN_OR_INF_VFP", "NAN or INF value encountered during VFP calculation, the value is set to zero");
|
||||
}
|
||||
|
||||
return nan_or_inf ? 0.0 : value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns zero if input value is NaN
|
||||
* Returns zero if input value is NaN or INF
|
||||
*/
|
||||
template <class EvalWell>
|
||||
inline EvalWell zeroIfNan(const EvalWell& value) {
|
||||
return (std::isnan(value.value())) ? 0.0 : value;
|
||||
inline EvalWell zeroIfNanInf(const EvalWell& value) {
|
||||
const bool nan_or_inf = std::isnan(value.value()) || std::isinf(value.value());
|
||||
|
||||
if (nan_or_inf) {
|
||||
OpmLog::warning("NAN_OR_INF_VFP_EVAL", "NAN or INF Evalution encountered during VFP calculation, the Evalution is set to zero");
|
||||
}
|
||||
|
||||
return nan_or_inf ? 0.0 : value;
|
||||
}
|
||||
|
||||
|
||||
@ -120,14 +133,14 @@ static T getWFR(const T& aqua, const T& liquid, const T& vapour,
|
||||
case VFPProdTable::WFR_WOR: {
|
||||
//Water-oil ratio = water / oil
|
||||
T wor = aqua / liquid;
|
||||
return zeroIfNan(wor);
|
||||
return zeroIfNanInf(wor);
|
||||
}
|
||||
case VFPProdTable::WFR_WCT:
|
||||
//Water cut = water / (water + oil)
|
||||
return zeroIfNan(aqua / (aqua + liquid));
|
||||
return zeroIfNanInf(aqua / (aqua + liquid));
|
||||
case VFPProdTable::WFR_WGR:
|
||||
//Water-gas ratio = water / gas
|
||||
return zeroIfNan(aqua / vapour);
|
||||
return zeroIfNanInf(aqua / vapour);
|
||||
case VFPProdTable::WFR_INVALID: //Intentional fall-through
|
||||
default:
|
||||
OPM_THROW(std::logic_error, "Invalid WFR_TYPE: '" << type << "'");
|
||||
@ -149,13 +162,13 @@ static T getGFR(const T& aqua, const T& liquid, const T& vapour,
|
||||
switch(type) {
|
||||
case VFPProdTable::GFR_GOR:
|
||||
// Gas-oil ratio = gas / oil
|
||||
return zeroIfNan(vapour / liquid);
|
||||
return zeroIfNanInf(vapour / liquid);
|
||||
case VFPProdTable::GFR_GLR:
|
||||
// Gas-liquid ratio = gas / (oil + water)
|
||||
return zeroIfNan(vapour / (liquid + aqua));
|
||||
return zeroIfNanInf(vapour / (liquid + aqua));
|
||||
case VFPProdTable::GFR_OGR:
|
||||
// Oil-gas ratio = oil / gas
|
||||
return zeroIfNan(liquid / vapour);
|
||||
return zeroIfNanInf(liquid / vapour);
|
||||
case VFPProdTable::GFR_INVALID: //Intentional fall-through
|
||||
default:
|
||||
OPM_THROW(std::logic_error, "Invalid GFR_TYPE: '" << type << "'");
|
||||
|
@ -37,15 +37,15 @@ typedef AutoDiffBlock<double> ADB;
|
||||
|
||||
|
||||
/**
|
||||
* Returns zero for every entry in the ADB which is NaN
|
||||
*/
|
||||
inline ADB zeroIfNan(const ADB& values) {
|
||||
Selector<ADB::V::Scalar> not_nan_selector(values.value(), Selector<ADB::V::Scalar>::NotNaN);
|
||||
* * Returns zero for every entry in the ADB which is NaN or INF
|
||||
* */
|
||||
inline ADB zeroIfNanInf(const ADB& values) {
|
||||
Selector<ADB::V::Scalar> not_nan_inf_selector(values.value(), Selector<ADB::V::Scalar>::NotNaNInf);
|
||||
|
||||
const ADB::V z = ADB::V::Zero(values.size());
|
||||
const ADB zero = ADB::constant(z, values.blockPattern());
|
||||
|
||||
ADB retval = not_nan_selector.select(values, zero);
|
||||
ADB retval = not_nan_inf_selector.select(values, zero);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user