Initial version of summary data

This commit is contained in:
babrodtk 2016-09-26 14:17:52 +02:00
parent 955ffbd80e
commit b774982878
5 changed files with 281 additions and 82 deletions

View File

@ -131,9 +131,20 @@ namespace Opm {
struct SimulatorData {
SimulatorData(int num_phases);
enum FipId {
FIP_AQUA = Opm::Phases::Water,
FIP_LIQUID = Opm::Phases::Oil,
FIP_VAPOUR = Opm::Phases::Gas,
FIP_DISSOLVED_GAS = 3,
FIP_VAPORIZED_OIL = 4,
FIP_PV = 5, //< Pore volume
FIP_WEIGHTED_PRESSURE = 6
};
std::vector<ReservoirResidualQuant> rq;
ADB rsSat;
ADB rvSat;
ADB rsSat; // Saturated gas-oil ratio
ADB rvSat; // Saturated oil-gas ratio
std::array<V, 7> fip;
};
typedef typename ModelTraits<Implementation>::ReservoirState ReservoirState;

View File

@ -490,6 +490,7 @@ namespace detail {
: rq(num_phases)
, rsSat(ADB::null())
, rvSat(ADB::null())
, fip()
{
}
@ -2363,21 +2364,18 @@ namespace detail {
const ADB pv_mult = poroMult(pressure);
const V& pv = geo_.poreVolume();
const int maxnp = Opm::BlackoilPhases::MaxNumPhases;
std::vector<V> fip(5, V::Zero(nc));
for (int phase = 0; phase < maxnp; ++phase) {
if (active_[ phase ]) {
const int pos = pu.phase_pos[ phase ];
const auto& b = asImpl().fluidReciprocFVF(phase, canonical_phase_pressures[phase], temperature, rs, rv, cond);
fip[phase] = ((pv_mult * b * saturation[pos] * pv).value());
sd_.fip[phase] = ((pv_mult * b * saturation[pos] * pv).value());
}
}
if (active_[ Oil ] && active_[ Gas ]) {
// Account for gas dissolved in oil and vaporized oil
const int po = pu.phase_pos[Oil];
const int pg = pu.phase_pos[Gas];
fip[3] = rs.value() * fip[po];
fip[4] = rv.value() * fip[pg];
sd_.fip[SimulatorData::FIP_DISSOLVED_GAS] = rs.value() * sd_.fip[SimulatorData::FIP_LIQUID];
sd_.fip[SimulatorData::FIP_VAPORIZED_OIL] = rv.value() * sd_.fip[SimulatorData::FIP_VAPOUR];
}
// For a parallel run this is just a local maximum and needs to be updated later
@ -2390,23 +2388,57 @@ namespace detail {
if ( !isParallel() )
{
for (int i = 0; i < 5; ++i) {
//Accumulate phases for each region
for (int phase = 0; phase < maxnp; ++phase) {
for (int c = 0; c < nc; ++c) {
if (fipnum[c] != 0) {
values[fipnum[c]-1][i] += fip[i][c];
const int region = fipnum[c] - 1;
if (region != -1) {
values[region][phase] += sd_.fip[phase][c];
}
}
}
//Accumulate RS and RV-volumes for each region
if (active_[ Oil ] && active_[ Gas ]) {
for (int c = 0; c < nc; ++c) {
const int region = fipnum[c] - 1;
if (region != -1) {
values[region][SimulatorData::FIP_DISSOLVED_GAS] += sd_.fip[SimulatorData::FIP_DISSOLVED_GAS][c];
values[region][SimulatorData::FIP_VAPORIZED_OIL] += sd_.fip[SimulatorData::FIP_VAPORIZED_OIL][c];
}
}
}
hcpv = V::Zero(dims);
pres = V::Zero(dims);
for (int c = 0; c < nc; ++c) {
if (fipnum[c] != 0) {
hcpv[fipnum[c]-1] += pv[c] * hydrocarbon[c];
pres[fipnum[c]-1] += pv[c] * pressure.value()[c];
values[fipnum[c]-1][5] += pv[c];
values[fipnum[c]-1][6] += pv[c] * pressure.value()[c] * hydrocarbon[c];
const int region = fipnum[c] - 1;
if (region != -1) {
hcpv[region] += pv[c] * hydrocarbon[c];
pres[region] += pv[c] * pressure.value()[c];
}
}
sd_.fip[SimulatorData::FIP_PV] = V::Zero(nc);
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE] = V::Zero(nc);
for (int c = 0; c < nc; ++c) {
const int region = fipnum[c] - 1;
if (region != -1) {
sd_.fip[SimulatorData::FIP_PV][c] = pv[c];
//Compute hydrocarbon pore volume weighted average pressure.
//If we have no hydrocarbon in region, use pore volume weighted average pressure instead
if (hcpv[region] != 0) {
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c] = pv[c] * pressure.value()[c] * hydrocarbon[c] / hcpv[region];
} else {
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
}
values[region][SimulatorData::FIP_PV] += sd_.fip[SimulatorData::FIP_PV][c];
values[region][SimulatorData::FIP_WEIGHTED_PRESSURE] += sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c];
}
}
}
@ -2422,10 +2454,23 @@ namespace detail {
dims = comm.max(dims);
values.resize(dims, V::Zero(7));
for (int i = 0; i < 5; ++i) {
//Accumulate phases for each region
for (int phase = 0; phase < maxnp; ++phase) {
for (int c = 0; c < nc; ++c) {
if (fipnum[c] != 0 && mask[c]) {
values[fipnum[c]-1][i] += fip[i][c];
const int region = fipnum[c] - 1;
if (region != -1 && mask[c]) {
values[region][phase] += sd_.fip[phase][c];
}
}
}
//Accumulate RS and RV-volumes for each region
if (active_[ Oil ] && active_[ Gas ]) {
for (int c = 0; c < nc; ++c) {
const int region = fipnum[c] - 1;
if (region != -1 && mask[c]) {
values[region][SimulatorData::FIP_DISSOLVED_GAS] += sd_.fip[SimulatorData::FIP_DISSOLVED_GAS][c];
values[region][SimulatorData::FIP_VAPORIZED_OIL] += sd_.fip[SimulatorData::FIP_VAPORIZED_OIL][c];
}
}
}
@ -2434,11 +2479,29 @@ namespace detail {
pres = V::Zero(dims);
for (int c = 0; c < nc; ++c) {
if (fipnum[c] != 0 && mask[c]) {
hcpv[fipnum[c]-1] += pv[c] * hydrocarbon[c];
pres[fipnum[c]-1] += pv[c] * pressure.value()[c];
values[fipnum[c]-1][5] += pv[c];
values[fipnum[c]-1][6] += pv[c] * pressure.value()[c] * hydrocarbon[c];
const int region = fipnum[c] - 1;
if (region != -1 && mask[c]) {
hcpv[region] += pv[c] * hydrocarbon[c];
pres[region] += pv[c] * pressure.value()[c];
}
}
sd_.fip[SimulatorData::FIP_PV] = V::Zero(nc);
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE] = V::Zero(nc);
for (int c = 0; c < nc; ++c) {
const int region = fipnum[c] - 1;
if (region != -1 && mask[c]) {
sd_.fip[SimulatorData::FIP_PV][c] = pv[c];
if (hcpv[region] != 0) {
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c] = pv[c] * pressure.value()[c] * hydrocarbon[c] / hcpv[region];
} else {
sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
}
values[region][SimulatorData::FIP_PV] += sd_.fip[SimulatorData::FIP_PV][c];
values[region][SimulatorData::FIP_WEIGHTED_PRESSURE] += sd_.fip[SimulatorData::FIP_WEIGHTED_PRESSURE][c];
}
}
@ -2458,15 +2521,6 @@ namespace detail {
#endif
}
// compute PAV and PORV for every regions.
for (int reg = 0; reg < dims; ++reg) {
if (hcpv[reg] != 0) {
values[reg][6] /= hcpv[reg];
} else {
values[reg][6] = pres[reg] / values[reg][5];
}
}
return values;
}

View File

@ -253,7 +253,6 @@ namespace Opm {
/// Compute fluid in place.
/// \param[in] ReservoirState
/// \param[in] WellState
/// \param[in] FIPNUM for active cells not global cells.
/// \return fluid in place, number of fip regions, each region contains 5 values which are liquid, vapour, water, free gas and dissolved gas.
std::vector<V>

View File

@ -422,13 +422,32 @@ namespace Opm
namespace detail {
/**
* Converts an ADB::V into a standard vector by copy
*/
inline std::vector<double> adbVToDoubleVector(const Opm::AutoDiffBlock<double>::V& adb_v) {
std::vector<double> vec(adb_v.data(), adb_v.data() + adb_v.size());
return vec;
}
/**
* Converts an ADB into a standard vector by copy
*/
inline std::vector<double> adbToDoubleVector(const Opm::AutoDiffBlock<double>& adb) {
const auto& adb_v = adb.value();
std::vector<double> vec(adb_v.data(), adb_v.data() + adb_v.size());
return vec;
return adbVToDoubleVector(adb.value());
}
/**
* Checks if the summaryConfig has a keyword with the standardized field, region, or block prefixes.
*/
inline bool hasFRBKeyword(const SummaryConfig& summaryConfig, const std::string keyword) {
std::string field_kw = "F" + keyword;
std::string region_kw = "R" + keyword;
std::string block_kw = "B" + keyword;
return summaryConfig.hasKeyword(field_kw)
|| summaryConfig.hasKeyword(region_kw)
|| summaryConfig.hasKeyword(block_kw);
}
@ -437,15 +456,18 @@ namespace Opm
const Opm::PhaseUsage& phaseUsage,
const Model& model,
const RestartConfig& restartConfig,
const SummaryConfig& summaryConfig,
const int reportStepNum,
const bool log) {
typedef Opm::AutoDiffBlock<double> ADB;
//Our return vector of properties
std::vector<data::CellData> simProps;
//Get the value of each of the keys
std::map<std::string, int> outKeywords = restartConfig.getRestartKeywords(reportStepNum);
for (auto& keyValue : outKeywords) {
//Get the value of each of the keys for the restart keywords
std::map<std::string, int> rstKeywords = restartConfig.getRestartKeywords(reportStepNum);
for (auto& keyValue : rstKeywords) {
keyValue.second = restartConfig.getKeyword(keyValue.first, reportStepNum);
}
@ -464,88 +486,98 @@ namespace Opm
/**
* Formation volume factors for water, oil, gas
*/
if (aqua_active && outKeywords["BW"] > 0) {
outKeywords["BW"] = 0;
if (aqua_active && rstKeywords["BW"] > 0) {
rstKeywords["BW"] = 0;
simProps.emplace_back(data::CellData{
"1OVERBW",
Opm::UnitSystem::measure::water_inverse_formation_volume_factor,
std::move(adbToDoubleVector(sd.rq[aqua_idx].b))});
std::move(adbToDoubleVector(sd.rq[aqua_idx].b)),
true});
}
if (liquid_active && outKeywords["BO"] > 0) {
outKeywords["BO"] = 0;
if (liquid_active && rstKeywords["BO"] > 0) {
rstKeywords["BO"] = 0;
simProps.emplace_back(data::CellData{
"1OVERBO",
Opm::UnitSystem::measure::oil_inverse_formation_volume_factor,
std::move(adbToDoubleVector(sd.rq[liquid_idx].b))});
std::move(adbToDoubleVector(sd.rq[liquid_idx].b)),
true});
}
if (vapour_active && outKeywords["BG"] > 0) {
outKeywords["BG"] = 0;
if (vapour_active && rstKeywords["BG"] > 0) {
rstKeywords["BG"] = 0;
simProps.emplace_back(data::CellData{
"1OVERBG",
Opm::UnitSystem::measure::gas_inverse_formation_volume_factor,
std::move(adbToDoubleVector(sd.rq[vapour_idx].b))});
std::move(adbToDoubleVector(sd.rq[vapour_idx].b)),
true});
}
/**
* Densities for water, oil gas
*/
if (outKeywords["DEN"] > 0) {
outKeywords["DEN"] = 0;
if (rstKeywords["DEN"] > 0) {
rstKeywords["DEN"] = 0;
if (aqua_active) {
simProps.emplace_back(data::CellData{
"WAT_DEN",
Opm::UnitSystem::measure::density,
std::move(adbToDoubleVector(sd.rq[aqua_idx].rho))});
std::move(adbToDoubleVector(sd.rq[aqua_idx].rho)),
true});
}
if (liquid_active) {
simProps.emplace_back(data::CellData{
"OIL_DEN",
Opm::UnitSystem::measure::density,
std::move(adbToDoubleVector(sd.rq[liquid_idx].rho))});
std::move(adbToDoubleVector(sd.rq[liquid_idx].rho)),
true});
}
if (vapour_active) {
simProps.emplace_back(data::CellData{
"GAS_DEN",
Opm::UnitSystem::measure::density,
std::move(adbToDoubleVector(sd.rq[vapour_idx].rho))});
std::move(adbToDoubleVector(sd.rq[vapour_idx].rho)),
true});
}
}
/**
* Viscosities for water, oil gas
*/
if (outKeywords["VISC"] > 0) {
outKeywords["VISC"] = 0;
if (rstKeywords["VISC"] > 0) {
rstKeywords["VISC"] = 0;
if (aqua_active) {
simProps.emplace_back(data::CellData{
"WAT_VISC",
Opm::UnitSystem::measure::viscosity,
std::move(adbToDoubleVector(sd.rq[aqua_idx].mu))});
std::move(adbToDoubleVector(sd.rq[aqua_idx].mu)),
true});
}
if (liquid_active) {
simProps.emplace_back(data::CellData{
"OIL_VISC",
Opm::UnitSystem::measure::viscosity,
std::move(adbToDoubleVector(sd.rq[liquid_idx].mu))});
std::move(adbToDoubleVector(sd.rq[liquid_idx].mu)),
true});
}
if (vapour_active) {
simProps.emplace_back(data::CellData{
"GAS_VISC",
Opm::UnitSystem::measure::viscosity,
std::move(adbToDoubleVector(sd.rq[vapour_idx].mu))});
std::move(adbToDoubleVector(sd.rq[vapour_idx].mu)),
true});
}
}
/**
* Relative permeabilities for water, oil, gas
*/
if (aqua_active && outKeywords["KRW"] > 0) {
if (aqua_active && rstKeywords["KRW"] > 0) {
if (sd.rq[aqua_idx].kr.size() > 0) {
outKeywords["KRW"] = 0;
rstKeywords["KRW"] = 0;
simProps.emplace_back(data::CellData{
"WATKR",
Opm::UnitSystem::measure::permeability,
std::move(adbToDoubleVector(sd.rq[aqua_idx].kr))});
std::move(adbToDoubleVector(sd.rq[aqua_idx].kr)),
true});
}
else {
if ( log )
@ -555,13 +587,14 @@ namespace Opm
}
}
}
if (liquid_active && outKeywords["KRO"] > 0) {
if (liquid_active && rstKeywords["KRO"] > 0) {
if (sd.rq[liquid_idx].kr.size() > 0) {
outKeywords["KRO"] = 0;
rstKeywords["KRO"] = 0;
simProps.emplace_back(data::CellData{
"OILKR",
Opm::UnitSystem::measure::permeability,
std::move(adbToDoubleVector(sd.rq[liquid_idx].kr))});
std::move(adbToDoubleVector(sd.rq[liquid_idx].kr)),
true});
}
else {
if ( log )
@ -571,13 +604,14 @@ namespace Opm
}
}
}
if (vapour_active && outKeywords["KRG"] > 0) {
if (vapour_active && rstKeywords["KRG"] > 0) {
if (sd.rq[vapour_idx].kr.size() > 0) {
outKeywords["KRG"] = 0;
rstKeywords["KRG"] = 0;
simProps.emplace_back(data::CellData{
"GASKR",
Opm::UnitSystem::measure::permeability,
std::move(adbToDoubleVector(sd.rq[vapour_idx].kr))});
std::move(adbToDoubleVector(sd.rq[vapour_idx].kr)),
true});
}
else {
if ( log )
@ -591,19 +625,21 @@ namespace Opm
/**
* Vaporized and dissolved gas/oil ratio
*/
if (vapour_active && liquid_active && outKeywords["RSSAT"] > 0) {
outKeywords["RSSAT"] = 0;
if (vapour_active && liquid_active && rstKeywords["RSSAT"] > 0) {
rstKeywords["RSSAT"] = 0;
simProps.emplace_back(data::CellData{
"RSSAT",
Opm::UnitSystem::measure::gas_oil_ratio,
std::move(adbToDoubleVector(sd.rsSat))});
std::move(adbToDoubleVector(sd.rsSat)),
true});
}
if (vapour_active && liquid_active && outKeywords["RVSAT"] > 0) {
outKeywords["RVSAT"] = 0;
if (vapour_active && liquid_active && rstKeywords["RVSAT"] > 0) {
rstKeywords["RVSAT"] = 0;
simProps.emplace_back(data::CellData{
"RVSAT",
Opm::UnitSystem::measure::oil_gas_ratio,
std::move(adbToDoubleVector(sd.rvSat))});
std::move(adbToDoubleVector(sd.rvSat)),
true});
}
@ -611,17 +647,16 @@ namespace Opm
* Bubble point and dew point pressures
*/
if (log && vapour_active &&
liquid_active && outKeywords["PBPD"] > 0) {
outKeywords["PBPD"] = 0;
liquid_active && rstKeywords["PBPD"] > 0) {
rstKeywords["PBPD"] = 0;
Opm::OpmLog::warning("Bubble/dew point pressure output unsupported",
"Writing bubble points and dew points (PBPD) to file is unsupported, "
"as the simulator does not use these internally.");
}
//Warn for any unhandled keyword
if (log)
{
for (auto& keyValue : outKeywords) {
if (log) {
for (auto& keyValue : rstKeywords) {
if (keyValue.second > 0) {
std::string logstring = "Keyword '";
logstring.append(keyValue.first);
@ -631,6 +666,92 @@ namespace Opm
}
}
/**
* Now process all of the summary config files
*/
// Water in place
if (aqua_active && hasFRBKeyword(summaryConfig, "WIP")) {
simProps.emplace_back(data::CellData{
"WIP",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_AQUA])),
false});
}
if (liquid_active) {
//Oil in place (liquid phase only)
if (hasFRBKeyword(summaryConfig, "OIPL")) {
simProps.emplace_back(data::CellData{
"OIPL",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_LIQUID])),
false});
}
//Oil in place (gas phase only)
if (hasFRBKeyword(summaryConfig, "OIPG")) {
simProps.emplace_back(data::CellData{
"OIPG",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL])),
false});
}
// Oil in place (in liquid and gas phases)
if (hasFRBKeyword(summaryConfig, "OIP")) {
ADB::V oip = sd.fip[Model::SimulatorData::FIP_LIQUID] +
sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL];
simProps.emplace_back(data::CellData{
"OIP",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(oip)),
false});
}
}
if (vapour_active) {
// Gas in place (gas phase only)
if (hasFRBKeyword(summaryConfig, "GIPG")) {
simProps.emplace_back(data::CellData{
"GIPG",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_VAPOUR])),
false});
}
// Gas in place (liquid phase only)
if (hasFRBKeyword(summaryConfig, "GIPL")) {
simProps.emplace_back(data::CellData{
"GIPL",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS])),
false});
}
// Gas in place (in both liquid and gas phases)
if (hasFRBKeyword(summaryConfig, "GIP")) {
ADB::V gip = sd.fip[Model::SimulatorData::FIP_VAPOUR] +
sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS];
simProps.emplace_back(data::CellData{
"GIP",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(gip)),
false});
}
}
// Cell pore volume in reservoir conditions
if (hasFRBKeyword(summaryConfig, "RPV")) {
simProps.emplace_back(data::CellData{
"RPV",
Opm::UnitSystem::measure::volume,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_PV])),
false});
}
// Pressure averaged value (hydrocarbon pore volume weighted)
if (summaryConfig.hasKeyword("FPRH") || summaryConfig.hasKeyword("RPRH")) {
simProps.emplace_back(data::CellData{
"PRH",
Opm::UnitSystem::measure::pressure,
std::move(adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_WEIGHTED_PRESSURE])),
false});
}
return simProps;
}
@ -649,11 +770,13 @@ namespace Opm
bool substep)
{
const RestartConfig& restartConfig = eclipseState_->getRestartConfig();
const SummaryConfig& summaryConfig = eclipseState_->getSummaryConfig();
const int reportStepNum = timer.reportStepNum();
bool logMessages = output_ && parallelOutput_->isIORank();
std::vector<data::CellData> cellData =
detail::getCellData( phaseUsage_,physicalModel, restartConfig,
reportStepNum, logMessages );
detail::getCellData( phaseUsage_, physicalModel, restartConfig,
summaryConfig, reportStepNum, logMessages );
writeTimeStepWithCellProperties(timer, localState, localWellState, cellData, substep);
}
}

View File

@ -80,11 +80,23 @@ namespace Opm {
: rq(num_phases)
, rsSat(ADB::null())
, rvSat(ADB::null())
, fip()
{
}
enum FipId {
FIP_AQUA = BlackoilPropsAdInterface::Water,
FIP_LIQUID = BlackoilPropsAdInterface::Oil,
FIP_VAPOUR = BlackoilPropsAdInterface::Gas,
FIP_DISSOLVED_GAS = 3,
FIP_VAPORIZED_OIL = 4,
FIP_PV = 5, //< Pore volume
FIP_WEIGHTED_PRESSURE = 6
};
std::vector<ReservoirResidualQuant> rq;
ADB rsSat;
ADB rvSat;
std::array<V, 7> fip;
};
/// Construct a solver. It will retain references to the