mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #934 from andlaus/frankenstein_merge_master_v12
Frankenstein merge master v12
This commit is contained in:
@@ -28,7 +28,7 @@ namespace Opm
|
||||
: BlackoilState( number_of_cells , number_of_faces , number_of_phases)
|
||||
{
|
||||
registerCellData( SSOL , 1 );
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
|
||||
@@ -48,13 +48,19 @@ namespace Opm
|
||||
virtual ~ParallelDebugOutputInterface() {}
|
||||
|
||||
//! \brief gather solution to rank 0 for EclipseWriter
|
||||
//! \param localReservoirState The reservoir state
|
||||
//! \param localWellState The well state
|
||||
//! \param localCellData The cell data used for eclipse output
|
||||
//! (needs to include the cell data of
|
||||
//! localReservoirState)
|
||||
//! \param wellStateStepNumber The step number of the well state.
|
||||
virtual bool collectToIORank( const SimulationDataContainer& localReservoirState,
|
||||
const WellState& localWellState,
|
||||
const data::Solution& localCellData,
|
||||
const int wellStateStepNumber ) = 0;
|
||||
|
||||
virtual const SimulationDataContainer& globalReservoirState() const = 0 ;
|
||||
virtual const data::Solution& globalCellData() const = 0 ;
|
||||
virtual const WellState& globalWellState() const = 0 ;
|
||||
virtual bool isIORank() const = 0;
|
||||
virtual bool isParallel() const = 0;
|
||||
@@ -70,25 +76,33 @@ namespace Opm
|
||||
|
||||
const SimulationDataContainer* globalState_;
|
||||
const WellState* wellState_;
|
||||
const data::Solution* globalCellData_;
|
||||
|
||||
public:
|
||||
ParallelDebugOutput ( const GridImpl& grid,
|
||||
const EclipseState& /* eclipseState */,
|
||||
const int,
|
||||
const double* )
|
||||
const double*,
|
||||
const Opm::PhaseUsage& )
|
||||
: grid_( grid ) {}
|
||||
|
||||
// gather solution to rank 0 for EclipseWriter
|
||||
virtual bool collectToIORank( const SimulationDataContainer& localReservoirState,
|
||||
const WellState& localWellState,
|
||||
const data::Solution& localCellData,
|
||||
const int /* wellStateStepNumber */)
|
||||
{
|
||||
globalState_ = &localReservoirState;
|
||||
wellState_ = &localWellState;
|
||||
globalCellData_ = &localCellData;
|
||||
return true ;
|
||||
}
|
||||
|
||||
virtual const SimulationDataContainer& globalReservoirState() const { return *globalState_; }
|
||||
virtual const data::Solution& globalCellData() const
|
||||
{
|
||||
return *globalCellData_;
|
||||
}
|
||||
virtual const WellState& globalWellState() const { return *wellState_; }
|
||||
virtual bool isIORank () const { return true; }
|
||||
virtual bool isParallel () const { return false; }
|
||||
@@ -231,12 +245,16 @@ namespace Opm
|
||||
ParallelDebugOutput( const Dune::CpGrid& otherGrid,
|
||||
const EclipseState& eclipseState,
|
||||
const int numPhases,
|
||||
const double* permeability )
|
||||
const double* permeability,
|
||||
const Opm::PhaseUsage& phaseUsage)
|
||||
: grid_(),
|
||||
eclipseState_( eclipseState ),
|
||||
permeability_( permeability ),
|
||||
toIORankComm_( otherGrid.comm() ),
|
||||
isIORank_( otherGrid.comm().rank() == ioRank )
|
||||
globalCellData_(new data::Solution),
|
||||
isIORank_( otherGrid.comm().rank() == ioRank ),
|
||||
phaseUsage_(phaseUsage)
|
||||
|
||||
{
|
||||
const CollectiveCommunication& comm = otherGrid.comm();
|
||||
if( comm.size() > 1 )
|
||||
@@ -321,6 +339,8 @@ namespace Opm
|
||||
{
|
||||
const SimulationDataContainer& localState_;
|
||||
SimulationDataContainer& globalState_;
|
||||
const data::Solution& localCellData_;
|
||||
data::Solution& globalCellData_;
|
||||
const WellState& localWellState_;
|
||||
WellState& globalWellState_;
|
||||
const IndexMapType& localIndexMap_;
|
||||
@@ -328,14 +348,18 @@ namespace Opm
|
||||
|
||||
public:
|
||||
PackUnPackSimulationDataContainer( const SimulationDataContainer& localState,
|
||||
SimulationDataContainer& globalState,
|
||||
const WellState& localWellState,
|
||||
WellState& globalWellState,
|
||||
const IndexMapType& localIndexMap,
|
||||
const IndexMapStorageType& indexMaps,
|
||||
const bool isIORank )
|
||||
SimulationDataContainer& globalState,
|
||||
const data::Solution& localCellData,
|
||||
data::Solution& globalCellData,
|
||||
const WellState& localWellState,
|
||||
WellState& globalWellState,
|
||||
const IndexMapType& localIndexMap,
|
||||
const IndexMapStorageType& indexMaps,
|
||||
const bool isIORank )
|
||||
: localState_( localState ),
|
||||
globalState_( globalState ),
|
||||
localCellData_( localCellData ),
|
||||
globalCellData_( globalCellData ),
|
||||
localWellState_( localWellState ),
|
||||
globalWellState_( globalWellState ),
|
||||
localIndexMap_( localIndexMap ),
|
||||
@@ -351,6 +375,18 @@ namespace Opm
|
||||
}
|
||||
}
|
||||
|
||||
// add missing data to global cell data
|
||||
for (const auto& pair : localCellData_) {
|
||||
const std::string& key = pair.first;
|
||||
std::size_t container_size = globalState_.numCells() *
|
||||
pair.second.data.size() / localState_.numCells();
|
||||
auto ret = globalCellData_.insert(key, pair.second.dim,
|
||||
std::vector<double>(container_size),
|
||||
pair.second.target);
|
||||
assert(ret.second);
|
||||
DUNE_UNUSED_PARAMETER(ret.second); //dummy op to prevent warning with -DNDEBUG
|
||||
}
|
||||
|
||||
MessageBufferType buffer;
|
||||
pack( 0, buffer );
|
||||
// the last index map is the local one
|
||||
@@ -367,10 +403,10 @@ namespace Opm
|
||||
}
|
||||
|
||||
// write all cell data registered in local state
|
||||
for (const auto& pair : localState_.cellData()) {
|
||||
for (const auto& pair : localCellData_) {
|
||||
const std::string& key = pair.first;
|
||||
const auto& data = pair.second;
|
||||
const size_t stride = localState_.numCellDataComponents( key );
|
||||
const auto& data = pair.second.data;
|
||||
const size_t stride = data.size()/localState_.numCells();
|
||||
|
||||
for( size_t i=0; i<stride; ++i )
|
||||
{
|
||||
@@ -388,10 +424,11 @@ namespace Opm
|
||||
// write all cell data registered in local state
|
||||
// we loop over the data of the local state as
|
||||
// its order governs the order the data got received.
|
||||
for (auto& pair : localState_.cellData()) {
|
||||
for (auto& pair : localCellData_) {
|
||||
const std::string& key = pair.first;
|
||||
auto& data = globalState_.getCellData(key);
|
||||
const size_t stride = globalState_.numCellDataComponents( key );
|
||||
|
||||
auto& data = globalCellData_.data(key);
|
||||
const size_t stride = data.size() / globalState_.numCells();
|
||||
|
||||
for( size_t i=0; i<stride; ++i )
|
||||
{
|
||||
@@ -525,6 +562,7 @@ namespace Opm
|
||||
// gather solution to rank 0 for EclipseWriter
|
||||
bool collectToIORank( const SimulationDataContainer& localReservoirState,
|
||||
const WellState& localWellState,
|
||||
const data::Solution& localCellData,
|
||||
const int wellStateStepNumber )
|
||||
{
|
||||
if( isIORank() )
|
||||
@@ -556,22 +594,36 @@ namespace Opm
|
||||
|
||||
const Wells* wells = wells_manager.c_wells();
|
||||
globalWellState_.init(wells, *globalReservoirState_, globalWellState_ );
|
||||
globalCellData_->clear();
|
||||
}
|
||||
|
||||
PackUnPackSimulationDataContainer packUnpack( localReservoirState, *globalReservoirState_,
|
||||
localWellState, globalWellState_,
|
||||
localIndexMap_, indexMaps_, isIORank() );
|
||||
localCellData, *globalCellData_,
|
||||
localWellState, globalWellState_,
|
||||
localIndexMap_, indexMaps_,
|
||||
isIORank() );
|
||||
|
||||
//toIORankComm_.exchangeCached( packUnpack );
|
||||
toIORankComm_.exchange( packUnpack );
|
||||
#ifndef NDEBUG
|
||||
// mkae sure every process is on the same page
|
||||
// make sure every process is on the same page
|
||||
toIORankComm_.barrier();
|
||||
#endif
|
||||
if( isIORank() )
|
||||
{
|
||||
// Update values in the globalReservoirState
|
||||
solutionToSim(*globalCellData_, phaseUsage_, *globalReservoirState_);
|
||||
}
|
||||
return isIORank();
|
||||
}
|
||||
|
||||
const SimulationDataContainer& globalReservoirState() const { return *globalReservoirState_; }
|
||||
|
||||
const data::Solution& globalCellData() const
|
||||
{
|
||||
return *globalCellData_;
|
||||
}
|
||||
|
||||
const WellState& globalWellState() const { return globalWellState_; }
|
||||
|
||||
bool isIORank() const
|
||||
@@ -600,10 +652,13 @@ namespace Opm
|
||||
IndexMapType localIndexMap_;
|
||||
IndexMapStorageType indexMaps_;
|
||||
std::unique_ptr<SimulationDataContainer> globalReservoirState_;
|
||||
std::unique_ptr<data::Solution> globalCellData_;
|
||||
// this needs to be revised
|
||||
WellStateFullyImplicitBlackoil globalWellState_;
|
||||
// true if we are on I/O rank
|
||||
const bool isIORank_;
|
||||
// Phase usage needed to convert solution to simulation data container
|
||||
Opm::PhaseUsage phaseUsage_;
|
||||
};
|
||||
#endif // #if HAVE_OPM_GRID
|
||||
|
||||
|
||||
@@ -94,66 +94,6 @@ namespace Opm
|
||||
Opm::writeVtkData(grid, dm, vtkfile);
|
||||
}
|
||||
|
||||
|
||||
void outputStateMatlab(const UnstructuredGrid& grid,
|
||||
const Opm::SimulationDataContainer& state,
|
||||
const int step,
|
||||
const std::string& output_dir)
|
||||
{
|
||||
Opm::DataMap dm;
|
||||
dm["saturation"] = &state.saturation();
|
||||
dm["pressure"] = &state.pressure();
|
||||
for (const auto& pair : state.cellData()) {
|
||||
const std::string& name = pair.first;
|
||||
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
|
||||
dm[ key ] = &pair.second;
|
||||
}
|
||||
|
||||
std::vector<double> cell_velocity;
|
||||
Opm::estimateCellVelocity(AutoDiffGrid::numCells(grid),
|
||||
AutoDiffGrid::numFaces(grid),
|
||||
AutoDiffGrid::beginFaceCentroids(grid),
|
||||
UgGridHelpers::faceCells(grid),
|
||||
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;
|
||||
boost::filesystem::path fpath = fname.str();
|
||||
try {
|
||||
create_directories(fpath);
|
||||
}
|
||||
catch (...) {
|
||||
OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath);
|
||||
}
|
||||
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"));
|
||||
}
|
||||
}
|
||||
void outputWellStateMatlab(const Opm::WellState& well_state,
|
||||
const int step,
|
||||
const std::string& output_dir)
|
||||
@@ -300,7 +240,13 @@ namespace Opm
|
||||
const WellState& localWellState,
|
||||
bool substep)
|
||||
{
|
||||
writeTimeStepWithCellProperties(timer, localState, localWellState, {} , substep);
|
||||
data::Solution localCellData{};
|
||||
if( output_ )
|
||||
{
|
||||
localCellData = simToSolution(localState, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...);
|
||||
}
|
||||
writeTimeStepWithCellProperties(timer, localState, localCellData ,
|
||||
localWellState, substep);
|
||||
}
|
||||
|
||||
|
||||
@@ -312,8 +258,8 @@ namespace Opm
|
||||
writeTimeStepWithCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& localState,
|
||||
const data::Solution& localCellData,
|
||||
const WellState& localWellState,
|
||||
const data::Solution& cellData,
|
||||
bool substep)
|
||||
{
|
||||
// VTK output (is parallel if grid is parallel)
|
||||
@@ -332,9 +278,12 @@ namespace Opm
|
||||
int wellStateStepNumber = ( ! substep && timer.reportStepNum() > 0) ?
|
||||
(timer.reportStepNum() - 1) : timer.reportStepNum();
|
||||
// collect all solutions to I/O rank
|
||||
isIORank = parallelOutput_->collectToIORank( localState, localWellState, wellStateStepNumber );
|
||||
isIORank = parallelOutput_->collectToIORank( localState, localWellState,
|
||||
localCellData,
|
||||
wellStateStepNumber );
|
||||
}
|
||||
|
||||
const data::Solution& cellData = ( parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalCellData() : localCellData;
|
||||
const SimulationDataContainer& state = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalReservoirState() : localState;
|
||||
const WellState& wellState = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalWellState() : localWellState;
|
||||
|
||||
@@ -374,12 +323,11 @@ namespace Opm
|
||||
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(simProps.begin(), simProps.end()); // ... insert "extra" data (KR, VISC, ...)
|
||||
// ... insert "extra" data (KR, VISC, ...)
|
||||
eclWriter_->writeTimeStep(timer.reportStepNum(),
|
||||
substep,
|
||||
timer.simulationTimeElapsed(),
|
||||
combined_sol,
|
||||
simProps,
|
||||
wellState.report(phaseUsage_));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,12 +68,6 @@ namespace Opm
|
||||
const int step,
|
||||
const std::string& output_dir);
|
||||
|
||||
|
||||
void outputStateMatlab(const UnstructuredGrid& grid,
|
||||
const Opm::SimulationDataContainer& state,
|
||||
const int step,
|
||||
const std::string& output_dir);
|
||||
|
||||
void outputWellStateMatlab(const Opm::WellState& well_state,
|
||||
const int step,
|
||||
const std::string& output_dir);
|
||||
@@ -243,8 +237,8 @@ namespace Opm
|
||||
void writeTimeStepWithCellProperties(
|
||||
const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const data::Solution& cellData,
|
||||
const Opm::WellState& wellState,
|
||||
const data::Solution& solution,
|
||||
bool substep = false);
|
||||
|
||||
/*!
|
||||
@@ -266,7 +260,7 @@ namespace Opm
|
||||
void writeTimeStepSerial(const SimulatorTimerInterface& timer,
|
||||
const SimulationDataContainer& reservoirState,
|
||||
const Opm::WellState& wellState,
|
||||
const data::Solution& cellData,
|
||||
const data::Solution& simProps,
|
||||
bool substep);
|
||||
|
||||
/** \brief return output directory */
|
||||
@@ -333,7 +327,7 @@ namespace Opm
|
||||
const Opm::PhaseUsage &phaseUsage,
|
||||
const double* permeability )
|
||||
: output_( param.getDefault("output", true) ),
|
||||
parallelOutput_( output_ ? new ParallelDebugOutput< Grid >( grid, eclipseState, phaseUsage.num_phases, permeability ) : 0 ),
|
||||
parallelOutput_( output_ ? new ParallelDebugOutput< Grid >( grid, eclipseState, phaseUsage.num_phases, permeability, phaseUsage ) : 0 ),
|
||||
outputDir_( output_ ? param.getDefault("output_dir", std::string("output")) : "." ),
|
||||
output_interval_( output_ ? param.getDefault("output_interval", 1): 0 ),
|
||||
lastBackupReportStep_( -1 ),
|
||||
@@ -350,9 +344,17 @@ namespace Opm
|
||||
.reset(new BlackoilVTKWriter< Grid >( grid, outputDir_ ));
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
if( parallelOutput_->isIORank() ) {
|
||||
|
||||
if ( param.getDefault("output_matlab", false ) )
|
||||
if ( output_matlab )
|
||||
{
|
||||
matlabWriter_
|
||||
.reset(new BlackoilMatlabWriter< Grid >( grid, outputDir_ ));
|
||||
@@ -468,8 +470,6 @@ namespace Opm
|
||||
const int reportStepNum,
|
||||
const bool log) {
|
||||
|
||||
typedef Opm::AutoDiffBlock<double> ADB;
|
||||
|
||||
const typename Model::SimulatorData& sd = physicalModel.getSimulatorData();
|
||||
//Get the value of each of the keys for the restart keywords
|
||||
std::map<std::string, int> rstKeywords = restartConfig.getRestartKeywords(reportStepNum);
|
||||
@@ -785,57 +785,21 @@ namespace Opm
|
||||
const Model& physicalModel,
|
||||
bool substep)
|
||||
{
|
||||
data::Solution cellData{};
|
||||
data::Solution localCellData{};
|
||||
const RestartConfig& restartConfig = eclipseState_.getRestartConfig();
|
||||
const SummaryConfig& summaryConfig = eclipseState_.getSummaryConfig();
|
||||
const int reportStepNum = timer.reportStepNum();
|
||||
bool logMessages = output_ && parallelOutput_->isIORank();
|
||||
|
||||
if( output_ && !parallelOutput_->isParallel() )
|
||||
if( output_ )
|
||||
{
|
||||
|
||||
detail::getRestartData( cellData, phaseUsage_, physicalModel,
|
||||
localCellData = simToSolution(localState, phaseUsage_); // Get "normal" data (SWAT, PRESSURE, ...);
|
||||
detail::getRestartData( localCellData, phaseUsage_, physicalModel,
|
||||
restartConfig, reportStepNum, logMessages );
|
||||
detail::getSummaryData( cellData, phaseUsage_, physicalModel, summaryConfig );
|
||||
detail::getSummaryData( localCellData, 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);
|
||||
writeTimeStepWithCellProperties(timer, localState, localCellData, localWellState, substep);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user