From 17e1e591f7b66efeb78057659bbf3138fbce67b1 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Thu, 26 Jan 2023 09:39:42 -0700 Subject: [PATCH 1/3] Add progress output (#22906) --- .../content/source/outputs/ProgressOutput.md | 19 +++++ framework/include/outputs/ProgressOutput.h | 33 +++++++++ framework/include/utils/FormattedTable.h | 5 -- framework/include/utils/MooseUtils.h | 5 ++ framework/src/actions/CommonOutputAction.C | 4 ++ framework/src/outputs/ProgressOutput.C | 69 +++++++++++++++++++ framework/src/utils/FormattedTable.C | 58 +--------------- framework/src/utils/MooseUtils.C | 51 ++++++++++++++ test/tests/outputs/progress/common.i | 27 ++++++++ test/tests/outputs/progress/full.i | 30 ++++++++ test/tests/outputs/progress/tests | 19 +++++ 11 files changed, 259 insertions(+), 61 deletions(-) create mode 100644 framework/doc/content/source/outputs/ProgressOutput.md create mode 100644 framework/include/outputs/ProgressOutput.h create mode 100644 framework/src/outputs/ProgressOutput.C create mode 100644 test/tests/outputs/progress/common.i create mode 100644 test/tests/outputs/progress/full.i create mode 100644 test/tests/outputs/progress/tests diff --git a/framework/doc/content/source/outputs/ProgressOutput.md b/framework/doc/content/source/outputs/ProgressOutput.md new file mode 100644 index 000000000000..f4f22b63b43b --- /dev/null +++ b/framework/doc/content/source/outputs/ProgressOutput.md @@ -0,0 +1,19 @@ +# Progress + +!syntax description /Outputs/Progress + +## Overview + +The Progress output displays an ASCII art progress bar at the end of each timestep, visualizing the amount of simulation time that has passed vs. the total simulation time. It requires the use of a transient executioner along with predetermined start and end times. The width of the bar widget an be specified using the [!param](/Outputs/Progress/progress_bar_width) parameter. If omitted the value of the `MOOSE_PPS_WIDTH` environment variable is queried. If that variable is not set the terminal window width is queried (with a fallback value of 132 chars). + +``` ++-Progress (full.i)--------------------------------+ +|#########################.........................| ++--------------------------------------------------+ +``` + +!syntax parameters /Outputs/DOFMap + +!syntax inputs /Outputs/DOFMap + +!syntax children /Outputs/DOFMap diff --git a/framework/include/outputs/ProgressOutput.h b/framework/include/outputs/ProgressOutput.h new file mode 100644 index 000000000000..92875f5feaba --- /dev/null +++ b/framework/include/outputs/ProgressOutput.h @@ -0,0 +1,33 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#pragma once + +#include "Output.h" + +class Transient; + +class ProgressOutput : public Output +{ +public: + static InputParameters validParams(); + + ProgressOutput(const InputParameters & parameters); + +protected: + void output() override; + + Transient * _transient_executioner; + + // display input file name in the progress bar title + const bool _use_filename; + + // total length of the progress bar + const unsigned int _length; +}; diff --git a/framework/include/utils/FormattedTable.h b/framework/include/utils/FormattedTable.h index ee8c87ea6820..7be093928a52 100644 --- a/framework/include/utils/FormattedTable.h +++ b/framework/include/utils/FormattedTable.h @@ -249,11 +249,6 @@ class FormattedTable std::vector::iterator & col_begin, std::vector::iterator & col_end) const; - /** - * Returns the width of the terminal using sys/ioctl - */ - unsigned short getTermWidth(bool use_environment) const; - /** * Data structure for the console table: * The first part of the pair tracks the independent variable (normally time) and is associated diff --git a/framework/include/utils/MooseUtils.h b/framework/include/utils/MooseUtils.h index eb730eec3680..c1f50e7601d3 100644 --- a/framework/include/utils/MooseUtils.h +++ b/framework/include/utils/MooseUtils.h @@ -286,6 +286,11 @@ std::string baseName(const std::string & name); */ std::string hostname(); +/** + * Returns the width of the terminal using sys/ioctl + */ +unsigned short getTermWidth(bool use_environment); + /** * @returns A cleaner representation of the c++ type \p cpp_type. */ diff --git a/framework/src/actions/CommonOutputAction.C b/framework/src/actions/CommonOutputAction.C index a4740404c51d..0eb7044aafe0 100644 --- a/framework/src/actions/CommonOutputAction.C +++ b/framework/src/actions/CommonOutputAction.C @@ -69,6 +69,7 @@ CommonOutputAction::validParams() "Output the scalar and postprocessor results using the default settings for GNUPlot output"); params.addParam( "solution_history", false, "Print a solution history file (.slh) using the default settings"); + params.addParam("progress", false, "Print a progress bar"); params.addParam("dofmap", false, "Create the dof map .json output file"); params.addParam("controls", false, "Enable the screen output of Control systems."); @@ -220,6 +221,9 @@ CommonOutputAction::act() if (getParam("solution_history")) create("SolutionHistory"); + if (getParam("progress")) + create("Progress"); + if (getParam("dofmap")) create("DOFMap"); diff --git a/framework/src/outputs/ProgressOutput.C b/framework/src/outputs/ProgressOutput.C new file mode 100644 index 000000000000..349b7f933c2e --- /dev/null +++ b/framework/src/outputs/ProgressOutput.C @@ -0,0 +1,69 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#include "ProgressOutput.h" +#include "Transient.h" + +registerMooseObjectAliased("MooseApp", ProgressOutput, "Progress"); + +InputParameters +ProgressOutput::validParams() +{ + auto params = Output::validParams(); + params.addClassDescription("Output a simulation time progress bar on the console."); + params.set("execute_on") = {EXEC_TIMESTEP_END}; + params.addParam( + "use_filename", true, "Put the input filename into the title of the progress bar"); + params.addParam( + "progress_bar_width", + "Explicitly specify the bar width. If omitted the MOOSE_PPS_WIDTH environment variable or - " + "if not set - the terminal width are queried."); + return params; +} + +ProgressOutput::ProgressOutput(const InputParameters & parameters) + : Output(parameters), + _transient_executioner(dynamic_cast(_app.getExecutioner())), + _use_filename(getParam("use_filename")), + _length(isParamValid("progress_bar_width") ? getParam("progress_bar_width") + : MooseUtils::getTermWidth(true) - 2) +{ +} + +void +ProgressOutput::output() +{ + if (_transient_executioner == nullptr || _current_execute_flag != EXEC_TIMESTEP_END || + !_transient) + return; + + auto passed = _transient_executioner->getTime() - _transient_executioner->getStartTime(); + auto total = _transient_executioner->endTime() - _transient_executioner->getStartTime(); + if (total == 0) + return; + + // length of filled portion + auto progress = std::round((passed * _length) / total); + + // title string + std::string title = name(); + if (_use_filename) + title += " (" + getMooseApp().getFileName() + ')'; + if (title.length() >= _length - 1) + title = title.substr(0, _length - 4) + "..."; + + // top line + Moose::out << "+-" << title << std::string(_length - 1 - title.length(), '-') << "+\n"; + + // bar + Moose::out << '|' << std::string(progress, '#') << std::string(_length - progress, '.') << "|\n"; + + // bottom line + Moose::out << '+' << std::string(_length, '-') << "+\n"; +} diff --git a/framework/src/utils/FormattedTable.C b/framework/src/utils/FormattedTable.C index bc7d6bf39a68..0e91013f324f 100644 --- a/framework/src/utils/FormattedTable.C +++ b/framework/src/utils/FormattedTable.C @@ -16,12 +16,6 @@ #include #include -// Used for terminal width -#ifndef __WIN32__ -#include -#endif -#include - const unsigned short FormattedTable::_column_width = 15; const unsigned short FormattedTable::_min_pps_width = 40; @@ -258,9 +252,9 @@ FormattedTable::printTable(std::ostream & out, unsigned short term_width; if (suggested_term_width == "ENVIRONMENT") - term_width = getTermWidth(true); + term_width = MooseUtils::getTermWidth(true); else if (suggested_term_width == "AUTO") - term_width = getTermWidth(false); + term_width = MooseUtils::getTermWidth(false); else term_width = MooseUtils::stringToInteger(suggested_term_width); @@ -583,54 +577,6 @@ FormattedTable::fillEmptyValues() std::dynamic_pointer_cast(std::make_shared>('0')); } -unsigned short -FormattedTable::getTermWidth(bool use_environment) const -{ -#ifndef __WIN32__ - struct winsize w; -#else - struct - { - unsigned short ws_col; - } w; -#endif - /** - * Initialize the value we intend to populate just in case - * the system call fails - */ - w.ws_col = std::numeric_limits::max(); - - if (use_environment) - { - char * pps_width = std::getenv("MOOSE_PPS_WIDTH"); - if (pps_width != NULL) - { - std::stringstream ss(pps_width); - ss >> w.ws_col; - } - } - // Default to AUTO if no environment variable was set - if (w.ws_col == std::numeric_limits::max()) - { -#ifndef __WIN32__ - try - { - ioctl(0, TIOCGWINSZ, &w); - } - catch (...) -#endif - { - } - } - - // Something bad happened, make sure we have a sane value - // 132 seems good for medium sized screens, and is available as a GNOME preset - if (w.ws_col == std::numeric_limits::max()) - w.ws_col = 132; - - return w.ws_col; -} - MooseEnum FormattedTable::getWidthModes() { diff --git a/framework/src/utils/MooseUtils.C b/framework/src/utils/MooseUtils.C index 1782f31a1ff4..55d8beb026d9 100644 --- a/framework/src/utils/MooseUtils.C +++ b/framework/src/utils/MooseUtils.C @@ -34,6 +34,7 @@ #include #include #include +#include // System includes #include @@ -46,6 +47,8 @@ #include #include #include +#else +#include #endif namespace MooseUtils @@ -649,6 +652,54 @@ hostname() return hostname; } +unsigned short +getTermWidth(bool use_environment) +{ +#ifndef __WIN32__ + struct winsize w; +#else + struct + { + unsigned short ws_col; + } w; +#endif + /** + * Initialize the value we intend to populate just in case + * the system call fails + */ + w.ws_col = std::numeric_limits::max(); + + if (use_environment) + { + char * pps_width = std::getenv("MOOSE_PPS_WIDTH"); + if (pps_width != NULL) + { + std::stringstream ss(pps_width); + ss >> w.ws_col; + } + } + // Default to AUTO if no environment variable was set + if (w.ws_col == std::numeric_limits::max()) + { +#ifndef __WIN32__ + try + { + ioctl(0, TIOCGWINSZ, &w); + } + catch (...) +#endif + { + } + } + + // Something bad happened, make sure we have a sane value + // 132 seems good for medium sized screens, and is available as a GNOME preset + if (w.ws_col == std::numeric_limits::max()) + w.ws_col = 132; + + return w.ws_col; +} + void MaterialPropertyStorageDump( const HashMap> & props) diff --git a/test/tests/outputs/progress/common.i b/test/tests/outputs/progress/common.i new file mode 100644 index 000000000000..48198c10b91d --- /dev/null +++ b/test/tests/outputs/progress/common.i @@ -0,0 +1,27 @@ +[Mesh] + [gen] + type = GeneratedMeshGenerator + dim = 1 + [] +[] + +[Variables] + [u] + [] +[] + +[Problem] + solve = false + kernel_coverage_check = false +[] + +[Executioner] + type = Transient + start_time = 10 + end_time = 20 + dt = 5 +[] + +[Outputs] + progress = true +[] diff --git a/test/tests/outputs/progress/full.i b/test/tests/outputs/progress/full.i new file mode 100644 index 000000000000..a293b3e8e585 --- /dev/null +++ b/test/tests/outputs/progress/full.i @@ -0,0 +1,30 @@ +[Mesh] + [gen] + type = GeneratedMeshGenerator + dim = 1 + [] +[] + +[Variables] + [u] + [] +[] + +[Problem] + solve = false + kernel_coverage_check = false +[] + +[Executioner] + type = Transient + start_time = 10 + end_time = 20 + dt = 5 +[] + +[Outputs] + [Progress] + type = Progress + progress_bar_width = 50 + [] +[] diff --git a/test/tests/outputs/progress/tests b/test/tests/outputs/progress/tests new file mode 100644 index 000000000000..9a9db7e7f21e --- /dev/null +++ b/test/tests/outputs/progress/tests @@ -0,0 +1,19 @@ +[Tests] + issues = '#22906' + design = ProgressOutput.md + [full] + type = RunApp + input = 'full.i' + expect_out = "\+-Progress \(.*\)-*\+\n\|#########################.........................\|\n\+--------------------------------------------------\+" + requirement = "The system shall support printing a progress bar that indicates the fraction of total simulation time passed." + [] + [common] + type = RunApp + input = 'common.i' + expect_out = '\+-progress \(.*\)-*\+' + requirement = "The system shall support using a shortcut to set up a progress bar output." + [] +[] + + + From 44ef55e98078f82aee429f3986e037e33c5867a1 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Tue, 19 Sep 2023 20:15:51 -0600 Subject: [PATCH 2/3] Apply suggestions from code review (#22906) Co-authored-by: Alex Lindsay --- framework/doc/content/source/outputs/ProgressOutput.md | 2 +- framework/include/outputs/ProgressOutput.h | 4 ++-- framework/src/outputs/ProgressOutput.C | 10 +++++----- test/tests/outputs/progress/tests | 2 -- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/framework/doc/content/source/outputs/ProgressOutput.md b/framework/doc/content/source/outputs/ProgressOutput.md index f4f22b63b43b..348e01433733 100644 --- a/framework/doc/content/source/outputs/ProgressOutput.md +++ b/framework/doc/content/source/outputs/ProgressOutput.md @@ -4,7 +4,7 @@ ## Overview -The Progress output displays an ASCII art progress bar at the end of each timestep, visualizing the amount of simulation time that has passed vs. the total simulation time. It requires the use of a transient executioner along with predetermined start and end times. The width of the bar widget an be specified using the [!param](/Outputs/Progress/progress_bar_width) parameter. If omitted the value of the `MOOSE_PPS_WIDTH` environment variable is queried. If that variable is not set the terminal window width is queried (with a fallback value of 132 chars). +The Progress output displays an ASCII art progress bar at the end of each timestep, visualizing the amount of simulation time that has passed vs. the total simulation time. It requires the use of a transient executioner along with predetermined start and end times. The width of the bar widget can be specified using the [!param](/Outputs/Progress/progress_bar_width) parameter. If omitted the value of the `MOOSE_PPS_WIDTH` environment variable is queried. If that variable is not set the terminal window width is queried (with a fallback value of 132 chars). ``` +-Progress (full.i)--------------------------------+ diff --git a/framework/include/outputs/ProgressOutput.h b/framework/include/outputs/ProgressOutput.h index 92875f5feaba..2f6051888e61 100644 --- a/framework/include/outputs/ProgressOutput.h +++ b/framework/include/outputs/ProgressOutput.h @@ -25,9 +25,9 @@ class ProgressOutput : public Output Transient * _transient_executioner; - // display input file name in the progress bar title + /// display input file name in the progress bar title const bool _use_filename; - // total length of the progress bar + /// total length of the progress bar const unsigned int _length; }; diff --git a/framework/src/outputs/ProgressOutput.C b/framework/src/outputs/ProgressOutput.C index 349b7f933c2e..1f7051b693a4 100644 --- a/framework/src/outputs/ProgressOutput.C +++ b/framework/src/outputs/ProgressOutput.C @@ -22,8 +22,8 @@ ProgressOutput::validParams() "use_filename", true, "Put the input filename into the title of the progress bar"); params.addParam( "progress_bar_width", - "Explicitly specify the bar width. If omitted the MOOSE_PPS_WIDTH environment variable or - " - "if not set - the terminal width are queried."); + "Explicitly specify the bar width. If omitted the MOOSE_PPS_WIDTH environment variable or, " + "if not set, the terminal width is queried."); return params; } @@ -43,13 +43,13 @@ ProgressOutput::output() !_transient) return; - auto passed = _transient_executioner->getTime() - _transient_executioner->getStartTime(); - auto total = _transient_executioner->endTime() - _transient_executioner->getStartTime(); + const auto passed = _transient_executioner->getTime() - _transient_executioner->getStartTime(); + const auto total = _transient_executioner->endTime() - _transient_executioner->getStartTime(); if (total == 0) return; // length of filled portion - auto progress = std::round((passed * _length) / total); + const auto progress = std::round((passed * _length) / total); // title string std::string title = name(); diff --git a/test/tests/outputs/progress/tests b/test/tests/outputs/progress/tests index 9a9db7e7f21e..9ae5719ff582 100644 --- a/test/tests/outputs/progress/tests +++ b/test/tests/outputs/progress/tests @@ -15,5 +15,3 @@ [] [] - - From 85c35767880edae09c9504286642c2c67fb354c8 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Tue, 19 Sep 2023 20:43:03 -0600 Subject: [PATCH 3/3] Add and use const getters (#22906) --- .../doc/content/source/outputs/ProgressOutput.md | 6 +++--- framework/include/executioners/Transient.h | 13 ++++++++++--- framework/include/outputs/ProgressOutput.h | 5 ++++- framework/src/outputs/ProgressOutput.C | 5 ++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/framework/doc/content/source/outputs/ProgressOutput.md b/framework/doc/content/source/outputs/ProgressOutput.md index 348e01433733..95d2a7263eda 100644 --- a/framework/doc/content/source/outputs/ProgressOutput.md +++ b/framework/doc/content/source/outputs/ProgressOutput.md @@ -12,8 +12,8 @@ The Progress output displays an ASCII art progress bar at the end of each timest +--------------------------------------------------+ ``` -!syntax parameters /Outputs/DOFMap +!syntax parameters /Outputs/Progress -!syntax inputs /Outputs/DOFMap +!syntax inputs /Outputs/Progress -!syntax children /Outputs/DOFMap +!syntax children /Outputs/Progress diff --git a/framework/include/executioners/Transient.h b/framework/include/executioners/Transient.h index bea46de0d3e3..f14bee2bdb05 100644 --- a/framework/include/executioners/Transient.h +++ b/framework/include/executioners/Transient.h @@ -92,7 +92,7 @@ class Transient : public Executioner /** * Get the current time. */ - virtual Real getTime() { return _time; }; + virtual Real getTime() const { return _time; }; /** * Get the current target time @@ -120,6 +120,7 @@ class Transient : public Executioner * @return Pointer to the time stepper for this Executioner */ TimeStepper * getTimeStepper() { return _time_stepper; } + const TimeStepper * getTimeStepper() const { return _time_stepper; } /** * Set the timestepper to use. @@ -143,7 +144,7 @@ class Transient : public Executioner * Get the time scheme used * @return MooseEnum with the time scheme */ - Moose::TimeIntegratorType getTimeScheme() { return _time_scheme; } + Moose::TimeIntegratorType getTimeScheme() const { return _time_scheme; } /** * Get the set of sync times @@ -167,12 +168,18 @@ class Transient : public Executioner * Return the start time * @return The start time */ - Real getStartTime() { return _start_time; } + Real getStartTime() const { return _start_time; } /** * Get the end time * @return The end time */ + Real getEndTime() const { return _end_time; } + + /** + * Get a modifiable reference to the end time + * @return The end time + */ Real & endTime() { return _end_time; } /** diff --git a/framework/include/outputs/ProgressOutput.h b/framework/include/outputs/ProgressOutput.h index 2f6051888e61..dd874ef38cbb 100644 --- a/framework/include/outputs/ProgressOutput.h +++ b/framework/include/outputs/ProgressOutput.h @@ -13,6 +13,9 @@ class Transient; +/** + * Output a simulation time progress bar on the console + */ class ProgressOutput : public Output { public: @@ -23,7 +26,7 @@ class ProgressOutput : public Output protected: void output() override; - Transient * _transient_executioner; + const Transient * const _transient_executioner; /// display input file name in the progress bar title const bool _use_filename; diff --git a/framework/src/outputs/ProgressOutput.C b/framework/src/outputs/ProgressOutput.C index 1f7051b693a4..e0537a4aa18c 100644 --- a/framework/src/outputs/ProgressOutput.C +++ b/framework/src/outputs/ProgressOutput.C @@ -39,12 +39,11 @@ ProgressOutput::ProgressOutput(const InputParameters & parameters) void ProgressOutput::output() { - if (_transient_executioner == nullptr || _current_execute_flag != EXEC_TIMESTEP_END || - !_transient) + if (_transient_executioner == nullptr || _current_execute_flag != EXEC_TIMESTEP_END) return; const auto passed = _transient_executioner->getTime() - _transient_executioner->getStartTime(); - const auto total = _transient_executioner->endTime() - _transient_executioner->getStartTime(); + const auto total = _transient_executioner->getEndTime() - _transient_executioner->getStartTime(); if (total == 0) return;