ug4
connection_viewer_output.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
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 CONNECTIONVIEWEROUTPUT_H_
34 #define CONNECTIONVIEWEROUTPUT_H_
35 
36 #include <iostream>
37 #include <fstream>
38 #include <vector>
39 #include <string>
40 #include <limits>
41 
42 #include "common/progress.h"
44 
45 #ifdef UG_PARALLEL
46 #include "pcl/pcl.h"
47 #include "pcl/parallel_archive.h"
48 #endif
49 
50 
51 #define CONNECTION_VIEWER_VERSION 1
52 
53 namespace ug
54 {
55 namespace ConnectionViewer
56 {
57 extern bool g_parallelConnectionViewer;
58 #ifdef UG_PARALLEL
62 std::string GetParallelName(std::string name, const pcl::ProcessCommunicator &pc, bool bWriteHeader=true);
63 
64 inline std::string GetParallelName(std::string name)
65 {
67  return GetParallelName(name, pc);
68 
69 }
70 template<typename T>
71 inline std::string GetParallelName(T &t, std::string name)
72 {
73  return GetParallelName(name, t.layouts()->proc_comm());
74 }
75 #else
76 template<typename T>
77 inline std::string GetParallelName(T &t, std::string name)
78 {
79  return name;
80 }
81 #endif
82 
83 
84 bool AddMarkers(std::string filename, std::string markfilename);
85 bool WriteMarkers(std::string markfilename, std::vector<bool> markers, float r, float g, float b, float alpha, int size);
86 
87 template<typename TPosition>
88 bool WriteGridHeader(std::ostream &f, const TPosition &positions, size_t N, int dimension)
89 {
90  // assert(dimension == 2 || dimension == 3);
91  f << 1 << "\n";
92  f << dimension << "\n";
93  f << N << "\n";
94  if(dimension == 1)
95  for(size_t i=0; i < N; i++)
96  f << positions[i][0] << " 0.0\n";
97  else if(dimension == 2)
98  for(size_t i=0; i < N; i++)
99  f << positions[i][0] << " " << positions[i][1] << "\n";
100  else
101  for(size_t i=0; i < N; i++)
102  f << positions[i][0] << " " << positions[i][1] << " " << positions[i][2] << "\n";
103 
104  f << 1 << "\n"; // stringsInWindow
105  return true;
106 }
107 
108 template<typename TPosition>
109 bool WriteGridHeader(std::ostream &f, const TPosition &positions, int dimension)
110 {
111  return WriteGridHeader(f, positions, positions.size(), dimension);
112 }
113 
114 // WriteMatrixToConnectionViewer
115 //--------------------------------------------------
123 template<typename Matrix_type, typename postype>
124 void WriteMatrix(std::ostream &file, const Matrix_type &A, postype *positions, int dimensions)
125 {
126  PROFILE_FUNC_GROUP("debug");
127  size_t rows = A.num_rows();
128 
129  WriteGridHeader(file, positions, rows, dimensions);
130  PROGRESS_START(prog, rows, "WriteMatrixToConnectionViewer " << dimensions << "d, " << rows << "x" << rows);
131 
132  // write connections
133  for(size_t i=0; i < rows; i++)
134  {
135  PROGRESS_UPDATE(prog, i);
136  for(typename Matrix_type::const_row_iterator conn = A.begin_row(i); conn != A.end_row(i); ++conn)
137  if(conn.value() != 0.0)
138  file << i << " " << conn.index() << " " << conn.value() << std::endl;
139  else
140  file << i << " " << conn.index() << " 0" << std::endl;
141  }
142 }
143 
144 template<typename Matrix_type, typename postype>
145 void WriteMatrix(std::string filename, const Matrix_type &A, postype *positions, int dimensions)
146 {
147  std::fstream file(filename.c_str(), std::ios::out);
148  WriteMatrix(file, A, positions, dimensions);
149 }
150 
151 
152 template<typename Matrix_type, typename postype>
153 void WriteMatrixPar(std::string name, const Matrix_type &A, const postype *positions, int dimensions)
154 {
156  WriteMatrix(GetParallelName(A, name), A, positions, dimensions);
157  else
158  {
159  #ifndef UG_PARALLEL
160  WriteMatrix(GetParallelName(A, name), A, positions, dimensions);
161  #else
162  const pcl::ProcessCommunicator &pc = A.layouts()->proc_comm();
163  if(pcl::NumProcs() == 1)
164  WriteMatrix(name, A, positions, dimensions);
165 
166  std::string buf; //char buf[20];
167  int rank = pcl::ProcRank();
168 
169 
170  std::string fname = FilenameWithoutExtension(name);
171  std::string ext = GetFilenameExtension(name);
172 
173  pcl::ParallelArchive ar(name + ".tarmat", pc);
174  if(rank == pc.get_proc_id(0))
175  {
176  // create the .pmat "header" file
177  std::stringstream &file = ar.create_stringstream_file(fname + ".p" + ext);
178  file << pc.size() << "\n";
179  for(size_t i=0; i<pc.size(); i++)
180  {
181  // snprintf(buf, sizeof(buf), "_p%04d.%s", pc.get_proc_id(i), ext.c_str());
182  buf = GetStringPrintf("_p%04d.%s", pc.get_proc_id(i), ext.c_str());
183  file << fname << buf << "\n";
184  }
185  }
186  // create the .mat file
187  buf = GetStringPrintf("_p%04d.%s", rank, ext.c_str());
188  WriteMatrix(ar.create_stringstream_file(fname + buf), A, positions, dimensions);
189  #endif
190  }
191 }
192 
193 
194 // NOTE: The commented version below contains a bug which only occurs in rare situations,
195 // resulting in a matrix output, where one entry has connections to
196 // many other entries. Most presumably a problem with the mappings.
197 // Instead of fixing it, the method was instead replaced by the method below
198 // the commented section, which simplifies the output. Since the version with
199 // the mapping might still be of interest, it remains in a commented form.
203 // * this version can handle different from and to spaces
204 // */
205 //template <typename Matrix_type, typename postype>
206 //bool WriteMatrixToConnectionViewerMapped(std::string filename,
207 // const Matrix_type &A,
208 // std::vector<postype> &positionsFrom, std::vector<postype> &positionsTo, size_t dimensions)
209 //{
210 // PROFILE_FUNC_GROUP("debug");
211 //#ifdef UG_PARALLEL
212 // filename = GetParallelName(A, filename);
213 //#endif
214 //
215 // /*const char * p = strstr(filename, ".mat");
216 // if(p == NULL)
217 // {
218 // UG_LOG("Currently only '.mat' format supported for domains.\n");
219 // return false;
220 // }*/
221 //
222 // if(positionsFrom.size() != A.num_cols())
223 // {
224 // UG_LOG("uFrom.size() != A.num_cols() !\n");
225 // return false;
226 // }
227 // if(positionsTo.size() != A.num_rows())
228 // {
229 // UG_LOG("uTo.size() != A.num_rows() !\n");
230 // return false;
231 // }
232 //
233 // std::vector<postype> positions;
234 // std::vector<size_t> mapFrom, mapTo;
235 // mapFrom.resize(positionsFrom.size());
236 // mapTo.resize(positionsTo.size());
237 //
238 // if(positionsFrom.size() > positionsTo.size())
239 // {
240 // positions.resize(positionsFrom.size());
241 // for(size_t i=0; i<positionsFrom.size(); i++)
242 // {
243 // positions[i] = positionsFrom[i];
244 // mapFrom[i] = i;
245 // }
246 //
247 //
248 // for(size_t i=0; i<positionsTo.size(); i++)
249 // {
250 // size_t j;
251 // for(j=0; j<positionsFrom.size(); j++)
252 // {
253 // if(positionsTo[i] == positionsFrom[j])
254 // break;
255 // }
256 // mapTo[i] = j;
257 // if(j == positionsFrom.size())
258 // positions.push_back(positionsTo[i]);
259 // }
260 // }
261 // else
262 // {
263 // positions.resize(positionsTo.size());
264 // for(size_t i=0; i<positionsTo.size(); i++)
265 // {
266 // positions[i] = positionsTo[i];
267 // mapTo[i] = i;
268 // }
269 //
270 // for(size_t i=0; i<positionsFrom.size(); i++)
271 // {
272 // size_t j;
273 // for(j=0; j<positionsTo.size(); j++)
274 // {
275 // if(positionsFrom[i] == positionsTo[j])
276 // break;
277 // }
278 // mapFrom[i] = j;
279 // if(j == positionsTo.size())
280 // positions.push_back(positionsFrom[i]);
281 // }
282 // }
283 //
284 //
285 // std::fstream file(filename.c_str(), std::ios::out);
286 // file << CONNECTION_VIEWER_VERSION << std::endl;
287 // file << dimensions << std::endl;
288 //
289 // // write positions
290 // file << positions.size() << std::endl;
291 //
292 // if(dimensions == 1)
293 // for(size_t i=0; i < positions.size(); i++)
294 // file << positions[i][0] << " 0.0" << std::endl;
295 // else if(dimensions == 2)
296 //
297 // for(size_t i=0; i < positions.size(); i++)
298 // file << positions[i][0] << " " << positions[i][1] << std::endl;
299 // else
300 // for(size_t i=0; i < positions.size(); i++)
301 // file << positions[i][0] << " " << positions[i][1] << " " << positions[i][2] << std::endl;
302 //
303 // file << 1 << std::endl; // show all cons
304 // // write connections
305 // for(size_t i=0; i < A.num_rows(); i++)
306 // {
307 // for(typename Matrix_type::const_row_iterator conn = A.begin_row(i); conn != A.end_row(i); ++conn)
308 // if(conn.value() != 0.0)
309 // file << mapTo[i] << " " << mapFrom[conn.index()] << " " << conn.value() << std::endl;
310 // else
311 // file << mapTo[i] << " " << mapFrom[conn.index()] << " 0" << std::endl;
312 // }
313 // return true;
314 //}
315 
316 // WriteMatrixToConnectionViewer
317 //--------------------------------------------------
321 template <typename Matrix_type, typename postype>
322 bool WriteMatrix( std::string filename,
323  const Matrix_type &A,
324  const std::vector<postype> &positionsFrom,
325  const std::vector<postype> &positionsTo, size_t dimensions)
326 {
327  PROFILE_FUNC_GROUP("debug");
328 
329  if(positionsFrom.size() != A.num_cols())
330  {
331  UG_LOG("uFrom.size() != A.num_cols() !\n");
332  return false;
333  }
334  if(positionsTo.size() != A.num_rows())
335  {
336  UG_LOG("uTo.size() != A.num_rows() !\n");
337  return false;
338  }
339 
340  size_t fromOffset = positionsTo.size();
341 
342 
343  std::fstream file(filename.c_str(), std::ios::out);
344  file << CONNECTION_VIEWER_VERSION << std::endl;
345  file << dimensions << std::endl;
346 
347  // write positions
348  file << positionsFrom.size() + positionsTo.size() << std::endl;
349 
350  if(dimensions == 1){
351  for(size_t i=0; i < positionsTo.size(); i++)
352  file << positionsTo[i][0] << " 0.0" << std::endl;
353  for(size_t i=0; i < positionsFrom.size(); i++)
354  file << positionsFrom[i][0] << " 0.0" << std::endl;
355  }
356  else if(dimensions == 2){
357  for(size_t i=0; i < positionsTo.size(); i++)
358  file << positionsTo[i][0] << " " << positionsTo[i][1] << std::endl;
359  for(size_t i=0; i < positionsFrom.size(); i++)
360  file << positionsFrom[i][0] << " " << positionsFrom[i][1] << std::endl;
361  }
362  else{
363  for(size_t i=0; i < positionsTo.size(); i++)
364  file << positionsTo[i][0] << " " << positionsTo[i][1] << " " << positionsTo[i][2] << std::endl;
365  for(size_t i=0; i < positionsFrom.size(); i++)
366  file << positionsFrom[i][0] << " " << positionsFrom[i][1] << " " << positionsFrom[i][2] << std::endl;
367  }
368 
369  file << 1 << std::endl; // show all cons
370  // write connections
371 
372  PROGRESS_START(prog, A.num_rows(), "WriteMatrixToConnectionViewer " << dimensions << "d, " << A.num_rows() << "x" << A.num_rows() );
373  for(size_t i=0; i < A.num_rows(); i++)
374  {
375  PROGRESS_UPDATE(prog, i);
376  for(typename Matrix_type::const_row_iterator conn = A.begin_row(i); conn != A.end_row(i); ++conn)
377  if(conn.value() != 0.0)
378  file << i << " " << conn.index() + fromOffset << " " << conn.value() << std::endl;
379  else
380  file << i << " " << conn.index() + fromOffset << " 0" << std::endl;
381  }
382  return true;
383 }
384 
385 
386 template <typename Matrix_type, typename postype>
387 bool WriteMatrixPar(std::string filename, const Matrix_type &A,
388  const std::vector<postype> &positionsFrom, const std::vector<postype> &positionsTo, size_t dimensions)
389 {
390  return WriteMatrix(GetParallelName(A, filename), A, positionsFrom, positionsTo, dimensions);
391 }
392 
393 // WriteVectorToConnectionViewer
394 //--------------------------------------------------
402 template<typename Vector_type, typename postype>
403 void WriteVector(std::string filename, const Vector_type &b, const postype *positions, int dimensions, const Vector_type *compareVec=NULL)
404 {
405  PROFILE_FUNC_GROUP("debug");
406 
407  std::fstream file(filename.c_str(), std::ios::out);
408  size_t rows = b.size();
409  WriteGridHeader(file, positions, rows, dimensions);
410 
411  // write connections
412  if(compareVec == NULL)
413  for(size_t i=0; i < rows; i++)
414  file << i << " " << i << " "
415  << std::setprecision(std::numeric_limits<number>::digits10 + 1)
416  << b[i] << std::endl;
417  else
418  for(size_t i=0; i < rows; i++)
419  file << i << " " << i << " "
420  << std::setprecision(std::numeric_limits<number>::digits10 + 1)
421  << b[i]-(*compareVec)[i] << std::endl;
422 }
423 
424 template<typename Vector_type, typename postype>
425 void WriteVectorPar(std::string filename, const Vector_type &b, const postype *positions, int dimensions, const Vector_type *compareVec=NULL)
426 {
427  WriteVector(GetParallelName(b, filename), b, positions, dimensions, compareVec);
428 }
429 
430 template<typename Matrix_type, typename Vector_type, typename postype>
431 void WriteVector(std::string filename, const Matrix_type &A, const Vector_type &v,
432  postype *positions, int dimensions, const Vector_type *compareVec=NULL)
433 {
434  PROFILE_FUNC_GROUP("debug");
435  if(dimensions != 2)
436  {
437  UG_LOG(__FILE__ << ":" << __LINE__ << " WriteVectorToConnectionViewer: only dimension=2 supported");
438  return;
439  }
440  filename = GetParallelName(A, filename);
441 
442  size_t rows = A.num_rows();
443  std::fstream file(filename.c_str(), std::ios::out);
444  WriteGridHeader(file, positions, rows, dimensions);
445 
446  PROGRESS_START(prog, rows, "WriteVectorToConnectionViewer " << dimensions << "d, " << A.num_rows() << "x" << A.num_rows() );
447  // write connections
448  for(size_t i=0; i < rows; i++)
449  {
450  PROGRESS_UPDATE(prog, i);
451  for(typename Matrix_type::const_row_iterator conn = A.begin_row(i); conn != A.end_row(i); ++conn)
452  if(conn.value() != 0.0)
453  file << i << " " << conn.index() << " "
454  << std::setprecision(std::numeric_limits<number>::digits10 + 1)
455  << conn.value() << std::endl;
456  else
457  file << i << " " << conn.index() << " 0" << std::endl;
458  }
459 
460 
461  std::string nameValues = filename;
462  nameValues.resize(nameValues.find_last_of("."));
463  nameValues.append(".values");
464  file << "v " << nameValues << "\n";
465 
466  std::fstream fileValues(nameValues.c_str(), std::ios::out);
467  if(compareVec == NULL)
468  {
469  for(size_t i=0; i < rows; i++)
470  fileValues << i << " " << v[i] << "\n";
471  }
472  else
473  {
474  typename Vector_type::value_type t;
475  for(size_t i=0; i < rows; i++)
476  {
477  t = v[i];
478  t -= (*compareVec)[i];
479  fileValues << i << " " << t << "\n";
480  }
481  }
482 
483 }
484 
485 template<typename Matrix_type, typename Vector_type, typename postype>
486 void WriteVectorPar(std::string filename, const Matrix_type &A, const Vector_type &v,
487  postype *positions, int dimensions, const Vector_type *compareVec=NULL)
488 {
489  WriteVector(GetParallelName(A, filename), A, v, positions, dimensions, compareVec);
490 }
491 
492 #if 0
493 template<typename Vector_type, typename postype>
494 void WriteVectorNEW(std::string filename, const Vector_type &b, postype *positions, int dimensions)
495 {
496  PROFILE_FUNC_GROUP("debug");
497  filename = GetParallelName(filename);
498 
499  std::fstream file(filename.c_str(), std::ios::out);
500  file << CONNECTION_VIEWER_VERSION << std::endl;
501  file << 3 << std::endl;
502 
503  double nmax=0;
504  for(size_t i=0; i<b.size(); i++)
505  if(nmax < BlockNorm(b[i])) nmax = BlockNorm(b[i]);
506 
507  nmax*=4;
508  double scale = 1.0/nmax;
509  size_t rows = b.size();
510  // write positions
511  file << rows << std::endl;
512  if(dimensions == 1)
513  for(size_t i=0; i < rows; i++)
514  file << positions[i][0] << " 0.0" << std::endl;
515  else if(dimensions == 2)
516  for(size_t i=0; i < rows; i++)
517  file << positions[i][0] << " " << positions[i][1] << " " << b[i] * scale << std::endl;
518  else
519  for(size_t i=0; i < rows; i++)
520  file << positions[i][0] << " " << positions[i][1] << " " << positions[i][2] << std::endl;
521 
522  file << 1 << std::endl; // show all cons
523  // write connections
524  for(size_t i=0; i < rows; i++)
525  {
526  file << i << " " << i << " " << b[i] << std::endl;
527  }
528 }
529 #endif
530 
531 } // namespace ConnectionViewer
532 } // namespace ug
533 #endif /* CONNECTIONVIEWEROUTPUT_H_ */
location name
Definition: checkpoint_util.lua:128
Definition: parallel_archive.h:102
std::stringstream & create_stringstream_file(std::string name)
Definition: parallel_archive.h:213
Definition: pcl_process_communicator.h:70
int get_proc_id(size_t index) const
returns the i-th process in the communicator
Definition: pcl_process_communicator.cpp:86
size_t size() const
returns the size of the communicator
Definition: pcl_process_communicator.cpp:71
#define CONNECTION_VIEWER_VERSION
Definition: connection_viewer_output.h:51
int ProcRank()
returns the rank of the process
Definition: pcl_base.cpp:83
int NumProcs()
returns the number of processes
Definition: pcl_base.cpp:91
number alpha
#define UG_LOG(msg)
Definition: log.h:367
bool g_parallelConnectionViewer
Definition: connection_viewer_output.cpp:48
void WriteMatrix(std::ostream &file, const Matrix_type &A, postype *positions, int dimensions)
writes to a file in somewhat SparseMatrix-market format (for connection viewer)
Definition: connection_viewer_output.h:124
bool WriteMarkers(string markfilename, vector< bool > markers, float r, float g, float b, float alpha, int size)
Definition: connection_viewer_output.cpp:95
bool AddMarkers(string filename, string markfilename)
Definition: connection_viewer_output.cpp:88
void WriteVectorPar(std::string filename, const Vector_type &b, const postype *positions, int dimensions, const Vector_type *compareVec=NULL)
Definition: connection_viewer_output.h:425
bool WriteGridHeader(std::ostream &f, const TPosition &positions, size_t N, int dimension)
Definition: connection_viewer_output.h:88
void WriteMatrixPar(std::string name, const Matrix_type &A, const postype *positions, int dimensions)
Definition: connection_viewer_output.h:153
void WriteVector(std::string filename, const Vector_type &b, const postype *positions, int dimensions, const Vector_type *compareVec=NULL)
writes to a file in somewhat SparseMatrix-market format (for connection viewer)
Definition: connection_viewer_output.h:403
string GetParallelName(string name, const pcl::ProcessCommunicator &pc, bool bWriteHeader)
Definition: connection_viewer_output.cpp:51
the ug namespace
std::string GetStringPrintf(const char *format, Args... args)
Definition: string_util.h:449
string FilenameWithoutExtension(string str)
Definition: string_util.cpp:209
string GetFilenameExtension(const string &str)
Definition: string_util.cpp:224
double BlockNorm(const TYPE &v)
Definition: blocks.h:57
#define PROFILE_FUNC_GROUP(groups)
Definition: profiler.h:258
#define PROGRESS_START(progVarName, dSize, msg)
Definition: progress.h:111
#define PROGRESS_UPDATE(progVarName, d)
Definition: progress.h:117
T value_type
Definition: sparsematrix_interface.h:2