From 29053dc18de06db8d53e658fed66dbb1afa6d210 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Mon, 21 Mar 2016 10:58:50 +0100 Subject: [PATCH] SimulFulImplBOOutput: asynchronous serial output. --- .../SimulatorFullyImplicitBlackoilOutput.cpp | 146 ++++++++++++------ .../SimulatorFullyImplicitBlackoilOutput.hpp | 6 + 2 files changed, 101 insertions(+), 51 deletions(-) diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp index a57fcdb8a..f57eb5872 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014 SINTEF ICT, Applied Mathematics. - Copyright (c) 2015 IRIS AS + Copyright (c) 2015-2016 IRIS AS This file is part of the Open Porous Media project (OPM). @@ -19,6 +19,8 @@ */ #include "config.h" +#include + #include "SimulatorFullyImplicitBlackoilOutput.hpp" #include @@ -252,6 +254,34 @@ namespace Opm } } + struct WriterCall + { + BlackoilOutputWriter& writer_; + std::unique_ptr< SimulatorTimerInterface > timer_; + const SimulatorState state_; + const WellState wellState_; + const bool substep_; + + explicit WriterCall( BlackoilOutputWriter& writer, + const SimulatorTimerInterface& timer, + const SimulatorState& state, + const WellState& wellState, + bool substep) + : writer_( writer ), + timer_( timer.clone() ), + state_( state ), + wellState_( wellState ), + substep_( substep ) + {} + + // callback to writer's serial writeTimeStep method + void operator () () + { + writer_.writeTimeStepSerial( *timer_, state_, wellState_, substep_ ); + } + }; + + void BlackoilOutputWriter:: writeTimeStep(const SimulatorTimerInterface& timer, @@ -274,63 +304,77 @@ namespace Opm const SimulatorState& state = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalReservoirState() : localState; const WellState& wellState = (parallelOutput_ && parallelOutput_->isParallel() ) ? parallelOutput_->globalWellState() : localWellState; - // output is only done on I/O rank + // serial output is only done on I/O rank if( isIORank ) { - // Matlab output - if( matlabWriter_ ) { - matlabWriter_->writeTimeStep( timer, state, wellState, substep ); - } - // ECL output - if ( eclWriter_ ) { - const auto initConfig = eclipseState_->getInitConfig(); - if (initConfig->getRestartInitiated() && ((initConfig->getRestartStep()) == (timer.currentStepNum()))) { - std::cout << "Skipping restart write in start of step " << timer.currentStepNum() << std::endl; - } else { - eclWriter_->writeTimeStep(timer, state, wellState, substep ); - } - } + // spawn write thread that calls eclWriter.writeTimeStepSerial + WriterCall call( *this, timer, state, wellState, substep ); + std::async( std::move( call ) ); + } + } - // write backup file - if( backupfile_ ) + void + BlackoilOutputWriter:: + writeTimeStepSerial(const SimulatorTimerInterface& timer, + const SimulatorState& state, + const WellState& wellState, + bool substep) + { + // Matlab output + if( matlabWriter_ ) { + matlabWriter_->writeTimeStep( timer, state, wellState, substep ); + } + + // ECL output + if ( eclWriter_ ) + { + const auto initConfig = eclipseState_->getInitConfig(); + if (initConfig->getRestartInitiated() && ((initConfig->getRestartStep()) == (timer.currentStepNum()))) { + std::cout << "Skipping restart write in start of step " << timer.currentStepNum() << std::endl; + } else { + eclWriter_->writeTimeStep(timer, state, wellState, substep ); + } + } + + // write backup file + if( backupfile_ ) + { + 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 { - 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) ); + // store report step + lastBackupReportStep_ = reportStep; + // write resport step number + backupfile_.write( (const char *) &reportStep, sizeof(int) ); - try { - const BlackoilState& boState = dynamic_cast< const BlackoilState& > (state); - backupfile_ << boState; + try { + const BlackoilState& boState = dynamic_cast< const BlackoilState& > (state); + backupfile_ << boState; - const WellStateFullyImplicitBlackoil& boWellState = static_cast< const WellStateFullyImplicitBlackoil& > (wellState); - backupfile_ << boWellState; - } - catch ( const std::bad_cast& e ) - { - - } - - /* - const WellStateFullyImplicitBlackoil* boWellState = - dynamic_cast< const WellStateFullyImplicitBlackoil* > (&wellState); - if( boWellState ) { - backupfile_ << (*boWellState); - } - else - OPM_THROW(std::logic_error,"cast to WellStateFullyImplicitBlackoil failed"); - */ - backupfile_ << std::flush; + const WellStateFullyImplicitBlackoil& boWellState = static_cast< const WellStateFullyImplicitBlackoil& > (wellState); + backupfile_ << boWellState; } - } // end backup - } // end isIORank + catch ( const std::bad_cast& e ) + { + + } + + /* + const WellStateFullyImplicitBlackoil* boWellState = + dynamic_cast< const WellStateFullyImplicitBlackoil* > (&wellState); + if( boWellState ) { + backupfile_ << (*boWellState); + } + else + OPM_THROW(std::logic_error,"cast to WellStateFullyImplicitBlackoil failed"); + */ + backupfile_ << std::flush; + } + } // end backup } void diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index a4e8e879c..1cd42e9e4 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -218,6 +218,12 @@ namespace Opm const Opm::WellState& wellState, bool substep = false); + /** \copydoc Opm::OutputWriter::writeTimeStep */ + void writeTimeStepSerial(const SimulatorTimerInterface& timer, + const SimulatorState& reservoirState, + const Opm::WellState& wellState, + bool substep); + /** \brief return output directory */ const std::string& outputDirectory() const { return outputDir_; }