diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 04396a5cd..51854af8e 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -2,215 +2,216 @@ # vim: set filetype=cmake autoindent tabstop=2 shiftwidth=2 noexpandtab softtabstop=2 nowrap: # This file sets up five lists: -# MAIN_SOURCE_FILES List of compilation units which will be included in -# the library. If it isn't on this list, it won't be -# part of the library. Please try to keep it sorted to -# maintain sanity. +# MAIN_SOURCE_FILES List of compilation units which will be included in +# the library. If it isn't on this list, it won't be +# part of the library. Please try to keep it sorted to +# maintain sanity. # -# TEST_SOURCE_FILES List of programs that will be run as unit tests. +# TEST_SOURCE_FILES List of programs that will be run as unit tests. # -# TEST_DATA_FILES Files from the source three that should be made -# available in the corresponding location in the build -# tree in order to run tests there. +# TEST_DATA_FILES Files from the source three that should be made +# available in the corresponding location in the build +# tree in order to run tests there. # -# EXAMPLE_SOURCE_FILES Other programs that will be compiled as part of the -# build, but which is not part of the library nor is -# run as tests. +# EXAMPLE_SOURCE_FILES Other programs that will be compiled as part of the +# build, but which is not part of the library nor is +# run as tests. # -# PUBLIC_HEADER_FILES List of public header files that should be -# distributed together with the library. The source -# files can of course include other files than these; -# you should only add to this list if the *user* of -# the library needs it. +# PUBLIC_HEADER_FILES List of public header files that should be +# distributed together with the library. The source +# files can of course include other files than these; +# you should only add to this list if the *user* of +# the library needs it. # originally generated with the command: # find opm -name '*.c*' -printf '\t%p\n' | sort list (APPEND MAIN_SOURCE_FILES - opm/autodiff/BlackoilPropsAdInterface.cpp - opm/autodiff/ExtractParallelGridInformationToISTL.cpp - opm/autodiff/NewtonIterationBlackoilCPR.cpp - opm/autodiff/NewtonIterationBlackoilInterleaved.cpp - opm/autodiff/NewtonIterationBlackoilSimple.cpp - opm/autodiff/NewtonIterationUtilities.cpp - opm/autodiff/GridHelpers.cpp - opm/autodiff/ImpesTPFAAD.cpp - opm/autodiff/moduleVersion.cpp - opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp - opm/autodiff/SimulatorIncompTwophaseAd.cpp - opm/autodiff/TransportSolverTwophaseAd.cpp - opm/autodiff/BlackoilPropsAdFromDeck.cpp - opm/autodiff/SolventPropsAdFromDeck.cpp - opm/autodiff/BlackoilModelParameters.cpp - opm/autodiff/WellDensitySegmented.cpp - opm/autodiff/LinearisedBlackoilResidual.cpp - opm/autodiff/VFPProperties.cpp - opm/autodiff/VFPProdProperties.cpp - opm/autodiff/VFPInjProperties.cpp - opm/autodiff/WellMultiSegment.cpp - opm/autodiff/StandardWells.cpp - opm/autodiff/BlackoilSolventState.cpp - opm/polymer/PolymerState.cpp - opm/polymer/PolymerBlackoilState.cpp - opm/polymer/CompressibleTpfaPolymer.cpp - opm/polymer/IncompTpfaPolymer.cpp - opm/polymer/PolymerInflow.cpp - opm/polymer/PolymerProperties.cpp - opm/polymer/polymerUtilities.cpp - opm/polymer/SimulatorCompressiblePolymer.cpp - opm/polymer/SimulatorPolymer.cpp - opm/polymer/TransportSolverTwophaseCompressiblePolymer.cpp - opm/polymer/TransportSolverTwophasePolymer.cpp - opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp - opm/polymer/fullyimplicit/PolymerPropsAd.cpp - ) + opm/autodiff/BlackoilPropsAdInterface.cpp + opm/autodiff/ExtractParallelGridInformationToISTL.cpp + opm/autodiff/NewtonIterationBlackoilCPR.cpp + opm/autodiff/NewtonIterationBlackoilInterleaved.cpp + opm/autodiff/NewtonIterationBlackoilSimple.cpp + opm/autodiff/NewtonIterationUtilities.cpp + opm/autodiff/GridHelpers.cpp + opm/autodiff/ImpesTPFAAD.cpp + opm/autodiff/moduleVersion.cpp + opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp + opm/autodiff/SimulatorIncompTwophaseAd.cpp + opm/autodiff/TransportSolverTwophaseAd.cpp + opm/autodiff/BlackoilPropsAdFromDeck.cpp + opm/autodiff/SolventPropsAdFromDeck.cpp + opm/autodiff/BlackoilModelParameters.cpp + opm/autodiff/WellDensitySegmented.cpp + opm/autodiff/LinearisedBlackoilResidual.cpp + opm/autodiff/VFPProperties.cpp + opm/autodiff/VFPProdProperties.cpp + opm/autodiff/VFPInjProperties.cpp + opm/autodiff/WellMultiSegment.cpp + opm/autodiff/StandardWells.cpp + opm/autodiff/BlackoilSolventState.cpp + opm/autodiff/ThreadHandle.hpp + opm/polymer/PolymerState.cpp + opm/polymer/PolymerBlackoilState.cpp + opm/polymer/CompressibleTpfaPolymer.cpp + opm/polymer/IncompTpfaPolymer.cpp + opm/polymer/PolymerInflow.cpp + opm/polymer/PolymerProperties.cpp + opm/polymer/polymerUtilities.cpp + opm/polymer/SimulatorCompressiblePolymer.cpp + opm/polymer/SimulatorPolymer.cpp + opm/polymer/TransportSolverTwophaseCompressiblePolymer.cpp + opm/polymer/TransportSolverTwophasePolymer.cpp + opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp + opm/polymer/fullyimplicit/PolymerPropsAd.cpp + ) # originally generated with the command: # find tests -name '*.cpp' -a ! -wholename '*/not-unit/*' -printf '\t%p\n' | sort list (APPEND TEST_SOURCE_FILES - tests/test_autodiffhelpers.cpp - tests/test_autodiffmatrix.cpp - tests/test_block.cpp - tests/test_boprops_ad.cpp - tests/test_rateconverter.cpp - tests/test_span.cpp - tests/test_syntax.cpp - tests/test_scalar_mult.cpp - tests/test_transmissibilitymultipliers.cpp - tests/test_welldensitysegmented.cpp - tests/test_vfpproperties.cpp - tests/test_singlecellsolves.cpp - tests/test_solventprops_ad.cpp - ) + tests/test_autodiffhelpers.cpp + tests/test_autodiffmatrix.cpp + tests/test_block.cpp + tests/test_boprops_ad.cpp + tests/test_rateconverter.cpp + tests/test_span.cpp + tests/test_syntax.cpp + tests/test_scalar_mult.cpp + tests/test_transmissibilitymultipliers.cpp + tests/test_welldensitysegmented.cpp + tests/test_vfpproperties.cpp + tests/test_singlecellsolves.cpp + tests/test_solventprops_ad.cpp + ) list (APPEND TEST_DATA_FILES - tests/fluid.data - tests/VFPPROD1 - tests/VFPPROD2 - ) + tests/fluid.data + tests/VFPPROD1 + tests/VFPPROD2 + ) # originally generated with the command: # find tutorials examples -name '*.c*' -printf '\t%p\n' | sort list (APPEND EXAMPLE_SOURCE_FILES - examples/find_zero.cpp - examples/flow.cpp - examples/flow_multisegment.cpp - examples/flow_solvent.cpp - examples/sim_2p_incomp_ad.cpp - examples/sim_simple.cpp - examples/opm_init_check.cpp - examples/sim_poly2p_comp_reorder.cpp - examples/sim_poly2p_incomp_reorder.cpp - examples/sim_poly_fi2p_comp_ad.cpp - examples/flow_polymer.cpp - ) + examples/find_zero.cpp + examples/flow.cpp + examples/flow_multisegment.cpp + examples/flow_solvent.cpp + examples/sim_2p_incomp_ad.cpp + examples/sim_simple.cpp + examples/opm_init_check.cpp + examples/sim_poly2p_comp_reorder.cpp + examples/sim_poly2p_incomp_reorder.cpp + examples/sim_poly_fi2p_comp_ad.cpp + examples/flow_polymer.cpp + ) # programs listed here will not only be compiled, but also marked for # installation list (APPEND PROGRAM_SOURCE_FILES - examples/sim_2p_incomp_ad.cpp - examples/flow.cpp - examples/flow_solvent.cpp - examples/opm_init_check.cpp - examples/sim_poly2p_comp_reorder.cpp - examples/sim_poly2p_incomp_reorder.cpp - examples/sim_poly_fi2p_comp_ad.cpp - examples/flow_polymer.cpp - ) + examples/sim_2p_incomp_ad.cpp + examples/flow.cpp + examples/flow_solvent.cpp + examples/opm_init_check.cpp + examples/sim_poly2p_comp_reorder.cpp + examples/sim_poly2p_incomp_reorder.cpp + examples/sim_poly_fi2p_comp_ad.cpp + examples/flow_polymer.cpp + ) # originally generated with the command: # find opm -name '*.h*' -a ! -name '*-pch.hpp' -printf '\t%p\n' | sort list (APPEND PUBLIC_HEADER_FILES - opm/autodiff/AdditionalObjectDeleter.hpp - opm/autodiff/AutoDiffBlock.hpp - opm/autodiff/AutoDiffHelpers.hpp - opm/autodiff/AutoDiffMatrix.hpp - opm/autodiff/AutoDiff.hpp - opm/autodiff/BackupRestore.hpp - opm/autodiff/BlackoilModel.hpp - opm/autodiff/BlackoilModelBase.hpp - opm/autodiff/BlackoilModelBase_impl.hpp - opm/autodiff/BlackoilModelEnums.hpp - opm/autodiff/BlackoilModelParameters.hpp - opm/autodiff/BlackoilPropsAdFromDeck.hpp - opm/autodiff/SolventPropsAdFromDeck.hpp - opm/autodiff/BlackoilPropsAdInterface.hpp - opm/autodiff/CPRPreconditioner.hpp - opm/autodiff/createGlobalCellArray.hpp - opm/autodiff/BlackoilSolventModel.hpp - opm/autodiff/BlackoilSolventModel_impl.hpp - opm/autodiff/BlackoilSolventState.hpp - opm/autodiff/BlackoilMultiSegmentModel.hpp - opm/autodiff/BlackoilMultiSegmentModel_impl.hpp - opm/autodiff/fastSparseOperations.hpp - opm/autodiff/DuneMatrix.hpp - opm/autodiff/ExtractParallelGridInformationToISTL.hpp - opm/autodiff/FlowMain.hpp - opm/autodiff/FlowMainPolymer.hpp - opm/autodiff/FlowMainSolvent.hpp - opm/autodiff/GeoProps.hpp - opm/autodiff/GridHelpers.hpp - opm/autodiff/GridInit.hpp - opm/autodiff/ImpesTPFAAD.hpp - opm/autodiff/moduleVersion.hpp - opm/autodiff/NewtonIterationBlackoilCPR.hpp - opm/autodiff/NewtonIterationBlackoilInterface.hpp - opm/autodiff/NewtonIterationBlackoilInterleaved.hpp - opm/autodiff/NewtonIterationBlackoilSimple.hpp - opm/autodiff/NewtonIterationUtilities.hpp - opm/autodiff/NonlinearSolver.hpp - opm/autodiff/NonlinearSolver_impl.hpp - opm/autodiff/LinearisedBlackoilResidual.hpp - opm/autodiff/ParallelDebugOutput.hpp - opm/autodiff/ParallelOverlappingILU0.hpp - opm/autodiff/ParallelRestrictedAdditiveSchwarz.hpp - opm/autodiff/RateConverter.hpp - opm/autodiff/RedistributeDataHandles.hpp - opm/autodiff/SimulatorBase.hpp - opm/autodiff/SimulatorBase_impl.hpp - opm/autodiff/SimulatorFullyImplicitBlackoil.hpp - opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp - opm/autodiff/SimulatorFullyImplicitBlackoilSolvent_impl.hpp - opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment.hpp - opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp - opm/autodiff/SimulatorIncompTwophaseAd.hpp - opm/autodiff/TransportSolverTwophaseAd.hpp - opm/autodiff/WellDensitySegmented.hpp - opm/autodiff/WellStateFullyImplicitBlackoil.hpp - opm/autodiff/WellStateFullyImplicitBlackoilSolvent.hpp - opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp - opm/autodiff/VFPProperties.hpp - opm/autodiff/VFPHelpers.hpp - opm/autodiff/VFPProdProperties.hpp - opm/autodiff/VFPInjProperties.hpp - opm/autodiff/WellStateMultiSegment.hpp - opm/autodiff/WellMultiSegment.hpp - opm/autodiff/StandardWells.hpp - opm/polymer/CompressibleTpfaPolymer.hpp - opm/polymer/GravityColumnSolverPolymer.hpp - opm/polymer/GravityColumnSolverPolymer_impl.hpp - opm/polymer/IncompPropertiesDefaultPolymer.hpp - opm/polymer/IncompTpfaPolymer.hpp - opm/polymer/PolymerBlackoilState.hpp - opm/polymer/PolymerInflow.hpp - opm/polymer/PolymerProperties.hpp - opm/polymer/PolymerState.hpp - opm/polymer/polymerUtilities.hpp - opm/polymer/SimulatorCompressiblePolymer.hpp - opm/polymer/SimulatorPolymer.hpp - opm/polymer/SinglePointUpwindTwoPhasePolymer.hpp - opm/polymer/TransportSolverTwophaseCompressiblePolymer.hpp - opm/polymer/Point2D.hpp - opm/polymer/TransportSolverTwophasePolymer.hpp - opm/polymer/fullyimplicit/PolymerPropsAd.hpp - opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp - opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp - opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp - opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp - opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp - opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp - opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp - opm/polymer/fullyimplicit/WellStateFullyImplicitBlackoilPolymer.hpp - ) + opm/autodiff/AdditionalObjectDeleter.hpp + opm/autodiff/AutoDiffBlock.hpp + opm/autodiff/AutoDiffHelpers.hpp + opm/autodiff/AutoDiffMatrix.hpp + opm/autodiff/AutoDiff.hpp + opm/autodiff/BackupRestore.hpp + opm/autodiff/BlackoilModel.hpp + opm/autodiff/BlackoilModelBase.hpp + opm/autodiff/BlackoilModelBase_impl.hpp + opm/autodiff/BlackoilModelEnums.hpp + opm/autodiff/BlackoilModelParameters.hpp + opm/autodiff/BlackoilPropsAdFromDeck.hpp + opm/autodiff/SolventPropsAdFromDeck.hpp + opm/autodiff/BlackoilPropsAdInterface.hpp + opm/autodiff/CPRPreconditioner.hpp + opm/autodiff/createGlobalCellArray.hpp + opm/autodiff/BlackoilSolventModel.hpp + opm/autodiff/BlackoilSolventModel_impl.hpp + opm/autodiff/BlackoilSolventState.hpp + opm/autodiff/BlackoilMultiSegmentModel.hpp + opm/autodiff/BlackoilMultiSegmentModel_impl.hpp + opm/autodiff/fastSparseOperations.hpp + opm/autodiff/DuneMatrix.hpp + opm/autodiff/ExtractParallelGridInformationToISTL.hpp + opm/autodiff/FlowMain.hpp + opm/autodiff/FlowMainPolymer.hpp + opm/autodiff/FlowMainSolvent.hpp + opm/autodiff/GeoProps.hpp + opm/autodiff/GridHelpers.hpp + opm/autodiff/GridInit.hpp + opm/autodiff/ImpesTPFAAD.hpp + opm/autodiff/moduleVersion.hpp + opm/autodiff/NewtonIterationBlackoilCPR.hpp + opm/autodiff/NewtonIterationBlackoilInterface.hpp + opm/autodiff/NewtonIterationBlackoilInterleaved.hpp + opm/autodiff/NewtonIterationBlackoilSimple.hpp + opm/autodiff/NewtonIterationUtilities.hpp + opm/autodiff/NonlinearSolver.hpp + opm/autodiff/NonlinearSolver_impl.hpp + opm/autodiff/LinearisedBlackoilResidual.hpp + opm/autodiff/ParallelDebugOutput.hpp + opm/autodiff/ParallelOverlappingILU0.hpp + opm/autodiff/ParallelRestrictedAdditiveSchwarz.hpp + opm/autodiff/RateConverter.hpp + opm/autodiff/RedistributeDataHandles.hpp + opm/autodiff/SimulatorBase.hpp + opm/autodiff/SimulatorBase_impl.hpp + opm/autodiff/SimulatorFullyImplicitBlackoil.hpp + opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp + opm/autodiff/SimulatorFullyImplicitBlackoilSolvent_impl.hpp + opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment.hpp + opm/autodiff/SimulatorFullyImplicitBlackoilMultiSegment_impl.hpp + opm/autodiff/SimulatorIncompTwophaseAd.hpp + opm/autodiff/TransportSolverTwophaseAd.hpp + opm/autodiff/WellDensitySegmented.hpp + opm/autodiff/WellStateFullyImplicitBlackoil.hpp + opm/autodiff/WellStateFullyImplicitBlackoilSolvent.hpp + opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp + opm/autodiff/VFPProperties.hpp + opm/autodiff/VFPHelpers.hpp + opm/autodiff/VFPProdProperties.hpp + opm/autodiff/VFPInjProperties.hpp + opm/autodiff/WellStateMultiSegment.hpp + opm/autodiff/WellMultiSegment.hpp + opm/autodiff/StandardWells.hpp + opm/polymer/CompressibleTpfaPolymer.hpp + opm/polymer/GravityColumnSolverPolymer.hpp + opm/polymer/GravityColumnSolverPolymer_impl.hpp + opm/polymer/IncompPropertiesDefaultPolymer.hpp + opm/polymer/IncompTpfaPolymer.hpp + opm/polymer/PolymerBlackoilState.hpp + opm/polymer/PolymerInflow.hpp + opm/polymer/PolymerProperties.hpp + opm/polymer/PolymerState.hpp + opm/polymer/polymerUtilities.hpp + opm/polymer/SimulatorCompressiblePolymer.hpp + opm/polymer/SimulatorPolymer.hpp + opm/polymer/SinglePointUpwindTwoPhasePolymer.hpp + opm/polymer/TransportSolverTwophaseCompressiblePolymer.hpp + opm/polymer/Point2D.hpp + opm/polymer/TransportSolverTwophasePolymer.hpp + opm/polymer/fullyimplicit/PolymerPropsAd.hpp + opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp + opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp + opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp + opm/polymer/fullyimplicit/BlackoilPolymerModel.hpp + opm/polymer/fullyimplicit/BlackoilPolymerModel_impl.hpp + opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp + opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp + opm/polymer/fullyimplicit/WellStateFullyImplicitBlackoilPolymer.hpp + ) diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.cpp index f5c38820b..f55fddc9e 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). @@ -253,6 +253,40 @@ namespace Opm } } + + namespace detail { + + struct WriterCall : public ThreadHandle :: ObjectInterface + { + BlackoilOutputWriter& writer_; + std::unique_ptr< SimulatorTimerInterface > timer_; + const SimulationDataContainer state_; + const WellState wellState_; + const bool substep_; + + explicit WriterCall( BlackoilOutputWriter& writer, + const SimulatorTimerInterface& timer, + const SimulationDataContainer& 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 run () + { + // write data + writer_.writeTimeStepSerial( *timer_, state_, wellState_, substep_ ); + } + }; + } + + void BlackoilOutputWriter:: writeTimeStep(const SimulatorTimerInterface& timer, @@ -265,7 +299,7 @@ namespace Opm vtkWriter_->writeTimeStep( timer, localState, localWellState, false ); } - bool isIORank = true ; + bool isIORank = output_ ; if( parallelOutput_ && parallelOutput_->isParallel() ) { // collect all solutions to I/O rank @@ -275,65 +309,71 @@ namespace Opm const SimulationDataContainer& 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 ); + if( asyncOutput_ ) { + // dispatch the write call to the extra thread + asyncOutput_->dispatch( detail::WriterCall( *this, 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 ); - } + else { + // just write the data to disk + writeTimeStepSerial( timer, state, wellState, substep ); } + } + } - // write backup file - if( backupfile_ ) + void + BlackoilOutputWriter:: + writeTimeStepSerial(const SimulatorTimerInterface& timer, + const SimulationDataContainer& 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_.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 { - 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 { + backupfile_ << state; - 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 ) + { + } + + backupfile_ << std::flush; + } + } // end backup } void diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp index 352e8986c..d2b0b678b 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilOutput.hpp @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include @@ -85,7 +87,7 @@ namespace Opm Opm::DataMap dm; dm["saturation"] = &state.saturation(); dm["pressure"] = &state.pressure(); - for (const auto& pair : state.cellData()) + for (const auto& pair : state.cellData()) { const std::string& name = pair.first; std::string key; @@ -220,6 +222,12 @@ namespace Opm const Opm::WellState& wellState, bool substep = false); + /** \copydoc Opm::OutputWriter::writeTimeStep */ + void writeTimeStepSerial(const SimulatorTimerInterface& timer, + const SimulationDataContainer& reservoirState, + const Opm::WellState& wellState, + bool substep); + /** \brief return output directory */ const std::string& outputDirectory() const { return outputDir_; } @@ -257,6 +265,8 @@ namespace Opm std::unique_ptr< OutputWriter > matlabWriter_; std::unique_ptr< EclipseWriter > eclWriter_; EclipseStateConstPtr eclipseState_; + + std::unique_ptr< ThreadHandle > asyncOutput_; }; @@ -289,8 +299,15 @@ namespace Opm parallelOutput_->numCells(), parallelOutput_->globalCell() ) : 0 ), - eclipseState_(eclipseState) + eclipseState_(eclipseState), + asyncOutput_() { + // create output thread if needed + if( output_ && param.getDefault("async_output", bool( false ) ) ) + { + asyncOutput_.reset( new ThreadHandle() ); + } + // For output. if (output_ && parallelOutput_->isIORank() ) { // Ensure that output dir exists diff --git a/opm/autodiff/ThreadHandle.hpp b/opm/autodiff/ThreadHandle.hpp new file mode 100644 index 000000000..2888e054a --- /dev/null +++ b/opm/autodiff/ThreadHandle.hpp @@ -0,0 +1,158 @@ +#ifndef OPM_THREADHANDLE_HPP +#define OPM_THREADHANDLE_HPP + +#include +#include + +#include +#include +#include + +namespace Opm +{ + + class ThreadHandle + { + public: + class ObjectInterface + { + protected: + ObjectInterface() {} + public: + virtual ~ObjectInterface() {} + virtual void run() = 0; + virtual bool isEndMarker () const { return false; } + }; + + template + class ObjectWrapper : public ObjectInterface + { + Object obj_; + public: + ObjectWrapper( Object&& obj ) : obj_( std::move( obj ) ) {} + void run() { obj_.run(); } + }; + + protected: + class EndObject : public ObjectInterface + { + public: + void run () { } + bool isEndMarker () const { return true; } + }; + + //////////////////////////////////////////// + // class ThreadHandleQueue + //////////////////////////////////////////// + class ThreadHandleQueue + { + protected: + std::queue< std::unique_ptr< ObjectInterface > > objQueue_; + std::mutex mutex_; + + // no copying + ThreadHandleQueue( const ThreadHandleQueue& ) = delete; + + public: + //! constructor creating object that is executed by thread + ThreadHandleQueue() + : objQueue_(), mutex_() + { + } + + //! insert object into threads queue + void push_back( std::unique_ptr< ObjectInterface >&& obj ) + { + // lock mutex to make sure objPtr is not used + mutex_.lock(); + objQueue_.emplace( std::move(obj) ); + mutex_.unlock(); + } + + //! do the work until the queue received an end object + void run() + { + // wait until objects have been pushed to the queue + while( objQueue_.empty() ) + { + // sleep one second + std::this_thread::sleep_for( std::chrono::seconds(1) ); + } + + { + // lock mutex for access to objQueue_ + mutex_.lock(); + + // get next object from queue + std::unique_ptr< ObjectInterface > obj( objQueue_.front().release() ); + // remove object from queue + objQueue_.pop(); + + // unlock mutex for access to objQueue_ + mutex_.unlock(); + + // if object is end marker terminate thread + if( obj->isEndMarker() ){ + if( ! objQueue_.empty() ) { + OPM_THROW(std::logic_error,"ThreadHandleQueue: not all queued objects were executed"); + } + return; + } + + // execute object action + obj->run(); + } + + // keep thread running + run(); + } + }; // end ThreadHandleQueue + + //////////////////////////////////////////////////// + // end ThreadHandleQueue + //////////////////////////////////////////////////// + + // start the thread by calling method run + static void startThread( ThreadHandleQueue* obj ) + { + obj->run(); + } + + ThreadHandleQueue threadObjectQueue_; + std::thread thread_; + + private: + // prohibit copying + ThreadHandle( const ThreadHandle& ) = delete; + + public: + //! default constructor + ThreadHandle() + : threadObjectQueue_(), + thread_( startThread, &threadObjectQueue_ ) + { + // detach thread into nirvana + thread_.detach(); + } // end constructor + + //! dispatch object to queue of separate thread + template + void dispatch( Object&& obj ) + { + typedef ObjectWrapper< Object > ObjectPointer; + ObjectInterface* objPtr = new ObjectPointer( std::move(obj) ); + + // add object to queue of objects + threadObjectQueue_.push_back( std::unique_ptr< ObjectInterface > (objPtr) ); + } + + //! destructor terminating the thread + ~ThreadHandle() + { + // dispatch end object which will terminate the thread + threadObjectQueue_.push_back( std::unique_ptr< ObjectInterface > (new EndObject()) ) ; + } + }; + +} // end namespace Opm +#endif