ug4
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 
36 #include "common/util/stringify.h"
38 
39 namespace ug{
40 
41 template <typename TDomain, typename TAlgebra>
43 MGStats() :
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 
57 template <typename TDomain, typename TAlgebra>
59 set_exit_on_error(bool exitOnError)
60 {
61  m_exitOnError = exitOnError;
62 }
63 
64 
65 template <typename TDomain, typename TAlgebra>
67 set_write_err_vecs(bool writeErrVecs)
68 {
69  m_writeErrVecs = writeErrVecs;
70 }
71 
72 template <typename TDomain, typename TAlgebra>
74 set_write_err_diffs(bool writeErrDiffs)
75 {
76  m_writeErrDiffs = writeErrDiffs;
77 }
78 
79 template <typename TDomain, typename TAlgebra>
81 set_filename_prefix(const char* filename)
82 {
83  m_filenamePrefix = filename;
84 }
85 
86 template <typename TDomain, typename TAlgebra>
88 set_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 
101 template <typename TDomain, typename TAlgebra>
104 {
105  std::string filename = mkstr(m_filenamePrefix << ".log");
106  save_stats_to_file(filename.c_str());
107 }
108 
109 template <typename TDomain, typename TAlgebra>
111 save_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 
127 template <typename TDomain, typename TAlgebra>
129 print()
130 {
131  UG_LOG(m_stats << std::endl);
132 }
133 
134 template <typename TDomain, typename TAlgebra>
136 clear()
137 {
138  m_stats.clear();
139 }
140 
141 
142 template <typename TDomain, typename TAlgebra>
144 set_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();
162  fe.tmpFunc = 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 
246 template <typename TDomain, typename TAlgebra>
248 level_required(int lvl)
249 {
250  if((int)m_funcs.size() <= lvl)
251  m_funcs.resize(lvl + 1);
252 }
253 
254 
255 template <typename TDomain, typename TAlgebra>
257 write_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