Merge pull request #3671 from bska/dont-crash-on-unexpected

Don't crash on Unexpected Input
This commit is contained in:
Magne Sjaastad
2018-11-13 10:24:14 +01:00
committed by GitHub
4 changed files with 66 additions and 15 deletions

View File

@@ -107,10 +107,14 @@ namespace {
const ::Opm::ECLInitFileData& init,
const std::string& vector,
const std::vector<double>& dflt,
CvrtVal&& cvrt)
CvrtVal&& cvrt,
const std::vector<double>& fallback
= std::vector<double>{})
{
auto ret = std::vector<double>(G.numCells());
const auto sentinel = 1.0e20;
assert (! dflt.empty() && "Internal Error");
auto cellID = std::vector<double>::size_type{0};
@@ -126,8 +130,20 @@ namespace {
: std::vector<double>(nc, -1.0e21);
for (auto c = 0*nc; c < nc; ++c, ++cellID) {
ret[cellID] = (std::abs(val[c]) < 1.0e20)
? cvrt(val[c]) : dflt[snum[c] - 1];
const auto fb = fallback.empty()
? -sentinel : fallback[c];
auto& r = ret[cellID];
if (std::abs(val[c]) < sentinel) {
r = cvrt(val[c]);
}
else if (std::abs(fb) < sentinel) {
r = cvrt(fb);
}
else {
r = dflt[snum[c] - 1];
}
}
}
@@ -488,14 +504,12 @@ vertScale(const FunctionValues& f,
const SaturationPoints& sp,
std::vector<double> val) const
{
assert ((sp.size() == val.size()) && "Internal Error in Vertical Scaling");
assert (! (f.max.val < f.disp.val) && "Internal Error in Table Extraction");
assert (! (f.max.sat < f.disp.sat) && "Internal Error in Table Extraction");
assert ((sp.size() == val.size()) && "Internal Error in Vertical Scaling");
auto ret = std::move(val);
const auto fdisp = f.disp.val;
const auto fmax = f.max .val;
const auto fmax = std::max(f.disp.val, f.max.val);
const auto sepfv = fmax > fdisp;
for (auto n = sp.size(), i = 0*n; i < n; ++i) {
@@ -1049,10 +1063,12 @@ Create::TwoPoint::Pc::GO(const ::Opm::ECLGraph& G,
// Use dedicated scaled Sg_conn for Pc if defined in at least one
// subgrid. Use SGL otherwise. Same default value (i.e., table's
// connate gas saturation) for both vectors.
auto sgl = haveKeywordData(G, init, "SGLPC")
const auto sgl = ::Opm::SatFunc::scaledConnateGas(G, init, tep);
auto sglpc = haveKeywordData(G, init, "SGLPC")
? gridDefaultedVector(G, init, "SGLPC", tep.conn.gas,
[](const double s) { return s; })
: ::Opm::SatFunc::scaledConnateGas(G, init, tep);
[](const double s) { return s; }, sgl)
: sgl;
auto sgu = sgMax(G, init, tep);
@@ -1066,7 +1082,7 @@ Create::TwoPoint::Pc::GO(const ::Opm::ECLGraph& G,
}
return EPSPtr {
new EPS { std::move(sgl), std::move(sgu) }
new EPS { std::move(sglpc), std::move(sgu) }
};
}
@@ -1078,10 +1094,12 @@ Create::TwoPoint::Pc::OW(const ::Opm::ECLGraph& G,
// Use dedicated scaled Sw_conn for Pc if defined in at least one
// subgrid. Use SWL otherwise. Same default value (i.e., table's
// connate water saturation) for both vectors.
auto swl = haveKeywordData(G, init, "SWLPC")
const auto swl = ::Opm::SatFunc::scaledConnateWater(G, init, tep);
auto swlpc = haveKeywordData(G, init, "SWLPC")
? gridDefaultedVector(G, init, "SWLPC", tep.conn.water,
[](const double s) { return s; })
: ::Opm::SatFunc::scaledConnateWater(G, init, tep);
[](const double s) { return s; }, swl)
: swl;
auto swu = swMax(G, init, tep);
@@ -1095,7 +1113,7 @@ Create::TwoPoint::Pc::OW(const ::Opm::ECLGraph& G,
}
return EPSPtr {
new EPS { std::move(swl), std::move(swu) }
new EPS { std::move(swlpc), std::move(swu) }
};
}
@@ -2514,6 +2532,9 @@ unscaledFunctionValues(const ECLGraph& G,
ret.resize(uep.size());
for (auto n = uep.size(), i = 0*n; i < n; ++i) {
ret[i].disp.sat = uep[i].disp;
ret[i].disp.val = evalSF(static_cast<int>(i), ret[i].disp.sat);
ret[i].max.sat = uep[i].high;
ret[i].max.val = evalSF(static_cast<int>(i), ret[i].max.sat);
}

View File

@@ -208,6 +208,11 @@ namespace Opm
ECLFluxCalc::flux(const ECLRestartData& rstrt,
const ECLPhaseIndex phase) const
{
if (! this->phaseIsActive(phase)) {
// Inactive phase. Return empty flux vector.
return {};
}
// Obtain dynamic data.
const auto dyn_data = this->phaseProperties(rstrt, phase);
@@ -225,6 +230,11 @@ namespace Opm
ECLFluxCalc::massflux(const ECLRestartData& rstrt,
const ECLPhaseIndex phase) const
{
if (! this->phaseIsActive(phase)) {
// Inactive phase. Return empty (mass) flux vector.
return {};
}
// Obtain dynamic data.
const auto dyn_data = this->phaseProperties(rstrt, phase);
@@ -297,6 +307,19 @@ namespace Opm
}
bool ECLFluxCalc::phaseIsActive(const ECLPhaseIndex phase) const
{
switch (phase) {
case ECLPhaseIndex::Aqua: return this->pvtWat_ != nullptr;
case ECLPhaseIndex::Liquid: return this->pvtOil_ != nullptr;
case ECLPhaseIndex::Vapour: return this->pvtGas_ != nullptr;
}
throw std::invalid_argument {
"phaseIsActive(): Invalid Phase Identifier"
};
}
ECLFluxCalc::DynamicData
ECLFluxCalc::phaseProperties(const ECLRestartData& rstrt,

View File

@@ -131,6 +131,8 @@ namespace Opm
const DynamicData& dyn_data) const;
bool phaseIsActive(const ECLPhaseIndex phase) const;
DynamicData gasPVT(const ECLRestartData& rstrt,
DynamicData&& dyn_data) const;

View File

@@ -1357,6 +1357,11 @@ private:
return host.wat_->pcow(regID, { sat })[0];
});
// Special case treatment of PCOW. Maximum value at minimum S.
for (auto& fval : *eps.vertfuncval) {
fval.max.val = std::max(fval.disp.val, fval.max.val);
}
eps.vertscaling = Create::Vertical::
fromECLOutput(G, init, opt, ep,
*eps.vertfuncval);