2015-01-26 09:43:45 -06:00
|
|
|
|
/*
|
|
|
|
|
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/>.
|
|
|
|
|
*/
|
2014-02-20 06:17:18 -06:00
|
|
|
|
#ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED
|
|
|
|
|
#define OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED
|
2018-02-09 06:42:16 -06:00
|
|
|
|
#include <opm/grid/UnstructuredGrid.h>
|
2017-02-10 09:07:25 -06:00
|
|
|
|
#include <opm/simulators/timestepping/SimulatorTimerInterface.hpp>
|
2014-02-20 06:17:18 -06:00
|
|
|
|
#include <opm/core/simulator/WellState.hpp>
|
2016-09-23 06:25:02 -05:00
|
|
|
|
#include <opm/autodiff/Compat.hpp>
|
2014-02-27 05:57:51 -06:00
|
|
|
|
#include <opm/core/utility/DataMap.hpp>
|
2015-10-08 04:43:36 -05:00
|
|
|
|
#include <opm/common/ErrorMacros.hpp>
|
2016-09-02 07:15:10 -05:00
|
|
|
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
2014-02-27 05:57:51 -06:00
|
|
|
|
#include <opm/core/utility/miscUtilities.hpp>
|
2018-01-30 06:25:35 -06:00
|
|
|
|
#include <opm/common/utility/parameters/ParameterGroup.hpp>
|
2016-06-27 06:39:25 -05:00
|
|
|
|
#include <opm/core/wells/DynamicListEconLimited.hpp>
|
2017-03-16 04:22:27 -05:00
|
|
|
|
#include <opm/core/simulator/BlackoilState.hpp>
|
2017-06-06 14:35:05 -05:00
|
|
|
|
#include <opm/core/simulator/SimulatorReport.hpp>
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
2016-10-04 08:55:29 -05:00
|
|
|
|
#include <opm/output/data/Cells.hpp>
|
|
|
|
|
#include <opm/output/data/Solution.hpp>
|
2017-01-06 08:13:53 -06:00
|
|
|
|
#include <opm/output/eclipse/EclipseIO.hpp>
|
2014-02-27 05:57:51 -06:00
|
|
|
|
|
|
|
|
|
#include <opm/autodiff/GridHelpers.hpp>
|
2015-09-14 09:51:27 -05:00
|
|
|
|
#include <opm/autodiff/ParallelDebugOutput.hpp>
|
2014-02-20 06:17:18 -06:00
|
|
|
|
|
2015-02-11 05:46:11 -06:00
|
|
|
|
#include <opm/autodiff/WellStateFullyImplicitBlackoil.hpp>
|
2018-03-12 09:17:39 -05:00
|
|
|
|
#include <opm/autodiff/ThreadHandle.hpp>
|
2016-09-02 02:38:25 -05:00
|
|
|
|
#include <opm/autodiff/AutoDiffBlock.hpp>
|
2015-02-11 05:46:11 -06:00
|
|
|
|
|
2016-01-05 05:39:02 -06:00
|
|
|
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
2017-10-29 15:06:19 -05:00
|
|
|
|
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
2016-01-05 05:39:02 -06:00
|
|
|
|
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
|
2017-04-06 05:14:54 -05:00
|
|
|
|
#include <opm/simulators/ensureDirectoryExists.hpp>
|
2016-01-05 05:39:02 -06:00
|
|
|
|
|
2014-02-20 06:17:18 -06:00
|
|
|
|
#include <string>
|
2014-02-27 05:57:51 -06:00
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <fstream>
|
2016-04-01 08:28:14 -05:00
|
|
|
|
#include <thread>
|
2017-03-01 02:50:32 -06:00
|
|
|
|
#include <map>
|
2014-02-27 05:57:51 -06:00
|
|
|
|
|
|
|
|
|
#include <boost/filesystem.hpp>
|
2014-02-20 06:17:18 -06:00
|
|
|
|
|
2016-04-05 08:17:17 -05:00
|
|
|
|
#ifdef HAVE_OPM_GRID
|
2018-02-09 06:42:16 -06:00
|
|
|
|
#include <opm/grid/CpGrid.hpp>
|
2014-02-20 06:17:18 -06:00
|
|
|
|
#endif
|
|
|
|
|
namespace Opm
|
|
|
|
|
{
|
|
|
|
|
|
2016-02-28 04:27:00 -06:00
|
|
|
|
class SimulationDataContainer;
|
|
|
|
|
class BlackoilState;
|
|
|
|
|
|
2014-02-20 06:17:18 -06:00
|
|
|
|
void outputStateVtk(const UnstructuredGrid& grid,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const Opm::SimulationDataContainer& state,
|
2014-02-20 06:17:18 -06:00
|
|
|
|
const int step,
|
|
|
|
|
const std::string& output_dir);
|
|
|
|
|
|
|
|
|
|
void outputWellStateMatlab(const Opm::WellState& well_state,
|
|
|
|
|
const int step,
|
|
|
|
|
const std::string& output_dir);
|
2016-04-05 08:17:17 -05:00
|
|
|
|
#ifdef HAVE_OPM_GRID
|
2014-02-20 06:17:18 -06:00
|
|
|
|
void outputStateVtk(const Dune::CpGrid& grid,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const Opm::SimulationDataContainer& state,
|
2014-02-20 06:17:18 -06:00
|
|
|
|
const int step,
|
|
|
|
|
const std::string& output_dir);
|
2014-02-27 05:57:51 -06:00
|
|
|
|
#endif
|
2014-02-20 06:17:18 -06:00
|
|
|
|
|
2014-02-27 05:57:51 -06:00
|
|
|
|
template<class Grid>
|
|
|
|
|
void outputStateMatlab(const Grid& grid,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const Opm::SimulationDataContainer& state,
|
2014-02-20 06:17:18 -06:00
|
|
|
|
const int step,
|
2014-02-27 05:57:51 -06:00
|
|
|
|
const std::string& output_dir)
|
|
|
|
|
{
|
|
|
|
|
Opm::DataMap dm;
|
|
|
|
|
dm["saturation"] = &state.saturation();
|
|
|
|
|
dm["pressure"] = &state.pressure();
|
2016-04-01 08:28:14 -05:00
|
|
|
|
for (const auto& pair : state.cellData())
|
2015-09-16 06:05:23 -05:00
|
|
|
|
{
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const std::string& name = pair.first;
|
2015-09-16 06:05:23 -05:00
|
|
|
|
std::string key;
|
|
|
|
|
if( name == "SURFACEVOL" ) {
|
|
|
|
|
key = "surfvolume";
|
|
|
|
|
}
|
|
|
|
|
else if( name == "RV" ) {
|
|
|
|
|
key = "rv";
|
|
|
|
|
}
|
|
|
|
|
else if( name == "GASOILRATIO" ) {
|
|
|
|
|
key = "rs";
|
|
|
|
|
}
|
|
|
|
|
else { // otherwise skip entry
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// set data to datmap
|
2016-02-28 04:27:00 -06:00
|
|
|
|
dm[ key ] = &pair.second;
|
2015-09-16 06:05:23 -05:00
|
|
|
|
}
|
2014-08-18 01:51:14 -05:00
|
|
|
|
|
2014-02-27 05:57:51 -06:00
|
|
|
|
std::vector<double> cell_velocity;
|
|
|
|
|
Opm::estimateCellVelocity(AutoDiffGrid::numCells(grid),
|
|
|
|
|
AutoDiffGrid::numFaces(grid),
|
|
|
|
|
AutoDiffGrid::beginFaceCentroids(grid),
|
2014-08-28 07:44:13 -05:00
|
|
|
|
UgGridHelpers::faceCells(grid),
|
2014-02-27 05:57:51 -06:00
|
|
|
|
AutoDiffGrid::beginCellCentroids(grid),
|
|
|
|
|
AutoDiffGrid::beginCellVolumes(grid),
|
|
|
|
|
AutoDiffGrid::dimensions(grid),
|
|
|
|
|
state.faceflux(), cell_velocity);
|
|
|
|
|
dm["velocity"] = &cell_velocity;
|
|
|
|
|
|
|
|
|
|
// Write data (not grid) in Matlab format
|
|
|
|
|
for (Opm::DataMap::const_iterator it = dm.begin(); it != dm.end(); ++it) {
|
|
|
|
|
std::ostringstream fname;
|
|
|
|
|
fname << output_dir << "/" << it->first;
|
2017-04-06 05:14:54 -05:00
|
|
|
|
ensureDirectoryExists(fname.str());
|
2014-02-27 05:57:51 -06:00
|
|
|
|
fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt";
|
|
|
|
|
std::ofstream file(fname.str().c_str());
|
|
|
|
|
if (!file) {
|
|
|
|
|
OPM_THROW(std::runtime_error, "Failed to open " << fname.str());
|
|
|
|
|
}
|
|
|
|
|
file.precision(15);
|
|
|
|
|
const std::vector<double>& d = *(it->second);
|
|
|
|
|
std::copy(d.begin(), d.end(), std::ostream_iterator<double>(file, "\n"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-20 09:15:23 -05:00
|
|
|
|
class BlackoilSubWriter {
|
|
|
|
|
public:
|
|
|
|
|
BlackoilSubWriter( const std::string& outputDir )
|
|
|
|
|
: outputDir_( outputDir )
|
2015-01-26 09:43:45 -06:00
|
|
|
|
{}
|
|
|
|
|
|
2016-05-20 09:15:23 -05:00
|
|
|
|
virtual void writeTimeStep(const SimulatorTimerInterface& timer,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const SimulationDataContainer& state,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const WellStateFullyImplicitBlackoil&,
|
2016-05-20 09:15:23 -05:00
|
|
|
|
bool /*substep*/ = false) = 0;
|
|
|
|
|
protected:
|
|
|
|
|
const std::string outputDir_;
|
2015-01-26 09:43:45 -06:00
|
|
|
|
};
|
|
|
|
|
|
2016-05-20 09:15:23 -05:00
|
|
|
|
template< class Grid >
|
|
|
|
|
class BlackoilVTKWriter : public BlackoilSubWriter {
|
|
|
|
|
public:
|
|
|
|
|
BlackoilVTKWriter( const Grid& grid,
|
|
|
|
|
const std::string& outputDir )
|
|
|
|
|
: BlackoilSubWriter( outputDir )
|
|
|
|
|
, grid_( grid )
|
2015-01-26 09:43:45 -06:00
|
|
|
|
{}
|
|
|
|
|
|
2016-05-20 09:15:23 -05:00
|
|
|
|
void writeTimeStep(const SimulatorTimerInterface& timer,
|
|
|
|
|
const SimulationDataContainer& state,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const WellStateFullyImplicitBlackoil&,
|
2016-05-20 09:15:23 -05:00
|
|
|
|
bool /*substep*/ = false) override
|
|
|
|
|
{
|
|
|
|
|
outputStateVtk(grid_, state, timer.currentStepNum(), outputDir_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
const Grid& grid_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename Grid >
|
|
|
|
|
class BlackoilMatlabWriter : public BlackoilSubWriter
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
BlackoilMatlabWriter( const Grid& grid,
|
|
|
|
|
const std::string& outputDir )
|
|
|
|
|
: BlackoilSubWriter( outputDir )
|
|
|
|
|
, grid_( grid )
|
2015-02-17 06:44:33 -06:00
|
|
|
|
{}
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
|
|
|
|
void writeTimeStep(const SimulatorTimerInterface& timer,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const SimulationDataContainer& reservoirState,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const WellStateFullyImplicitBlackoil& wellState,
|
2016-05-20 09:15:23 -05:00
|
|
|
|
bool /*substep*/ = false) override
|
2015-01-26 09:43:45 -06:00
|
|
|
|
{
|
2015-09-16 06:05:23 -05:00
|
|
|
|
outputStateMatlab(grid_, reservoirState, timer.currentStepNum(), outputDir_);
|
2015-01-26 09:43:45 -06:00
|
|
|
|
outputWellStateMatlab(wellState, timer.currentStepNum(), outputDir_);
|
|
|
|
|
}
|
2016-05-20 09:15:23 -05:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
const Grid& grid_;
|
2015-01-26 09:43:45 -06:00
|
|
|
|
};
|
2014-02-27 05:57:51 -06:00
|
|
|
|
|
2017-02-24 07:52:12 -06:00
|
|
|
|
|
2017-02-24 09:42:32 -06:00
|
|
|
|
/// Extra data to read/write for OPM restarting
|
2017-02-24 07:52:12 -06:00
|
|
|
|
struct ExtraData
|
|
|
|
|
{
|
2017-03-01 02:50:32 -06:00
|
|
|
|
double suggested_step = -1.0;
|
2017-02-24 07:52:12 -06:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2015-02-11 05:46:11 -06:00
|
|
|
|
/** \brief Wrapper class for VTK, Matlab, and ECL output. */
|
2016-05-20 09:15:23 -05:00
|
|
|
|
class BlackoilOutputWriter
|
2015-01-26 09:43:45 -06:00
|
|
|
|
{
|
2016-01-05 05:39:02 -06:00
|
|
|
|
|
2015-01-26 09:43:45 -06:00
|
|
|
|
public:
|
|
|
|
|
// constructor creating different sub writers
|
|
|
|
|
template <class Grid>
|
|
|
|
|
BlackoilOutputWriter(const Grid& grid,
|
2017-04-28 08:36:25 -05:00
|
|
|
|
const ParameterGroup& param,
|
2016-10-14 02:23:26 -05:00
|
|
|
|
const Opm::EclipseState& eclipseState,
|
2017-10-29 15:06:19 -05:00
|
|
|
|
const Opm::Schedule& schedule,
|
|
|
|
|
const Opm::SummaryConfig& summaryConfig,
|
2017-01-06 08:13:53 -06:00
|
|
|
|
std::unique_ptr<EclipseIO>&& eclIO,
|
2017-01-26 10:29:22 -06:00
|
|
|
|
const Opm::PhaseUsage &phaseUsage);
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
2016-09-02 08:38:46 -05:00
|
|
|
|
/** \copydoc Opm::OutputWriter::writeInit */
|
2016-10-04 08:55:29 -05:00
|
|
|
|
void writeInit(const data::Solution& simProps, const NNC& nnc);
|
2016-09-02 08:38:46 -05:00
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \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.
|
|
|
|
|
*/
|
2016-09-01 04:38:04 -05:00
|
|
|
|
template<class Model>
|
2015-01-26 09:43:45 -06:00
|
|
|
|
void writeTimeStep(const SimulatorTimerInterface& timer,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
const SimulationDataContainer& reservoirState,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
2016-09-01 04:38:04 -05:00
|
|
|
|
const Model& physicalModel,
|
2017-06-06 14:35:05 -05:00
|
|
|
|
const bool substep = false,
|
|
|
|
|
const double nextstep = -1.0,
|
2017-07-20 05:12:41 -05:00
|
|
|
|
const SimulatorReport& simulatorReport = SimulatorReport());
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
2016-09-02 08:38:46 -05:00
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Write a blackoil reservoir state to disk for later inspection with
|
|
|
|
|
* visualization tools like ResInsight. This function will write all
|
2017-06-06 04:42:51 -05:00
|
|
|
|
* CellData in simProps to the file as well as the extraRestartData.
|
2016-09-02 08:38:46 -05:00
|
|
|
|
*/
|
|
|
|
|
void writeTimeStepWithCellProperties(
|
|
|
|
|
const SimulatorTimerInterface& timer,
|
|
|
|
|
const SimulationDataContainer& reservoirState,
|
2016-11-16 05:33:08 -06:00
|
|
|
|
const data::Solution& cellData,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
2017-06-06 04:42:51 -05:00
|
|
|
|
const std::map<std::string, double>& miscSummaryData,
|
|
|
|
|
const std::map<std::string, std::vector<double>>& extraRestartData,
|
2017-07-20 05:37:01 -05:00
|
|
|
|
bool substep = false);
|
2016-09-02 08:38:46 -05:00
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \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,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
2017-06-06 04:42:51 -05:00
|
|
|
|
const std::map<std::string, double>& miscSummaryData,
|
|
|
|
|
const std::map<std::string, std::vector<double>>& extraRestartData,
|
2016-09-02 08:38:46 -05:00
|
|
|
|
bool substep = false);
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Write a blackoil reservoir state to disk for later inspection with
|
|
|
|
|
* visualization tools like ResInsight. This is the function which does
|
|
|
|
|
* the actual write to file.
|
|
|
|
|
*/
|
2016-04-01 08:28:14 -05:00
|
|
|
|
void writeTimeStepSerial(const SimulatorTimerInterface& timer,
|
|
|
|
|
const SimulationDataContainer& reservoirState,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const Opm::WellStateFullyImplicitBlackoil& wellState,
|
2016-11-16 05:33:08 -06:00
|
|
|
|
const data::Solution& simProps,
|
2017-06-06 04:42:51 -05:00
|
|
|
|
const std::map<std::string, double>& miscSummaryData,
|
|
|
|
|
const std::map<std::string, std::vector<double>>& extraRestartData,
|
2017-07-20 05:12:41 -05:00
|
|
|
|
bool substep );
|
2016-04-01 08:28:14 -05:00
|
|
|
|
|
2015-01-26 09:43:45 -06:00
|
|
|
|
/** \brief return output directory */
|
|
|
|
|
const std::string& outputDirectory() const { return outputDir_; }
|
|
|
|
|
|
|
|
|
|
/** \brief return true if output is enabled */
|
2015-02-17 06:45:14 -06:00
|
|
|
|
bool output () const { return output_; }
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
2016-10-14 04:14:54 -05:00
|
|
|
|
/** \brief Whether this process does write to disk */
|
|
|
|
|
bool isIORank () const
|
|
|
|
|
{
|
2016-10-17 06:39:06 -05:00
|
|
|
|
return parallelOutput_->isIORank();
|
2016-10-14 04:14:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-24 07:52:12 -06:00
|
|
|
|
template <class Grid, class WellState>
|
2017-02-09 06:54:42 -06:00
|
|
|
|
void initFromRestartFile(const PhaseUsage& phaseUsage,
|
2016-01-05 05:39:02 -06:00
|
|
|
|
const Grid& grid,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
SimulationDataContainer& simulatorstate,
|
2017-02-24 07:52:12 -06:00
|
|
|
|
WellState& wellstate,
|
|
|
|
|
ExtraData& extra);
|
2016-01-05 05:39:02 -06:00
|
|
|
|
|
|
|
|
|
bool isRestart() const;
|
|
|
|
|
|
2017-02-06 09:51:22 -06:00
|
|
|
|
bool requireFIPNUM() const;
|
|
|
|
|
|
2015-01-26 09:43:45 -06:00
|
|
|
|
protected:
|
2015-09-15 08:44:26 -05:00
|
|
|
|
const bool output_;
|
2015-09-14 09:51:27 -05:00
|
|
|
|
std::unique_ptr< ParallelDebugOutputInterface > parallelOutput_;
|
|
|
|
|
|
2015-01-26 09:43:45 -06:00
|
|
|
|
// Parameters for output.
|
|
|
|
|
const std::string outputDir_;
|
2017-02-24 10:07:25 -06:00
|
|
|
|
const bool restart_double_si_;
|
2015-01-26 09:43:45 -06:00
|
|
|
|
|
2016-05-20 09:15:23 -05:00
|
|
|
|
Opm::PhaseUsage phaseUsage_;
|
|
|
|
|
std::unique_ptr< BlackoilSubWriter > vtkWriter_;
|
|
|
|
|
std::unique_ptr< BlackoilSubWriter > matlabWriter_;
|
2017-01-06 08:13:53 -06:00
|
|
|
|
std::unique_ptr< EclipseIO > eclIO_;
|
2016-10-14 02:23:26 -05:00
|
|
|
|
const EclipseState& eclipseState_;
|
2017-10-29 15:06:19 -05:00
|
|
|
|
const Schedule& schedule_;
|
|
|
|
|
const SummaryConfig& summaryConfig_;
|
2016-04-01 08:28:14 -05:00
|
|
|
|
|
|
|
|
|
std::unique_ptr< ThreadHandle > asyncOutput_;
|
2018-01-15 06:06:42 -06:00
|
|
|
|
const int* globalCellIdxMap_;
|
2015-01-26 09:43:45 -06:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Implementation
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
|
template <class Grid>
|
|
|
|
|
inline
|
|
|
|
|
BlackoilOutputWriter::
|
|
|
|
|
BlackoilOutputWriter(const Grid& grid,
|
2017-04-28 08:36:25 -05:00
|
|
|
|
const ParameterGroup& param,
|
2016-10-14 02:23:26 -05:00
|
|
|
|
const Opm::EclipseState& eclipseState,
|
2017-10-29 15:06:19 -05:00
|
|
|
|
const Opm::Schedule& schedule,
|
|
|
|
|
const Opm::SummaryConfig& summaryConfig,
|
2017-01-06 08:13:53 -06:00
|
|
|
|
std::unique_ptr<EclipseIO>&& eclIO,
|
2017-01-26 10:29:22 -06:00
|
|
|
|
const Opm::PhaseUsage &phaseUsage)
|
2017-06-20 08:49:13 -05:00
|
|
|
|
: output_( [ ¶m ] () -> bool {
|
2017-06-20 06:11:16 -05:00
|
|
|
|
// If output parameter is true or all, then we do output
|
2017-06-20 08:27:05 -05:00
|
|
|
|
const std::string outputString = param.getDefault("output", std::string("all"));
|
|
|
|
|
return ( outputString == "all" || outputString == "true" );
|
|
|
|
|
}()
|
2017-06-20 06:11:16 -05:00
|
|
|
|
),
|
2017-10-29 15:06:19 -05:00
|
|
|
|
parallelOutput_( output_ ? new ParallelDebugOutput< Grid >( grid, eclipseState, schedule, phaseUsage.num_phases, phaseUsage ) : 0 ),
|
2017-03-16 09:40:24 -05:00
|
|
|
|
outputDir_( eclipseState.getIOConfig().getOutputDir() ),
|
2017-02-24 10:07:25 -06:00
|
|
|
|
restart_double_si_( output_ ? param.getDefault("restart_double_si", false) : false ),
|
2016-05-20 09:15:23 -05:00
|
|
|
|
phaseUsage_( phaseUsage ),
|
2016-04-01 08:28:14 -05:00
|
|
|
|
eclipseState_(eclipseState),
|
2017-10-29 15:06:19 -05:00
|
|
|
|
schedule_(schedule),
|
|
|
|
|
summaryConfig_(summaryConfig),
|
2018-01-15 06:06:42 -06:00
|
|
|
|
asyncOutput_(),
|
|
|
|
|
globalCellIdxMap_(Opm::UgGridHelpers::globalCell(grid))
|
2015-01-26 09:43:45 -06:00
|
|
|
|
{
|
|
|
|
|
// For output.
|
2016-11-10 06:28:21 -06:00
|
|
|
|
if ( output_ )
|
|
|
|
|
{
|
|
|
|
|
if ( param.getDefault("output_vtk",false) )
|
|
|
|
|
{
|
|
|
|
|
vtkWriter_
|
|
|
|
|
.reset(new BlackoilVTKWriter< Grid >( grid, outputDir_ ));
|
2015-01-26 09:43:45 -06:00
|
|
|
|
}
|
2015-02-11 05:46:11 -06:00
|
|
|
|
|
2016-11-16 05:24:09 -06:00
|
|
|
|
auto output_matlab = param.getDefault("output_matlab", false );
|
|
|
|
|
|
|
|
|
|
if ( parallelOutput_->isParallel() && output_matlab )
|
|
|
|
|
{
|
|
|
|
|
Opm::OpmLog::warning("Parallel Output Config",
|
|
|
|
|
"Velocity output for matlab is broken in parallel.");
|
|
|
|
|
}
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
2016-11-10 06:28:21 -06:00
|
|
|
|
if( parallelOutput_->isIORank() ) {
|
|
|
|
|
|
2016-11-16 05:24:09 -06:00
|
|
|
|
if ( output_matlab )
|
2016-11-10 06:28:21 -06:00
|
|
|
|
{
|
|
|
|
|
matlabWriter_
|
|
|
|
|
.reset(new BlackoilMatlabWriter< Grid >( grid, outputDir_ ));
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-06 08:13:53 -06:00
|
|
|
|
eclIO_ = std::move(eclIO);
|
2016-11-10 06:28:21 -06:00
|
|
|
|
|
|
|
|
|
// Ensure that output dir exists
|
2017-04-06 05:14:54 -05:00
|
|
|
|
ensureDirectoryExists(outputDir_);
|
2015-02-11 05:46:11 -06:00
|
|
|
|
}
|
2017-05-29 11:08:18 -05:00
|
|
|
|
|
2017-06-02 06:07:44 -05:00
|
|
|
|
// create output thread if enabled and rank is I/O rank
|
|
|
|
|
// async output is enabled by default if pthread are enabled
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#if HAVE_PTHREAD
|
2017-06-02 06:07:44 -05:00
|
|
|
|
const bool asyncOutputDefault = true;
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#else
|
2017-06-02 06:07:44 -05:00
|
|
|
|
const bool asyncOutputDefault = false;
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#endif
|
2017-06-02 06:07:44 -05:00
|
|
|
|
if( param.getDefault("async_output", asyncOutputDefault ) )
|
|
|
|
|
{
|
|
|
|
|
const bool isIORank = parallelOutput_ ? parallelOutput_->isIORank() : true;
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#if HAVE_PTHREAD
|
2017-06-02 06:07:44 -05:00
|
|
|
|
asyncOutput_.reset( new ThreadHandle( isIORank ) );
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#else
|
2017-06-02 06:07:44 -05:00
|
|
|
|
OPM_THROW(std::runtime_error,"Pthreads were not found, cannot enable async_output");
|
2017-05-29 11:08:18 -05:00
|
|
|
|
#endif
|
2017-06-02 06:07:44 -05:00
|
|
|
|
}
|
2017-05-29 11:08:18 -05:00
|
|
|
|
}
|
2015-01-26 09:43:45 -06:00
|
|
|
|
}
|
2016-01-05 05:39:02 -06:00
|
|
|
|
|
|
|
|
|
|
2017-02-23 03:21:45 -06:00
|
|
|
|
template <class Grid, class WellState>
|
2016-01-05 05:39:02 -06:00
|
|
|
|
inline void
|
|
|
|
|
BlackoilOutputWriter::
|
2017-02-09 06:54:42 -06:00
|
|
|
|
initFromRestartFile( const PhaseUsage& phaseUsage,
|
2016-01-05 05:39:02 -06:00
|
|
|
|
const Grid& grid,
|
2016-02-28 04:27:00 -06:00
|
|
|
|
SimulationDataContainer& simulatorstate,
|
2017-02-24 07:52:12 -06:00
|
|
|
|
WellState& wellstate,
|
|
|
|
|
ExtraData& extra )
|
2016-01-05 05:39:02 -06:00
|
|
|
|
{
|
2017-06-09 11:45:11 -05:00
|
|
|
|
std::map<std::string, RestartKey> solution_keys {{"PRESSURE" , RestartKey(UnitSystem::measure::pressure)},
|
|
|
|
|
{"SWAT" , RestartKey(UnitSystem::measure::identity)},
|
|
|
|
|
{"SGAS" , RestartKey(UnitSystem::measure::identity)},
|
|
|
|
|
{"TEMP" , RestartKey(UnitSystem::measure::temperature)},
|
|
|
|
|
{"RS" , RestartKey(UnitSystem::measure::gas_oil_ratio)},
|
|
|
|
|
{"RV" , RestartKey(UnitSystem::measure::oil_gas_ratio)},
|
2017-04-11 07:42:32 -05:00
|
|
|
|
{"SOMAX", {UnitSystem::measure::identity, false}},
|
|
|
|
|
{"PCSWM_OW", {UnitSystem::measure::identity, false}},
|
|
|
|
|
{"KRNSW_OW", {UnitSystem::measure::identity, false}},
|
|
|
|
|
{"PCSWM_GO", {UnitSystem::measure::identity, false}},
|
|
|
|
|
{"KRNSW_GO", {UnitSystem::measure::identity, false}}};
|
|
|
|
|
|
2017-04-07 09:20:35 -05:00
|
|
|
|
std::map<std::string, bool> extra_keys {
|
2017-04-11 07:42:32 -05:00
|
|
|
|
{"OPMEXTRA" , false}
|
2017-04-07 09:20:35 -05:00
|
|
|
|
};
|
2017-01-06 08:13:53 -06:00
|
|
|
|
|
2017-02-24 10:07:25 -06:00
|
|
|
|
if (restart_double_si_) {
|
|
|
|
|
// Avoid any unit conversions, treat restart input as SI units.
|
|
|
|
|
for (auto& elem : solution_keys) {
|
2017-06-09 11:45:11 -05:00
|
|
|
|
elem.second = RestartKey(UnitSystem::measure::identity);
|
2017-02-24 10:07:25 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-27 06:39:25 -05:00
|
|
|
|
// gives a dummy dynamic_list_econ_limited
|
|
|
|
|
DynamicListEconLimited dummy_list_econ_limited;
|
2016-01-05 05:39:02 -06:00
|
|
|
|
WellsManager wellsmanager(eclipseState_,
|
2017-10-29 15:06:19 -05:00
|
|
|
|
schedule_,
|
2016-10-14 02:23:26 -05:00
|
|
|
|
eclipseState_.getInitConfig().getRestartStep(),
|
2016-01-05 05:39:02 -06:00
|
|
|
|
Opm::UgGridHelpers::numCells(grid),
|
|
|
|
|
Opm::UgGridHelpers::globalCell(grid),
|
|
|
|
|
Opm::UgGridHelpers::cartDims(grid),
|
|
|
|
|
Opm::UgGridHelpers::dimensions(grid),
|
|
|
|
|
Opm::UgGridHelpers::cell2Faces(grid),
|
|
|
|
|
Opm::UgGridHelpers::beginFaceCentroids(grid),
|
2016-09-12 05:32:34 -05:00
|
|
|
|
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::unordered_set<std::string>());
|
2016-01-05 05:39:02 -06:00
|
|
|
|
|
|
|
|
|
const Wells* wells = wellsmanager.c_wells();
|
2017-02-09 06:54:42 -06:00
|
|
|
|
wellstate.resize(wells, simulatorstate, phaseUsage ); //Resize for restart step
|
2017-03-01 02:50:32 -06:00
|
|
|
|
auto restart_values = eclIO_->loadRestart(solution_keys, extra_keys);
|
2016-05-20 09:15:23 -05:00
|
|
|
|
|
2017-04-07 09:20:35 -05:00
|
|
|
|
solutionToSim( restart_values.solution, restart_values.extra, phaseUsage, simulatorstate );
|
2017-03-01 02:50:32 -06:00
|
|
|
|
wellsToState( restart_values.wells, phaseUsage, wellstate );
|
2017-02-24 07:52:12 -06:00
|
|
|
|
|
2017-03-01 02:50:32 -06:00
|
|
|
|
const auto opmextra_iter = restart_values.extra.find("OPMEXTRA");
|
|
|
|
|
if (opmextra_iter != restart_values.extra.end()) {
|
|
|
|
|
std::vector<double> opmextra = opmextra_iter->second;
|
2017-02-24 07:52:12 -06:00
|
|
|
|
assert(opmextra.size() == 1);
|
|
|
|
|
extra.suggested_step = opmextra[0];
|
2017-03-01 02:50:32 -06:00
|
|
|
|
} else {
|
2017-03-16 07:34:24 -05:00
|
|
|
|
OpmLog::warning("Restart data is missing OPMEXTRA field, restart run may deviate from original run.");
|
|
|
|
|
extra.suggested_step = -1.0;
|
2017-02-24 07:52:12 -06:00
|
|
|
|
}
|
2016-01-05 05:39:02 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-09-01 04:38:04 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
|
|
|
|
template <class V>
|
|
|
|
|
void addToSimData( SimulationDataContainer& simData,
|
|
|
|
|
const std::string& name,
|
|
|
|
|
const V& vec )
|
|
|
|
|
{
|
2017-04-19 02:58:54 -05:00
|
|
|
|
if (vec.size() == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
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() ) ) );
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
2016-09-01 04:38:04 -05:00
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
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() );
|
|
|
|
|
}
|
2016-09-01 04:38:04 -05:00
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
|
|
|
|
// 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 );
|
|
|
|
|
|
2017-03-15 07:51:51 -05:00
|
|
|
|
addToSimData( simData, "SOMAX", sd.soMax );
|
2017-04-18 04:29:49 -05:00
|
|
|
|
addToSimData( simData, "PBUB", sd.Pb );
|
|
|
|
|
addToSimData( simData, "PDEW", sd.Pd );
|
|
|
|
|
addToSimData( simData, "PCSWMDC_OW", sd.pcswmdc_ow );
|
|
|
|
|
addToSimData( simData, "KRNSWMDC_OW", sd.krnswdc_ow );
|
|
|
|
|
addToSimData( simData, "PCSWMDC_GO", sd.pcswmdc_go );
|
|
|
|
|
addToSimData( simData, "KRNSWMDC_GO", sd.krnswdc_go );
|
2017-03-15 07:51:51 -05:00
|
|
|
|
|
2017-02-14 03:50:31 -06:00
|
|
|
|
return simData;
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
// 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 );
|
|
|
|
|
}
|
2016-09-26 07:55:03 -05:00
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
/**
|
2016-09-26 07:55:03 -05:00
|
|
|
|
* Returns the data requested in the restartConfig
|
2017-02-22 02:56:43 -06:00
|
|
|
|
* NOTE: Since this function steals data from the SimulationDataContainer (std::move),
|
|
|
|
|
* the variable sd becomes "invalid" after calling this function.
|
2016-09-26 07:17:52 -05:00
|
|
|
|
*/
|
2016-09-01 04:38:04 -05:00
|
|
|
|
template<class Model>
|
2016-10-04 08:55:29 -05:00
|
|
|
|
void getRestartData(data::Solution& output,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
SimulationDataContainer&& sd,
|
2017-02-14 03:50:31 -06:00
|
|
|
|
const Opm::PhaseUsage& /* phaseUsage */,
|
|
|
|
|
const Model& /* physicalModel */,
|
2016-10-04 08:55:29 -05:00
|
|
|
|
const RestartConfig& restartConfig,
|
|
|
|
|
const int reportStepNum,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
const bool log)
|
|
|
|
|
{
|
2016-09-26 07:17:52 -05:00
|
|
|
|
//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) {
|
2016-09-01 04:38:04 -05:00
|
|
|
|
keyValue.second = restartConfig.getKeyword(keyValue.first, reportStepNum);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
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")
|
|
|
|
|
)
|
|
|
|
|
);
|
2016-09-02 02:38:25 -05:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Formation volume factors for water, oil, gas
|
|
|
|
|
*/
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (aqua_active && rstKeywords["BW"] > 0) {
|
|
|
|
|
rstKeywords["BW"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("1OVERBW",
|
|
|
|
|
Opm::UnitSystem::measure::water_inverse_formation_volume_factor,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("1OVERBW") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-01 04:38:04 -05:00
|
|
|
|
}
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (liquid_active && rstKeywords["BO"] > 0) {
|
|
|
|
|
rstKeywords["BO"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("1OVERBO",
|
|
|
|
|
Opm::UnitSystem::measure::oil_inverse_formation_volume_factor,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("1OVERBO") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-01 04:38:04 -05:00
|
|
|
|
}
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (vapour_active && rstKeywords["BG"] > 0) {
|
|
|
|
|
rstKeywords["BG"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("1OVERBG",
|
|
|
|
|
Opm::UnitSystem::measure::gas_inverse_formation_volume_factor,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("1OVERBG") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-01 04:38:04 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 02:38:25 -05:00
|
|
|
|
/**
|
|
|
|
|
* Densities for water, oil gas
|
|
|
|
|
*/
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (rstKeywords["DEN"] > 0) {
|
|
|
|
|
rstKeywords["DEN"] = 0;
|
2016-09-02 02:38:25 -05:00
|
|
|
|
if (aqua_active) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("WAT_DEN",
|
|
|
|
|
Opm::UnitSystem::measure::density,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("WAT_DEN") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
if (liquid_active) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OIL_DEN",
|
|
|
|
|
Opm::UnitSystem::measure::density,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("OIL_DEN") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
if (vapour_active) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GAS_DEN",
|
|
|
|
|
Opm::UnitSystem::measure::density,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("GAS_DEN") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Viscosities for water, oil gas
|
|
|
|
|
*/
|
2017-02-22 04:18:24 -06:00
|
|
|
|
{
|
|
|
|
|
const bool has_vwat = (rstKeywords["VISC"] > 0) || (rstKeywords["VWAT"] > 0);
|
|
|
|
|
const bool has_voil = (rstKeywords["VISC"] > 0) || (rstKeywords["VOIL"] > 0);
|
|
|
|
|
const bool has_vgas = (rstKeywords["VISC"] > 0) || (rstKeywords["VGAS"] > 0);
|
2016-09-26 07:17:52 -05:00
|
|
|
|
rstKeywords["VISC"] = 0;
|
2017-02-24 03:56:44 -06:00
|
|
|
|
if (aqua_active && has_vwat) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("WAT_VISC",
|
|
|
|
|
Opm::UnitSystem::measure::viscosity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("WAT_VISC") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2017-02-22 04:18:24 -06:00
|
|
|
|
rstKeywords["VWAT"] = 0;
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
2017-02-24 03:56:44 -06:00
|
|
|
|
if (liquid_active && has_voil) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OIL_VISC",
|
|
|
|
|
Opm::UnitSystem::measure::viscosity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("OIL_VISC") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2017-02-22 04:18:24 -06:00
|
|
|
|
rstKeywords["VOIL"] = 0;
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
2017-02-24 03:56:44 -06:00
|
|
|
|
if (vapour_active && has_vgas) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GAS_VISC",
|
|
|
|
|
Opm::UnitSystem::measure::viscosity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("GAS_VISC") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2017-02-22 04:18:24 -06:00
|
|
|
|
rstKeywords["VGAS"] = 0;
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Relative permeabilities for water, oil, gas
|
|
|
|
|
*/
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (aqua_active && rstKeywords["KRW"] > 0) {
|
2017-02-09 06:54:42 -06:00
|
|
|
|
auto& krWater = sd.getCellData("WATKR");
|
|
|
|
|
if (krWater.size() > 0) {
|
2016-09-26 07:17:52 -05:00
|
|
|
|
rstKeywords["KRW"] = 0;
|
2017-02-09 06:54:42 -06:00
|
|
|
|
output.insert("WATKR", // WAT_KR ???
|
2016-11-24 10:43:06 -06:00
|
|
|
|
Opm::UnitSystem::measure::identity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( krWater ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
|
|
|
|
else {
|
2016-10-05 03:59:32 -05:00
|
|
|
|
if ( log )
|
2016-09-15 10:12:09 -05:00
|
|
|
|
{
|
|
|
|
|
Opm::OpmLog::warning("Empty:WATKR",
|
|
|
|
|
"Not emitting empty Water Rel-Perm");
|
|
|
|
|
}
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (liquid_active && rstKeywords["KRO"] > 0) {
|
2017-02-09 06:54:42 -06:00
|
|
|
|
auto& krOil = sd.getCellData("OILKR");
|
|
|
|
|
if (krOil.size() > 0) {
|
2016-09-26 07:17:52 -05:00
|
|
|
|
rstKeywords["KRO"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OILKR",
|
2016-11-24 10:43:06 -06:00
|
|
|
|
Opm::UnitSystem::measure::identity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( krOil ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
|
|
|
|
else {
|
2016-10-05 03:59:32 -05:00
|
|
|
|
if ( log )
|
2016-09-15 10:12:09 -05:00
|
|
|
|
{
|
|
|
|
|
Opm::OpmLog::warning("Empty:OILKR",
|
|
|
|
|
"Not emitting empty Oil Rel-Perm");
|
|
|
|
|
}
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (vapour_active && rstKeywords["KRG"] > 0) {
|
2017-02-09 06:54:42 -06:00
|
|
|
|
auto& krGas = sd.getCellData("GASKR");
|
|
|
|
|
if (krGas.size() > 0) {
|
2016-09-26 07:17:52 -05:00
|
|
|
|
rstKeywords["KRG"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GASKR",
|
2016-11-24 10:43:06 -06:00
|
|
|
|
Opm::UnitSystem::measure::identity,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( krGas ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
|
|
|
|
else {
|
2016-10-05 03:59:32 -05:00
|
|
|
|
if ( log )
|
2016-09-15 10:12:09 -05:00
|
|
|
|
{
|
|
|
|
|
Opm::OpmLog::warning("Empty:GASKR",
|
|
|
|
|
"Not emitting empty Gas Rel-Perm");
|
|
|
|
|
}
|
2016-09-08 06:41:59 -05:00
|
|
|
|
}
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Vaporized and dissolved gas/oil ratio
|
|
|
|
|
*/
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (vapour_active && liquid_active && rstKeywords["RSSAT"] > 0) {
|
|
|
|
|
rstKeywords["RSSAT"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("RSSAT",
|
|
|
|
|
Opm::UnitSystem::measure::gas_oil_ratio,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("RSSAT") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-02 08:38:46 -05:00
|
|
|
|
}
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (vapour_active && liquid_active && rstKeywords["RVSAT"] > 0) {
|
|
|
|
|
rstKeywords["RVSAT"] = 0;
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("RVSAT",
|
|
|
|
|
Opm::UnitSystem::measure::oil_gas_ratio,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( sd.getCellData("RVSAT") ),
|
2017-02-15 07:47:24 -06:00
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
2016-09-02 07:15:10 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 02:38:25 -05:00
|
|
|
|
|
2016-09-02 07:15:10 -05:00
|
|
|
|
/**
|
|
|
|
|
* Bubble point and dew point pressures
|
|
|
|
|
*/
|
2017-02-27 03:28:31 -06:00
|
|
|
|
if (vapour_active && liquid_active && rstKeywords["PBPD"] > 0) {
|
2016-09-26 07:17:52 -05:00
|
|
|
|
rstKeywords["PBPD"] = 0;
|
2017-04-18 03:21:26 -05:00
|
|
|
|
if (sd.hasCellData("PBUB")) {
|
|
|
|
|
output.insert("PBUB",
|
|
|
|
|
Opm::UnitSystem::measure::pressure,
|
|
|
|
|
std::move( sd.getCellData("PBUB") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
2017-04-18 04:09:09 -05:00
|
|
|
|
else if (log) {
|
2017-04-18 04:29:49 -05:00
|
|
|
|
Opm::OpmLog::warning("Bubble point pressure unavailable", "Output of bubble point pressure requested but not available in this simulator. Ignoring.");
|
2017-04-18 04:09:09 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 03:21:26 -05:00
|
|
|
|
if (sd.hasCellData("PDEW")) {
|
|
|
|
|
output.insert("PDEW",
|
|
|
|
|
Opm::UnitSystem::measure::pressure,
|
|
|
|
|
std::move( sd.getCellData("PDEW") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
2017-04-18 04:09:09 -05:00
|
|
|
|
else if (log) {
|
2017-04-18 04:29:49 -05:00
|
|
|
|
Opm::OpmLog::warning("Dew point pressure unavailable", "Output of dew point pressure requested but not available in this simulator. Ignoring.");
|
2017-04-18 04:09:09 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 02:38:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-07 04:29:14 -06:00
|
|
|
|
if (sd.hasCellData("SOMAX")) {
|
|
|
|
|
output.insert("SOMAX",
|
|
|
|
|
Opm::UnitSystem::measure::identity,
|
|
|
|
|
std::move( sd.getCellData("SOMAX") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-24 10:10:25 -06:00
|
|
|
|
if (sd.hasCellData("PCSWMDC_OW")) {
|
|
|
|
|
output.insert("PCSWM_OW", //FIXME: Eight-long variable name
|
|
|
|
|
Opm::UnitSystem::measure::identity,
|
|
|
|
|
std::move( sd.getCellData("PCSWMDC_OW") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
|
|
|
|
if (sd.hasCellData("KRNSWMDC_OW")) {
|
|
|
|
|
output.insert("KRNSW_OW",
|
|
|
|
|
Opm::UnitSystem::measure::identity,
|
|
|
|
|
std::move( sd.getCellData("KRNSWMDC_OW") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sd.hasCellData("PCSWMDC_GO")) {
|
|
|
|
|
output.insert("PCSWM_GO", //FIXME: Eight-long variable name
|
|
|
|
|
Opm::UnitSystem::measure::identity,
|
|
|
|
|
std::move( sd.getCellData("PCSWMDC_GO") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
|
|
|
|
if (sd.hasCellData("KRNSWMDC_GO")) {
|
|
|
|
|
output.insert("KRNSW_GO",
|
|
|
|
|
Opm::UnitSystem::measure::identity,
|
|
|
|
|
std::move( sd.getCellData("KRNSWMDC_GO") ),
|
|
|
|
|
data::TargetType::RESTART_AUXILIARY);
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-06 03:48:34 -05:00
|
|
|
|
//Warn for any unhandled keyword
|
2016-09-26 07:17:52 -05:00
|
|
|
|
if (log) {
|
|
|
|
|
for (auto& keyValue : rstKeywords) {
|
2016-09-15 10:12:09 -05:00
|
|
|
|
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);
|
|
|
|
|
}
|
2016-09-06 03:48:34 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-26 07:55:03 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 02:38:25 -05:00
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
|
2016-09-26 07:55:03 -05:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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>
|
2016-10-04 08:55:29 -05:00
|
|
|
|
void getSummaryData(data::Solution& output,
|
|
|
|
|
const Opm::PhaseUsage& phaseUsage,
|
|
|
|
|
const Model& physicalModel,
|
|
|
|
|
const SummaryConfig& summaryConfig) {
|
2016-09-26 07:55:03 -05:00
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
typedef typename Model::FIPDataType FIPDataType;
|
|
|
|
|
typedef typename FIPDataType::VectorType VectorType;
|
2016-09-26 07:55:03 -05:00
|
|
|
|
|
2017-02-09 06:54:42 -06:00
|
|
|
|
FIPDataType fd = physicalModel.getFIPData();
|
2016-09-26 07:55:03 -05:00
|
|
|
|
|
|
|
|
|
//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];
|
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
/**
|
|
|
|
|
* Now process all of the summary config files
|
|
|
|
|
*/
|
|
|
|
|
// Water in place
|
|
|
|
|
if (aqua_active && hasFRBKeyword(summaryConfig, "WIP")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("WIP",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( fd.fip[ FIPDataType::FIP_AQUA ] ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
if (liquid_active) {
|
2017-02-09 06:54:42 -06:00
|
|
|
|
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 ];
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-27 04:02:04 -05:00
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
//Oil in place (liquid phase only)
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "OIPL")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OIPL",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( oipl ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
//Oil in place (gas phase only)
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "OIPG")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OIPG",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( oipg ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
// Oil in place (in liquid and gas phases)
|
2017-08-01 09:40:34 -05:00
|
|
|
|
if (hasFRBKeyword(summaryConfig, "OIP") || hasFRBKeyword(summaryConfig, "OE")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("OIP",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( oip ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (vapour_active) {
|
2017-02-09 06:54:42 -06:00
|
|
|
|
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 ];
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-27 04:02:04 -05:00
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
// Gas in place (gas phase only)
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "GIPG")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GIPG",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( gipg ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
2016-09-26 07:17:52 -05:00
|
|
|
|
// Gas in place (liquid phase only)
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "GIPL")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GIPL",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( gipl ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
// Gas in place (in both liquid and gas phases)
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "GIP")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("GIP",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( gip ),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Cell pore volume in reservoir conditions
|
|
|
|
|
if (hasFRBKeyword(summaryConfig, "RPV")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("RPV",
|
|
|
|
|
Opm::UnitSystem::measure::volume,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move( fd.fip[FIPDataType::FIP_PV]),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
|
|
|
|
// Pressure averaged value (hydrocarbon pore volume weighted)
|
|
|
|
|
if (summaryConfig.hasKeyword("FPRH") || summaryConfig.hasKeyword("RPRH")) {
|
2016-10-04 08:55:29 -05:00
|
|
|
|
output.insert("PRH",
|
|
|
|
|
Opm::UnitSystem::measure::pressure,
|
2017-02-09 06:54:42 -06:00
|
|
|
|
std::move(fd.fip[FIPDataType::FIP_WEIGHTED_PRESSURE]),
|
2016-10-04 08:55:29 -05:00
|
|
|
|
data::TargetType::SUMMARY );
|
2016-09-26 07:17:52 -05:00
|
|
|
|
}
|
2016-09-01 04:38:04 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class Model>
|
|
|
|
|
inline void
|
|
|
|
|
BlackoilOutputWriter::
|
|
|
|
|
writeTimeStep(const SimulatorTimerInterface& timer,
|
|
|
|
|
const SimulationDataContainer& localState,
|
2016-11-21 10:06:22 -06:00
|
|
|
|
const WellStateFullyImplicitBlackoil& localWellState,
|
2016-09-01 04:38:04 -05:00
|
|
|
|
const Model& physicalModel,
|
2017-06-06 14:35:05 -05:00
|
|
|
|
const bool substep,
|
|
|
|
|
const double nextstep,
|
2017-07-20 05:12:41 -05:00
|
|
|
|
const SimulatorReport& simulatorReport)
|
2016-09-01 04:38:04 -05:00
|
|
|
|
{
|
2016-11-16 05:33:08 -06:00
|
|
|
|
data::Solution localCellData{};
|
2016-10-14 02:23:26 -05:00
|
|
|
|
const RestartConfig& restartConfig = eclipseState_.getRestartConfig();
|
2016-09-01 04:38:04 -05:00
|
|
|
|
const int reportStepNum = timer.reportStepNum();
|
2016-10-05 03:59:32 -05:00
|
|
|
|
bool logMessages = output_ && parallelOutput_->isIORank();
|
2017-06-06 04:42:51 -05:00
|
|
|
|
std::map<std::string, std::vector<double>> extraRestartData;
|
|
|
|
|
std::map<std::string, double> miscSummaryData;
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
2016-11-16 05:33:08 -06:00
|
|
|
|
if( output_ )
|
2016-11-10 10:46:49 -06:00
|
|
|
|
{
|
2017-02-09 06:54:42 -06:00
|
|
|
|
{
|
|
|
|
|
// 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 =
|
2017-03-16 04:22:27 -05:00
|
|
|
|
detail::convertToSimulationDataContainer( physicalModel.getSimulatorData(localState), localState, phaseUsage_ );
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
2017-02-24 10:07:25 -06:00
|
|
|
|
localCellData = simToSolution( sd, restart_double_si_, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...);
|
2017-02-09 06:54:42 -06:00
|
|
|
|
|
|
|
|
|
detail::getRestartData( localCellData, std::move(sd), phaseUsage_, physicalModel,
|
|
|
|
|
restartConfig, reportStepNum, logMessages );
|
|
|
|
|
// sd will be invalid after getRestartData has been called
|
|
|
|
|
}
|
2017-10-29 15:06:19 -05:00
|
|
|
|
detail::getSummaryData( localCellData, phaseUsage_, physicalModel, summaryConfig_ );
|
2017-02-24 07:52:12 -06:00
|
|
|
|
assert(!localCellData.empty());
|
2017-03-01 02:50:32 -06:00
|
|
|
|
|
|
|
|
|
// Add suggested next timestep to extra data.
|
2017-06-06 04:42:51 -05:00
|
|
|
|
extraRestartData["OPMEXTRA"] = std::vector<double>(1, nextstep);
|
|
|
|
|
|
2017-06-06 14:35:05 -05:00
|
|
|
|
// Add TCPU if simulatorReport is not defaulted.
|
|
|
|
|
const double totalSolverTime = simulatorReport.solver_time;
|
|
|
|
|
if (totalSolverTime != 0.0) {
|
|
|
|
|
miscSummaryData["TCPU"] = totalSolverTime;
|
|
|
|
|
}
|
2016-11-10 10:46:49 -06:00
|
|
|
|
}
|
2017-11-08 06:57:36 -06:00
|
|
|
|
writeTimeStepWithCellProperties(timer, localState, localCellData, physicalModel.wellModel().wellState(localWellState), miscSummaryData, extraRestartData, substep);
|
2016-09-01 04:38:04 -05:00
|
|
|
|
}
|
2014-02-20 06:17:18 -06:00
|
|
|
|
}
|
|
|
|
|
#endif
|