Line data Source code
1 : /*
2 : * Copyright (c) 2010-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 : #include "vtkoutput.h"
34 :
35 : #include "common/util/os_info.h" // for GetPathSeparator
36 :
37 : #include <sstream>
38 :
39 : namespace ug{
40 :
41 : ////////////////////////////////////////////////////////////////////////////////
42 : // Domain Output
43 : ////////////////////////////////////////////////////////////////////////////////
44 : template <int TDim>
45 0 : void VTKOutput<TDim>::
46 : print(const char* filename, Domain<TDim>& domain)
47 : {
48 : // get the grid associated to the solution
49 0 : MultiGrid& grid = *domain.grid();
50 0 : MGSubsetHandler& sh = *domain.subset_handler();
51 :
52 : // attach help indices
53 : typedef ug::Attachment<int> AVrtIndex;
54 : AVrtIndex aVrtIndex;
55 : Grid::VertexAttachmentAccessor<AVrtIndex> aaVrtIndex;
56 0 : grid.attach_to_vertices(aVrtIndex);
57 : aaVrtIndex.access(grid, aVrtIndex);
58 :
59 : // get rank of process
60 : int rank = 0;
61 : #ifdef UG_PARALLEL
62 : rank = pcl::ProcRank();
63 : #endif
64 :
65 0 : SubsetGroup ssg (domain.subset_handler());
66 0 : ssg.add_all ();
67 :
68 : // get name for *.vtu file
69 : std::string name;
70 : try{
71 0 : vtu_filename(name, filename, rank, -1, sh.num_subsets()-1, -1);
72 : }
73 0 : UG_CATCH_THROW("VTK::print_subset: Failed to write vtu file.");
74 :
75 :
76 : // open the file
77 : try
78 : {
79 0 : VTKFileWriter File(name.c_str());
80 :
81 : // header
82 0 : File << VTKFileWriter::normal;
83 0 : File << "<?xml version=\"1.0\"?>\n";
84 :
85 0 : write_comment(File);
86 :
87 0 : File << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"";
88 0 : if(IsLittleEndian()) File << "LittleEndian";
89 : else File << "BigEndian";
90 0 : File << "\">\n";
91 :
92 : // opening the grid
93 0 : File << " <UnstructuredGrid>\n";
94 :
95 : // get dimension of grid-piece
96 0 : int dim = DimensionOfSubsets(sh);
97 :
98 : // write piece of grid
99 0 : if(dim >= 0)
100 : {
101 : try{
102 : write_grid_piece<MGSubsetHandler>
103 0 : (File, aaVrtIndex, domain.position_accessor(), grid, sh, ssg, dim);
104 : }
105 0 : UG_CATCH_THROW("VTK::print: Failed to write subsets.");
106 : }
107 : else
108 : {
109 : // if dim < 0, some is wrong with grid, except no element is in the grid
110 0 : if(grid.num<Vertex>() != 0)
111 : {
112 0 : UG_THROW("VTK::print: Dimension of grid/subset not"
113 : " detected correctly although grid objects present.");
114 : }
115 :
116 0 : write_empty_grid_piece(File);
117 : }
118 :
119 : // write closing xml tags
120 0 : File << " </UnstructuredGrid>\n";
121 0 : File << "</VTKFile>\n";
122 :
123 : // detach help indices
124 : grid.detach_from_vertices(aVrtIndex);
125 :
126 0 : }
127 :
128 0 : UG_CATCH_THROW("VTK::print: Can not open file: '" << filename << "' for output.");
129 : #ifdef UG_PARALLEL
130 : PCL_DEBUG_BARRIER_ALL();
131 : #endif
132 0 : }
133 :
134 : template <int TDim>
135 0 : void VTKOutput<TDim>::
136 : write_empty_grid_piece(VTKFileWriter& File, bool binary)
137 : {
138 : // write that no elements are in the grid
139 : int n = 0;
140 0 : File << " <Piece NumberOfPoints=\"0\" NumberOfCells=\"0\">\n";
141 0 : File << " <Points>\n";
142 0 : File << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format="
143 0 : << (binary ? "\"binary\"" : "\"ascii\"") << ">\n";
144 0 : if(binary)
145 0 : File << VTKFileWriter::base64_binary << n << VTKFileWriter::normal;
146 : else
147 0 : File << n;
148 0 : File << "\n </DataArray>\n";
149 0 : File << " </Points>\n";
150 0 : File << " <Cells>\n";
151 0 : File << " <DataArray type=\"Int32\" Name=\"connectivity\" format="
152 0 : << (binary ? "\"binary\"" : "\"ascii\"") << ">\n";
153 0 : if(binary)
154 0 : File << VTKFileWriter::base64_binary << n << VTKFileWriter::normal;
155 : else
156 0 : File << n;
157 0 : File << "\n </DataArray>\n";
158 0 : File << " <DataArray type=\"Int32\" Name=\"offsets\" format="
159 0 : << (binary ? "\"binary\"" : "\"ascii\"") << ">\n";
160 0 : File << VTKFileWriter::base64_binary << n << VTKFileWriter::normal;
161 0 : File << "\n </DataArray>\n";
162 0 : File << " <DataArray type=\"Int8\" Name=\"types\" format="
163 0 : << (binary ? "\"binary\"" : "\"ascii\"") << ">\n";
164 0 : if(binary)
165 0 : File << VTKFileWriter::base64_binary << n << VTKFileWriter::normal;
166 : else
167 0 : File << n;
168 0 : File << "\n </DataArray>\n";
169 0 : File << " </Cells>\n";
170 0 : File << " </Piece>\n";
171 0 : }
172 :
173 : ////////////////////////////////////////////////////////////////////////////////
174 : // Comments
175 : ////////////////////////////////////////////////////////////////////////////////
176 :
177 : template <int TDim>
178 0 : void VTKOutput<TDim>::
179 : write_comment(VTKFileWriter& File)
180 : {
181 0 : if (!m_sComment.size()){
182 : return;
183 : }
184 :
185 0 : File << VTKFileWriter::normal;
186 0 : File << "<!--";
187 0 : File << m_sComment;
188 0 : File << "-->\n";
189 : }
190 :
191 : template <int TDim>
192 0 : void VTKOutput<TDim>::
193 : write_comment_printf(FILE* File)
194 : {
195 0 : if (!m_sComment.size()){
196 : return;
197 : }
198 :
199 : fprintf(File, "<!--");
200 : fprintf(File, "%s", m_sComment.c_str());
201 : fprintf(File, "-->\n");
202 : }
203 :
204 : ////////////////////////////////////////////////////////////////////////////////
205 : // FileNames
206 : ////////////////////////////////////////////////////////////////////////////////
207 :
208 :
209 0 : void baseName(std::string& nameOut, const std::string& nameIn)
210 : {
211 : // This hack is a little bit ugly. What is supposed to be achieved is the following:
212 : // As simply using
213 : // nameIn.substr(0, nameIn.find_last_of('.'));
214 : // will cause unexpected results if filename is a path that
215 : // includes a ".", e.g. "./path/to/someFileName" or "stupid.path.name/fileName",
216 : // we check whether there is a '/' in the file name _after_ the last '.';
217 : // in that case, we take the whole file name, otherwise only up to the last dot.
218 : // This will treat the two example cases above (on Unix systems).
219 : // A proper solution would use boost::filesystem and throw away the file extension
220 : // if present. However, this would require linking against a boost library.
221 0 : size_t lo_pathSep = nameIn.rfind(GetPathSeparator());
222 : size_t lo_dot = nameIn.find_last_of('.');
223 0 : if (lo_pathSep == std::string::npos || lo_pathSep < lo_dot)
224 0 : nameOut = nameIn.substr(0, lo_dot);
225 : else
226 : nameOut = nameIn;
227 0 : }
228 :
229 :
230 : template <int TDim>
231 0 : void VTKOutput<TDim>::
232 : vtu_filename(std::string& nameOut, std::string nameIn, int rank,
233 : int si, int maxSi, int step)
234 : {
235 : // remove extension of file if necessary
236 0 : baseName(nameOut, nameIn);
237 :
238 : #ifdef UG_PARALLEL
239 : // process index
240 : if(pcl::NumProcs() > 1)
241 : AppendCounterToString(nameOut, "_p", rank, pcl::NumProcs() - 1);
242 : #endif
243 :
244 : // subset index
245 0 : if(si >= 0)
246 0 : AppendCounterToString(nameOut, "_s", si, maxSi);
247 :
248 : // time index
249 0 : if(step >= 0)
250 0 : AppendCounterToString(nameOut, "_t", (int) step);
251 :
252 : // add file extension
253 0 : nameOut.append(".vtu");
254 0 : }
255 :
256 :
257 : template <int TDim>
258 0 : void VTKOutput<TDim>::
259 : pvtu_filename(std::string& nameOut, std::string nameIn,
260 : int si, int maxSi, int step)
261 : {
262 : // remove extension of file if necessary
263 0 : baseName(nameOut, nameIn);
264 :
265 : // subset index
266 0 : if(si >= 0)
267 0 : AppendCounterToString(nameOut, "_s", si, maxSi);
268 :
269 : // time index
270 0 : if(step >= 0)
271 0 : AppendCounterToString(nameOut, "_t", (int) step);
272 :
273 : // add file extension
274 0 : nameOut.append(".pvtu");
275 0 : }
276 :
277 :
278 : template <int TDim>
279 0 : void VTKOutput<TDim>::
280 : pvd_filename(std::string& nameOut, std::string nameIn)
281 : {
282 : // remove extension of file if necessary
283 0 : baseName(nameOut, nameIn);
284 :
285 : // add file extension
286 0 : nameOut.append(".pvd");
287 0 : }
288 :
289 :
290 : template <int TDim>
291 0 : void VTKOutput<TDim>::
292 : pvd_time_filename(std::string& nameOut, std::string nameIn, int step)
293 : {
294 : // remove extension of file if necessary
295 0 : baseName(nameOut, nameIn);
296 :
297 : // time index
298 0 : if(step >= 0)
299 0 : AppendCounterToString(nameOut, "_t", (int) step);
300 :
301 : // add file extension
302 0 : nameOut.append(".pvd");
303 0 : }
304 :
305 : template <int TDim>
306 0 : void VTKOutput<TDim>::
307 : write_subset_pvd(int numSubset, const std::string& filename, int step, number time)
308 : {
309 : // file pointer
310 : FILE* file;
311 :
312 : // to store name of file
313 : std::string name;
314 :
315 : // get rank, outproc bool and number of processes
316 0 : bool isOutputProc = GetLogAssistant().is_output_process();
317 : int rank = 0;
318 : int numProcs = 1;
319 :
320 : #ifdef UG_PARALLEL
321 : rank = pcl::ProcRank();
322 : numProcs = pcl::NumProcs();
323 : #endif
324 :
325 : // change locale to ensure decimal . is really a .
326 0 : char* oldLocale = setlocale (LC_ALL, NULL);
327 0 : setlocale(LC_NUMERIC, "C");
328 :
329 : // only output proc writes this file
330 0 : if (isOutputProc)
331 : {
332 : // get file name
333 0 : if(step >= 0) pvd_time_filename(name, filename, step);
334 0 : else pvd_filename(name, filename);
335 :
336 : // open file
337 0 : file = fopen(name.c_str(), "w");
338 0 : if (file == NULL)
339 0 : UG_THROW("VTKOutput: Cannot print to file.");
340 :
341 : // Write beginning of file
342 : fprintf(file, "<?xml version=\"1.0\"?>\n");
343 : fprintf(file, "<VTKFile type=\"Collection\" version=\"0.1\">\n");
344 : fprintf(file, " <Collection>\n");
345 :
346 : // Include files for all subsets
347 0 : for(int si = 0; si < numSubset; ++si)
348 : {
349 0 : vtu_filename(name, filename, rank, si, numSubset-1, step);
350 : if(numProcs > 1) pvtu_filename(name, filename, si, numSubset-1, step);
351 :
352 0 : name = FilenameWithoutPath(name);
353 : fprintf(file, " <DataSet timestep=\"%.17g\" part=\"%d\" file=\"%s\"/>\n",
354 : time, si, name.c_str());
355 : }
356 :
357 : // write closing tag
358 : fprintf(file, " </Collection>\n");
359 : fprintf(file, "</VTKFile>\n");
360 0 : fclose(file);
361 : }
362 :
363 : if (isOutputProc && numProcs > 1)
364 : {
365 : std::string procName(filename);
366 : procName.append("_processwise");
367 :
368 : // get file name
369 : if(step >= 0) pvd_time_filename(name, filename, step);
370 : else pvd_filename(name, filename);
371 :
372 : // open File
373 : file = fopen(name.c_str(), "w");
374 : if (file == NULL)
375 : UG_THROW("VTKOutput: Cannot print to file.");
376 :
377 : // Write to file
378 : fprintf(file, "<?xml version=\"1.0\"?>\n");
379 : fprintf(file, "<VTKFile type=\"Collection\" version=\"0.1\">\n");
380 : fprintf(file, " <Collection>\n");
381 :
382 : // include files from all procs
383 : for (int r = 0; r < numProcs; r++)
384 : for(int si = 0; si < numSubset; ++si)
385 : {
386 : vtu_filename(name, filename, rank, si, numSubset-1, step);
387 : if(numProcs > 1) pvtu_filename(name, filename, si, numSubset-1, step);
388 :
389 : name = FilenameWithoutPath(name);
390 : fprintf(file, " <DataSet timestep=\"%.17g\" part=\"%d\" file=\"%s\"/>\n",
391 : time, r, name.c_str());
392 : }
393 :
394 : // end file
395 : fprintf(file, " </Collection>\n");
396 : fprintf(file, "</VTKFile>\n");
397 : fclose(file);
398 : }
399 :
400 : // restore old locale
401 0 : setlocale(LC_NUMERIC, oldLocale);
402 :
403 : #ifdef UG_PARALLEL
404 : PCL_DEBUG_BARRIER_ALL();
405 : #endif
406 0 : }
407 :
408 : template <int TDim>
409 0 : void VTKOutput<TDim>::
410 : select(const std::vector<std::string>& vFct, const char* name)
411 : {
412 : // set select all to false, since now user-chosen
413 : select_all(false);
414 :
415 : // check that admissible number of components passed
416 0 : if(vFct.size() != 1 && vFct.size() != (size_t)TDim){
417 0 : std::stringstream ss;
418 : ss <<"VTK:select_nodal: In order to select"
419 : " a element data of a grid function for output to vtk,"
420 0 : " 1 or "<<TDim<<" function components must be chosen, but passed are "
421 0 : <<vFct.size()<<" components in '";
422 0 : for(size_t i = 0; i < vFct.size(); ++i){
423 0 : if(i > 0) ss << ", ";
424 : ss << vFct[i];
425 : }
426 0 : ss <<"'. Please select 1 or "<<TDim<<" components in world dimension "<<TDim;
427 0 : UG_THROW(ss.str());
428 0 : }
429 :
430 : // check if name is not in use
431 0 : if(vtk_name_used(name))
432 0 : UG_THROW("VTK:select_nodal: Using name " << name <<
433 : " that is already used by other data is not allowed.");
434 :
435 0 : m_vSymbFct[name] = vFct;
436 0 : }
437 :
438 : template <int TDim>
439 0 : void VTKOutput<TDim>::
440 : select(const char* fctNames, const char* name)
441 : {
442 : // set select all to false, since now user-chosen
443 : select_all(false);
444 :
445 0 : TrimString(name);
446 : std::vector<std::string> vFct;
447 0 : std::string fctString(fctNames);
448 0 : TokenizeString(fctString, vFct, ',');
449 :
450 0 : select(vFct, name);
451 0 : }
452 :
453 : template <int TDim>
454 0 : void VTKOutput<TDim>::
455 : select(SmartPtr<UserData<number, TDim> > spData, const char* name)
456 : {
457 0 : if(spData->continuous())
458 0 : select_nodal(spData, name);
459 : else
460 0 : select_element(spData, name);
461 0 : }
462 :
463 : template <int TDim>
464 0 : void VTKOutput<TDim>::
465 : select(SmartPtr<UserData<MathVector<TDim>, TDim> > spData, const char* name)
466 : {
467 0 : if(spData->continuous())
468 0 : select_nodal(spData, name);
469 : else
470 0 : select_element(spData, name);
471 0 : }
472 :
473 : template <int TDim>
474 0 : void VTKOutput<TDim>::
475 : select(SmartPtr<UserData<MathMatrix<TDim,TDim>, TDim> > spData, const char* name)
476 : {
477 0 : if(spData->continuous())
478 0 : select_nodal(spData, name);
479 : else
480 0 : select_element(spData, name);
481 0 : }
482 :
483 : template <int TDim>
484 0 : void VTKOutput<TDim>::
485 : select_nodal(const std::vector<std::string>& vFct, const char* name)
486 : {
487 : // set select all to false, since now user-chosen
488 : select_all(false);
489 :
490 : // check that admissible number of components passed
491 0 : if(vFct.size() != 1 && vFct.size() != (size_t)TDim){
492 0 : std::stringstream ss;
493 : ss <<"VTK:select_nodal: In order to select"
494 : " a element data of a grid function for output to vtk,"
495 0 : " 1 or "<<TDim<<" function components must be chosen, but passed are "
496 0 : <<vFct.size()<<" components in '";
497 0 : for(size_t i = 0; i < vFct.size(); ++i){
498 0 : if(i > 0) ss << ", ";
499 : ss << vFct[i];
500 : }
501 0 : ss <<"'. Please select 1 or "<<TDim<<" components in world dimension "<<TDim;
502 0 : UG_THROW(ss.str());
503 0 : }
504 :
505 : // check if name is not in use
506 0 : if(vtk_name_used(name))
507 0 : UG_THROW("VTK:select_nodal: Using name " << name <<
508 : " that is already used by other data is not allowed.");
509 :
510 0 : m_vSymbFctNodal[name] = vFct;
511 0 : }
512 :
513 : template <int TDim>
514 0 : void VTKOutput<TDim>::
515 : select_nodal(const char* fctNames, const char* name)
516 : {
517 : // set select all to false, since now user-chosen
518 : select_all(false);
519 :
520 0 : TrimString(name);
521 : std::vector<std::string> vFct;
522 0 : std::string fctString(fctNames);
523 0 : TokenizeString(fctString, vFct, ',');
524 :
525 0 : select_nodal(vFct, name);
526 0 : }
527 :
528 : template <int TDim>
529 0 : void VTKOutput<TDim>::
530 : select_nodal(SmartPtr<UserData<number, TDim> > spData, const char* name)
531 : {
532 : // set select all to false, since now user-chosen
533 : select_all(false);
534 :
535 0 : TrimString(name);
536 0 : if(vtk_name_used(name))
537 0 : UG_THROW("VTK:select_nodal: Using name " << name <<
538 : " that is already used by other data is not allowed.");
539 :
540 0 : m_vScalarNodalData[name] = spData;
541 0 : }
542 :
543 : template <int TDim>
544 0 : void VTKOutput<TDim>::
545 : select_nodal(SmartPtr<UserData<MathVector<TDim>, TDim> > spData, const char* name)
546 : {
547 : // set select all to false, since now user-chosen
548 : select_all(false);
549 :
550 0 : TrimString(name);
551 0 : if(vtk_name_used(name))
552 0 : UG_THROW("VTK:select_nodal: Using name " << name <<
553 : " that is already used by other data is not allowed.");
554 :
555 0 : m_vVectorNodalData[name] = spData;
556 0 : }
557 :
558 : template <int TDim>
559 0 : void VTKOutput<TDim>::
560 : select_nodal(SmartPtr<UserData<MathMatrix<TDim,TDim>, TDim> > spData, const char* name)
561 : {
562 : // set select all to false, since now user-chosen
563 : select_all(false);
564 :
565 0 : TrimString(name);
566 0 : if(vtk_name_used(name))
567 0 : UG_THROW("VTK:select_nodal: Using name " << name <<
568 : " that is already used by other data is not allowed.");
569 :
570 0 : m_vMatrixNodalData[name] = spData;
571 0 : }
572 :
573 :
574 : template <int TDim>
575 0 : void VTKOutput<TDim>::
576 : select_element(const std::vector<std::string>& vFct, const char* name)
577 : {
578 : // set select all to false, since now user-chosen
579 : select_all(false);
580 :
581 : // check that admissible number of components passed
582 0 : if(vFct.size() != 1 && vFct.size() != (size_t)TDim){
583 0 : std::stringstream ss;
584 : ss <<"VTK:select_element: In order to select"
585 : " a element data of a grid function for output to vtk,"
586 0 : " 1 or "<<TDim<<" function components must be chosen, but passed are "
587 0 : <<vFct.size()<<" components in '";
588 0 : for(size_t i = 0; i < vFct.size(); ++i){
589 0 : if(i > 0) ss << ", ";
590 : ss << vFct[i];
591 : }
592 0 : ss <<"'. Please select 1 or "<<TDim<<" components in world dimension "<<TDim;
593 0 : UG_THROW(ss.str());
594 0 : }
595 :
596 : // check if name is not in use
597 0 : if(vtk_name_used(name))
598 0 : UG_THROW("VTK:select_element: Using name " << name <<
599 : " that is already used by other data is not allowed.");
600 :
601 0 : m_vSymbFctElem[name] = vFct;
602 0 : }
603 :
604 :
605 : template <int TDim>
606 0 : void VTKOutput<TDim>::
607 : select_element(const char* fctNames, const char* name)
608 : {
609 0 : TrimString(name);
610 : std::vector<std::string> vFct;
611 0 : std::string fctString(fctNames);
612 0 : TokenizeString(fctString, vFct, ',');
613 :
614 0 : select_element(vFct, name);
615 0 : }
616 :
617 :
618 : template <int TDim>
619 0 : void VTKOutput<TDim>::
620 : select_element(SmartPtr<UserData<number, TDim> > spData, const char* name)
621 : {
622 : // set select all to false, since now user-chosen
623 : select_all(false);
624 :
625 0 : TrimString(name);
626 0 : if(vtk_name_used(name))
627 0 : UG_THROW("VTK:select_element: Using name " << name <<
628 : " that is already used by other data is not allowed.");
629 :
630 0 : m_vScalarElemData[name] = spData;
631 0 : }
632 :
633 : template <int TDim>
634 0 : void VTKOutput<TDim>::
635 : select_element(SmartPtr<UserData<MathVector<TDim>, TDim> > spData, const char* name)
636 : {
637 : // set select all to false, since now user-chosen
638 : select_all(false);
639 :
640 0 : TrimString(name);
641 0 : if(vtk_name_used(name))
642 0 : UG_THROW("VTK:select_element: Using name " << name <<
643 : " that is already used by other data is not allowed.");
644 :
645 0 : m_vVectorElemData[name] = spData;
646 0 : }
647 :
648 : template <int TDim>
649 0 : void VTKOutput<TDim>::
650 : select_element(SmartPtr<UserData<MathMatrix<TDim,TDim>, TDim> > spData, const char* name)
651 : {
652 : // set select all to false, since now user-chosen
653 : select_all(false);
654 :
655 0 : TrimString(name);
656 0 : if(vtk_name_used(name))
657 0 : UG_THROW("VTK:select_element: Using name " << name <<
658 : " that is already used by other data is not allowed.");
659 :
660 0 : m_vMatrixElemData[name] = spData;
661 0 : }
662 :
663 : template <int TDim>
664 0 : bool VTKOutput<TDim>::
665 : vtk_name_used(const char* name) const
666 : {
667 0 : if (m_vSymbFct.find(name) != m_vSymbFct.end())
668 : return true;
669 :
670 0 : if (m_vSymbFctNodal.find(name) != m_vSymbFctNodal.end())
671 : return true;
672 :
673 0 : if (m_vScalarNodalData.find(name) != m_vScalarNodalData.end())
674 : return true;
675 :
676 0 : if (m_vVectorNodalData.find(name) != m_vVectorNodalData.end())
677 : return true;
678 :
679 0 : if (m_vSymbFctElem.find(name) != m_vSymbFctElem.end())
680 : return true;
681 :
682 0 : if (m_vScalarElemData.find(name) != m_vScalarElemData.end())
683 : return true;
684 :
685 0 : if (m_vVectorElemData.find(name) != m_vVectorElemData.end())
686 : return true;
687 :
688 : return false;
689 : }
690 :
691 : #ifdef UG_DIM_1
692 : template class VTKOutput<1>;
693 : #endif
694 : #ifdef UG_DIM_2
695 : template class VTKOutput<2>;
696 : #endif
697 : #ifdef UG_DIM_3
698 : template class VTKOutput<3>;
699 : #endif
700 :
701 : } // end namespace ug
|