-
Notifications
You must be signed in to change notification settings - Fork 4
/
tests.h
167 lines (143 loc) · 4.44 KB
/
tests.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// ---------------------------------------------------------------------
//
// PartExa - A Particle Library for the Exa-Scale
//
// Copyright (C) 2021-2022 by the PartExa authors
//
// This program 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.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
//
// This file is adopted from the deal.II library.
// https://github.com/dealii/dealii/blob/master/tests/tests.h
//
// ---------------------------------------------------------------------
#ifndef dealii_tests_h
#define dealii_tests_h
#include <deal.II/base/logstream.h>
#include <deal.II/base/mpi.h>
#include <fstream>
DEAL_II_NAMESPACE_OPEN
// given the name of a file, copy it to deallog
// and then delete it
void
cat_file(const char *filename)
{
{
std::ifstream in(filename);
Assert(in, dealii::ExcIO());
deallog.get_file_stream() << in.rdbuf() << "\n";
}
std::remove(filename);
}
// Function to initialize deallog. Normally, it should be called at
// the beginning of main() like
//
// initlog();
//
// This will open the correct output file, divert log output there and
// switch off screen output. If screen output is desired, provide the
// optional first argument as 'true'.
std::string deallogname;
std::ofstream deallogfile;
void
initlog(const bool console = false,
const std::ios_base::fmtflags flags = std::ios::showpoint | std::ios::left)
{
deallogname = "output";
deallogfile.open(deallogname);
deallog.attach(deallogfile, true, flags);
deallog.depth_console(console ? 10 : 0);
}
inline void
mpi_initlog(const bool console = false,
const std::ios_base::fmtflags flags = std::ios::showpoint | std::ios::left)
{
#ifdef DEAL_II_WITH_MPI
unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
if (myid == 0)
{
deallogname = "output";
deallogfile.open(deallogname.c_str());
deallog.attach(deallogfile, true, flags);
deallog.depth_console(console ? 10 : 0);
}
#else
(void)console;
(void)flags;
// can't use this function if not using MPI
Assert(false, ExcInternalError());
#endif
}
/**
* A helper class that gives each MPI process its own output file
* for the `deallog` stream, and at the end of the program (or,
* more correctly, the end of the current object), concatenates them
* all into the output file used on processor 0.
*/
struct MPILogInitAll
{
MPILogInitAll(const bool console = false,
const std::ios_base::fmtflags flags = std::ios::showpoint | std::ios::left)
{
#ifdef DEAL_II_WITH_MPI
const unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
#else
constexpr unsigned int myid = 0;
#endif
if (myid == 0)
{
if (!deallog.has_file())
{
deallogfile.open("output");
deallog.attach(deallogfile, true, flags);
}
}
else
{
deallogname = "output" + Utilities::int_to_string(myid);
deallogfile.open(deallogname.c_str());
deallog.attach(deallogfile, true, flags);
}
deallog.depth_console(console ? 10 : 0);
deallog.push(Utilities::int_to_string(myid));
}
~MPILogInitAll()
{
// pop the prefix for the MPI rank of the current process
deallog.pop();
#ifdef DEAL_II_WITH_MPI
const unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
const unsigned int nproc = Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
if (myid != 0)
{
deallog.detach();
deallogfile.close();
}
MPI_Barrier(MPI_COMM_WORLD);
if (myid == 0)
{
for (unsigned int i = 1; i < nproc; ++i)
{
std::string filename = "output" + Utilities::int_to_string(i);
cat_file(filename.c_str());
}
}
MPI_Barrier(MPI_COMM_WORLD);
#endif
}
};
DEAL_II_NAMESPACE_CLOSE
#endif