/* 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 . */ #ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED #define OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DUNE_CORNERPOINT #include #endif namespace Opm { void outputStateVtk(const UnstructuredGrid& grid, const Opm::SimulatorState& state, const int step, const std::string& output_dir); void outputStateMatlab(const UnstructuredGrid& grid, const Opm::BlackoilState& state, const int step, const std::string& output_dir); void outputWellStateMatlab(const Opm::WellState& well_state, const int step, const std::string& output_dir); #ifdef HAVE_DUNE_CORNERPOINT void outputStateVtk(const Dune::CpGrid& grid, const Opm::SimulatorState& state, const int step, const std::string& output_dir); #endif template void outputStateMatlab(const Grid& grid, const Opm::BlackoilState& state, const int step, const std::string& output_dir) { Opm::DataMap dm; dm["saturation"] = &state.saturation(); dm["pressure"] = &state.pressure(); dm["surfvolume"] = &state.surfacevol(); dm["rs"] = &state.gasoilratio(); dm["rv"] = &state.rv(); std::vector 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& d = *(it->second); std::copy(d.begin(), d.end(), std::ostream_iterator(file, "\n")); } } /** Wrapper class satisfying the OutputWriter interface and writing VTK output. */ template class BlackoilVTKWriter : public OutputWriter { public: // constructor taking grid and directory BlackoilVTKWriter(const Grid& grid, const std::string& outputDir) : grid_( grid ), outputDir_( outputDir ) {} /** \copydoc Opm::OutputWriter::writeInit */ void writeInit(const SimulatorTimerInterface& /* timer */) {} /** \copydoc Opm::OutputWriter::writeTimeStep */ void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& state, const WellState& ) { outputStateVtk(grid_, state, timer.currentStepNum(), outputDir_); } protected: const Grid& grid_; const std::string outputDir_; }; /** Wrapper class satisfying the OutputWriter interface and writing Matlab output. */ template class BlackoilMatlabWriter : public OutputWriter { public: // constructor taking grid and directory BlackoilMatlabWriter(const Grid& grid, const std::string& outputDir) : grid_( grid ), outputDir_( outputDir ) {} /** \copydoc Opm::OutputWriter::writeInit */ void writeInit(const SimulatorTimerInterface& /* timer */) {} /** \copydoc Opm::OutputWriter::writeTimeStep */ void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState) { const BlackoilState* state = dynamic_cast< const BlackoilState* > (&reservoirState); if( state ) { outputStateMatlab(grid_, *state, timer.currentStepNum(), outputDir_); } else { OPM_THROW(std::logic_error,"BlackoilMatlabWriter only works for BlackoilState"); } outputWellStateMatlab(wellState, timer.currentStepNum(), outputDir_); } protected: const Grid& grid_; const std::string outputDir_; }; /** \brief Wrapper class for VTK, Matlab, and ECL output. */ class BlackoilOutputWriter : public OutputWriter { public: // constructor creating different sub writers template BlackoilOutputWriter(const Grid& grid, const parameter::ParameterGroup& param, Opm::EclipseStateConstPtr eclipseState, const Opm::PhaseUsage &phaseUsage); /** \copydoc Opm::OutputWriter::writeInit */ void writeInit(const SimulatorTimerInterface &timer); /** \copydoc Opm::OutputWriter::writeTimeStep */ void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState); /** \brief return output directory */ const std::string& outputDirectory() const { return outputDir_; } /** \brief return true if output is enabled */ bool output () const { return output_; } void restore(SimulatorTimerInterface& timer, BlackoilState& state, WellStateFullyImplicitBlackoil& wellState, const std::string& filename, const int desiredReportStep); protected: // Parameters for output. const bool output_; const std::string outputDir_; const int output_interval_; int lastBackupReportStep_; std::ofstream backupfile_; std::unique_ptr< OutputWriter > vtkWriter_; std::unique_ptr< OutputWriter > matlabWriter_; std::unique_ptr< EclipseWriter > eclWriter_; }; ////////////////////////////////////////////////////////////// // // Implementation // ////////////////////////////////////////////////////////////// template inline BlackoilOutputWriter:: BlackoilOutputWriter(const Grid& grid, const parameter::ParameterGroup& param, Opm::EclipseStateConstPtr eclipseState, const Opm::PhaseUsage &phaseUsage ) : output_( param.getDefault("output", true) ), outputDir_( output_ ? param.getDefault("output_dir", std::string("output")) : "." ), output_interval_( output_ ? param.getDefault("output_interval", 1): 0 ), lastBackupReportStep_( -1 ), vtkWriter_( output_ && param.getDefault("output_vtk",false) ? new BlackoilVTKWriter< Grid >( grid, outputDir_ ) : 0 ), matlabWriter_( output_ && param.getDefault("output_matlab", false) ? new BlackoilMatlabWriter< Grid >( grid, outputDir_ ) : 0 ), eclWriter_( output_ && param.getDefault("output_ecl", true) ? new EclipseWriter(param, eclipseState, phaseUsage, Opm::UgGridHelpers::numCells( grid ), Opm::UgGridHelpers::globalCell( grid ) ) : 0 ) { // For output. if (output_) { // Ensure that output dir exists boost::filesystem::path fpath(outputDir_); try { create_directories(fpath); } catch (...) { OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath); } std::string backupfilename = param.getDefault("backupfile", std::string("") ); if( ! backupfilename.empty() ) { backupfile_.open( backupfilename.c_str() ); } } } } #endif