Revision of black oil output. Put everything into a class following the OutputWriter

interface.
This commit is contained in:
Robert K 2015-01-26 16:43:45 +01:00
parent 12248f5c14
commit 2068b7ea16
6 changed files with 231 additions and 134 deletions

View File

@ -33,7 +33,6 @@
#include <opm/core/utility/parameters/ParameterGroup.hpp> #include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/core/utility/thresholdPressures.hpp> #include <opm/core/utility/thresholdPressures.hpp>
#include <opm/core/io/eclipse/EclipseWriter.hpp>
#include <opm/core/props/BlackoilPropertiesBasic.hpp> #include <opm/core/props/BlackoilPropertiesBasic.hpp>
#include <opm/core/props/BlackoilPropertiesFromDeck.hpp> #include <opm/core/props/BlackoilPropertiesFromDeck.hpp>
#include <opm/core/props/rock/RockCompressibility.hpp> #include <opm/core/props/rock/RockCompressibility.hpp>
@ -132,11 +131,10 @@ try
grid.reset(new GridManager(eclipseState->getEclipseGrid(), porv)); grid.reset(new GridManager(eclipseState->getEclipseGrid(), porv));
auto &cGrid = *grid->c_grid(); auto &cGrid = *grid->c_grid();
const PhaseUsage pu = Opm::phaseUsageFromDeck(deck); const PhaseUsage pu = Opm::phaseUsageFromDeck(deck);
Opm::EclipseWriter outputWriter(param, Opm::BlackoilOutputWriter outputWriter(cGrid,
param,
eclipseState, eclipseState,
pu, pu );
cGrid.number_of_cells,
cGrid.global_cell);
// Rock and fluid init // Rock and fluid init
props.reset(new BlackoilPropertiesFromDeck(deck, eclipseState, *grid->c_grid(), param)); props.reset(new BlackoilPropertiesFromDeck(deck, eclipseState, *grid->c_grid(), param));

View File

