add progress bar

This commit is contained in:
Hannes Signer 2023-08-10 14:20:48 +02:00
parent cc46a893a4
commit 0fc6bf4a79
3 changed files with 196 additions and 1 deletions

View File

@ -45,7 +45,7 @@ int main(int argc, char *argv[]) {
// Simulation
Simulation sim = Simulation(grid, bc, FTCS_APPROACH);
sim.setTimestep(0.001);
sim.setIterations(100);
sim.setIterations(10000);
sim.setOutputCSV(CSV_OUTPUT_OFF);
sim.setOutputConsole(CONSOLE_OUTPUT_OFF);

191
include/tug/progressbar.hpp Normal file
View File

@ -0,0 +1,191 @@
// The MIT License (MIT)
//
// Copyright (c) 2019 Luigi Pertoldi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
// ============================================================================
// ___ ___ ___ __ ___ ____ __ __ ___ __ ___
// | |_) | |_) / / \ / /`_ | |_) | |_ ( (` ( (` | |_) / /\ | |_)
// |_| |_| \ \_\_/ \_\_/ |_| \ |_|__ _)_) _)_) |_|_) /_/--\ |_| \_
//
// Very simple progress bar for c++ loops with internal running variable
//
// Author: Luigi Pertoldi
// Created: 3 dic 2016
//
// Notes: The bar must be used when there's no other possible source of output
// inside the for loop
//
#ifndef __PROGRESSBAR_HPP
#define __PROGRESSBAR_HPP
#include <iostream>
#include <ostream>
#include <string>
#include <stdexcept>
class progressbar {
public:
// default destructor
~progressbar() = default;
// delete everything else
progressbar (progressbar const&) = delete;
progressbar& operator=(progressbar const&) = delete;
progressbar (progressbar&&) = delete;
progressbar& operator=(progressbar&&) = delete;
// default constructor, must call set_niter later
inline progressbar();
inline progressbar(int n, bool showbar=true, std::ostream& out=std::cerr);
// reset bar to use it again
inline void reset();
// set number of loop iterations
inline void set_niter(int iter);
// chose your style
inline void set_done_char(const std::string& sym) {done_char = sym;}
inline void set_todo_char(const std::string& sym) {todo_char = sym;}
inline void set_opening_bracket_char(const std::string& sym) {opening_bracket_char = sym;}
inline void set_closing_bracket_char(const std::string& sym) {closing_bracket_char = sym;}
// to show only the percentage
inline void show_bar(bool flag = true) {do_show_bar = flag;}
// set the output stream
inline void set_output_stream(const std::ostream& stream) {output.rdbuf(stream.rdbuf());}
// main function
inline void update();
private:
int progress;
int n_cycles;
int last_perc;
bool do_show_bar;
bool update_is_called;
std::string done_char;
std::string todo_char;
std::string opening_bracket_char;
std::string closing_bracket_char;
std::ostream& output;
};
inline progressbar::progressbar() :
progress(0),
n_cycles(0),
last_perc(0),
do_show_bar(true),
update_is_called(false),
done_char("#"),
todo_char(" "),
opening_bracket_char("["),
closing_bracket_char("]"),
output(std::cerr) {}
inline progressbar::progressbar(int n, bool showbar, std::ostream& out) :
progress(0),
n_cycles(n),
last_perc(0),
do_show_bar(showbar),
update_is_called(false),
done_char("#"),
todo_char(" "),
opening_bracket_char("["),
closing_bracket_char("]"),
output(out) {}
inline void progressbar::reset() {
progress = 0,
update_is_called = false;
last_perc = 0;
return;
}
inline void progressbar::set_niter(int niter) {
if (niter <= 0) throw std::invalid_argument(
"progressbar::set_niter: number of iterations null or negative");
n_cycles = niter;
return;
}
inline void progressbar::update() {
if (n_cycles == 0) throw std::runtime_error(
"progressbar::update: number of cycles not set");
if (!update_is_called) {
if (do_show_bar == true) {
output << opening_bracket_char;
for (int _ = 0; _ < 50; _++) output << todo_char;
output << closing_bracket_char << " 0%";
}
else output << "0%";
}
update_is_called = true;
int perc = 0;
// compute percentage, if did not change, do nothing and return
perc = progress*100./(n_cycles-1);
if (perc < last_perc) return;
// update percentage each unit
if (perc == last_perc + 1) {
// erase the correct number of characters
if (perc <= 10) output << "\b\b" << perc << '%';
else if (perc > 10 and perc < 100) output << "\b\b\b" << perc << '%';
else if (perc == 100) output << "\b\b\b" << perc << '%';
}
if (do_show_bar == true) {
// update bar every ten units
if (perc % 2 == 0) {
// erase closing bracket
output << std::string(closing_bracket_char.size(), '\b');
// erase trailing percentage characters
if (perc < 10) output << "\b\b\b";
else if (perc >= 10 && perc < 100) output << "\b\b\b\b";
else if (perc == 100) output << "\b\b\b\b\b";
// erase 'todo_char'
for (int j = 0; j < 50-(perc-1)/2; ++j) {
output << std::string(todo_char.size(), '\b');
}
// add one additional 'done_char'
if (perc == 0) output << todo_char;
else output << done_char;
// refill with 'todo_char'
for (int j = 0; j < 50-(perc-1)/2-1; ++j) output << todo_char;
// readd trailing percentage characters
output << closing_bracket_char << ' ' << perc << '%';
}
}
last_perc = perc;
++progress;
output << std::flush;
return;
}
#endif

View File

@ -9,6 +9,8 @@
#include "FTCS.cpp"
#include "TugUtils.hpp"
#include <tug/progressbar.hpp>
using namespace std;
@ -210,6 +212,7 @@ void Simulation::run() {
if (approach == FTCS_APPROACH) {
auto begin = std::chrono::high_resolution_clock::now();
progressbar bar(iterations * innerIterations);
for (int i = 0; i < iterations * innerIterations; i++) {
// MDL: distinguish between "outer" and "inner" iterations
// std::cout << ":: run(): Outer iteration " << i+1 << "/" << iterations << endl;
@ -221,6 +224,7 @@ void Simulation::run() {
}
FTCS(this->grid, this->bc, this->timestep);
bar.update();
}
auto end = std::chrono::high_resolution_clock::now();
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);