Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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"
48#endif
49
50
51#define CONNECTION_VIEWER_VERSION 1
52
53namespace ug
54{
55namespace ConnectionViewer
56{
58#ifdef UG_PARALLEL
62std::string GetParallelName(std::string name, const pcl::ProcessCommunicator &pc, bool bWriteHeader=true);
63
64inline std::string GetParallelName(std::string name)
65{
67 return GetParallelName(name, pc);
68
69}
70template<typename T>
71inline std::string GetParallelName(T &t, std::string name)
72{
73 return GetParallelName(name, t.layouts()->proc_comm());
74}
75#else
76template<typename T>
77inline std::string GetParallelName(T &t, std::string name)
78{
79 return name;
80}
81#endif
82
83
84bool AddMarkers(std::string filename, std::string markfilename);
85bool WriteMarkers(std::string markfilename, std::vector<bool> markers, float r, float g, float b, float alpha, int size);
86
87template<typename TPosition>
88bool 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
108template<typename TPosition>
109bool WriteGridHeader(std::ostream &f, const TPosition &positions, int dimension)
110{
111 return WriteGridHeader(f, positions, positions.size(), dimension);
112}
113
114// WriteMatrixToConnectionViewer
115//--------------------------------------------------
123template<typename Matrix_type, typename postype>
124void 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
144template<typename Matrix_type, typename postype>
145void 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
152template<typename Matrix_type, typename postype>
153void 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//--------------------------------------------------
321template <typename Matrix_type, typename postype>
322bool 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
386template <typename Matrix_type, typename postype>
387bool 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//--------------------------------------------------
402template<typename Vector_type, typename postype>
403void 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
424template<typename Vector_type, typename postype>
425void 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
430template<typename Matrix_type, typename Vector_type, typename postype>
431void 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
485template<typename Matrix_type, typename Vector_type, typename postype>
486void 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
493template<typename Vector_type, typename postype>
494void 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
#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