Line data Source code
1 : /*
2 : * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
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__LIB_ALGEBRA__OPERATOR__DEBUG_WRITER__
34 : #define __H__LIB_ALGEBRA__OPERATOR__DEBUG_WRITER__
35 :
36 : #include "common/util/smart_pointer.h"
37 : #include "common/math/ugmath.h"
38 : #include "common/profiler/profiler.h"
39 : #include "common/util/file_util.h"
40 :
41 : namespace ug{
42 :
43 : /// Interface for providing vertex positions
44 : template <size_t dim>
45 : class IPositionProvider
46 : {
47 : public:
48 : /// Assigns position information to given vector
49 : /** \param vec vector to be modified
50 : * todo: change to assign_positions () const?*/
51 : virtual bool get_positions(std::vector<MathVector<dim> >&vec) = 0;
52 : virtual ~IPositionProvider() {}
53 : };
54 :
55 : /// Context of a debugger writer: Keeps the debugging section etc.
56 0 : class DebugWriterContext
57 : {
58 : public:
59 :
60 : /// constructor
61 0 : DebugWriterContext () : m_baseDir(".") {}
62 :
63 : /// set the base directory for output files (.vec and .mat)
64 0 : inline void set_base_dir(const char* const baseDir) {m_baseDir = std::string(baseDir);}
65 0 : std::string get_base_dir() { return m_baseDir; }
66 :
67 : /// enter a new debugging section
68 0 : inline void enter_section(const char* secDir) {m_secDir.push_back(secDir);}
69 :
70 : /// leave the current debugging section
71 0 : inline void leave_section () {m_secDir.pop_back();}
72 :
73 : /// prints a message
74 0 : void print_message(const char * msg)
75 : {
76 : UG_LOG ("DBG > ");
77 0 : for (size_t i = 0; i < m_secDir.size (); i++)
78 : {
79 : UG_LOG (":" << m_secDir[i]);
80 : }
81 0 : UG_LOG (" > " << msg);
82 0 : }
83 :
84 : /// composes the path for the files and creates the intermediate directories (up to the base one):
85 0 : void compose_file_path(std::string& path)
86 : {
87 0 : path = get_base_dir ();
88 0 : if (! FileExists (path))
89 : {
90 : UG_WARNING ("IVectorDebugWriter: Directory '" << path << "' does not exist. Using cwd instead.\n");
91 : path = ".";
92 : }
93 0 : for (size_t i = 0; i < m_secDir.size (); i++)
94 : {
95 0 : path.append ("/"); //TODO: This can be OS-dependent.
96 : path.append (m_secDir[i]);
97 0 : if ((! FileExists (path)) && ! CreateDirectory (path))
98 : UG_WARNING ("IVectorDebugWriter: Could not create directory '" << path << "'. Using cwd instead.\n");
99 : }
100 0 : path.append ("/"); //TODO: This can be OS-dependent.
101 0 : }
102 :
103 : protected:
104 :
105 : /// base directory for the debugging output
106 : std::string m_baseDir;
107 :
108 : /// debuging section subdirectories
109 : std::vector<std::string> m_secDir;
110 : };
111 :
112 : /// base class for all vector debug writer
113 : /**
114 : * This is the base class for debug output of algebraic vectors
115 : */
116 : template <typename TVector>
117 : class IVectorDebugWriter
118 : {
119 : public:
120 : /// type of vector
121 : typedef TVector vector_type;
122 :
123 : public:
124 : /// Constructor
125 0 : IVectorDebugWriter()
126 0 : : m_spContext (new DebugWriterContext), m_currentDim(-1) {}
127 :
128 : /// virtual destructor
129 0 : virtual ~IVectorDebugWriter(){}
130 :
131 : /// write vector
132 : virtual void write_vector(const vector_type& vec, const char* name) = 0;
133 :
134 : /// returns the current dimension
135 0 : int current_dimension() const {return m_currentDim;}
136 :
137 : /// returns the positions (only available for current dimension)
138 : template <int dim>
139 0 : const std::vector<MathVector<dim> >& get_positions() const
140 : {
141 0 : if(m_currentDim != dim) throw(UGError("Current dim is different."));
142 0 : return get_pos(Int2Type<dim>());
143 : }
144 :
145 : /// gives subclasses the oportunity to calculate the positions
146 : /// this is used e.g. in GridFunctionDebugWriter
147 : /// after this has been called, get_positions gives valid positions
148 : /// those positions are used e.g. in AMG or Schur methods.
149 0 : virtual void update_positions() {};
150 :
151 : /// sets the current positions
152 : template <int dim>
153 : void set_positions(const std::vector<MathVector<dim> >& vPos)
154 : {
155 0 : get_pos(Int2Type<dim>()) = vPos; m_currentDim = dim;
156 : }
157 :
158 : /// employs a position provider to set the current positions
159 : template <int dim>
160 : void set_positions(IPositionProvider<dim> & provider)
161 : {
162 : provider.get_positions(get_pos(Int2Type<dim>()));
163 : m_currentDim = dim;
164 : }
165 :
166 : /// get the dimensionality
167 : int get_dim() const
168 : {
169 0 : return m_currentDim;
170 : }
171 :
172 : /// set the debugging writer context
173 0 : void set_context(SmartPtr<DebugWriterContext> context) {m_spContext = context;}
174 :
175 : /// get the debugging writer context
176 0 : SmartPtr<DebugWriterContext> get_context() {return m_spContext;}
177 :
178 : /// get the debugging writer context
179 : ConstSmartPtr<DebugWriterContext> get_context() const {return m_spContext;}
180 :
181 : /// prints a message
182 0 : virtual void print_message(const char * msg) {if (m_spContext.valid()) m_spContext->print_message(msg);}
183 :
184 : /// set the base directory for output files (.vec and .mat)
185 0 : inline void set_base_dir(const char* const baseDir)
186 : {
187 0 : if (! m_spContext.valid())
188 0 : set_context (SmartPtr<DebugWriterContext> (new DebugWriterContext));
189 0 : m_spContext->set_base_dir (baseDir);
190 0 : }
191 :
192 0 : std::string get_base_dir() {return (m_spContext.valid())? m_spContext->get_base_dir() : "";}
193 :
194 : /// enter a new debugging section
195 0 : inline void enter_section(const char* secDir) {if (m_spContext.valid()) m_spContext->enter_section (secDir);}
196 :
197 : /// leave the current debugging section
198 0 : inline void leave_section () {if (m_spContext.valid()) m_spContext->leave_section ();}
199 :
200 : protected:
201 :
202 : /// returns the positions and sets the current dim
203 : template <int dim>
204 : std::vector<MathVector<dim> >& positions()
205 : {
206 0 : m_currentDim = dim; return get_pos(Int2Type<dim>());
207 : }
208 :
209 : /// composes the path for the files and creates the intermediate directories (up to the base one):
210 0 : void compose_file_path(std::string& path)
211 : {
212 0 : if (m_spContext.valid()) m_spContext->compose_file_path (path);
213 : else path = ".";
214 0 : }
215 :
216 : protected:
217 :
218 : /// debugging writer context
219 : SmartPtr<DebugWriterContext> m_spContext;
220 :
221 : /// current dimension
222 : int m_currentDim;
223 :
224 : /// vectors of positions
225 : std::vector<MathVector<1> > m_vPos1d;
226 : std::vector<MathVector<2> > m_vPos2d;
227 : std::vector<MathVector<3> > m_vPos3d;
228 :
229 : /// help function to get local ips
230 0 : std::vector<MathVector<1> >& get_pos(Int2Type<1>) {return m_vPos1d;}
231 0 : std::vector<MathVector<2> >& get_pos(Int2Type<2>) {return m_vPos2d;}
232 0 : std::vector<MathVector<3> >& get_pos(Int2Type<3>) {return m_vPos3d;}
233 0 : const std::vector<MathVector<1> >& get_pos(Int2Type<1>) const {return m_vPos1d;}
234 0 : const std::vector<MathVector<2> >& get_pos(Int2Type<2>) const {return m_vPos2d;}
235 0 : const std::vector<MathVector<3> >& get_pos(Int2Type<3>) const {return m_vPos3d;}
236 : };
237 :
238 : /// base class for all debug writer
239 : /**
240 : * This is the base class for debug output of algebraic vectors and matrices.
241 : */
242 : template <typename TAlgebra>
243 0 : class IDebugWriter : public IVectorDebugWriter<typename TAlgebra::vector_type>
244 : {
245 : public:
246 : /// type of algebra
247 : typedef TAlgebra algebra_type;
248 :
249 : /// type of vector
250 : typedef typename TAlgebra::vector_type vector_type;
251 :
252 : /// type of matrix
253 : typedef typename TAlgebra::matrix_type matrix_type;
254 :
255 : public:
256 : /// write vector
257 : virtual void write_vector(const vector_type& vec, const char* name) = 0;
258 :
259 : /// write matrix
260 : virtual void write_matrix(const matrix_type& mat, const char* name) = 0;
261 : };
262 :
263 :
264 : template <typename TVector>
265 : class VectorDebugWritingObject
266 : {
267 : public:
268 : /// type of vector
269 : typedef TVector vector_type;
270 :
271 : public:
272 0 : VectorDebugWritingObject() : m_spVectorDebugWriter(NULL) {}
273 0 : VectorDebugWritingObject(SmartPtr<IVectorDebugWriter<vector_type> > spDebugWriter)
274 0 : : m_spVectorDebugWriter(spDebugWriter) {}
275 :
276 : /// virtual destructor
277 0 : virtual ~VectorDebugWritingObject() {}
278 :
279 : /// set debug writer
280 0 : virtual void set_debug(SmartPtr<IVectorDebugWriter<vector_type> > spDebugWriter)
281 : {
282 0 : m_spVectorDebugWriter = spDebugWriter;
283 0 : }
284 :
285 : /// returns the debug writer
286 0 : SmartPtr<IVectorDebugWriter<vector_type> > vector_debug_writer() {return m_spVectorDebugWriter;}
287 0 : ConstSmartPtr<IVectorDebugWriter<vector_type> > vector_debug_writer() const {return m_spVectorDebugWriter;}
288 :
289 : /// returns true if the debug writer is set
290 : bool vector_debug_writer_valid() const {return m_spVectorDebugWriter.valid();}
291 :
292 : /// writing debug output for a vector (if debug writer set)
293 0 : void write_debug(const vector_type& vec, const char* filename)
294 : {
295 0 : write_debug(vec, std::string (filename));
296 0 : }
297 :
298 : protected:
299 : /// writing debug output for a vector (if debug writer set)
300 0 : virtual void write_debug(const vector_type& vec, std::string name)
301 : {
302 : PROFILE_FUNC_GROUP("algebra debug");
303 : // if no debug writer set, we're done
304 0 : if(m_spVectorDebugWriter.invalid()) return;
305 :
306 : // check ending
307 : size_t iExtPos = name.find_last_of(".");
308 0 : if(iExtPos != std::string::npos && name.substr(iExtPos).compare(".vec") != 0)
309 0 : UG_THROW("Only '.vec' format supported for vectors, but"
310 : " filename is '"<<name<<"'.");
311 :
312 0 : if(iExtPos == std::string::npos)
313 0 : name.append(".vec");
314 :
315 : // write
316 0 : m_spVectorDebugWriter->write_vector(vec, name.c_str());
317 : }
318 :
319 : /// prints a debugger message (listing all the sections)
320 : void print_debugger_message(std::string msg)
321 : {
322 : print_debugger_message(msg.c_str());
323 : }
324 : /// prints a debugger message (listing all the sections)
325 : void print_debugger_message(const char * msg)
326 : {
327 0 : if (m_spVectorDebugWriter.valid()) m_spVectorDebugWriter->print_message(msg);
328 : }
329 :
330 : /// enters a debugging section
331 : void enter_vector_debug_writer_section(std::string secDir)
332 : {
333 : enter_vector_debug_writer_section(secDir.c_str());
334 : }
335 : /// enters a debugging section
336 : void enter_vector_debug_writer_section(const char * secDir)
337 : {
338 0 : if (m_spVectorDebugWriter.valid()) m_spVectorDebugWriter->enter_section(secDir);
339 : }
340 :
341 : /// leaves a debugging section
342 0 : void leave_vector_debug_writer_section()
343 : {
344 0 : if (m_spVectorDebugWriter.valid()) m_spVectorDebugWriter->leave_section();
345 0 : }
346 :
347 : protected:
348 : /// Debug Writer
349 : SmartPtr<IVectorDebugWriter<vector_type> > m_spVectorDebugWriter;
350 : };
351 :
352 : template <typename TAlgebra>
353 : class DebugWritingObject : public VectorDebugWritingObject<typename TAlgebra::vector_type>
354 : {
355 : public:
356 : /// type of algebra
357 : typedef TAlgebra algebra_type;
358 :
359 : /// type of vector
360 : typedef typename TAlgebra::vector_type vector_type;
361 :
362 : /// type of matrix
363 : typedef typename TAlgebra::matrix_type matrix_type;
364 :
365 : protected:
366 : using VectorDebugWritingObject<vector_type>::write_debug;
367 : using VectorDebugWritingObject<vector_type>::set_debug;
368 :
369 : public:
370 0 : DebugWritingObject() : m_spDebugWriter(NULL) {}
371 : DebugWritingObject(SmartPtr<IDebugWriter<algebra_type> > spDebugWriter)
372 : : VectorDebugWritingObject<vector_type>(spDebugWriter),
373 : m_spDebugWriter(spDebugWriter) {}
374 :
375 : /// clone constructor
376 0 : DebugWritingObject(const DebugWritingObject<algebra_type> &parent)
377 : : VectorDebugWritingObject<vector_type>(parent.m_spDebugWriter),
378 0 : m_spDebugWriter(parent.m_spDebugWriter) {}
379 :
380 : /// virtual destructor
381 0 : virtual ~DebugWritingObject() {}
382 :
383 : /// set debug writer
384 0 : virtual void set_debug(SmartPtr<IDebugWriter<algebra_type> > spDebugWriter)
385 : {
386 0 : m_spDebugWriter = spDebugWriter;
387 0 : VectorDebugWritingObject<vector_type>::set_debug(m_spDebugWriter);
388 0 : }
389 :
390 : /// returns the debug writer
391 0 : SmartPtr<IDebugWriter<algebra_type> > debug_writer() {return m_spDebugWriter;}
392 0 : ConstSmartPtr<IDebugWriter<algebra_type> > debug_writer() const {return m_spDebugWriter;}
393 :
394 : /// returns true if the debug writer is set
395 : bool debug_writer_valid() const {return m_spDebugWriter.valid();}
396 :
397 : protected:
398 : /// write debug output for a matrix (if debug writer set)
399 0 : void write_debug(const matrix_type& mat, const char* filename)
400 : {
401 0 : write_debug(mat, std::string(filename));
402 0 : }
403 : /// write debug output for a matrix (if debug writer set)
404 0 : void write_debug(const matrix_type& mat, std::string name)
405 : {
406 : PROFILE_FUNC_GROUP("algebra debug");
407 : // if no debug writer set, we're done
408 0 : if(m_spDebugWriter.invalid()) return;
409 :
410 : // check ending
411 : size_t iExtPos = name.find_last_of(".");
412 0 : if(iExtPos != std::string::npos && name.substr(iExtPos).compare(".mat") != 0)
413 0 : UG_THROW("Only '.mat' format supported for matrices, but"
414 : " filename is '"<<name<<"'.");
415 :
416 0 : if(iExtPos == std::string::npos)
417 0 : name.append(".mat");
418 :
419 : // write
420 0 : m_spDebugWriter->write_matrix(mat, name.c_str());
421 : }
422 :
423 : /// enters a debugging section
424 : void enter_debug_writer_section(std::string secDir)
425 : {
426 : enter_debug_writer_section(secDir.c_str());
427 : }
428 : /// enters a debugging section
429 : void enter_debug_writer_section(const char * secDir)
430 : {
431 0 : if (m_spDebugWriter.valid()) m_spDebugWriter->enter_section(secDir);
432 : }
433 :
434 : /// leaves a debugging section
435 0 : void leave_debug_writer_section()
436 : {
437 0 : if (m_spDebugWriter.valid()) m_spDebugWriter->leave_section();
438 0 : }
439 :
440 : protected:
441 : /// Debug Writer
442 : SmartPtr<IDebugWriter<algebra_type> > m_spDebugWriter;
443 : };
444 :
445 : } // end namespace ug
446 :
447 : #endif /* __H__LIB_ALGEBRA__OPERATOR__DEBUG_WRITER__ */
|