@ -54,7 +54,6 @@
#include <opm/core/utility/parameters/ParameterGroup.hpp> #include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/core/utility/thresholdPressures.hpp> // Note: the GridHelpers must be included before this (to make overloads available). \TODO: Fix. #include <opm/core/utility/thresholdPressures.hpp> // Note: the GridHelpers must be included before this (to make overloads available). \TODO: Fix.
#include <opm/core/io/eclipse/EclipseWriter.hpp>
#include <opm/core/props/BlackoilPropertiesBasic.hpp> #include <opm/core/props/BlackoilPropertiesBasic.hpp>
#include <opm/core/props/BlackoilPropertiesFromDeck.hpp> #include <opm/core/props/BlackoilPropertiesFromDeck.hpp>
#include <opm/core/props/rock/RockCompressibility.hpp> #include <opm/core/props/rock/RockCompressibility.hpp>
@ -68,6 +67,7 @@
#include <opm/autodiff/SimulatorFullyImplicitBlackoil.hpp> #include <opm/autodiff/SimulatorFullyImplicitBlackoil.hpp>
#include <opm/autodiff/BlackoilPropsAdFromDeck.hpp> #include <opm/autodiff/BlackoilPropsAdFromDeck.hpp>
#include <opm/core/utility/share_obj.hpp> #include <opm/core/utility/share_obj.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
@ -132,7 +132,6 @@ try
Opm::ParserPtr parser(new Opm::Parser() ); Opm::ParserPtr parser(new Opm::Parser() );
Opm::LoggerPtr logger(new Opm::Logger()); Opm::LoggerPtr logger(new Opm::Logger());
bool strict_parsing = param.getDefault("strict_parsing", true);
Opm::DeckConstPtr deck; Opm::DeckConstPtr deck;
std::shared_ptr<EclipseState> eclipseState; std::shared_ptr<EclipseState> eclipseState;
try { try {
@ -160,9 +159,7 @@ try
grid->processEclipseFormat(deck, false, false, false, porv); grid->processEclipseFormat(deck, false, false, false, porv);
const PhaseUsage pu = Opm::phaseUsageFromDeck(deck); const PhaseUsage pu = Opm::phaseUsageFromDeck(deck);
Opm::EclipseWriter outputWriter(param, eclipseState, pu, Opm::BlackoilOutputWriter outputWriter(*grid, param, eclipseState, pu );
Opm::UgGridHelpers::numCells(*grid),
Opm::UgGridHelpers::globalCell(*grid));
// Rock and fluid init // Rock and fluid init
props.reset(new BlackoilPropertiesFromDeck(deck, eclipseState, props.reset(new BlackoilPropertiesFromDeck(deck, eclipseState,

View File

@ -38,7 +38,7 @@ namespace Opm
class BlackoilState; class BlackoilState;
class WellStateFullyImplicitBlackoil; class WellStateFullyImplicitBlackoil;
class EclipseState; class EclipseState;
class EclipseWriter; class BlackoilOutputWriter;
struct SimulatorReport; struct SimulatorReport;
/// Class collecting all necessary components for a two-phase simulation. /// Class collecting all necessary components for a two-phase simulation.
@ -85,7 +85,7 @@ namespace Opm
const bool disgas, const bool disgas,
const bool vapoil, const bool vapoil,
std::shared_ptr<EclipseState> eclipse_state, std::shared_ptr<EclipseState> eclipse_state,
EclipseWriter& output_writer, BlackoilOutputWriter& output_writer,
const std::vector<double>& threshold_pressures_by_face); const std::vector<double>& threshold_pressures_by_face);
/// Run the simulation. /// Run the simulation.

View File

@ -1,3 +1,22 @@
/*
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/>.
*/
#include "config.h" #include "config.h"
#include "SimulatorFullyImplicitBlackoilOutput.hpp" #include "SimulatorFullyImplicitBlackoilOutput.hpp"
@ -26,7 +45,7 @@ namespace Opm
void outputStateVtk(const UnstructuredGrid& grid, void outputStateVtk(const UnstructuredGrid& grid,
const Opm::BlackoilState& state, const SimulatorState& state,
const int step, const int step,
const std::string& output_dir) const std::string& output_dir)
{ {
@ -163,7 +182,7 @@ namespace Opm
#ifdef HAVE_DUNE_CORNERPOINT #ifdef HAVE_DUNE_CORNERPOINT
void outputStateVtk(const Dune::CpGrid& grid, void outputStateVtk(const Dune::CpGrid& grid,
const Opm::BlackoilState& state, const Opm::SimulatorState& state,
const int step, const int step,
const std::string& output_dir) const std::string& output_dir)
{ {
@ -202,4 +221,32 @@ namespace Opm
} }
#endif #endif
void
BlackoilOutputWriter::
writeInit(const SimulatorTimerInterface& timer)
{
if( eclWriter_ ) {
eclWriter_->writeInit(timer);
}
}
void
BlackoilOutputWriter::
writeTimeStep(const SimulatorTimerInterface& timer,
const SimulatorState& state,
const WellState& wellState)
{
// VTK output
if( vtkWriter_ ) {
vtkWriter_->writeTimeStep( timer, state, wellState );
}
// Matlab output
if( matlabWriter_ ) {
matlabWriter_->writeTimeStep( timer, state, wellState );
}
// ECL output
if ( eclWriter_ ) {
eclWriter_->writeTimeStep(timer, state, wellState);
}
}
} }

View File

@ -1,3 +1,22 @@
/*
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/>.
*/
#ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED #ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED
#define OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED #define OPM_SIMULATORFULLYIMPLICITBLACKOILOUTPUT_HEADER_INCLUDED
#include <opm/core/grid.h> #include <opm/core/grid.h>
@ -6,6 +25,10 @@
#include <opm/core/utility/DataMap.hpp> #include <opm/core/utility/DataMap.hpp>
#include <opm/core/utility/ErrorMacros.hpp> #include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/miscUtilities.hpp> #include <opm/core/utility/miscUtilities.hpp>
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/core/io/OutputWriter.hpp>
#include <opm/core/io/eclipse/EclipseWriter.hpp>
#include <opm/autodiff/GridHelpers.hpp> #include <opm/autodiff/GridHelpers.hpp>
@ -23,7 +46,7 @@ namespace Opm
{ {
void outputStateVtk(const UnstructuredGrid& grid, void outputStateVtk(const UnstructuredGrid& grid,
const Opm::BlackoilState& state, const Opm::SimulatorState& state,
const int step, const int step,
const std::string& output_dir); const std::string& output_dir);
@ -38,7 +61,7 @@ namespace Opm
const std::string& output_dir); const std::string& output_dir);
#ifdef HAVE_DUNE_CORNERPOINT #ifdef HAVE_DUNE_CORNERPOINT
void outputStateVtk(const Dune::CpGrid& grid, void outputStateVtk(const Dune::CpGrid& grid,
const Opm::BlackoilState& state, const Opm::SimulatorState& state,
const int step, const int step,
const std::string& output_dir); const std::string& output_dir);
#endif #endif
@ -89,6 +112,141 @@ namespace Opm
} }
} }
/** Wrapper class satisfying the OutputWriter interface */
template <class Grid>
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_;
};
template <class Grid>
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_;
};
class BlackoilOutputWriter : public OutputWriter
{
public:
// constructor creating different sub writers
template <class Grid>
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 */
const bool output () const { return output_; }
protected:
// Parameters for output.
const bool output_;
const std::string outputDir_;
const int output_interval_;
std::unique_ptr< OutputWriter > vtkWriter_;
std::unique_ptr< OutputWriter > matlabWriter_;
std::unique_ptr< EclipseWriter > eclWriter_;
};
//////////////////////////////////////////////////////////////
//
// Implementation
//
//////////////////////////////////////////////////////////////
template <class Grid>
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 ),
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);
}
}
}
} }
#endif #endif

