diff --git a/examples/sim_fibo_ad_cp.cpp b/examples/sim_fibo_ad_cp.cpp index 45a5b8733..07f463509 100644 --- a/examples/sim_fibo_ad_cp.cpp +++ b/examples/sim_fibo_ad_cp.cpp @@ -265,8 +265,8 @@ try fis_solver.reset(new NewtonIterationBlackoilSimple(param, parallel_information)); } - // Write parameters used for later reference. - bool output = param.getDefault("output", true); + // Write parameters used for later reference. (only if rank is zero) + bool output = ( grid->comm().rank() == 0 ) && param.getDefault("output", true); std::string output_dir; if (output) { // Create output directory if needed. @@ -306,13 +306,19 @@ try outputWriter, threshold_pressures); - std::cout << "\n\n================ Starting main simulation loop ===============\n" - << std::flush; + if( grid->comm().rank()==0 ) + { + std::cout << "\n\n================ Starting main simulation loop ===============\n" + << std::flush; + } SimulatorReport fullReport = simulator.run(simtimer, must_distribute ? distributed_state : state); - std::cout << "\n\n================ End of simulation ===============\n\n"; - fullReport.report(std::cout); + if( grid->comm().rank()==0 ) + { + std::cout << "\n\n================ End of simulation ===============\n\n"; + fullReport.report(std::cout); + } if (output) { std::string filename = output_dir + "/walltime.txt"; diff --git a/opm/autodiff/FullyImplicitBlackoilSolver.hpp b/opm/autodiff/FullyImplicitBlackoilSolver.hpp index d21ce552d..1f9c819bf 100644 --- a/opm/autodiff/FullyImplicitBlackoilSolver.hpp +++ b/opm/autodiff/FullyImplicitBlackoilSolver.hpp @@ -196,6 +196,9 @@ namespace Opm { LinearisedBlackoilResidual residual_; + /// \brief Whether we print something to std::cout + bool terminal_output_; + std::vector primalVariable_; // Private methods. diff --git a/opm/autodiff/FullyImplicitBlackoilSolver_impl.hpp b/opm/autodiff/FullyImplicitBlackoilSolver_impl.hpp index 407739ff4..89b8bf2ac 100644 --- a/opm/autodiff/FullyImplicitBlackoilSolver_impl.hpp +++ b/opm/autodiff/FullyImplicitBlackoilSolver_impl.hpp @@ -212,7 +212,17 @@ namespace detail { , residual_ ( { std::vector(fluid.numPhases(), ADB::null()), ADB::null(), ADB::null() } ) + , terminal_output_ (true) { +#if HAVE_MPI + if ( linsolver_.parallelInformation().type() == typeid(ParallelISTLInformation) ) + { + const ParallelISTLInformation& info = + boost::any_cast(linsolver_.parallelInformation()); + // Only rank 0 does print to std::cout + terminal_output_ = (info.communicator().rank()==0); + } +#endif } @@ -289,7 +299,10 @@ namespace detail { if (isOscillate) { omega -= relaxIncrement(); omega = std::max(omega, relaxMax()); - std::cout << " Oscillating behavior detected: Relaxation set to " << omega << std::endl; + if (terminal_output_) + { + std::cout << " Oscillating behavior detected: Relaxation set to " << omega << std::endl; + } } stablizeNewton(dx, dxOld, omega, relaxtype); @@ -1132,9 +1145,12 @@ namespace detail { } if (ctrl_index != nwc) { // Constraint number ctrl_index was broken, switch to it. - std::cout << "Switching control mode for well " << wells().name[w] - << " from " << modestring[well_controls_iget_type(wc, current)] - << " to " << modestring[well_controls_iget_type(wc, ctrl_index)] << std::endl; + if (terminal_output_) + { + std::cout << "Switching control mode for well " << wells().name[w] + << " from " << modestring[well_controls_iget_type(wc, current)] + << " to " << modestring[well_controls_iget_type(wc, ctrl_index)] << std::endl; + } xw.currentControls()[w] = ctrl_index; // Also updating well state and primary variables. // We can only be switching to BHP and SURFACE_RATE @@ -1890,7 +1906,7 @@ namespace detail { { // Do the global reductions #if HAVE_MPI - if(linsolver_.parallelInformation().type()==typeid(ParallelISTLInformation)) + if ( linsolver_.parallelInformation().type() == typeid(ParallelISTLInformation) ) { const ParallelISTLInformation& info = boost::any_cast(linsolver_.parallelInformation()); @@ -2000,7 +2016,7 @@ namespace detail { const bool converged = converged_MB && converged_CNV && converged_Well; // if one of the residuals is NaN, throw exception, so that the solver can be restarted - if( std::isnan(mass_balance_residual[Water]) || mass_balance_residual[Water] > maxResidualAllowed() || + if ( std::isnan(mass_balance_residual[Water]) || mass_balance_residual[Water] > maxResidualAllowed() || std::isnan(mass_balance_residual[Oil]) || mass_balance_residual[Oil] > maxResidualAllowed() || std::isnan(mass_balance_residual[Gas]) || mass_balance_residual[Gas] > maxResidualAllowed() || std::isnan(CNV[Water]) || CNV[Water] > maxResidualAllowed() || @@ -2012,23 +2028,27 @@ namespace detail { OPM_THROW(Opm::NumericalProblem,"One of the residuals is NaN or to large!"); } - if (iteration == 0) { - std::cout << "\nIter MB(OIL) MB(WATER) MB(GAS) CNVW CNVO CNVG WELL-FLOW WELL-CNTRL\n"; + if ( terminal_output_ ) + { + // Only rank 0 does print to std::cout + if (iteration == 0) { + std::cout << "\nIter MB(OIL) MB(WATER) MB(GAS) CNVW CNVO CNVG WELL-FLOW WELL-CNTRL\n"; + } + const std::streamsize oprec = std::cout.precision(3); + const std::ios::fmtflags oflags = std::cout.setf(std::ios::scientific); + std::cout << std::setw(4) << iteration + << std::setw(11) << mass_balance_residual[Water] + << std::setw(11) << mass_balance_residual[Oil] + << std::setw(11) << mass_balance_residual[Gas] + << std::setw(11) << CNV[Water] + << std::setw(11) << CNV[Oil] + << std::setw(11) << CNV[Gas] + << std::setw(11) << residualWellFlux + << std::setw(11) << residualWell + << std::endl; + std::cout.precision(oprec); + std::cout.flags(oflags); } - const std::streamsize oprec = std::cout.precision(3); - const std::ios::fmtflags oflags = std::cout.setf(std::ios::scientific); - std::cout << std::setw(4) << iteration - << std::setw(11) << mass_balance_residual[Water] - << std::setw(11) << mass_balance_residual[Oil] - << std::setw(11) << mass_balance_residual[Gas] - << std::setw(11) << CNV[Water] - << std::setw(11) << CNV[Oil] - << std::setw(11) << CNV[Gas] - << std::setw(11) << residualWellFlux - << std::setw(11) << residualWell - << std::endl; - std::cout.precision(oprec); - std::cout.flags(oflags); return converged; } diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoil_impl.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoil_impl.hpp index d161979b9..085dd9621 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoil_impl.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoil_impl.hpp @@ -112,6 +112,7 @@ namespace Opm std::vector allcells_; const bool has_disgas_; const bool has_vapoil_; + bool terminal_output_; // eclipse_state std::shared_ptr eclipse_state_; // output_writer @@ -184,6 +185,7 @@ namespace Opm solver_(linsolver), has_disgas_(has_disgas), has_vapoil_(has_vapoil), + terminal_output_(true), eclipse_state_(eclipse_state), output_writer_(output_writer), rateConverter_(props_, std::vector(AutoDiffGrid::numCells(grid_), 0)), @@ -195,6 +197,15 @@ namespace Opm for (int cell = 0; cell < num_cells; ++cell) { allcells_[cell] = cell; } +#if HAVE_MPI + if ( solver_.parallelInformation().type() == typeid(ParallelISTLInformation) ) + { + const ParallelISTLInformation& info = + boost::any_cast(solver_.parallelInformation()); + // Only rank 0 does print to std::cout + terminal_output_= (info.communicator().rank()==0); + } +#endif } @@ -239,7 +250,10 @@ namespace Opm while (!timer.done()) { // Report timestep. step_timer.start(); - timer.report(std::cout); + if ( terminal_output_ ) + { + timer.report(std::cout); + } // Create wells and well state. WellsManager wells_manager(eclipse_state_, @@ -292,7 +306,12 @@ namespace Opm // Report timing. const double st = solver_timer.secsSinceStart(); - std::cout << "Fully implicit solver took: " << st << " seconds." << std::endl; + + if ( terminal_output_ ) + { + std::cout << "Fully implicit solver took: " << st << " seconds." << std::endl; + } + stime += st; if ( output_writer_.output() ) { SimulatorReport step_report;