OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ProgressBar.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#include <cstdlib>
49#include <iostream>
50
51#ifdef _MSC_VER
52#define NOMINMAX
53#include <Windows.h>
54#include <io.h>
55#include <stdio.h>
56#define isatty _isatty
57#define fileno _fileno
58#else
59#include <unistd.h>
60
61#include <cstdio>
62
63#include <sys/ioctl.h>
64#endif
65
66#ifdef IS_MPI
67#include <mpi.h>
68#endif
69
70#include "utils/ProgressBar.hpp"
71
72using namespace std;
73
74namespace OpenMD {
75
76 const char* progressSpinner_ = "|/-\\";
77
78 ProgressBar::ProgressBar() :
79 value_(0.0), maximum_(-1.0), iteration_(0), start_(time(NULL)) {}
80
81 void ProgressBar::clear() {
82#ifdef IS_MPI
83 int myRank;
84 MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
85 if (myRank == 0) {
86#endif
87 cout << endl;
88 cout.flush();
89#ifdef IS_MPI
90 }
91#endif
92 iteration_ = 0;
93 value_ = 0;
94 maximum_ = -1;
95 start_ = time(NULL);
96 }
97
98 void ProgressBar::update() {
99#ifdef IS_MPI
100 int myRank;
101 MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
102 if (myRank == 0) {
103#endif
104
105 // only do the progress bar if we are actually running in a tty:
106 if (isatty(fileno(stdout)) && (getenv("SGE_TASK_ID") == NULL)) {
107 // get the window width:
108
109 int width = 0;
110#ifdef _MSC_VER
111 CONSOLE_SCREEN_BUFFER_INFO csbi;
112 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
113 int ret = GetConsoleScreenBufferInfo(hConsole, &csbi);
114 if (ret) { width = csbi.dwSize.X - 1; }
115#else
116 struct winsize w;
117 ioctl(fileno(stdout), TIOCGWINSZ, &w);
118 width = w.ws_col;
119#endif
120
121 // handle the case when the width is returned as a nonsensical value.
122 if (width <= 0) width = 80;
123
124 // We'll use:
125 // 31 characters for the completion estimate,
126 // 6 for the % complete,
127 // 2 characters for the open and closing brackets.
128
129 int avail = width - 31 - 6 - 2;
130
131 ++iteration_;
132
133 if (maximum_ > 0.0) {
134 // we know the maximum, so draw a progress bar
135
136 RealType percent =
137 std::min(std::max(value_ * 100.0 / maximum_, 1e-6), 100.0);
138
139 int hashes = int(percent * avail / 100.0);
140
141 // compute the best estimate of the ending time:
142 time_t current_ = time(NULL);
143 time_t end_ = static_cast<time_t>(start_ + (current_ - start_) *
144 (100.0 / percent));
145 struct tm* ender = localtime(&end_);
146 char buffer[22];
147 strftime(buffer, 22, "%a %b %d @ %I:%M %p", ender);
148
149#ifdef _MSC_VER
150 csbi.dwCursorPosition.X = 0;
151 SetConsoleCursorPosition(hConsole, csbi.dwCursorPosition);
152#else
153 cout << '\r';
154#endif
155 cout.width(3);
156 cout << right << int(percent);
157 cout.width(3);
158 cout << "% [";
159 cout.fill('#');
160 if (hashes + 1 < avail) {
161 cout.width(hashes + 1);
162 cout << progressSpinner_[iteration_ & 3];
163 } else {
164 cout.width(avail);
165 cout << '#';
166 }
167 cout.fill(' ');
168 if (avail - hashes - 1 > 0) {
169 cout.width(avail - hashes - 1);
170 cout << ' ';
171 }
172 cout.width(11);
173 cout << "] Estimate:";
174 cout.width(22);
175 cout << buffer;
176 }
177 cout.flush();
178 }
179#ifdef IS_MPI
180 }
181#endif
182 }
183
184 void ProgressBar::setStatus(RealType val, RealType max) {
185 value_ = val;
186 maximum_ = max;
187 }
188} // namespace OpenMD
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.