mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #1047 from dr-robertk/PR/cleanup-output-writers
[WIP] Unify output writers to avoid code duplication.
This commit is contained in:
commit
0ebff11099
@ -35,7 +35,6 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/autodiff/ImpesTPFAAD.cpp
|
||||
opm/autodiff/moduleVersion.cpp
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilOutputEbos.cpp
|
||||
opm/autodiff/SimulatorIncompTwophaseAd.cpp
|
||||
opm/autodiff/TransportSolverTwophaseAd.cpp
|
||||
opm/autodiff/BlackoilPropsAdFromDeck.cpp
|
||||
@ -209,7 +208,6 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilSolvent_impl.hpp
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment.hpp
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp
|
||||
opm/autodiff/SimulatorFullyImplicitBlackoilOutputEbos.hpp
|
||||
opm/autodiff/SimulatorIncompTwophaseAd.hpp
|
||||
opm/autodiff/SimulatorSequentialBlackoil.hpp
|
||||
opm/autodiff/TransportSolverTwophaseAd.hpp
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include <opm/simulators/timestepping/SimulatorTimerInterface.hpp>
|
||||
#include <opm/core/simulator/SimulatorReport.hpp>
|
||||
|
||||
#include <opm/common/data/SimulationDataContainer.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
struct Wells;
|
||||
@ -50,7 +52,6 @@ namespace Opm {
|
||||
class RockCompressibility;
|
||||
class NewtonIterationBlackoilInterface;
|
||||
class VFPProperties;
|
||||
class SimulationDataContainer;
|
||||
|
||||
/// Traits to encapsulate the types used by classes using or
|
||||
/// extending this model. Forward declared here, must be
|
||||
@ -92,24 +93,21 @@ namespace Opm {
|
||||
ADB mob; // Phase mobility (per cell)
|
||||
};
|
||||
|
||||
struct SimulatorData {
|
||||
struct SimulatorData : public Opm::FIPDataEnums {
|
||||
SimulatorData(int num_phases);
|
||||
|
||||
enum FipId {
|
||||
FIP_AQUA = Opm::Water,
|
||||
FIP_LIQUID = Opm::Oil,
|
||||
FIP_VAPOUR = Opm::Gas,
|
||||
FIP_DISSOLVED_GAS = 3,
|
||||
FIP_VAPORIZED_OIL = 4,
|
||||
FIP_PV = 5, //< Pore volume
|
||||
FIP_WEIGHTED_PRESSURE = 6
|
||||
};
|
||||
using Opm::FIPDataEnums :: FipId ;
|
||||
using Opm::FIPDataEnums :: fipValues ;
|
||||
|
||||
std::vector<ReservoirResidualQuant> rq;
|
||||
ADB rsSat; // Saturated gas-oil ratio
|
||||
ADB rvSat; // Saturated oil-gas ratio
|
||||
std::array<V, 7> fip;
|
||||
|
||||
std::array<V, fipValues> fip;
|
||||
};
|
||||
|
||||
typedef Opm::FIPData FIPDataType;
|
||||
|
||||
typedef typename ModelTraits<Implementation>::ReservoirState ReservoirState;
|
||||
typedef typename ModelTraits<Implementation>::WellState WellState;
|
||||
typedef typename ModelTraits<Implementation>::ModelParameters ModelParameters;
|
||||
@ -264,6 +262,11 @@ namespace Opm {
|
||||
return sd_;
|
||||
}
|
||||
|
||||
/// Return fluid-in-place data (for output functionality)
|
||||
FIPDataType getFIPData() const {
|
||||
return FIPDataType( sd_.fip );
|
||||
}
|
||||
|
||||
/// Compute fluid in place.
|
||||
/// \param[in] ReservoirState
|
||||
/// \param[in] FIPNUM for active cells not global cells.
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include <opm/core/utility/parameters/ParameterGroup.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/common/data/SimulationDataContainer.hpp>
|
||||
|
||||
#include <dune/common/timer.hh>
|
||||
|
||||
@ -389,7 +388,6 @@ typedef Eigen::Array<double,
|
||||
|
||||
|
||||
|
||||
|
||||
template <class Grid, class WellModel, class Implementation>
|
||||
int
|
||||
BlackoilModelBase<Grid, WellModel, Implementation>::
|
||||
@ -445,7 +443,6 @@ typedef Eigen::Array<double,
|
||||
|
||||
|
||||
|
||||
|
||||
template <class Grid, class WellModel, class Implementation>
|
||||
BlackoilModelBase<Grid, WellModel, Implementation>::
|
||||
ReservoirResidualQuant::ReservoirResidualQuant()
|
||||
|
@ -143,19 +143,7 @@ namespace Opm {
|
||||
using RateConverterType = RateConverter::
|
||||
SurfaceToReservoirVoidage<BlackoilPropsAdFromDeck::FluidSystem, std::vector<int> >;
|
||||
|
||||
struct FIPData {
|
||||
enum FipId {
|
||||
FIP_AQUA = Opm::Water,
|
||||
FIP_LIQUID = Opm::Oil,
|
||||
FIP_VAPOUR = Opm::Gas,
|
||||
FIP_DISSOLVED_GAS = 3,
|
||||
FIP_VAPORIZED_OIL = 4,
|
||||
FIP_PV = 5, //< Pore volume
|
||||
FIP_WEIGHTED_PRESSURE = 6
|
||||
};
|
||||
static const int fipValues = FIP_WEIGHTED_PRESSURE + 1 ;
|
||||
std::array<std::vector<double>, fipValues> fip;
|
||||
};
|
||||
typedef Opm::FIPData FIPDataType;
|
||||
|
||||
// --------- Public methods ---------
|
||||
|
||||
@ -1022,7 +1010,7 @@ namespace Opm {
|
||||
const auto& pv = geo_.poreVolume();
|
||||
const int maxnp = Opm::BlackoilPhases::MaxNumPhases;
|
||||
|
||||
for (int i = 0; i<FIPData::fipValues; i++) {
|
||||
for (int i = 0; i<FIPDataType::fipValues; i++) {
|
||||
fip_.fip[i].resize(nc,0.0);
|
||||
}
|
||||
|
||||
@ -1051,14 +1039,14 @@ namespace Opm {
|
||||
|
||||
if (active_[ Oil ] && active_[ Gas ]) {
|
||||
// Account for gas dissolved in oil and vaporized oil
|
||||
fip_.fip[FIPData::FIP_DISSOLVED_GAS][cellIdx] = fs.Rs().value() * fip_.fip[FIPData::FIP_LIQUID][cellIdx];
|
||||
fip_.fip[FIPData::FIP_VAPORIZED_OIL][cellIdx] = fs.Rv().value() * fip_.fip[FIPData::FIP_VAPOUR][cellIdx];
|
||||
fip_.fip[FIPDataType::FIP_DISSOLVED_GAS][cellIdx] = fs.Rs().value() * fip_.fip[FIPDataType::FIP_LIQUID][cellIdx];
|
||||
fip_.fip[FIPDataType::FIP_VAPORIZED_OIL][cellIdx] = fs.Rv().value() * fip_.fip[FIPDataType::FIP_VAPOUR][cellIdx];
|
||||
}
|
||||
}
|
||||
|
||||
// For a parallel run this is just a local maximum and needs to be updated later
|
||||
int dims = *std::max_element(fipnum.begin(), fipnum.end());
|
||||
std::vector<std::vector<double>> values(dims, std::vector<double>(FIPData::fipValues,0.0));
|
||||
std::vector<std::vector<double>> values(dims, std::vector<double>(FIPDataType::fipValues,0.0));
|
||||
|
||||
std::vector<double> hcpv(dims, 0.0);
|
||||
std::vector<double> pres(dims, 0.0);
|
||||
@ -1082,8 +1070,8 @@ namespace Opm {
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
const int region = fipnum[c] - 1;
|
||||
if (region != -1) {
|
||||
values[region][FIPData::FIP_DISSOLVED_GAS] += fip_.fip[FIPData::FIP_DISSOLVED_GAS][c];
|
||||
values[region][FIPData::FIP_VAPORIZED_OIL] += fip_.fip[FIPData::FIP_VAPORIZED_OIL][c];
|
||||
values[region][FIPDataType::FIP_DISSOLVED_GAS] += fip_.fip[FIPDataType::FIP_DISSOLVED_GAS][c];
|
||||
values[region][FIPDataType::FIP_VAPORIZED_OIL] += fip_.fip[FIPDataType::FIP_VAPORIZED_OIL][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1102,7 +1090,7 @@ namespace Opm {
|
||||
const int region = fipnum[c] - 1;
|
||||
if (region != -1) {
|
||||
|
||||
fip_.fip[FIPData::FIP_PV][c] = pv[c];
|
||||
fip_.fip[FIPDataType::FIP_PV][c] = pv[c];
|
||||
const auto& intQuants = *ebosSimulator_.model().cachedIntensiveQuantities(c, /*timeIdx=*/0);
|
||||
const auto& fs = intQuants.fluidState();
|
||||
const double hydrocarbon = fs.saturation(FluidSystem::oilPhaseIdx).value() + fs.saturation(FluidSystem::gasPhaseIdx).value();
|
||||
@ -1110,13 +1098,13 @@ namespace Opm {
|
||||
//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) {
|
||||
fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c] = pv[c] * fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbon / hcpv[region];
|
||||
fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c] = pv[c] * fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbon / hcpv[region];
|
||||
} else {
|
||||
fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
|
||||
fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
|
||||
}
|
||||
|
||||
values[region][FIPData::FIP_PV] += fip_.fip[FIPData::FIP_PV][c];
|
||||
values[region][FIPData::FIP_WEIGHTED_PRESSURE] += fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c];
|
||||
values[region][FIPDataType::FIP_PV] += fip_.fip[FIPDataType::FIP_PV][c];
|
||||
values[region][FIPDataType::FIP_WEIGHTED_PRESSURE] += fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1131,7 +1119,7 @@ namespace Opm {
|
||||
auto comm = pinfo.communicator();
|
||||
// Compute the global dims value and resize values accordingly.
|
||||
dims = comm.max(dims);
|
||||
values.resize(dims, std::vector<double>(FIPData::fipValues,0.0));
|
||||
values.resize(dims, std::vector<double>(FIPDataType::fipValues,0.0));
|
||||
|
||||
//Accumulate phases for each region
|
||||
for (int phase = 0; phase < maxnp; ++phase) {
|
||||
@ -1148,8 +1136,8 @@ namespace Opm {
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
const int region = fipnum[c] - 1;
|
||||
if (region != -1 && mask[c]) {
|
||||
values[region][FIPData::FIP_DISSOLVED_GAS] += fip_.fip[FIPData::FIP_DISSOLVED_GAS][c];
|
||||
values[region][FIPData::FIP_VAPORIZED_OIL] += fip_.fip[FIPData::FIP_VAPORIZED_OIL][c];
|
||||
values[region][FIPDataType::FIP_DISSOLVED_GAS] += fip_.fip[FIPDataType::FIP_DISSOLVED_GAS][c];
|
||||
values[region][FIPDataType::FIP_VAPORIZED_OIL] += fip_.fip[FIPDataType::FIP_VAPORIZED_OIL][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1174,19 +1162,19 @@ namespace Opm {
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
const int region = fipnum[c] - 1;
|
||||
if (region != -1 && mask[c]) {
|
||||
fip_.fip[FIPData::FIP_PV][c] = pv[c];
|
||||
fip_.fip[FIPDataType::FIP_PV][c] = pv[c];
|
||||
const auto& intQuants = *ebosSimulator_.model().cachedIntensiveQuantities(c, /*timeIdx=*/0);
|
||||
const auto& fs = intQuants.fluidState();
|
||||
const double hydrocarbon = fs.saturation(FluidSystem::oilPhaseIdx).value() + fs.saturation(FluidSystem::gasPhaseIdx).value();
|
||||
|
||||
if (hcpv[region] != 0) {
|
||||
fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c] = pv[c] * fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbon / hcpv[region];
|
||||
fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c] = pv[c] * fs.pressure(FluidSystem::oilPhaseIdx).value() * hydrocarbon / hcpv[region];
|
||||
} else {
|
||||
fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
|
||||
fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c] = pres[region] / pv[c];
|
||||
}
|
||||
|
||||
values[region][FIPData::FIP_PV] += fip_.fip[FIPData::FIP_PV][c];
|
||||
values[region][FIPData::FIP_WEIGHTED_PRESSURE] += fip_.fip[FIPData::FIP_WEIGHTED_PRESSURE][c];
|
||||
values[region][FIPDataType::FIP_PV] += fip_.fip[FIPDataType::FIP_PV][c];
|
||||
values[region][FIPDataType::FIP_WEIGHTED_PRESSURE] += fip_.fip[FIPDataType::FIP_WEIGHTED_PRESSURE][c];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1206,7 +1194,131 @@ namespace Opm {
|
||||
return values;
|
||||
}
|
||||
|
||||
const FIPData& getFIPData() const {
|
||||
SimulationDataContainer getSimulatorData () const
|
||||
{
|
||||
typedef std::vector<double> VectorType;
|
||||
|
||||
const auto& ebosModel = ebosSimulator().model();
|
||||
const auto& phaseUsage = fluid_.phaseUsage();
|
||||
|
||||
// extract everything which can possibly be written to disk
|
||||
const int numCells = ebosModel.numGridDof();
|
||||
const int num_phases = numPhases();
|
||||
|
||||
SimulationDataContainer simData( numCells, 0, num_phases );
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_active = phaseUsage.phase_used[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_active = phaseUsage.phase_used[Opm::PhaseUsage::Vapour];
|
||||
|
||||
const int aqua_pos = phaseUsage.phase_pos[ Opm::PhaseUsage::Aqua ];
|
||||
const int liquid_pos = phaseUsage.phase_pos[ Opm::PhaseUsage::Liquid ];
|
||||
const int vapour_pos = phaseUsage.phase_pos[ Opm::PhaseUsage::Vapour ];
|
||||
|
||||
VectorType zero;
|
||||
|
||||
VectorType& pressureOil = simData.pressure();
|
||||
VectorType& temperature = simData.temperature();
|
||||
VectorType& saturation = simData.saturation();
|
||||
|
||||
// WATER
|
||||
if( aqua_active ) {
|
||||
simData.registerCellData("1OVERBW", 1 );
|
||||
simData.registerCellData("WAT_DEN", 1 );
|
||||
simData.registerCellData("WAT_VISC", 1 );
|
||||
simData.registerCellData("WATKR", 1 );
|
||||
}
|
||||
|
||||
VectorType& bWater = aqua_active ? simData.getCellData( "1OVERBW" ) : zero;
|
||||
VectorType& rhoWater = aqua_active ? simData.getCellData( "WAT_DEN" ) : zero;
|
||||
VectorType& muWater = aqua_active ? simData.getCellData( "WAT_VISC" ) : zero;
|
||||
VectorType& krWater = aqua_active ? simData.getCellData( "WATKR" ) : zero;
|
||||
|
||||
// OIL
|
||||
if( liquid_active ) {
|
||||
simData.registerCellData("1OVERBO", 1 );
|
||||
simData.registerCellData("OIL_DEN", 1 );
|
||||
simData.registerCellData("OIL_VISC", 1 );
|
||||
simData.registerCellData("OILKR", 1 );
|
||||
}
|
||||
|
||||
VectorType& bOil = liquid_active ? simData.getCellData( "1OVERBO" ) : zero;
|
||||
VectorType& rhoOil = liquid_active ? simData.getCellData( "OIL_DEN" ) : zero;
|
||||
VectorType& muOil = liquid_active ? simData.getCellData( "OIL_VISC" ) : zero;
|
||||
VectorType& krOil = liquid_active ? simData.getCellData( "OILKR" ) : zero;
|
||||
|
||||
// GAS
|
||||
if( vapour_active ) {
|
||||
simData.registerCellData("1OVERBG", 1 );
|
||||
simData.registerCellData("GAS_DEN", 1 );
|
||||
simData.registerCellData("GAS_VISC", 1 );
|
||||
simData.registerCellData("GASKR", 1 );
|
||||
}
|
||||
|
||||
VectorType& bGas = vapour_active ? simData.getCellData( "1OVERBG" ) : zero;
|
||||
VectorType& rhoGas = vapour_active ? simData.getCellData( "GAS_DEN" ) : zero;
|
||||
VectorType& muGas = vapour_active ? simData.getCellData( "GAS_VISC" ) : zero;
|
||||
VectorType& krGas = vapour_active ? simData.getCellData( "GASKR" ) : zero;
|
||||
|
||||
simData.registerCellData( BlackoilState::GASOILRATIO, 1 );
|
||||
simData.registerCellData( BlackoilState::RV, 1 );
|
||||
simData.registerCellData("RSSAT", 1 );
|
||||
simData.registerCellData("RVSAT", 1 );
|
||||
|
||||
VectorType& Rs = simData.getCellData( BlackoilState::GASOILRATIO );
|
||||
VectorType& Rv = simData.getCellData( BlackoilState::RV );
|
||||
VectorType& RsSat = simData.getCellData( "RSSAT" );
|
||||
VectorType& RvSat = simData.getCellData( "RVSAT" );
|
||||
|
||||
for (int cellIdx = 0; cellIdx < numCells; ++cellIdx) {
|
||||
const auto& intQuants = *ebosModel.cachedIntensiveQuantities(cellIdx, /*timeIdx=*/0);
|
||||
const auto& fs = intQuants.fluidState();
|
||||
|
||||
const int satIdx = cellIdx * num_phases;
|
||||
|
||||
pressureOil[cellIdx] = fs.pressure(FluidSystem::oilPhaseIdx).value();
|
||||
|
||||
temperature[cellIdx] = fs.temperature(FluidSystem::oilPhaseIdx).value();
|
||||
|
||||
if (aqua_active) {
|
||||
saturation[ satIdx + aqua_pos ] = fs.saturation(FluidSystem::waterPhaseIdx).value();
|
||||
bWater[cellIdx] = fs.invB(FluidSystem::waterPhaseIdx).value();
|
||||
rhoWater[cellIdx] = fs.density(FluidSystem::waterPhaseIdx).value();
|
||||
muWater[cellIdx] = fs.viscosity(FluidSystem::waterPhaseIdx).value();
|
||||
krWater[cellIdx] = intQuants.relativePermeability(FluidSystem::waterPhaseIdx).value();
|
||||
}
|
||||
if (vapour_active) {
|
||||
saturation[ satIdx + vapour_pos ] = fs.saturation(FluidSystem::gasPhaseIdx).value();
|
||||
bGas[cellIdx] = fs.invB(FluidSystem::gasPhaseIdx).value();
|
||||
rhoGas[cellIdx] = fs.density(FluidSystem::gasPhaseIdx).value();
|
||||
muGas[cellIdx] = fs.viscosity(FluidSystem::gasPhaseIdx).value();
|
||||
krGas[cellIdx] = intQuants.relativePermeability(FluidSystem::gasPhaseIdx).value();
|
||||
Rs[cellIdx] = fs.Rs().value();
|
||||
Rv[cellIdx] = fs.Rv().value();
|
||||
RsSat[cellIdx] = FluidSystem::saturatedDissolutionFactor(fs,
|
||||
FluidSystem::oilPhaseIdx,
|
||||
intQuants.pvtRegionIndex(),
|
||||
/*maxOilSaturation=*/1.0).value();
|
||||
RvSat[cellIdx] = FluidSystem::saturatedDissolutionFactor(fs,
|
||||
FluidSystem::gasPhaseIdx,
|
||||
intQuants.pvtRegionIndex(),
|
||||
/*maxOilSaturation=*/1.0).value();
|
||||
}
|
||||
if( liquid_active )
|
||||
{
|
||||
saturation[ satIdx + liquid_pos ] = fs.saturation(FluidSystem::oilPhaseIdx).value();
|
||||
bOil[cellIdx] = fs.invB(FluidSystem::oilPhaseIdx).value();
|
||||
rhoOil[cellIdx] = fs.density(FluidSystem::oilPhaseIdx).value();
|
||||
muOil[cellIdx] = fs.viscosity(FluidSystem::oilPhaseIdx).value();
|
||||
krOil[cellIdx] = intQuants.relativePermeability(FluidSystem::oilPhaseIdx).value();
|
||||
}
|
||||
}
|
||||
|
||||
return simData;
|
||||
}
|
||||
|
||||
const FIPDataType& getFIPData() const {
|
||||
return fip_;
|
||||
}
|
||||
|
||||
@ -1254,7 +1366,7 @@ namespace Opm {
|
||||
std::vector<std::vector<double>> residual_norms_history_;
|
||||
double current_relaxation_;
|
||||
BVector dx_old_;
|
||||
mutable FIPData fip_;
|
||||
mutable FIPDataType fip_;
|
||||
|
||||
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
@ -45,6 +48,44 @@ namespace Opm
|
||||
Next // For extension.
|
||||
};
|
||||
|
||||
struct FIPDataEnums {
|
||||
|
||||
enum FipId {
|
||||
FIP_AQUA = Opm::Water,
|
||||
FIP_LIQUID = Opm::Oil,
|
||||
FIP_VAPOUR = Opm::Gas,
|
||||
FIP_DISSOLVED_GAS = 3,
|
||||
FIP_VAPORIZED_OIL = 4,
|
||||
FIP_PV = 5, //< Pore volume
|
||||
FIP_WEIGHTED_PRESSURE = 6
|
||||
};
|
||||
|
||||
static const int fipValues = FIP_WEIGHTED_PRESSURE + 1 ;
|
||||
};
|
||||
|
||||
class FIPData : public FIPDataEnums
|
||||
{
|
||||
public:
|
||||
typedef std::vector<double> VectorType;
|
||||
|
||||
using FIPDataEnums :: FipId;
|
||||
using FIPDataEnums :: fipValues ;
|
||||
std::array< VectorType, fipValues> fip;
|
||||
|
||||
// default constructor
|
||||
FIPData() {}
|
||||
|
||||
// initialize from array of Eigen vectors (or std::vectors)
|
||||
template <class V>
|
||||
explicit FIPData( const std::array< V, fipValues>& otherFip )
|
||||
{
|
||||
// copy fip vector from V to std::vector
|
||||
for( int i=0; i<fipValues; ++i ) {
|
||||
fip[ i ] = VectorType(otherFip[ i ].data(), otherFip[ i ].data() + otherFip[ i ].size() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
#endif // OPM_BLACKOILMODELENUMS_HEADER_INCLUDED
|
||||
|
@ -56,6 +56,7 @@ namespace Opm {
|
||||
typedef BlackoilPressureModel<Grid, WellModel> PressureModel;
|
||||
typedef BlackoilTransportModel<Grid, WellModel> TransportModel;
|
||||
typedef typename TransportModel::SimulatorData SimulatorData;
|
||||
typedef typename TransportModel::FIPDataType FIPDataType;
|
||||
|
||||
/// Construct the model. It will retain references to the
|
||||
/// arguments of this functions, and they are expected to
|
||||
@ -276,6 +277,11 @@ namespace Opm {
|
||||
return transport_solver_.model().getSimulatorData();
|
||||
}
|
||||
|
||||
/// Return fluid-in-place data (for output functionality)
|
||||
FIPDataType getFIPData() const {
|
||||
return transport_solver_.model().getFIPData();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
typedef NonlinearSolver<PressureModel> PressureSolver;
|
||||
|
@ -556,12 +556,11 @@ namespace Opm
|
||||
// output_writer_
|
||||
void setupOutputWriter()
|
||||
{
|
||||
const PhaseUsage pu = Opm::phaseUsageFromDeck(deck());
|
||||
output_writer_.reset(new OutputWriter(grid(),
|
||||
param_,
|
||||
eclState(),
|
||||
*eclIO_,
|
||||
pu));
|
||||
std::move( eclIO_ ),
|
||||
Opm::phaseUsageFromDeck(deck())) );
|
||||
}
|
||||
|
||||
// Run the simulator.
|
||||
|
@ -22,7 +22,8 @@
|
||||
#define OPM_SIMULATORFULLYIMPLICITBLACKOILEBOS_HEADER_INCLUDED
|
||||
|
||||
//#include <opm/autodiff/SimulatorBase.hpp>
|
||||
#include <opm/autodiff/SimulatorFullyImplicitBlackoilOutputEbos.hpp>
|
||||
//#include <opm/autodiff/SimulatorFullyImplicitBlackoilOutputEbos.hpp>
|
||||
#include <opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp>
|
||||
#include <opm/autodiff/IterationReport.hpp>
|
||||
#include <opm/autodiff/NonlinearSolver.hpp>
|
||||
#include <opm/autodiff/BlackoilModelEbos.hpp>
|
||||
@ -59,7 +60,7 @@ public:
|
||||
|
||||
typedef WellStateFullyImplicitBlackoilDense WellState;
|
||||
typedef BlackoilState ReservoirState;
|
||||
typedef BlackoilOutputWriterEbos OutputWriter;
|
||||
typedef BlackoilOutputWriter OutputWriter;
|
||||
typedef BlackoilModelEbos Model;
|
||||
typedef BlackoilModelParameters ModelParameters;
|
||||
typedef NonlinearSolver<Model> Solver;
|
||||
@ -98,7 +99,7 @@ public:
|
||||
const bool has_disgas,
|
||||
const bool has_vapoil,
|
||||
const EclipseState& /* eclState */,
|
||||
BlackoilOutputWriterEbos& output_writer,
|
||||
OutputWriter& output_writer,
|
||||
const std::unordered_set<std::string>& defunct_well_names)
|
||||
: ebosSimulator_(ebosSimulator),
|
||||
param_(param),
|
||||
|
@ -280,11 +280,11 @@ namespace Opm
|
||||
const int desiredReportStep);
|
||||
|
||||
|
||||
template <class Grid>
|
||||
void initFromRestartFile(const PhaseUsage& phaseusage,
|
||||
template <class Grid, class WellStateFullyImplicitBlackOel>
|
||||
void initFromRestartFile(const PhaseUsage& phaseUsage,
|
||||
const Grid& grid,
|
||||
SimulationDataContainer& simulatorstate,
|
||||
WellStateFullyImplicitBlackoil& wellstate);
|
||||
WellStateFullyImplicitBlackOel& wellstate);
|
||||
|
||||
bool isRestart() const;
|
||||
|
||||
@ -349,7 +349,7 @@ namespace Opm
|
||||
Opm::OpmLog::warning("Parallel Output Config",
|
||||
"Velocity output for matlab is broken in parallel.");
|
||||
}
|
||||
|
||||
|
||||
if( parallelOutput_->isIORank() ) {
|
||||
|
||||
if ( output_matlab )
|
||||
@ -395,13 +395,13 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
template <class Grid>
|
||||
template <class Grid, class WellStateFullyImplicitBlackOel>
|
||||
inline void
|
||||
BlackoilOutputWriter::
|
||||
initFromRestartFile( const PhaseUsage& phaseusage,
|
||||
initFromRestartFile( const PhaseUsage& phaseUsage,
|
||||
const Grid& grid,
|
||||
SimulationDataContainer& simulatorstate,
|
||||
WellStateFullyImplicitBlackoil& wellstate)
|
||||
WellStateFullyImplicitBlackOel& wellstate)
|
||||
{
|
||||
std::map<std::string, UnitSystem::measure> solution_keys {{"PRESSURE" , UnitSystem::measure::pressure},
|
||||
{"SWAT" , UnitSystem::measure::identity},
|
||||
@ -430,11 +430,11 @@ namespace Opm
|
||||
std::unordered_set<std::string>());
|
||||
|
||||
const Wells* wells = wellsmanager.c_wells();
|
||||
wellstate.resize(wells, simulatorstate); //Resize for restart step
|
||||
wellstate.resize(wells, simulatorstate, phaseUsage ); //Resize for restart step
|
||||
auto state = eclIO_->loadRestart(solution_keys);
|
||||
|
||||
solutionToSim( state.first, phaseusage, simulatorstate );
|
||||
wellsToState( state.second, phaseusage, wellstate );
|
||||
solutionToSim( state.first, phaseUsage, simulatorstate );
|
||||
wellsToState( state.second, phaseUsage, wellstate );
|
||||
}
|
||||
|
||||
|
||||
@ -443,50 +443,130 @@ 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;
|
||||
|
||||
template <class V>
|
||||
void addToSimData( SimulationDataContainer& simData,
|
||||
const std::string& name,
|
||||
const V& vec )
|
||||
{
|
||||
typedef std::vector< double > OutputVectorType;
|
||||
|
||||
// get data map
|
||||
auto& dataMap = simData.cellData();
|
||||
|
||||
// insert name,vector into data map
|
||||
dataMap.insert( std::make_pair( name, OutputVectorType( vec.data(), vec.data() + vec.size() ) ) );
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void addToSimData( SimulationDataContainer& simData,
|
||||
const std::string& name,
|
||||
const AutoDiffBlock<Scalar>& adb )
|
||||
{
|
||||
// forward value of ADB to output
|
||||
addToSimData( simData, name, adb.value() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an ADB into a standard vector by copy
|
||||
*/
|
||||
inline std::vector<double> adbToDoubleVector(const Opm::AutoDiffBlock<double>& adb) {
|
||||
return adbVToDoubleVector(adb.value());
|
||||
// this method basically converts all Eigen vectors to std::vectors
|
||||
// stored in a SimulationDataContainer
|
||||
template <class SimulatorData>
|
||||
SimulationDataContainer
|
||||
convertToSimulationDataContainer( const SimulatorData& sd,
|
||||
const SimulationDataContainer& localState,
|
||||
const Opm::PhaseUsage& phaseUsage )
|
||||
{
|
||||
// copy local state and then add missing data
|
||||
SimulationDataContainer simData( localState );
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_active = phaseUsage.phase_used[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_active = phaseUsage.phase_used[Opm::PhaseUsage::Vapour];
|
||||
|
||||
const int aqua_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Vapour];
|
||||
|
||||
// WATER
|
||||
if( aqua_active ) {
|
||||
addToSimData( simData, "1OVERBW", sd.rq[aqua_idx].b );
|
||||
addToSimData( simData, "WAT_DEN", sd.rq[aqua_idx].rho );
|
||||
addToSimData( simData, "WAT_VISC", sd.rq[aqua_idx].mu );
|
||||
addToSimData( simData, "WATKR", sd.rq[aqua_idx].kr );
|
||||
}
|
||||
|
||||
// OIL
|
||||
if( liquid_active ) {
|
||||
addToSimData( simData, "1OVERBO", sd.rq[liquid_idx].b );
|
||||
addToSimData( simData, "OIL_DEN", sd.rq[liquid_idx].rho );
|
||||
addToSimData( simData, "OIL_VISC", sd.rq[liquid_idx].mu );
|
||||
addToSimData( simData, "OILKR", sd.rq[liquid_idx].kr );
|
||||
}
|
||||
|
||||
// GAS
|
||||
if( vapour_active ) {
|
||||
addToSimData( simData, "1OVERBG", sd.rq[vapour_idx].b );
|
||||
addToSimData( simData, "GAS_DEN", sd.rq[vapour_idx].rho );
|
||||
addToSimData( simData, "GAS_VISC", sd.rq[vapour_idx].mu );
|
||||
addToSimData( simData, "GASKR", sd.rq[vapour_idx].kr );
|
||||
}
|
||||
|
||||
// RS and RV
|
||||
addToSimData( simData, "RSSAT", sd.rsSat );
|
||||
addToSimData( simData, "RVSAT", sd.rvSat );
|
||||
|
||||
return simData;
|
||||
}
|
||||
|
||||
// in case the data is already in a SimulationDataContainer no
|
||||
// conversion is needed
|
||||
inline
|
||||
SimulationDataContainer&&
|
||||
convertToSimulationDataContainer( SimulationDataContainer&& sd,
|
||||
const SimulationDataContainer& ,
|
||||
const Opm::PhaseUsage& )
|
||||
{
|
||||
return std::move( sd );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data requested in the restartConfig
|
||||
*/
|
||||
template<class Model>
|
||||
void getRestartData(data::Solution& output,
|
||||
const Opm::PhaseUsage& phaseUsage,
|
||||
const Model& physicalModel,
|
||||
SimulationDataContainer&& sd,
|
||||
const Opm::PhaseUsage& /* phaseUsage */,
|
||||
const Model& /* physicalModel */,
|
||||
const RestartConfig& restartConfig,
|
||||
const int reportStepNum,
|
||||
const bool log) {
|
||||
|
||||
const typename Model::SimulatorData& sd = physicalModel.getSimulatorData();
|
||||
const bool log)
|
||||
{
|
||||
//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);
|
||||
}
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_active = phaseUsage.phase_used[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_active = phaseUsage.phase_used[Opm::PhaseUsage::Vapour];
|
||||
|
||||
const int aqua_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_idx = phaseUsage.phase_pos[Opm::PhaseUsage::Vapour];
|
||||
const bool aqua_active = sd.hasCellData("1OVERBW");
|
||||
const bool liquid_active = sd.hasCellData("1OVERBO");
|
||||
const bool vapour_active = sd.hasCellData("1OVERBG");
|
||||
|
||||
assert( aqua_active == (sd.hasCellData("WAT_DEN") &&
|
||||
sd.hasCellData("WAT_VISC") &&
|
||||
sd.hasCellData("WATKR")
|
||||
)
|
||||
);
|
||||
assert( liquid_active == (sd.hasCellData("OIL_DEN") &&
|
||||
sd.hasCellData("OIL_VISC") &&
|
||||
sd.hasCellData("OILKR")
|
||||
)
|
||||
);
|
||||
assert( vapour_active == (sd.hasCellData("GAS_DEN") &&
|
||||
sd.hasCellData("GAS_VISC") &&
|
||||
sd.hasCellData("GASKR")
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Formation volume factors for water, oil, gas
|
||||
@ -495,21 +575,21 @@ namespace Opm
|
||||
rstKeywords["BW"] = 0;
|
||||
output.insert("1OVERBW",
|
||||
Opm::UnitSystem::measure::water_inverse_formation_volume_factor,
|
||||
adbToDoubleVector(sd.rq[aqua_idx].b),
|
||||
std::move( sd.getCellData("1OVERBW") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active && rstKeywords["BO"] > 0) {
|
||||
rstKeywords["BO"] = 0;
|
||||
output.insert("1OVERBO",
|
||||
Opm::UnitSystem::measure::oil_inverse_formation_volume_factor,
|
||||
adbToDoubleVector(sd.rq[liquid_idx].b),
|
||||
std::move( sd.getCellData("1OVERBO") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active && rstKeywords["BG"] > 0) {
|
||||
rstKeywords["BG"] = 0;
|
||||
output.insert("1OVERBG",
|
||||
Opm::UnitSystem::measure::gas_inverse_formation_volume_factor,
|
||||
adbToDoubleVector(sd.rq[vapour_idx].b),
|
||||
std::move( sd.getCellData("1OVERBG") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
|
||||
@ -521,19 +601,19 @@ namespace Opm
|
||||
if (aqua_active) {
|
||||
output.insert("WAT_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
adbToDoubleVector(sd.rq[aqua_idx].rho),
|
||||
std::move( sd.getCellData("WAT_DEN") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active) {
|
||||
output.insert("OIL_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
adbToDoubleVector(sd.rq[liquid_idx].rho),
|
||||
std::move( sd.getCellData("OIL_DEN") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active) {
|
||||
output.insert("GAS_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
adbToDoubleVector(sd.rq[vapour_idx].rho),
|
||||
std::move( sd.getCellData("GAS_DEN") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
}
|
||||
@ -546,19 +626,19 @@ namespace Opm
|
||||
if (aqua_active) {
|
||||
output.insert("WAT_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
adbToDoubleVector(sd.rq[aqua_idx].mu),
|
||||
std::move( sd.getCellData("WAT_VISC") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active) {
|
||||
output.insert("OIL_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
adbToDoubleVector(sd.rq[liquid_idx].mu),
|
||||
std::move( sd.getCellData("OIL_VISC") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active) {
|
||||
output.insert("GAS_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
adbToDoubleVector(sd.rq[vapour_idx].mu),
|
||||
std::move( sd.getCellData("GAS_VISC") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
}
|
||||
@ -567,11 +647,12 @@ namespace Opm
|
||||
* Relative permeabilities for water, oil, gas
|
||||
*/
|
||||
if (aqua_active && rstKeywords["KRW"] > 0) {
|
||||
if (sd.rq[aqua_idx].kr.size() > 0) {
|
||||
auto& krWater = sd.getCellData("WATKR");
|
||||
if (krWater.size() > 0) {
|
||||
rstKeywords["KRW"] = 0;
|
||||
output.insert("WATKR",
|
||||
output.insert("WATKR", // WAT_KR ???
|
||||
Opm::UnitSystem::measure::identity,
|
||||
adbToDoubleVector(sd.rq[aqua_idx].kr),
|
||||
std::move( krWater ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
else {
|
||||
@ -583,11 +664,12 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
if (liquid_active && rstKeywords["KRO"] > 0) {
|
||||
if (sd.rq[liquid_idx].kr.size() > 0) {
|
||||
auto& krOil = sd.getCellData("OILKR");
|
||||
if (krOil.size() > 0) {
|
||||
rstKeywords["KRO"] = 0;
|
||||
output.insert("OILKR",
|
||||
Opm::UnitSystem::measure::identity,
|
||||
adbToDoubleVector(sd.rq[liquid_idx].kr),
|
||||
std::move( krOil ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
else {
|
||||
@ -599,11 +681,12 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
if (vapour_active && rstKeywords["KRG"] > 0) {
|
||||
if (sd.rq[vapour_idx].kr.size() > 0) {
|
||||
auto& krGas = sd.getCellData("GASKR");
|
||||
if (krGas.size() > 0) {
|
||||
rstKeywords["KRG"] = 0;
|
||||
output.insert("GASKR",
|
||||
Opm::UnitSystem::measure::identity,
|
||||
adbToDoubleVector(sd.rq[vapour_idx].kr),
|
||||
std::move( krGas ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
else {
|
||||
@ -622,14 +705,14 @@ namespace Opm
|
||||
rstKeywords["RSSAT"] = 0;
|
||||
output.insert("RSSAT",
|
||||
Opm::UnitSystem::measure::gas_oil_ratio,
|
||||
adbToDoubleVector(sd.rsSat),
|
||||
std::move( sd.getCellData("RSSAT") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active && liquid_active && rstKeywords["RVSAT"] > 0) {
|
||||
rstKeywords["RVSAT"] = 0;
|
||||
output.insert("RVSAT",
|
||||
Opm::UnitSystem::measure::oil_gas_ratio,
|
||||
adbToDoubleVector(sd.rvSat),
|
||||
std::move( sd.getCellData("RVSAT") ),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
|
||||
@ -637,7 +720,7 @@ namespace Opm
|
||||
/**
|
||||
* Bubble point and dew point pressures
|
||||
*/
|
||||
if (log && vapour_active &&
|
||||
if (log && vapour_active &&
|
||||
liquid_active && rstKeywords["PBPD"] > 0) {
|
||||
rstKeywords["PBPD"] = 0;
|
||||
Opm::OpmLog::warning("Bubble/dew point pressure output unsupported",
|
||||
@ -683,9 +766,10 @@ namespace Opm
|
||||
const Model& physicalModel,
|
||||
const SummaryConfig& summaryConfig) {
|
||||
|
||||
typedef Opm::AutoDiffBlock<double> ADB;
|
||||
typedef typename Model::FIPDataType FIPDataType;
|
||||
typedef typename FIPDataType::VectorType VectorType;
|
||||
|
||||
const typename Model::SimulatorData& sd = physicalModel.getSimulatorData();
|
||||
FIPDataType fd = physicalModel.getFIPData();
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
@ -699,60 +783,79 @@ namespace Opm
|
||||
if (aqua_active && hasFRBKeyword(summaryConfig, "WIP")) {
|
||||
output.insert("WIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_AQUA]),
|
||||
std::move( fd.fip[ FIPDataType::FIP_AQUA ] ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
if (liquid_active) {
|
||||
const ADB::V& oipl = sd.fip[Model::SimulatorData::FIP_LIQUID];
|
||||
const ADB::V& oipg = vapour_active ? sd.fip[Model::SimulatorData::FIP_VAPORIZED_OIL] : ADB::V();
|
||||
const ADB::V& oip = vapour_active ? oipl + oipg : oipl;
|
||||
const VectorType& oipl = fd.fip[FIPDataType::FIP_LIQUID];
|
||||
VectorType oip ( oipl );
|
||||
const size_t size = oip.size();
|
||||
|
||||
const VectorType& oipg = vapour_active ? fd.fip[FIPDataType::FIP_VAPORIZED_OIL] : VectorType(size, 0.0);
|
||||
if( vapour_active )
|
||||
{
|
||||
// oip = oipl + oipg
|
||||
for( size_t i=0; i<size; ++ i ) {
|
||||
oip[ i ] += oipg[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
//Oil in place (liquid phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "OIPL")) {
|
||||
output.insert("OIPL",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(oipl),
|
||||
std::move( oipl ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
//Oil in place (gas phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "OIPG")) {
|
||||
output.insert("OIPG",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(oipg),
|
||||
std::move( oipg ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Oil in place (in liquid and gas phases)
|
||||
if (hasFRBKeyword(summaryConfig, "OIP")) {
|
||||
output.insert("OIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(oip),
|
||||
std::move( oip ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
}
|
||||
if (vapour_active) {
|
||||
const ADB::V& gipg = sd.fip[Model::SimulatorData::FIP_VAPOUR];
|
||||
const ADB::V& gipl = liquid_active ? sd.fip[Model::SimulatorData::FIP_DISSOLVED_GAS] : ADB::V();
|
||||
const ADB::V& gip = liquid_active ? gipg + gipl : gipg;
|
||||
const VectorType& gipg = fd.fip[ FIPDataType::FIP_VAPOUR];
|
||||
VectorType gip( gipg );
|
||||
const size_t size = gip.size();
|
||||
|
||||
const VectorType& gipl = liquid_active ? fd.fip[ FIPDataType::FIP_DISSOLVED_GAS ] : VectorType(size,0.0);
|
||||
if( liquid_active )
|
||||
{
|
||||
// gip = gipg + gipl
|
||||
for( size_t i=0; i<size; ++ i ) {
|
||||
gip[ i ] += gipl[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
// Gas in place (gas phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "GIPG")) {
|
||||
output.insert("GIPG",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(gipg),
|
||||
std::move( gipg ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
|
||||
// Gas in place (liquid phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "GIPL")) {
|
||||
output.insert("GIPL",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(gipl),
|
||||
std::move( gipl ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Gas in place (in both liquid and gas phases)
|
||||
if (hasFRBKeyword(summaryConfig, "GIP")) {
|
||||
output.insert("GIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(gip),
|
||||
std::move( gip ),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
}
|
||||
@ -760,14 +863,14 @@ namespace Opm
|
||||
if (hasFRBKeyword(summaryConfig, "RPV")) {
|
||||
output.insert("RPV",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_PV]),
|
||||
std::move( fd.fip[FIPDataType::FIP_PV]),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Pressure averaged value (hydrocarbon pore volume weighted)
|
||||
if (summaryConfig.hasKeyword("FPRH") || summaryConfig.hasKeyword("RPRH")) {
|
||||
output.insert("PRH",
|
||||
Opm::UnitSystem::measure::pressure,
|
||||
adbVToDoubleVector(sd.fip[Model::SimulatorData::FIP_WEIGHTED_PRESSURE]),
|
||||
std::move(fd.fip[FIPDataType::FIP_WEIGHTED_PRESSURE]),
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
}
|
||||
@ -791,15 +894,26 @@ namespace Opm
|
||||
const SummaryConfig& summaryConfig = eclipseState_.getSummaryConfig();
|
||||
const int reportStepNum = timer.reportStepNum();
|
||||
bool logMessages = output_ && parallelOutput_->isIORank();
|
||||
|
||||
|
||||
if( output_ )
|
||||
{
|
||||
localCellData = simToSolution(localState, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...);
|
||||
detail::getRestartData( localCellData, phaseUsage_, physicalModel,
|
||||
restartConfig, reportStepNum, logMessages );
|
||||
{
|
||||
// get all data that need to be included in output from the model
|
||||
// for flow_legacy and polymer this is a struct holding the data
|
||||
// while for flow_ebos a SimulationDataContainer is returned
|
||||
// this is addressed in the above specialized methods
|
||||
SimulationDataContainer sd =
|
||||
detail::convertToSimulationDataContainer( physicalModel.getSimulatorData(), localState, phaseUsage_ );
|
||||
|
||||
localCellData = simToSolution( sd, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...);
|
||||
|
||||
detail::getRestartData( localCellData, std::move(sd), phaseUsage_, physicalModel,
|
||||
restartConfig, reportStepNum, logMessages );
|
||||
// sd will be invalid after getRestartData has been called
|
||||
}
|
||||
detail::getSummaryData( localCellData, phaseUsage_, physicalModel, summaryConfig );
|
||||
}
|
||||
|
||||
|
||||
writeTimeStepWithCellProperties(timer, localState, localCellData, localWellState, substep);
|
||||
}
|
||||
}
|
||||
|
@ -1,307 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2014 SINTEF ICT, Applied Mathematics.
|
||||
Copyright (c) 2015-2016 IRIS AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "SimulatorFullyImplicitBlackoilOutputEbos.hpp"
|
||||
|
||||
#include <opm/common/data/SimulationDataContainer.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/utility/DataMap.hpp>
|
||||
#include <opm/autodiff/Compat.hpp>
|
||||
#include <opm/simulators/vtk/writeVtkData.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/core/utility/miscUtilities.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <opm/autodiff/GridHelpers.hpp>
|
||||
#include <opm/autodiff/BackupRestore.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
//For OutputWriterHelper
|
||||
#include <map>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
|
||||
#ifdef HAVE_OPM_GRID
|
||||
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
||||
#include <dune/common/version.hh>
|
||||
#include <dune/grid/io/file/vtk/vtkwriter.hh>
|
||||
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
|
||||
#endif
|
||||
namespace Opm
|
||||
{
|
||||
namespace detail {
|
||||
|
||||
struct WriterCallEbos : public ThreadHandle :: ObjectInterface
|
||||
{
|
||||
BlackoilOutputWriterEbos& writer_;
|
||||
std::unique_ptr< SimulatorTimerInterface > timer_;
|
||||
const SimulationDataContainer state_;
|
||||
const WellStateFullyImplicitBlackoil wellState_;
|
||||
data::Solution simProps_;
|
||||
const bool substep_;
|
||||
|
||||
explicit WriterCallEbos( BlackoilOutputWriterEbos& writer,
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& state,
|
||||
const WellStateFullyImplicitBlackoil& wellState,
|
||||
const data::Solution& simProps,
|
||||
bool substep )
|
||||
: writer_( writer ),
|
||||
timer_( timer.clone() ),
|
||||
state_( state ),
|
||||
wellState_( wellState ),
|
||||
simProps_( simProps ),
|
||||
substep_( substep )
|
||||
{
|
||||
}
|
||||
|
||||
// callback to writer's serial writeTimeStep method
|
||||
void run ()
|
||||
{
|
||||
// write data
|
||||
writer_.writeTimeStepSerial( *timer_, state_, wellState_, simProps_, substep_ );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
BlackoilOutputWriterEbos::
|
||||
writeTimeStepWithoutCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& localState,
|
||||
const WellStateFullyImplicitBlackoil& localWellState,
|
||||
bool substep)
|
||||
{
|
||||
data::Solution noCellProperties;
|
||||
writeTimeStepWithCellProperties(timer, localState, localWellState, noCellProperties, substep);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
BlackoilOutputWriterEbos::
|
||||
writeTimeStepWithCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& localState,
|
||||
const WellStateFullyImplicitBlackoil& localWellState,
|
||||
const data::Solution& sol,
|
||||
bool substep)
|
||||
{
|
||||
bool isIORank = output_ ;
|
||||
if( parallelOutput_ && parallelOutput_->isParallel() )
|
||||
{
|
||||
// If this is not the initial write and no substep, then the well
|
||||
// state used in the computation is actually the one of the last
|
||||
// step. We need that well state for the gathering. Otherwise
|
||||
// It an exception with a message like "global state does not
|
||||
// contain well ..." might be thrown.
|
||||
int wellStateStepNumber = ( ! substep && timer.reportStepNum() > 0) ?
|
||||
(timer.reportStepNum() - 1) : timer.reportStepNum();
|
||||
// collect all solutions to I/O rank
|
||||
isIORank = parallelOutput_->collectToIORank( localState, localWellState, sol, wellStateStepNumber );
|
||||
}
|
||||
|
||||
const SimulationDataContainer& state = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalReservoirState() : localState;
|
||||
const WellStateFullyImplicitBlackoil& wellState = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalWellState() : localWellState;
|
||||
|
||||
// serial output is only done on I/O rank
|
||||
int err = 0;
|
||||
std::string emsg;
|
||||
if( isIORank )
|
||||
{
|
||||
if( asyncOutput_ ) {
|
||||
// dispatch the write call to the extra thread
|
||||
asyncOutput_->dispatch( detail::WriterCallEbos( *this, timer, state, wellState, sol, substep ) );
|
||||
}
|
||||
else {
|
||||
// just write the data to disk
|
||||
try {
|
||||
writeTimeStepSerial( timer, state, wellState, sol, substep );
|
||||
} catch (std::runtime_error& msg) {
|
||||
err = 1;
|
||||
emsg = msg.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!asyncOutput_) {
|
||||
#if HAVE_MPI
|
||||
MPI_Bcast(&err, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
#endif
|
||||
if (err) {
|
||||
if (isIORank) {
|
||||
throw std::runtime_error(emsg);
|
||||
} else {
|
||||
throw std::runtime_error("I/O process encountered problems.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
BlackoilOutputWriterEbos::
|
||||
writeTimeStepSerial(const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& state,
|
||||
const WellStateFullyImplicitBlackoil& wellState,
|
||||
const data::Solution& sol,
|
||||
bool substep)
|
||||
{
|
||||
// ECL output
|
||||
if (output())
|
||||
{
|
||||
const auto& initConfig = eclipseState_.getInitConfig();
|
||||
if (initConfig.restartRequested() && ((initConfig.getRestartStep()) == (timer.currentStepNum()))) {
|
||||
std::cout << "Skipping restart write in start of step " << timer.currentStepNum() << std::endl;
|
||||
} else {
|
||||
data::Solution combined_sol = simToSolution(state, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...)
|
||||
combined_sol.insert(sol.begin(), sol.end()); // ... insert "extra" data (KR, VISC, ...)
|
||||
eclIO_.writeTimeStep(timer.reportStepNum(),
|
||||
substep,
|
||||
timer.simulationTimeElapsed(),
|
||||
combined_sol,
|
||||
wellState.report(phaseUsage_));
|
||||
}
|
||||
}
|
||||
|
||||
// write backup file
|
||||
if( backupfile_.is_open() )
|
||||
{
|
||||
int reportStep = timer.reportStepNum();
|
||||
int currentTimeStep = timer.currentStepNum();
|
||||
if( (reportStep == currentTimeStep || // true for SimulatorTimer
|
||||
currentTimeStep == 0 || // true for AdaptiveSimulatorTimer at reportStep
|
||||
timer.done() ) // true for AdaptiveSimulatorTimer at reportStep
|
||||
&& lastBackupReportStep_ != reportStep ) // only backup report step once
|
||||
{
|
||||
// store report step
|
||||
lastBackupReportStep_ = reportStep;
|
||||
// write resport step number
|
||||
backupfile_.write( (const char *) &reportStep, sizeof(int) );
|
||||
|
||||
try {
|
||||
backupfile_ << state;
|
||||
|
||||
const WellStateFullyImplicitBlackoil& boWellState = static_cast< const WellStateFullyImplicitBlackoil& > (wellState);
|
||||
backupfile_ << boWellState;
|
||||
}
|
||||
catch ( const std::bad_cast& e )
|
||||
{
|
||||
}
|
||||
|
||||
backupfile_ << std::flush;
|
||||
}
|
||||
} // end backup
|
||||
}
|
||||
|
||||
void
|
||||
BlackoilOutputWriterEbos::
|
||||
restore(SimulatorTimerInterface& timer,
|
||||
BlackoilState& state,
|
||||
WellStateFullyImplicitBlackoilDense& wellState,
|
||||
const std::string& filename,
|
||||
const int desiredResportStep )
|
||||
{
|
||||
std::ifstream restorefile( filename.c_str() );
|
||||
if( restorefile )
|
||||
{
|
||||
std::cout << "============================================================================"<<std::endl;
|
||||
std::cout << "Restoring from ";
|
||||
if( desiredResportStep < 0 ) {
|
||||
std::cout << "last";
|
||||
}
|
||||
else {
|
||||
std::cout << desiredResportStep;
|
||||
}
|
||||
std::cout << " report step! filename = " << filename << std::endl << std::endl;
|
||||
|
||||
int reportStep;
|
||||
restorefile.read( (char *) &reportStep, sizeof(int) );
|
||||
|
||||
const int readReportStep = (desiredResportStep < 0) ?
|
||||
std::numeric_limits<int>::max() : desiredResportStep;
|
||||
|
||||
while( reportStep <= readReportStep && ! timer.done() && restorefile )
|
||||
{
|
||||
restorefile >> state;
|
||||
restorefile >> wellState;
|
||||
|
||||
// No per cell data is written for restore steps, but will be
|
||||
// for subsequent steps, when we have started simulating
|
||||
writeTimeStepWithoutCellProperties( timer, state, wellState );
|
||||
|
||||
// some output
|
||||
std::cout << "Restored step " << timer.reportStepNum() << " at day "
|
||||
<< unit::convert::to(timer.simulationTimeElapsed(),unit::day) << std::endl;
|
||||
|
||||
if( readReportStep == reportStep ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// if the stream is not valid anymore we just use the last state read
|
||||
if( ! restorefile ) {
|
||||
std::cerr << "Reached EOF, using last state read!" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// try to read next report step
|
||||
restorefile.read( (char *) &reportStep, sizeof(int) );
|
||||
|
||||
// if read failed, exit loop
|
||||
if( ! restorefile ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// next step
|
||||
timer.advance();
|
||||
|
||||
if( timer.reportStepNum() != reportStep ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Warning: Couldn't open restore file '" << filename << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BlackoilOutputWriterEbos::isRestart() const {
|
||||
const auto& initconfig = eclipseState_.getInitConfig();
|
||||
return initconfig.restartRequested();
|
||||
}
|
||||
|
||||
|
||||
bool BlackoilOutputWriterEbos::requireFIPNUM() const {
|
||||
return eclipseState_.getSummaryConfig().requireFIPNUM();
|
||||
}
|
||||
}
|
@ -1,749 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2014 SINTEF ICT, Applied Mathematics.
|
||||
Copyright (c) 2015 IRIS AS
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUTEBOS_HEADER_INCLUDED
|
||||
#define OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUTEBOS_HEADER_INCLUDED
|
||||
#include <opm/core/grid.h>
|
||||
#include <opm/simulators/timestepping/SimulatorTimerInterface.hpp>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/utility/DataMap.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
#include <opm/core/utility/miscUtilities.hpp>
|
||||
#include <opm/core/utility/parameters/ParameterGroup.hpp>
|
||||
#include <opm/core/wells/DynamicListEconLimited.hpp>
|
||||
|
||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||
|
||||
#include <opm/autodiff/Compat.hpp>
|
||||
#include <opm/autodiff/GridHelpers.hpp>
|
||||
#include <opm/autodiff/ParallelDebugOutput.hpp>
|
||||
|
||||
#include <opm/autodiff/WellStateFullyImplicitBlackoilDense.hpp>
|
||||
#include <opm/autodiff/ThreadHandle.hpp>
|
||||
#include <opm/autodiff/AutoDiffBlock.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#ifdef HAVE_OPM_GRID
|
||||
#include <dune/grid/CpGrid.hpp>
|
||||
#endif
|
||||
namespace Opm
|
||||
{
|
||||
class BlackoilState;
|
||||
|
||||
/** \brief Wrapper class for VTK, Matlab, and ECL output. */
|
||||
class BlackoilOutputWriterEbos
|
||||
{
|
||||
|
||||
public:
|
||||
// constructor creating different sub writers
|
||||
template <class Grid>
|
||||
BlackoilOutputWriterEbos(const Grid& grid,
|
||||
const parameter::ParameterGroup& param,
|
||||
const EclipseState& eclipseState,
|
||||
EclipseIO& eclIO,
|
||||
const Opm::PhaseUsage &phaseUsage);
|
||||
|
||||
/*!
|
||||
* \brief Write a blackoil reservoir state to disk for later inspection with
|
||||
* visualization tools like ResInsight. This function will extract the
|
||||
* requested output cell properties specified by the RPTRST keyword
|
||||
* and write these to file.
|
||||
*/
|
||||
template<class Model>
|
||||
void writeTimeStep(const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
||||
const Model& physicalModel,
|
||||
bool substep = false);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Write a blackoil reservoir state to disk for later inspection with
|
||||
* visualization tools like ResInsight. This function will write all
|
||||
* CellData in simProps to the file as well.
|
||||
*/
|
||||
void writeTimeStepWithCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
||||
const data::Solution& sol,
|
||||
bool substep = false);
|
||||
|
||||
/*!
|
||||
* \brief Write a blackoil reservoir state to disk for later inspection with
|
||||
* visualization tools like ResInsight. This function will not write
|
||||
* any cell properties (e.g., those requested by RPTRST keyword)
|
||||
*/
|
||||
void writeTimeStepWithoutCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
||||
bool substep = false);
|
||||
|
||||
/*!
|
||||
* \brief Write a blackoil reservoir state to disk for later inspection withS
|
||||
* visualization tools like ResInsight. This is the function which does
|
||||
* the actual write to file.
|
||||
*/
|
||||
void writeTimeStepSerial(const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
||||
const data::Solution& simProps,
|
||||
bool substep);
|
||||
|
||||
/** \brief return output directory */
|
||||
const std::string& outputDirectory() const { return outputDir_; }
|
||||
|
||||
/** \brief return true if output is enabled */
|
||||
bool output () const { return output_; }
|
||||
|
||||
/** \brief Whether this process does write to disk */
|
||||
bool isIORank () const
|
||||
{
|
||||
return parallelOutput_->isIORank();
|
||||
}
|
||||
|
||||
void restore(SimulatorTimerInterface& timer,
|
||||
BlackoilState& state,
|
||||
WellStateFullyImplicitBlackoilDense& wellState,
|
||||
const std::string& filename,
|
||||
const int desiredReportStep);
|
||||
|
||||
|
||||
template <class Grid>
|
||||
void initFromRestartFile(const PhaseUsage& phaseusage,
|
||||
const Grid& grid,
|
||||
SimulationDataContainer& simulatorstate,
|
||||
WellStateFullyImplicitBlackoilDense& wellstate);
|
||||
|
||||
bool isRestart() const;
|
||||
|
||||
bool requireFIPNUM() const;
|
||||
|
||||
protected:
|
||||
const bool output_;
|
||||
std::unique_ptr< ParallelDebugOutputInterface > parallelOutput_;
|
||||
|
||||
// Parameters for output.
|
||||
const std::string outputDir_;
|
||||
const int output_interval_;
|
||||
|
||||
int lastBackupReportStep_;
|
||||
|
||||
std::ofstream backupfile_;
|
||||
Opm::PhaseUsage phaseUsage_;
|
||||
EclipseIO& eclIO_;
|
||||
const EclipseState& eclipseState_;
|
||||
|
||||
std::unique_ptr< ThreadHandle > asyncOutput_;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
template <class Grid>
|
||||
inline
|
||||
BlackoilOutputWriterEbos::
|
||||
BlackoilOutputWriterEbos(const Grid& grid,
|
||||
const parameter::ParameterGroup& param,
|
||||
const Opm::EclipseState& eclipseState,
|
||||
EclipseIO& eclIO,
|
||||
const Opm::PhaseUsage &phaseUsage)
|
||||
: output_( param.getDefault("output", true) ),
|
||||
parallelOutput_( output_ ? new ParallelDebugOutput< Grid >( grid, eclipseState, phaseUsage.num_phases, phaseUsage ) : 0 ),
|
||||
outputDir_( output_ ? param.getDefault("output_dir", std::string("output")) : "." ),
|
||||
output_interval_( output_ ? param.getDefault("output_interval", 1): 0 ),
|
||||
lastBackupReportStep_( -1 ),
|
||||
phaseUsage_( phaseUsage ),
|
||||
eclIO_(eclIO),
|
||||
eclipseState_(eclipseState),
|
||||
asyncOutput_()
|
||||
{
|
||||
// For output.
|
||||
if (output_ && parallelOutput_->isIORank() ) {
|
||||
// Ensure that output dir exists
|
||||
boost::filesystem::path fpath(outputDir_);
|
||||
try {
|
||||
create_directories(fpath);
|
||||
}
|
||||
catch (...) {
|
||||
OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath);
|
||||
}
|
||||
|
||||
// create output thread if enabled and rank is I/O rank
|
||||
// async output is enabled by default if pthread are enabled
|
||||
#if HAVE_PTHREAD
|
||||
const bool asyncOutputDefault = false;
|
||||
#else
|
||||
const bool asyncOutputDefault = false;
|
||||
#endif
|
||||
if( param.getDefault("async_output", asyncOutputDefault ) )
|
||||
{
|
||||
#if HAVE_PTHREAD
|
||||
asyncOutput_.reset( new ThreadHandle() );
|
||||
#else
|
||||
OPM_THROW(std::runtime_error,"Pthreads were not found, cannot enable async_output");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string backupfilename = param.getDefault("backupfile", std::string("") );
|
||||
if( ! backupfilename.empty() )
|
||||
{
|
||||
backupfile_.open( backupfilename.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Grid>
|
||||
inline void
|
||||
BlackoilOutputWriterEbos::
|
||||
initFromRestartFile( const PhaseUsage& phaseusage,
|
||||
const Grid& grid,
|
||||
SimulationDataContainer& simulatorstate,
|
||||
WellStateFullyImplicitBlackoilDense& wellstate)
|
||||
{
|
||||
std::map<std::string, UnitSystem::measure> solution_keys {{"PRESSURE" , UnitSystem::measure::pressure},
|
||||
{"SWAT" , UnitSystem::measure::identity},
|
||||
{"SGAS" , UnitSystem::measure::identity},
|
||||
{"TEMP" , UnitSystem::measure::temperature},
|
||||
{"RS" , UnitSystem::measure::gas_oil_ratio},
|
||||
{"RV" , UnitSystem::measure::oil_gas_ratio}};
|
||||
|
||||
// gives a dummy dynamic_list_econ_limited
|
||||
DynamicListEconLimited dummy_list_econ_limited;
|
||||
WellsManager wellsmanager(eclipseState_,
|
||||
eclipseState_.getInitConfig().getRestartStep(),
|
||||
Opm::UgGridHelpers::numCells(grid),
|
||||
Opm::UgGridHelpers::globalCell(grid),
|
||||
Opm::UgGridHelpers::cartDims(grid),
|
||||
Opm::UgGridHelpers::dimensions(grid),
|
||||
Opm::UgGridHelpers::cell2Faces(grid),
|
||||
Opm::UgGridHelpers::beginFaceCentroids(grid),
|
||||
dummy_list_econ_limited
|
||||
// We need to pass the optionaly arguments
|
||||
// as we get the following error otherwise
|
||||
// with c++ (Debian 4.9.2-10) 4.9.2 and -std=c++11
|
||||
// converting to ‘const std::unordered_set<std::basic_string<char> >’ from initializer list would use explicit constructo
|
||||
, false,
|
||||
std::vector<double>(),
|
||||
std::unordered_set<std::string>());
|
||||
|
||||
const Wells* wells = wellsmanager.c_wells();
|
||||
wellstate.resize(wells, simulatorstate, phaseusage ); //Resize for restart step
|
||||
auto state = eclIO_.loadRestart(solution_keys);
|
||||
solutionToSim( state.first, phaseusage, simulatorstate );
|
||||
wellsToState( state.second, phaseusage, wellstate );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace detail {
|
||||
template<class Model>
|
||||
void getOutputDataEbos(data::Solution& output,
|
||||
const Opm::PhaseUsage& phaseUsage,
|
||||
const Model& model,
|
||||
const RestartConfig& restartConfig,
|
||||
const int reportStepNum,
|
||||
const bool log)
|
||||
{
|
||||
typedef typename Model::FluidSystem FluidSystem;
|
||||
|
||||
//Get the value of each of the keys
|
||||
std::map<std::string, int> outKeywords = restartConfig.getRestartKeywords(reportStepNum);
|
||||
for (auto& keyValue : outKeywords) {
|
||||
keyValue.second = restartConfig.getKeyword(keyValue.first, reportStepNum);
|
||||
}
|
||||
|
||||
const auto& ebosModel = model.ebosSimulator().model();
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_active = phaseUsage.phase_used[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_active = phaseUsage.phase_used[Opm::PhaseUsage::Vapour];
|
||||
|
||||
// extract everything which can possibly be written to disk
|
||||
int numCells = ebosModel.numGridDof();
|
||||
|
||||
std::vector<double> pressureOil(numCells);
|
||||
std::vector<double> temperature(numCells);
|
||||
|
||||
std::vector<double> satWater(numCells);
|
||||
std::vector<double> satGas(numCells);
|
||||
|
||||
std::vector<double> bWater(numCells);
|
||||
std::vector<double> bOil(numCells);
|
||||
std::vector<double> bGas(numCells);
|
||||
|
||||
std::vector<double> rhoWater(numCells);
|
||||
std::vector<double> rhoOil(numCells);
|
||||
std::vector<double> rhoGas(numCells);
|
||||
|
||||
std::vector<double> muWater(numCells);
|
||||
std::vector<double> muOil(numCells);
|
||||
std::vector<double> muGas(numCells);
|
||||
|
||||
std::vector<double> krWater(numCells);
|
||||
std::vector<double> krOil(numCells);
|
||||
std::vector<double> krGas(numCells);
|
||||
|
||||
std::vector<double> Rs(numCells);
|
||||
std::vector<double> Rv(numCells);
|
||||
std::vector<double> RsSat(numCells);
|
||||
std::vector<double> RvSat(numCells);
|
||||
|
||||
for (int cellIdx = 0; cellIdx < numCells; ++cellIdx) {
|
||||
const auto& intQuants = *ebosModel.cachedIntensiveQuantities(cellIdx, /*timeIdx=*/0);
|
||||
const auto& fs = intQuants.fluidState();
|
||||
|
||||
pressureOil[cellIdx] = fs.pressure(FluidSystem::oilPhaseIdx).value();
|
||||
|
||||
temperature[cellIdx] = fs.temperature(FluidSystem::oilPhaseIdx).value();
|
||||
|
||||
if (aqua_active) {
|
||||
satWater[cellIdx] = fs.saturation(FluidSystem::waterPhaseIdx).value();
|
||||
bWater[cellIdx] = fs.invB(FluidSystem::waterPhaseIdx).value();
|
||||
rhoWater[cellIdx] = fs.density(FluidSystem::waterPhaseIdx).value();
|
||||
muWater[cellIdx] = fs.viscosity(FluidSystem::waterPhaseIdx).value();
|
||||
krWater[cellIdx] = intQuants.relativePermeability(FluidSystem::waterPhaseIdx).value();
|
||||
}
|
||||
if (vapour_active) {
|
||||
satGas[cellIdx] = fs.saturation(FluidSystem::gasPhaseIdx).value();
|
||||
bGas[cellIdx] = fs.invB(FluidSystem::gasPhaseIdx).value();
|
||||
rhoGas[cellIdx] = fs.density(FluidSystem::gasPhaseIdx).value();
|
||||
muGas[cellIdx] = fs.viscosity(FluidSystem::gasPhaseIdx).value();
|
||||
krGas[cellIdx] = intQuants.relativePermeability(FluidSystem::gasPhaseIdx).value();
|
||||
Rs[cellIdx] = fs.Rs().value();
|
||||
Rv[cellIdx] = fs.Rv().value();
|
||||
RsSat[cellIdx] = FluidSystem::saturatedDissolutionFactor(fs,
|
||||
FluidSystem::oilPhaseIdx,
|
||||
intQuants.pvtRegionIndex(),
|
||||
/*maxOilSaturation=*/1.0).value();
|
||||
RvSat[cellIdx] = FluidSystem::saturatedDissolutionFactor(fs,
|
||||
FluidSystem::gasPhaseIdx,
|
||||
intQuants.pvtRegionIndex(),
|
||||
/*maxOilSaturation=*/1.0).value();
|
||||
}
|
||||
|
||||
// oil is always active
|
||||
bOil[cellIdx] = fs.invB(FluidSystem::oilPhaseIdx).value();
|
||||
rhoOil[cellIdx] = fs.density(FluidSystem::oilPhaseIdx).value();
|
||||
muOil[cellIdx] = fs.viscosity(FluidSystem::oilPhaseIdx).value();
|
||||
krOil[cellIdx] = intQuants.relativePermeability(FluidSystem::oilPhaseIdx).value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Oil Pressures
|
||||
*/
|
||||
outKeywords["PRESSURE"] = 0;
|
||||
output.insert("PRESSURE",
|
||||
UnitSystem::measure::pressure,
|
||||
std::move(pressureOil),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
|
||||
/**
|
||||
* Temperatures
|
||||
*/
|
||||
outKeywords["TEMP"] = 0;
|
||||
output.insert("TEMP",
|
||||
UnitSystem::measure::temperature,
|
||||
std::move(temperature),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
|
||||
/**
|
||||
* Water and gas saturation.
|
||||
*/
|
||||
outKeywords["SWAT"] = 0;
|
||||
outKeywords["SGAS"] = 0;
|
||||
output.insert("SWAT",
|
||||
UnitSystem::measure::identity,
|
||||
std::move(satWater),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
output.insert("SGAS",
|
||||
UnitSystem::measure::identity,
|
||||
std::move(satGas),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
|
||||
/**
|
||||
* the dissolution factors
|
||||
*/
|
||||
outKeywords["RS"] = 0;
|
||||
outKeywords["RV"] = 0;
|
||||
output.insert("RS",
|
||||
UnitSystem::measure::gas_oil_ratio,
|
||||
std::move(Rs),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
output.insert("RV",
|
||||
UnitSystem::measure::oil_gas_ratio,
|
||||
std::move(Rv),
|
||||
data::TargetType::RESTART_SOLUTION);
|
||||
|
||||
/**
|
||||
* Formation volume factors for water, oil, gas
|
||||
*/
|
||||
if (aqua_active && outKeywords["BW"] > 0) {
|
||||
outKeywords["BW"] = 0;
|
||||
output.insert("BW",
|
||||
Opm::UnitSystem::measure::water_inverse_formation_volume_factor,
|
||||
std::move(bWater),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
|
||||
}
|
||||
if (liquid_active && outKeywords["BO"] > 0) {
|
||||
outKeywords["BO"] = 0;
|
||||
output.insert("BO",
|
||||
Opm::UnitSystem::measure::oil_inverse_formation_volume_factor,
|
||||
std::move(bOil),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active && outKeywords["BG"] > 0) {
|
||||
outKeywords["BG"] = 0;
|
||||
output.insert("BG",
|
||||
Opm::UnitSystem::measure::gas_inverse_formation_volume_factor,
|
||||
std::move(bGas),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Densities for water, oil gas
|
||||
*/
|
||||
if (outKeywords["DEN"] > 0) {
|
||||
outKeywords["DEN"] = 0;
|
||||
if (aqua_active) {
|
||||
output.insert("WAT_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
std::move(rhoWater),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active) {
|
||||
output.insert("OIL_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
std::move(rhoOil),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active) {
|
||||
output.insert("GAS_DEN",
|
||||
Opm::UnitSystem::measure::density,
|
||||
std::move(rhoGas),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Viscosities for water, oil gas
|
||||
*/
|
||||
if (outKeywords["VISC"] > 0) {
|
||||
outKeywords["VISC"] = 0;
|
||||
if (aqua_active) {
|
||||
output.insert("WAT_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
std::move(muWater),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active) {
|
||||
output.insert("OIL_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
std::move(muOil),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active) {
|
||||
output.insert("GAS_VISC",
|
||||
Opm::UnitSystem::measure::viscosity,
|
||||
std::move(muGas),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Relative permeabilities for water, oil, gas
|
||||
*/
|
||||
if (aqua_active && outKeywords["KRW"] > 0) {
|
||||
outKeywords["KRW"] = 0;
|
||||
output.insert("WATKR",
|
||||
Opm::UnitSystem::measure::identity,
|
||||
std::move(krWater),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (liquid_active && outKeywords["KRO"] > 0) {
|
||||
outKeywords["KRO"] = 0;
|
||||
output.insert("OILKR",
|
||||
Opm::UnitSystem::measure::identity,
|
||||
std::move(krOil),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active && outKeywords["KRG"] > 0) {
|
||||
outKeywords["KRG"] = 0;
|
||||
output.insert("GASKR",
|
||||
Opm::UnitSystem::measure::identity,
|
||||
std::move(krGas),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vaporized and dissolved gas/oil ratio
|
||||
*/
|
||||
if (vapour_active && liquid_active && outKeywords["RSSAT"] > 0) {
|
||||
outKeywords["RSSAT"] = 0;
|
||||
output.insert("RSSAT",
|
||||
Opm::UnitSystem::measure::gas_oil_ratio,
|
||||
std::move(RsSat),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
if (vapour_active && liquid_active && outKeywords["RVSAT"] > 0) {
|
||||
outKeywords["RVSAT"] = 0;
|
||||
output.insert("RVSAT",
|
||||
Opm::UnitSystem::measure::oil_gas_ratio,
|
||||
std::move(RvSat),
|
||||
data::TargetType::RESTART_AUXILLARY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bubble point and dew point pressures
|
||||
*/
|
||||
if (log && vapour_active &&
|
||||
liquid_active && outKeywords["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 (keyValue.second > 0) {
|
||||
std::string logstring = "Keyword '";
|
||||
logstring.append(keyValue.first);
|
||||
logstring.append("' is unhandled for output to file.");
|
||||
Opm::OpmLog::warning("Unhandled output keyword", logstring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the data as asked for in the summaryConfig
|
||||
*/
|
||||
template<class Model>
|
||||
void getSummaryData(data::Solution& output,
|
||||
const Opm::PhaseUsage& phaseUsage,
|
||||
const Model& physicalModel,
|
||||
const SummaryConfig& summaryConfig) {
|
||||
|
||||
const typename Model::FIPData& fip = physicalModel.getFIPData();
|
||||
|
||||
//Get shorthands for water, oil, gas
|
||||
const int aqua_active = phaseUsage.phase_used[Opm::PhaseUsage::Aqua];
|
||||
const int liquid_active = phaseUsage.phase_used[Opm::PhaseUsage::Liquid];
|
||||
const int vapour_active = phaseUsage.phase_used[Opm::PhaseUsage::Vapour];
|
||||
|
||||
/**
|
||||
* Now process all of the summary config files
|
||||
*/
|
||||
// Water in place
|
||||
if (aqua_active && hasFRBKeyword(summaryConfig, "WIP")) {
|
||||
output.insert("WIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
fip.fip[Model::FIPData::FIP_AQUA],
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
if (liquid_active) {
|
||||
const std::vector<double>& oipl = fip.fip[Model::FIPData::FIP_LIQUID];
|
||||
const int size = oipl.size();
|
||||
|
||||
const std::vector<double>& oipg = vapour_active ? fip.fip[Model::FIPData::FIP_VAPORIZED_OIL] : std::vector<double>(size,0.0);
|
||||
std::vector<double> oip = oipl;
|
||||
if (vapour_active) {
|
||||
std::transform(oip.begin(), oip.end(), oipg.begin(), oip.begin(), std::plus<double>());
|
||||
}
|
||||
|
||||
//Oil in place (liquid phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "OIPL")) {
|
||||
output.insert("OIPL",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
oipl,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
|
||||
//Oil in place (gas phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "OIPG")) {
|
||||
output.insert("OIPG",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
oipg,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Oil in place (in liquid and gas phases)
|
||||
if (hasFRBKeyword(summaryConfig, "OIP")) {
|
||||
output.insert("OIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
oip,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
if (vapour_active) {
|
||||
const std::vector<double>& gipg = fip.fip[Model::FIPData::FIP_VAPOUR];
|
||||
const int size = gipg.size();
|
||||
|
||||
const std::vector<double>& gipl= liquid_active ? fip.fip[Model::FIPData::FIP_DISSOLVED_GAS] : std::vector<double>(size,0.0);
|
||||
std::vector<double> gip = gipg;
|
||||
if (liquid_active) {
|
||||
std::transform(gip.begin(), gip.end(), gipl.begin(), gip.begin(), std::plus<double>());
|
||||
}
|
||||
|
||||
// Gas in place (gas phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "GIPG")) {
|
||||
output.insert("GIPG",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
gipg,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Gas in place (liquid phase only)
|
||||
if (hasFRBKeyword(summaryConfig, "GIPL")) {
|
||||
output.insert("GIPL",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
gipl,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Gas in place (in both liquid and gas phases)
|
||||
if (hasFRBKeyword(summaryConfig, "GIP")) {
|
||||
output.insert("GIP",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
gip,
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
}
|
||||
// Cell pore volume in reservoir conditions
|
||||
if (hasFRBKeyword(summaryConfig, "RPV")) {
|
||||
output.insert("RPV",
|
||||
Opm::UnitSystem::measure::volume,
|
||||
fip.fip[Model::FIPData::FIP_PV],
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
// Pressure averaged value (hydrocarbon pore volume weighted)
|
||||
if (summaryConfig.hasKeyword("FPRH") || summaryConfig.hasKeyword("RPRH")) {
|
||||
output.insert("PRH",
|
||||
Opm::UnitSystem::measure::pressure,
|
||||
fip.fip[Model::FIPData::FIP_WEIGHTED_PRESSURE],
|
||||
data::TargetType::SUMMARY );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class Model>
|
||||
inline void
|
||||
BlackoilOutputWriterEbos::
|
||||
writeTimeStep(const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& localState,
|
||||
const WellStateFullyImplicitBlackoil& localWellState,
|
||||
const Model& physicalModel,
|
||||
bool substep)
|
||||
{
|
||||
data::Solution cellData{};
|
||||
const RestartConfig& restartConfig = eclipseState_.getRestartConfig();
|
||||
const SummaryConfig& summaryConfig = eclipseState_.getSummaryConfig();
|
||||
const int reportStepNum = timer.reportStepNum();
|
||||
bool logMessages = output_ && parallelOutput_->isIORank();
|
||||
|
||||
if( output_ && !parallelOutput_->isParallel() )
|
||||
{
|
||||
|
||||
detail::getOutputDataEbos( cellData, phaseUsage_, physicalModel,
|
||||
restartConfig, reportStepNum, logMessages );
|
||||
detail::getSummaryData( cellData, phaseUsage_, physicalModel, summaryConfig );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( logMessages )
|
||||
{
|
||||
std::map<std::string, int> rstKeywords = restartConfig.getRestartKeywords(reportStepNum);
|
||||
std::vector<const char*> keywords =
|
||||
{ "WIP", "OIPL", "OIPG", "OIP", "GIPG", "GIPL", "GIP",
|
||||
"RPV", "FRPH", "RPRH"};
|
||||
|
||||
std::ostringstream str;
|
||||
str << "Output of restart/summary config not supported in parallel. Requested keywords were ";
|
||||
std::size_t no_kw = 0;
|
||||
|
||||
auto func = [&] (const char* kw)
|
||||
{
|
||||
if ( detail::hasFRBKeyword(summaryConfig, kw) )
|
||||
{
|
||||
str << kw << " ";
|
||||
++ no_kw;
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(keywords.begin(), keywords.end(), func);
|
||||
|
||||
for (auto& keyValue : rstKeywords)
|
||||
{
|
||||
str << keyValue.first << " ";
|
||||
++ no_kw;
|
||||
}
|
||||
|
||||
if ( no_kw )
|
||||
{
|
||||
Opm::OpmLog::warning("Unhandled ouput request", str.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeTimeStepWithCellProperties(timer, localState, localWellState, cellData, substep);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -20,7 +20,7 @@
|
||||
#ifndef OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
|
||||
#define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
|
||||
|
||||
|
||||
#include <opm/autodiff/BlackoilModelEnums.hpp>
|
||||
#include <opm/core/wells.h>
|
||||
#include <opm/core/well_controls.h>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
@ -176,11 +176,15 @@ namespace Opm
|
||||
}
|
||||
|
||||
template <class State>
|
||||
void resize(const Wells* wells, const State& state) {
|
||||
void resize(const Wells* wells, const State& state ) {
|
||||
const WellStateFullyImplicitBlackoil dummy_state{}; // Init with an empty previous state only resizes
|
||||
init(wells, state, dummy_state) ;
|
||||
}
|
||||
|
||||
template <class State>
|
||||
void resize(const Wells* wells, const State& state, const PhaseUsage& ) {
|
||||
resize( wells, state );
|
||||
}
|
||||
|
||||
/// One rate per phase and well connection.
|
||||
std::vector<double>& perfPhaseRates() { return perfphaserates_; }
|
||||
|
@ -76,7 +76,7 @@ namespace Opm {
|
||||
std::vector<ADB> ads; // Adsorption term.
|
||||
};
|
||||
|
||||
struct SimulatorData {
|
||||
struct SimulatorData : public Opm::FIPDataEnums {
|
||||
SimulatorData(int num_phases)
|
||||
: rq(num_phases)
|
||||
, rsSat(ADB::null())
|
||||
@ -85,21 +85,18 @@ namespace Opm {
|
||||
{
|
||||
}
|
||||
|
||||
enum FipId {
|
||||
FIP_AQUA = Opm::Water,
|
||||
FIP_LIQUID = Opm::Oil,
|
||||
FIP_VAPOUR = Opm::Gas,
|
||||
FIP_DISSOLVED_GAS = 3,
|
||||
FIP_VAPORIZED_OIL = 4,
|
||||
FIP_PV = 5, //< Pore volume
|
||||
FIP_WEIGHTED_PRESSURE = 6
|
||||
};
|
||||
using Opm::FIPDataEnums::FipId;
|
||||
using Opm::FIPDataEnums::fipValues;
|
||||
|
||||
std::vector<ReservoirResidualQuant> rq;
|
||||
ADB rsSat;
|
||||
ADB rvSat;
|
||||
std::array<V, 7> fip;
|
||||
std::array<V, fipValues> fip;
|
||||
};
|
||||
|
||||
typedef Opm::FIPData FIPDataType;
|
||||
|
||||
|
||||
/// Construct a solver. It will retain references to the
|
||||
/// arguments of this functions, and they are expected to
|
||||
/// remain in scope for the lifetime of the solver.
|
||||
@ -153,12 +150,17 @@ namespace Opm {
|
||||
return sd_;
|
||||
}
|
||||
|
||||
/// Return reservoir simulation data (for output functionality)
|
||||
FIPDataType getFIPData() const {
|
||||
return FIPDataType( sd_.fip );
|
||||
}
|
||||
|
||||
/// 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<std::vector<double> >
|
||||
/// \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<std::vector<double> >
|
||||
computeFluidInPlace(const PolymerBlackoilState& x,
|
||||
const std::vector<int>& fipnum);
|
||||
|
||||
@ -224,7 +226,7 @@ namespace Opm {
|
||||
void
|
||||
assemble(const double dt,
|
||||
const PolymerBlackoilState& x,
|
||||
const WellStateFullyImplicitBlackoil& xw,
|
||||
const WellStateFullyImplicitBlackoil& xw,
|
||||
const std::vector<double>& polymer_inflow);
|
||||
|
||||
V solveJacobianSystem() const;
|
||||
@ -298,10 +300,10 @@ namespace Opm {
|
||||
|
||||
ADB
|
||||
transMult(const ADB& p) const;
|
||||
|
||||
|
||||
const std::vector<PhasePresence>
|
||||
phaseCondition() const { return phaseCondition_; }
|
||||
|
||||
|
||||
void
|
||||
classifyCondition(const PolymerBlackoilState& state);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user