Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mg_stats_impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017: G-CSC, Goethe University Frankfurt
3 * Author: Sebastian Reiter
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG_mg_stats_impl
34#define __H__UG_mg_stats_impl
35
38
39namespace ug{
40
41template <typename TDomain, typename TAlgebra>
43MGStats() :
44 m_statsRow(-1),
45 m_lastLvlWritten(-1),
46 m_maxLvl(0),
47 m_filenamePrefix("mgstats"),
48 m_exitOnError(false),
49 m_writeErrVecs(false),
50 m_writeErrDiffs(false)
51{
52 for(int i = 0; i < NUM_STAGES; ++i)
53 m_stageIsActive[i] = true;
54 m_stageIsActive[INVALID] = false;
55}
56
57template <typename TDomain, typename TAlgebra>
59set_exit_on_error(bool exitOnError)
60{
61 m_exitOnError = exitOnError;
62}
63
64
65template <typename TDomain, typename TAlgebra>
67set_write_err_vecs(bool writeErrVecs)
68{
69 m_writeErrVecs = writeErrVecs;
70}
71
72template <typename TDomain, typename TAlgebra>
74set_write_err_diffs(bool writeErrDiffs)
75{
76 m_writeErrDiffs = writeErrDiffs;
77}
78
79template <typename TDomain, typename TAlgebra>
81set_filename_prefix(const char* filename)
82{
83 m_filenamePrefix = filename;
84}
85
86template <typename TDomain, typename TAlgebra>
88set_active_stages(const std::vector<int>& activeStages)
89{
90 for(int i = 0; i < NUM_STAGES; ++i)
91 m_stageIsActive[i] = false;
92
93 for(size_t i = 0; i < activeStages.size(); ++i){
94 if(activeStages[i] >= 0 && (int)activeStages[i] < NUM_STAGES)
95 m_stageIsActive[activeStages[i]] = true;
96 }
97
98 m_stageIsActive[INVALID] = false;
99}
100
101template <typename TDomain, typename TAlgebra>
104{
105 std::string filename = mkstr(m_filenamePrefix << ".log");
106 save_stats_to_file(filename.c_str());
107}
108
109template <typename TDomain, typename TAlgebra>
111save_stats_to_file(const char* filename)
112{
113 #ifdef UG_PARALLEL
114 if(pcl::ProcRank() == 0){
115 #endif
116
117 std::ofstream out(filename);
118 UG_COND_THROW(!out, "MGStats: Couldn't open '" << filename << "' for writing.");
119 out << m_stats << std::endl;
120 out.close();
121
122 #ifdef UG_PARALLEL
123 }
124 #endif
125}
126
127template <typename TDomain, typename TAlgebra>
129print()
130{
131 UG_LOG(m_stats << std::endl);
132}
133
134template <typename TDomain, typename TAlgebra>
136clear()
137{
138 m_stats.clear();
139}
140
141
142template <typename TDomain, typename TAlgebra>
144set_defect(grid_func_t& gf, int lvl, Stage stage)
145{
146 if(lvl < 0)
147 return;
148
149 if(!m_stageIsActive[stage])
150 return;
151
152 level_required(lvl);
153 FuncEntry& fe = m_funcs[lvl];
154
155 if(stage == INVALID){
156 fe.stage = INVALID;
157 return;
158 }
159
160 if(fe.func.invalid() || fe.func->num_indices() != gf.num_indices()){
161 fe.func = gf.clone_without_values();
163 fe.stage = INVALID;
164 fe.norm = 0;
165 }
166
167// this is just an assumption that a new cycle started
168 if(stage <= fe.stage && lvl >= m_lastLvlWritten){
169 ++m_statsRow;
170 m_lastLvlWritten = -1;
171 write_header(lvl);
172 // write a line to cout so that the output and the stats can be connected
173 UG_LOG(" >>> mg-stats row: " << m_statsRow << std::endl);
174 }
175
176 ++m_statsRow;
177
178 const int r = m_statsRow;
179
180 m_lastLvlWritten = lvl;
181
182// write the current row index
183 m_stats(r, 0) = mkstr(r);
184 m_stats(r, 1) = stage_norm_name(stage);
185
186
187// compute statistics
188// copy gf to fe.tmpFunc to avoid any side effects on the multigrid iteration
189 fe.tmpFunc->assign(gf);
190 grid_func_t& newFunc = *fe.tmpFunc;
191 const number norm = newFunc.norm();
192 m_stats(r, 2 + m_maxLvl - lvl) = mkstr(norm);
193
194 if((fe.stage < stage) && (norm > fe.norm)){
195 // during the last operation the defect grew.
196 // output the old and new grid functions and their difference
197 std::string filename;
198
199 if(m_writeErrVecs){
200 filename = mkstr(m_filenamePrefix << "-row-" << r << "-lvl-"
201 << lvl << "--" << fe.stage << "-"
202 << stage_name(fe.stage) << ".vec");
203
204 SaveVectorForConnectionViewer((*fe.func), filename.c_str());
205
206
207 filename = mkstr(m_filenamePrefix << "-row-" << r << "-lvl-"
208 << lvl << "--" << stage << "-"
209 << stage_name(stage) << ".vec");
210
211 SaveVectorForConnectionViewer(gf, filename.c_str());
212 }
213
214 if(m_writeErrDiffs){
215 filename = mkstr(m_filenamePrefix << "-row-" << r << "-lvl-"
216 << lvl << "-diff--" << stage << "-"
217 << stage_name(fe.stage) << "-"
218 << stage_name(stage) << ".vec");
219 SaveVectorDiffForConnectionViewer(gf, *fe.func, filename.c_str());
220 }
221
222 std::string errMsg =
223 mkstr("MGStats: Defect deteriorated on level " << lvl
224 << " between stages '" << stage_name(fe.stage) << "' and '"
225 << stage_name(stage) << "'. (MGStats row: " << r << ")");
226
227 if(m_exitOnError){
228 save_stats_to_file();
229 print();
230 UG_THROW(errMsg);
231 }
232 else{
233 UG_LOG(errMsg << std::endl);
234 }
235 }
236
237// swap grid function of fe
238 sp_grid_func_t sptmp = fe.func;
239 fe.func = fe.tmpFunc;
240 fe.tmpFunc = sptmp;
241 fe.norm = norm;
242 fe.stage = stage;
243}
244
245
246template <typename TDomain, typename TAlgebra>
248level_required(int lvl)
249{
250 if((int)m_funcs.size() <= lvl)
251 m_funcs.resize(lvl + 1);
252}
253
254
255template <typename TDomain, typename TAlgebra>
257write_header(int maxLvl)
258{
259 m_maxLvl = maxLvl;
260 m_stats(m_statsRow, 0) = "row";
261 m_stats(m_statsRow, 1) = "stage";
262 for(int i = 0; i < maxLvl; ++i){
263 m_stats(m_statsRow, i+2) = mkstr("lvl " << maxLvl - i);
264 }
265}
266
267
268}// end of namespace
269
270#endif //__H__UG_mg_stats_impl
bool invalid() const
returns true if the pointer is invalid, false if not.
Definition smart_pointer.h:212
represents numerical solutions on a grid using an algebraic vector
Definition grid_function.h:121
size_t num_indices() const
return the number of indices distributed (proc local)
Definition grid_function.h:303
SmartPtr< this_type > clone_without_values() const
clone excluding values
Definition grid_function.h:219
void set_exit_on_error(bool exitOnError)
If enabled, a deterioration of the norm of the defect leads to an error.
Definition mg_stats_impl.hpp:59
void set_write_err_vecs(bool writeErrVecs)
If enabled, involved defects are written to file if the defect deteriorates.
Definition mg_stats_impl.hpp:67
void save_stats_to_file()
saves current stats to filenamePrefix.log
Definition mg_stats_impl.hpp:103
void clear()
clears the current stats
Definition mg_stats_impl.hpp:136
void set_active_stages(const std::vector< int > &activeStages)
sets the active stages. All other stages will be ignored.
Definition mg_stats_impl.hpp:88
MGStats()
Definition mg_stats_impl.hpp:43
void level_required(int lvl)
Definition mg_stats_impl.hpp:248
void write_header(int maxLvl)
Definition mg_stats_impl.hpp:257
Stage
Defines at which stage data is recorded in a given multigrid cycle.
Definition mg_stats.h:51
@ INVALID
Definition mg_stats.h:56
static const int NUM_STAGES
Definition mg_stats.h:59
void set_defect(grid_func_t &gf, int lvl, Stage stage)
set the defect on a certain level for a given stage
Definition mg_stats_impl.hpp:144
bool m_stageIsActive[NUM_STAGES]
Definition mg_stats.h:143
void set_filename_prefix(const char *filename)
sets the prefix with which files are written
Definition mg_stats_impl.hpp:81
void set_write_err_diffs(bool writeErrDiffs)
If enabled, a diff bettween defects involved is written to file if the defect deteriorates.
Definition mg_stats_impl.hpp:74
void print()
prints the current stats
Definition mg_stats_impl.hpp:129
int ProcRank()
returns the rank of the process
Definition pcl_base.cpp:83
function table print(data, style)
#define UG_THROW(msg)
Definition error.h:57
#define UG_LOG(msg)
Definition log.h:367
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition error.h:61
double number
Definition types.h:124
the ug namespace
void SaveVectorForConnectionViewer(TGridFunction &b, const char *filename)
Definition grid_function_util.h:828
void SaveVectorDiffForConnectionViewer(TGridFunction &b, TGridFunction &bCompare, const char *filename)
Definition grid_function_util.h:833
#define mkstr(s)
Comfortable (but not necessarily efficient) string building.
Definition stringify.h:100
Definition mg_stats.h:134
number norm
Definition mg_stats.h:139
Stage stage
Definition mg_stats.h:138
sp_grid_func_t func
Definition mg_stats.h:136
sp_grid_func_t tmpFunc
Definition mg_stats.h:137