View File

@ -34,7 +34,6 @@
#include <opm/core/well_controls.h> #include <opm/core/well_controls.h>
#include <opm/core/pressure/flow_bc.h> #include <opm/core/pressure/flow_bc.h>
#include <opm/core/io/eclipse/EclipseWriter.hpp>
#include <opm/core/simulator/SimulatorReport.hpp> #include <opm/core/simulator/SimulatorReport.hpp>
#include <opm/core/simulator/SimulatorTimer.hpp> #include <opm/core/simulator/SimulatorTimer.hpp>
#include <opm/core/simulator/AdaptiveSimulatorTimer.hpp> #include <opm/core/simulator/AdaptiveSimulatorTimer.hpp>
@ -87,7 +86,7 @@ namespace Opm
bool has_disgas, bool has_disgas,
bool has_vapoil, bool has_vapoil,
std::shared_ptr<EclipseState> eclipse_state, std::shared_ptr<EclipseState> eclipse_state,
EclipseWriter& output_writer, BlackoilOutputWriter& output_writer,
const std::vector<double>& threshold_pressures_by_face); const std::vector<double>& threshold_pressures_by_face);
SimulatorReport run(SimulatorTimer& timer, SimulatorReport run(SimulatorTimer& timer,
@ -101,13 +100,6 @@ namespace Opm
const parameter::ParameterGroup param_; const parameter::ParameterGroup param_;
// Parameters for output.
const bool output_;
const bool output_vtk_;
const bool output_matlab_;
const std::string output_dir_;
const int output_interval_;
// Observed objects. // Observed objects.
const Grid& grid_; const Grid& grid_;
BlackoilPropsAdInterface& props_; BlackoilPropsAdInterface& props_;
@ -123,7 +115,7 @@ namespace Opm
// eclipse_state // eclipse_state
std::shared_ptr<EclipseState> eclipse_state_; std::shared_ptr<EclipseState> eclipse_state_;
// output_writer // output_writer
EclipseWriter& output_writer_; BlackoilOutputWriter& output_writer_;
RateConverterType rateConverter_; RateConverterType rateConverter_;
// Threshold pressures. // Threshold pressures.
std::vector<double> threshold_pressures_by_face_; std::vector<double> threshold_pressures_by_face_;
@ -149,7 +141,7 @@ namespace Opm
const bool has_disgas, const bool has_disgas,
const bool has_vapoil, const bool has_vapoil,
std::shared_ptr<EclipseState> eclipse_state, std::shared_ptr<EclipseState> eclipse_state,
EclipseWriter& output_writer, BlackoilOutputWriter& output_writer,
const std::vector<double>& threshold_pressures_by_face) const std::vector<double>& threshold_pressures_by_face)
{ {
@ -169,64 +161,6 @@ namespace Opm
} }
static void outputWellStateMatlab(const Opm::WellStateFullyImplicitBlackoil& well_state,
const int step,
const std::string& output_dir)
{
Opm::DataMap dm;
dm["bhp"] = &well_state.bhp();
dm["wellrates"] = &well_state.wellRates();
// 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"));
}
}
#if 0
static void outputWaterCut(const Opm::Watercut& watercut,
const std::string& output_dir)
{
// Write water cut curve.
std::string fname = output_dir + "/watercut.txt";
std::ofstream os(fname.c_str());
if (!os) {
OPM_THROW(std::runtime_error, "Failed to open " << fname);
}
watercut.write(os);
}
static void outputWellReport(const Opm::WellReport& wellreport,
const std::string& output_dir)
{
// Write well report.
std::string fname = output_dir + "/wellreport.txt";
std::ofstream os(fname.c_str());
if (!os) {
OPM_THROW(std::runtime_error, "Failed to open " << fname);
}
wellreport.write(os);
}
#endif
// \TODO: Treat bcs. // \TODO: Treat bcs.
template<class T> template<class T>
SimulatorFullyImplicitBlackoil<T>::Impl::Impl(const parameter::ParameterGroup& param, SimulatorFullyImplicitBlackoil<T>::Impl::Impl(const parameter::ParameterGroup& param,
@ -239,14 +173,9 @@ namespace Opm
const bool has_disgas, const bool has_disgas,
const bool has_vapoil, const bool has_vapoil,
std::shared_ptr<EclipseState> eclipse_state, std::shared_ptr<EclipseState> eclipse_state,
EclipseWriter& output_writer, BlackoilOutputWriter& output_writer,
const std::vector<double>& threshold_pressures_by_face) const std::vector<double>& threshold_pressures_by_face)
: param_(param), : param_(param),
output_( param.getDefault("output", true) ),
output_vtk_( output_ ? param.getDefault("output_vtk",true) : false ),
output_matlab_( output_ ? param.getDefault("output_matlab", true) : false ),
output_dir_( output_ ? param.getDefault("output_dir", std::string("output")) : "" ),
output_interval_( output_ ? param.getDefault("output_interval", 1): 0 ),
grid_(grid), grid_(grid),
props_(props), props_(props),
rock_comp_props_(rock_comp_props), rock_comp_props_(rock_comp_props),
@ -260,18 +189,6 @@ namespace Opm
rateConverter_(props_, std::vector<int>(AutoDiffGrid::numCells(grid_), 0)), rateConverter_(props_, std::vector<int>(AutoDiffGrid::numCells(grid_), 0)),
threshold_pressures_by_face_(threshold_pressures_by_face) threshold_pressures_by_face_(threshold_pressures_by_face)
{ {
// For output.
if (output_) {
// Ensure that output dir exists
boost::filesystem::path fpath(output_dir_);
try {
create_directories(fpath);
}
catch (...) {
OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath);
}
}
// Misc init. // Misc init.
const int num_cells = AutoDiffGrid::numCells(grid); const int num_cells = AutoDiffGrid::numCells(grid);
allcells_.resize(num_cells); allcells_.resize(num_cells);
@ -295,7 +212,7 @@ namespace Opm
Opm::time::StopWatch step_timer; Opm::time::StopWatch step_timer;
Opm::time::StopWatch total_timer; Opm::time::StopWatch total_timer;
total_timer.start(); total_timer.start();
std::string tstep_filename = output_dir_ + "/step_timing.txt"; std::string tstep_filename = output_writer_.outputDirectory() + "/step_timing.txt";
std::ofstream tstep_os(tstep_filename.c_str()); std::ofstream tstep_os(tstep_filename.c_str());
typename FullyImplicitBlackoilSolver<T>::SolverParameter solverParam( param_ ); typename FullyImplicitBlackoilSolver<T>::SolverParameter solverParam( param_ );
@ -307,6 +224,9 @@ namespace Opm
adaptiveTimeStepping.reset( new AdaptiveTimeStepping( param_ ) ); adaptiveTimeStepping.reset( new AdaptiveTimeStepping( param_ ) );
} }
// init output writer
output_writer_.writeInit( timer );
// Main simulation loop. // Main simulation loop.
while (!timer.done()) { while (!timer.done()) {
// Report timestep. // Report timestep.
@ -328,21 +248,7 @@ namespace Opm
WellStateFullyImplicitBlackoil well_state; WellStateFullyImplicitBlackoil well_state;
well_state.init(wells, state, prev_well_state); well_state.init(wells, state, prev_well_state);
// Output state at start of time step. if( ! adaptiveTimeStepping ) {
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
if (output_vtk_) {
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
}
if (output_matlab_) {
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
outputWellStateMatlab(well_state,timer.currentStepNum(), output_dir_);
}
}
if (output_) {
if (timer.currentStepNum() == 0) {
output_writer_.writeInit(timer);
}
if( ! adaptiveTimeStepping || timer.currentStepNum() == 0 )
output_writer_.writeTimeStep( timer, state, well_state ); output_writer_.writeTimeStep( timer, state, well_state );
} }
@ -381,7 +287,7 @@ namespace Opm
const double st = solver_timer.secsSinceStart(); const double st = solver_timer.secsSinceStart();
std::cout << "Fully implicit solver took: " << st << " seconds." << std::endl; std::cout << "Fully implicit solver took: " << st << " seconds." << std::endl;
stime += st; stime += st;
if (output_) { if ( output_writer_.output() ) {
SimulatorReport step_report; SimulatorReport step_report;
step_report.pressure_time = st; step_report.pressure_time = st;
step_report.total_time = step_timer.secsSinceStart(); step_report.total_time = step_timer.secsSinceStart();
@ -394,16 +300,7 @@ namespace Opm
} }
// Write final simulation state. // Write final simulation state.
if (output_) { if( ! adaptiveTimeStepping ) {
if (output_vtk_) {
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
}
if (output_matlab_) {
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
outputWellStateMatlab(prev_well_state, timer.currentStepNum(), output_dir_);
}
if( ! adaptiveTimeStepping )
//std::cout << "Write last step" << std::endl;
output_writer_.writeTimeStep( timer, state, prev_well_state ); output_writer_.writeTimeStep( timer, state, prev_well_state );
} }