LCOV - code coverage report
Current view: top level - ugbase/lib_disc/io - vtkoutput_impl.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 755 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 1761 0

            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              : //other libraries
      34              : #include <cstdio>
      35              : #include <iostream>
      36              : #include <cstring>
      37              : #include <string>
      38              : #include <algorithm>
      39              : 
      40              : // ug4 libraries
      41              : #include "common/log.h"
      42              : #include "common/util/string_util.h"
      43              : #include "common/util/endian_detection.h"
      44              : #include "common/profiler/profiler.h"
      45              : #include "common/util/provider.h"
      46              : #include "lib_disc/common/function_group.h"
      47              : #include "lib_disc/common/groups_util.h"
      48              : #include "lib_disc/common/multi_index.h"
      49              : #include "lib_disc/reference_element/reference_element.h"
      50              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      51              : #include "lib_disc/spatial_disc/disc_util/fv_util.h"
      52              : #include "lib_grid/algorithms/debug_util.h"
      53              : 
      54              : #ifdef UG_PARALLEL
      55              : #include "pcl/pcl_base.h"
      56              : #include "lib_algebra/parallelization/parallel_storage_type.h"
      57              : #endif
      58              : 
      59              : // own interface
      60              : #include "vtkoutput.h"
      61              : 
      62              : namespace ug{
      63              : 
      64              : /**
      65              :  * Writes a float in the VTU-compatible ascii format:
      66              :  */
      67              : template <int TDim>
      68            0 : VTKFileWriter& VTKOutput<TDim>::
      69              : write_asc_float(VTKFileWriter& File, float data)
      70              : {
      71            0 :         if (std::abs (data) < std::numeric_limits<float>::min ()) // a protection against the denormalized floats
      72            0 :                 File << '0';
      73              :         else
      74            0 :                 File << data;
      75            0 :         return File;
      76              : }
      77              : 
      78              : 
      79              : /* Functions that write data into the VTU file depending on the type.
      80              :  * Note that the data may be either scalars, 3-dimensional vectors or 3x3 tensors.
      81              :  * The binary values should be represented in the Float32 format, the ascii ones must
      82              :  * be representable in this format.
      83              :  */
      84              : 
      85              : template <int TDim>
      86            0 : void VTKOutput<TDim>::
      87              : write_item_to_file(VTKFileWriter& File, float data)
      88              : {
      89            0 :         if(m_bBinary)
      90            0 :                 File << (float) data;
      91              :         else
      92            0 :                 write_asc_float (File, data) << ' ';
      93            0 : }
      94              : 
      95              : // fill position data up with zeros if dim < 3.
      96              : template <int TDim>
      97            0 : void VTKOutput<TDim>::
      98              : write_item_to_file(VTKFileWriter& File, const ug::MathVector<1>& data)
      99              : {
     100            0 :         if(m_bBinary)
     101            0 :                 File << (float) data[0] << (float) 0.f << (float) 0.f;
     102              :         else
     103            0 :                 write_asc_float (File, data[0]) << " 0 0 ";
     104            0 : }
     105              : 
     106              : template <int TDim>
     107            0 : void VTKOutput<TDim>::
     108              : write_item_to_file(VTKFileWriter& File, const ug::MathVector<2>& data)
     109              : {
     110            0 :         if(m_bBinary)
     111            0 :                 File << (float) data[0] << (float) data[1] << (float) 0.f;
     112              :         else
     113              :         {
     114            0 :                 write_asc_float (File, data[0]) << ' ';
     115            0 :                 write_asc_float (File, data[1]) << " 0 ";
     116              :         }
     117            0 : }
     118              : 
     119              : template <int TDim>
     120            0 : void VTKOutput<TDim>::
     121              : write_item_to_file(VTKFileWriter& File, const ug::MathVector<3>& data)
     122              : {
     123            0 :         if(m_bBinary)
     124            0 :                 File << (float) data[0] << (float) data[1] << (float) data[2];
     125              :         else
     126              :         {
     127            0 :                 write_asc_float (File, data[0]) << ' ';
     128            0 :                 write_asc_float (File, data[1]) << ' ';
     129            0 :                 write_asc_float (File, data[2]) << ' ';
     130              :         }
     131            0 : }
     132              : 
     133              : template <int TDim>
     134            0 : void VTKOutput<TDim>::
     135              : write_item_to_file(VTKFileWriter& File, const ug::MathMatrix<1,1>& data)
     136              : {
     137            0 :         if(m_bBinary)
     138            0 :                 File << (float) data(0,0) << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f;
     139              :         else
     140            0 :                 write_asc_float (File, data(0,0)) << " 0 0 0 0 0 0 0 0 ";
     141            0 : }
     142              : 
     143              : template <int TDim>
     144            0 : void VTKOutput<TDim>::
     145              : write_item_to_file(VTKFileWriter& File, const ug::MathMatrix<2,2>& data)
     146              : {
     147            0 :         if(m_bBinary)
     148              :         {
     149            0 :                 File << (float) data(0,0) << (float) data(0,1) << (float) 0.f;
     150            0 :                 File << (float) data(1,0) << (float) data(1,1) << (float) 0.f << (float) 0.f << (float) 0.f << (float) 0.f;
     151              :         }
     152              :         else
     153              :         {
     154            0 :                 write_asc_float (File, data(0,0)) << ' '; write_asc_float (File, data(0,1)) << " 0 ";
     155            0 :                 write_asc_float (File, data(1,0)) << ' '; write_asc_float (File, data(1,1)) << " 0 0 0 0 ";
     156              :         }
     157            0 : }
     158              : 
     159              : template <int TDim>
     160            0 : void VTKOutput<TDim>::
     161              : write_item_to_file(VTKFileWriter& File, const ug::MathMatrix<3,3>& data)
     162              : {
     163            0 :         if(m_bBinary)
     164              :         {
     165            0 :                 File << (float) data(0,0) << (float) data(0,1) << (float) data(0,2);
     166            0 :                 File << (float) data(1,0) << (float) data(1,1) << (float) data(1,2);
     167            0 :                 File << (float) data(2,0) << (float) data(2,1) << (float) data(2,2);
     168              :         }
     169              :         else
     170              :         {
     171            0 :                 write_asc_float (File, data(0,0)) << ' '; write_asc_float (File, data(0,1)) << ' '; write_asc_float (File, data(0,2)) << ' ';
     172            0 :                 write_asc_float (File, data(1,0)) << ' '; write_asc_float (File, data(1,1)) << ' '; write_asc_float (File, data(1,2)) << ' ';
     173            0 :                 write_asc_float (File, data(2,0)) << ' '; write_asc_float (File, data(2,1)) << ' '; write_asc_float (File, data(2,2)) << ' ';
     174              :         }
     175            0 : }
     176              : 
     177              : /**
     178              :  * VTU output for the data based on the given grid function (u), for all the subsets
     179              :  * where this function is defined.
     180              :  */
     181              : template <int TDim>
     182              : template <typename TFunction>
     183            0 : void VTKOutput<TDim>::
     184              : print(const char* filename, TFunction& u, int step, number time, bool makeConsistent)
     185              : {
     186              :         PROFILE_FUNC();
     187              : #ifdef UG_PARALLEL
     188              :         if(makeConsistent)
     189              :                 if(!u.change_storage_type(PST_CONSISTENT))
     190              :                         UG_THROW("VTK::print: Cannot change storage type to consistent.");
     191              : #endif
     192              : 
     193              : //      check functions
     194              :         bool bEverywhere = true;
     195            0 :         for(size_t fct = 0; fct < u.num_fct(); ++fct)
     196              :         {
     197              :         //      check if function is defined everywhere
     198            0 :                 if(!u.is_def_everywhere(fct))
     199              :                         bEverywhere = false;
     200              :         }
     201              : 
     202              : //      in case that all functions are defined everywhere, we write the grid as
     203              : //      a whole. If not, we must write each subset separately and group the files
     204              : //      later using a *.pvd file.
     205            0 :         if(bEverywhere)
     206              :         {
     207              :         //      write whole grid to a single file
     208              :                 try
     209              :                 {
     210            0 :                         SubsetGroup all_ss (u.domain()->subset_handler ());
     211            0 :                         all_ss.add_all ();
     212            0 :                         print_subsets(filename, u, all_ss, step, time, makeConsistent);
     213              :                 }
     214            0 :                 UG_CATCH_THROW("VTK::print: Failed to write grid.");
     215              :         }
     216              :         else
     217              :         {
     218              :                 //      loop subsets
     219            0 :                 for(int si = 0; si < u.num_subsets(); ++si)
     220              :                 {
     221              :                 //      write each subset to a single file
     222              :                         try{
     223            0 :                                 print_subset(filename, u, si, step, time, makeConsistent);
     224              :                         }
     225            0 :                         UG_CATCH_THROW("VTK::print: Failed to write Subset "<< si << ".");
     226              :                 }
     227              : 
     228              :                 //      write grouping pvd file
     229              :                 try{
     230            0 :                         write_subset_pvd(u.num_subsets(), filename, step, time);
     231              :                 }
     232            0 :                 UG_CATCH_THROW("VTK::print: Failed to write pvd-file.");
     233              :         }
     234              :         #ifdef UG_PARALLEL
     235              :                 PCL_DEBUG_BARRIER_ALL();
     236              :         #endif
     237            0 : }
     238              : 
     239              : 
     240              : /**
     241              :  * VTU output for the data based on the given grid function (u), for only one given subset
     242              :  * si. The file name is composed with the number of the subset.
     243              :  */
     244              : template <int TDim>
     245              : template <typename TFunction>
     246            0 : void VTKOutput<TDim>::
     247              : print_subset(const char* filename, TFunction& u, int si, int step, number time, bool makeConsistent)
     248              : {
     249              :         PROFILE_FUNC();
     250              : 
     251              : #ifdef UG_PARALLEL
     252              :         if(makeConsistent)
     253              :                 if(!u.change_storage_type(PST_CONSISTENT))
     254              :                         UG_THROW("VTK::print_subset: Cannot change storage type to consistent.");
     255              : #endif
     256              : 
     257              : //      get the grid associated to the solution
     258            0 :         Grid& grid = *u.domain()->grid();
     259            0 :         SubsetGroup ssg (u.domain()->subset_handler ());
     260            0 :         ssg.add (si);
     261              : 
     262              : //      attach help indices
     263              :         typedef ug::Attachment<int> AVrtIndex;
     264              :         AVrtIndex aVrtIndex;
     265              :         Grid::VertexAttachmentAccessor<AVrtIndex> aaVrtIndex;
     266              :         grid.attach_to_vertices(aVrtIndex);
     267              :         aaVrtIndex.access(grid, aVrtIndex);
     268              : 
     269              : //      get rank of process
     270              :         int rank = 0;
     271              : #ifdef UG_PARALLEL
     272              :         rank = pcl::ProcRank();
     273              : #endif
     274              : 
     275              : //      get name for *.vtu file
     276              :         std::string name;
     277              :         try{
     278            0 :                 vtu_filename(name, filename, rank, si, u.num_subsets()-1, step);
     279              :         }
     280            0 :         UG_CATCH_THROW("VTK::print_subset: Failed to write vtu-file.");
     281              : 
     282              : 
     283              : //      open the file
     284              :         try
     285              :         {
     286            0 :                 VTKFileWriter File(name.c_str());
     287              : 
     288              :         //      bool if time point should be written to *.vtu file
     289              :         //      in parallel we must not (!) write it to the *.vtu file, but to the *.pvtu
     290              :                 bool bTimeDep = (step >= 0);
     291              : #ifdef UG_PARALLEL
     292              :                 if(pcl::NumProcs() > 1) bTimeDep = false;
     293              : #endif
     294              : 
     295              :         //      header
     296            0 :                 File << VTKFileWriter::normal;
     297            0 :                 File << "<?xml version=\"1.0\"?>\n";
     298              : 
     299            0 :                 write_comment(File);
     300              : 
     301            0 :                 File << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"";
     302            0 :                 if(IsLittleEndian()) File << "LittleEndian";
     303              :                 else File << "BigEndian";
     304            0 :                 File << "\">\n";
     305              : 
     306              :         //      writing time point
     307            0 :                 if(bTimeDep)
     308              :                 {
     309            0 :                         File << "  <Time timestep=\""<<time<<"\"/>\n";
     310              :                 }
     311              : 
     312              :         //      opening the grid
     313            0 :                 File << "  <UnstructuredGrid>\n";
     314              : 
     315              :         //      get dimension of grid-piece
     316            0 :                 int dim = DimensionOfSubset(*u.domain()->subset_handler(), si);
     317              : 
     318              :         //      write piece of grid
     319            0 :                 if(dim >= 0)
     320              :                 {
     321              :                         try{
     322            0 :                                 write_grid_solution_piece(File, aaVrtIndex, grid, u, time, ssg, dim);
     323              :                         }
     324            0 :                         UG_CATCH_THROW("VTK::print_subset: Can not write Subset: "<<si);
     325              :                 }
     326              :                 else
     327              :                 {
     328              :                 //      if dim < 0, something is wrong with grid, unless there are no elements in the grid
     329            0 :                         if((si >=0) && u.domain()->subset_handler()->template num<Vertex>(si) != 0)
     330              :                         {
     331            0 :                                 UG_THROW("VTK::print_subset: Dimension of grid/subset not"
     332              :                                                 " detected correctly although grid objects present.");
     333              :                         }
     334              : 
     335            0 :                         write_empty_grid_piece(File);
     336              :                 }
     337              : 
     338              :         //      write closing xml tags
     339            0 :                 File << VTKFileWriter::normal;
     340            0 :                 File << "  </UnstructuredGrid>\n";
     341            0 :                 File << "</VTKFile>\n";
     342              : 
     343              :         //      detach help indices
     344              :                 grid.detach_from_vertices(aVrtIndex);
     345              : 
     346              : #ifdef UG_PARALLEL
     347              :         //      write grouping *.pvtu file in parallel case
     348              :                 try{
     349              :                         write_pvtu(u, filename, si, step, time);
     350              :                 }
     351              :                 UG_CATCH_THROW("VTK::print_subset: Failed to write pvtu-file.");
     352              : #endif
     353              : 
     354              :         //      remember time step
     355            0 :                 if(step >= 0)
     356              :                 {
     357              :                 //      get vector of time points for the name
     358            0 :                         std::vector<number>& vTimestep = m_mTimestep[filename];
     359              : 
     360              :                 //      resize the vector
     361            0 :                         vTimestep.resize(step+1);
     362              : 
     363              :                 //      write time point
     364            0 :                         vTimestep[step] = time;
     365              :                 }
     366              : 
     367            0 :         }
     368            0 :         UG_CATCH_THROW("VTK::print_subset: Failed to open file: '" << filename << "' for output");
     369              :         #ifdef UG_PARALLEL
     370              :                 PCL_DEBUG_BARRIER_ALL();
     371              :         #endif
     372            0 : }
     373              : 
     374              : 
     375              : /**
     376              :  * VTU output for the data based on the given grid function (u), only for the subsets from
     377              :  * a given subset group.
     378              :  */
     379              : template <int TDim>
     380              : template <typename TFunction>
     381            0 : void VTKOutput<TDim>::
     382              : print_subsets(const char* filename, TFunction& u, const SubsetGroup& ssGrp, int step, number time, bool makeConsistent)
     383              : {
     384              :         PROFILE_FUNC();
     385              : 
     386              : #ifdef UG_PARALLEL
     387              :         if(makeConsistent)
     388              :                 if(!u.change_storage_type(PST_CONSISTENT))
     389              :                         UG_THROW("VTK::print_subset: Cannot change storage type to consistent.");
     390              : #endif
     391              : 
     392              : //      get the grid associated to the solution
     393            0 :         Grid& grid = *u.domain()->grid();
     394              :         
     395              : //      attach help indices
     396              :         typedef ug::Attachment<int> AVrtIndex;
     397              :         AVrtIndex aVrtIndex;
     398              :         Grid::VertexAttachmentAccessor<AVrtIndex> aaVrtIndex;
     399              :         grid.attach_to_vertices(aVrtIndex);
     400              :         aaVrtIndex.access(grid, aVrtIndex);
     401              : 
     402              : //      get rank of process
     403              :         int rank = 0;
     404              : #ifdef UG_PARALLEL
     405              :         rank = pcl::ProcRank();
     406              : #endif
     407              : 
     408              : //      get name for *.vtu file
     409              :         std::string name;
     410              :         try{
     411            0 :                 vtu_filename(name, filename, rank, -1, u.num_subsets()-1, step); // "si == -1" because we do not want any subset prefixes!
     412              :         }
     413            0 :         UG_CATCH_THROW("VTK::print_subsets: Failed to write vtu-file.");
     414              : 
     415              : 
     416              : //      open the file
     417              :         try
     418              :         {
     419            0 :                 VTKFileWriter File(name.c_str());
     420              : 
     421              :         //      bool if time point should be written to *.vtu file
     422              :         //      in parallel we must not (!) write it to the *.vtu file, but to the *.pvtu
     423              :                 bool bTimeDep = (step >= 0);
     424              : #ifdef UG_PARALLEL
     425              :                 if(pcl::NumProcs() > 1) bTimeDep = false;
     426              : #endif
     427              : 
     428              :         //      header
     429            0 :                 File << VTKFileWriter::normal;
     430            0 :                 File << "<?xml version=\"1.0\"?>\n";
     431              : 
     432            0 :                 write_comment(File);
     433              : 
     434            0 :                 File << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"";
     435            0 :                 if(IsLittleEndian()) File << "LittleEndian";
     436              :                 else File << "BigEndian";
     437            0 :                 File << "\">\n";
     438              : 
     439              :         //      writing time point
     440            0 :                 if(bTimeDep)
     441              :                 {
     442            0 :                         File << "  <Time timestep=\""<<time<<"\"/>\n";
     443              :                 }
     444              : 
     445              :         //      opening the grid
     446            0 :                 File << "  <UnstructuredGrid>\n";
     447              : 
     448              :         //      get dimension of grid-piece: the highest dimension of the specified subsets
     449              :                 int dim = -1;
     450            0 :                 for(size_t i = 0; i < ssGrp.size(); i++)
     451              :                 {
     452            0 :                         int ssDim = DimensionOfSubset(*u.domain()->subset_handler(), ssGrp[i]);
     453            0 :                         if(dim < ssDim)
     454              :                                 dim = ssDim;
     455              :                 }
     456              : 
     457              :         //      write piece of grid
     458            0 :                 if(dim >= 0)
     459              :                 {
     460              :                         try{
     461            0 :                                 write_grid_solution_piece(File, aaVrtIndex, grid, u, time, ssGrp, dim);
     462              :                         }
     463            0 :                         UG_CATCH_THROW("VTK::print_subsets: Can not write the subsets");
     464              :                 }
     465              :                 else
     466              :                 {
     467            0 :                         UG_THROW("VTK::print_subsets: Dimension of grid/subset not"
     468              :                                         " detected correctly although grid objects present.");
     469              :                 }
     470              : 
     471              :         //      write closing xml tags
     472            0 :                 File << VTKFileWriter::normal;
     473            0 :                 File << "  </UnstructuredGrid>\n";
     474            0 :                 File << "</VTKFile>\n";
     475              : 
     476              :         //      detach help indices
     477              :                 grid.detach_from_vertices(aVrtIndex);
     478              : 
     479              : #ifdef UG_PARALLEL
     480              :         //      write grouping *.pvtu file in parallel case
     481              :                 try{
     482              :                         write_pvtu(u, filename, -1, step, time); // "-1" because we do not want any subset prefixes!
     483              :                 }
     484              :                 UG_CATCH_THROW("VTK::print_subsets: Failed to write pvtu-file.");
     485              : #endif
     486              : 
     487              :         //      remember time step
     488            0 :                 if(step >= 0)
     489              :                 {
     490              :                 //      get vector of time points for the name
     491            0 :                         std::vector<number>& vTimestep = m_mTimestep[filename];
     492              : 
     493              :                 //      resize the vector
     494            0 :                         vTimestep.resize(step+1);
     495              : 
     496              :                 //      write time point
     497            0 :                         vTimestep[step] = time;
     498              :                 }
     499              : 
     500            0 :         }
     501            0 :         UG_CATCH_THROW("VTK::print_subset: Failed open file: '" << filename << "' for output");
     502              :         #ifdef UG_PARALLEL
     503              :                 PCL_DEBUG_BARRIER_ALL();
     504              :         #endif
     505            0 : }
     506              : 
     507              : 
     508              : /**
     509              :  * VTU output for the data based on the given grid function (u), only for the subsets from
     510              :  * a given list of subset names.
     511              :  */
     512              : template <int TDim>
     513              : template <typename TFunction>
     514            0 : void VTKOutput<TDim>::
     515              : print_subsets(const char* filename, TFunction& u, const char* ssNames, int step, number time, bool makeConsistent)
     516              : {
     517              :         std::vector<std::string> v_ss_names;
     518            0 :         SubsetGroup ssGrp (u.domain()->subset_handler());
     519              :         
     520            0 :         TokenizeTrimString (ssNames, v_ss_names);
     521            0 :         ssGrp.add (v_ss_names);
     522            0 :         print_subsets(filename, u, ssGrp, step, time, makeConsistent);
     523            0 : }
     524              : 
     525              : 
     526              : ////////////////////////////////////////////////////////////////////////////////
     527              : //      writing pieces
     528              : ////////////////////////////////////////////////////////////////////////////////
     529              : 
     530              : 
     531              : /**
     532              :  * This function composes the vtu sections with the coordinates of the grid points and
     533              :  * the connectivities (cells), a part of the unstructured grid description in the vtu file.
     534              :  */
     535              : template <int TDim>
     536              : template <typename T>
     537            0 : void VTKOutput<TDim>::
     538              : write_points_cells_piece(VTKFileWriter& File,
     539              :                          Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     540              :                          const Grid::VertexAttachmentAccessor<Attachment<MathVector<TDim> > >& aaPos,
     541              :                          Grid& grid, const T& iterContainer, const SubsetGroup& ssGrp, const int dim,
     542              :                          const int numVert, const int numElem, const int numConn)
     543              : {
     544              : //      write vertices of this piece
     545              :         try{
     546            0 :                 write_points<T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp, dim, numVert);
     547              :         }
     548            0 :         UG_CATCH_THROW("VTK::write_points_cells_piece: Failed to write vertices (Points).");
     549              : 
     550              : //      write elements of this piece
     551              :         try{
     552            0 :                 write_cells(File, aaVrtIndex, grid, iterContainer, ssGrp, dim, numElem, numConn);
     553              :         }
     554            0 :         UG_CATCH_THROW("VTK::write_points_cells_piece: Failed to write grid elements (Cells).");
     555            0 : }
     556              : 
     557              : /**
     558              :  * Composes only the vtu-piece of the description of the unstructured grid.
     559              :  */
     560              : template <int TDim>
     561              : template <typename T>
     562            0 : void VTKOutput<TDim>::
     563              : write_grid_piece(VTKFileWriter& File,
     564              :                  Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     565              :                  const Grid::VertexAttachmentAccessor<Attachment<MathVector<TDim> > >& aaPos,
     566              :                  Grid& grid, const T& iterContainer, SubsetGroup& ssGrp, int dim)
     567              : {
     568              : //      counters
     569            0 :         int numVert = 0, numElem = 0, numConn = 0;
     570              : 
     571              : //      Count needed sizes for vertices, elements and connections
     572              :         try{
     573            0 :                 count_piece_sizes(grid, iterContainer, ssGrp, dim, numVert, numElem, numConn);
     574              :         }
     575            0 :         UG_CATCH_THROW("VTK::write_piece: Failed to count piece sizes.");
     576              : 
     577              : //      write the beginning of the piece, indicating the number of vertices
     578              : //      and the number of elements for this piece of the grid.
     579            0 :         File << VTKFileWriter::normal;
     580            0 :         File << "    <Piece NumberOfPoints=\""<<numVert<<
     581            0 :         "\" NumberOfCells=\""<<numElem<<"\">\n";
     582              : 
     583              : //      write grid
     584              :         write_points_cells_piece<T>
     585            0 :         (File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp, dim, numVert, numElem, numConn);
     586              : 
     587              : //      write closing tag
     588            0 :         File << VTKFileWriter::normal;
     589            0 :         File << "    </Piece>\n";
     590            0 : }
     591              : 
     592              : /**
     593              :  * This function writes a piece of the grid to the vtk file. First the
     594              :  * geometric data is written (points, cells, connectivity). Then the data
     595              :  * associated to the points or cells is written.
     596              :  */
     597              : template <int TDim>
     598              : template <typename TFunction>
     599            0 : void VTKOutput<TDim>::
     600              : write_grid_solution_piece(VTKFileWriter& File,
     601              :                           Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     602              :                           Grid& grid, TFunction& u, number time,
     603              :                           const SubsetGroup& ssGrp, const int dim)
     604              : {
     605              : //      counters
     606            0 :         int numVert = 0, numElem = 0, numConn = 0;
     607              : 
     608              : //      Count needed sizes for vertices, elements and connections
     609              :         try{
     610            0 :                 count_piece_sizes(grid, u, ssGrp, dim, numVert, numElem, numConn);
     611              :         }
     612            0 :         UG_CATCH_THROW("VTK::write_piece: Failed to count piece sizes.");
     613              : 
     614              : //      write the beginning of the piece, indicating the number of vertices
     615              : //      and the number of elements for this piece of the grid.
     616            0 :         File << VTKFileWriter::normal;
     617            0 :         File << "    <Piece NumberOfPoints=\""<<numVert<<
     618            0 :         "\" NumberOfCells=\""<<numElem<<"\">\n";
     619              : 
     620              : //      write grid
     621              :         write_points_cells_piece<TFunction>
     622            0 :         (File, aaVrtIndex, u.domain()->position_accessor(), grid, u, ssGrp, dim, numVert, numElem, numConn);
     623              : 
     624              : //      add all components if 'selectAll' chosen
     625            0 :         if(m_bSelectAll){
     626            0 :                 for(size_t fct = 0; fct < u.num_fct(); ++fct){
     627            0 :                         if(!vtk_name_used(u.name(fct).c_str())){
     628            0 :                                 if(LocalFiniteElementProvider::continuous(u.local_finite_element_id(fct))){
     629            0 :                                         select_nodal(u.name(fct).c_str(), u.name(fct).c_str());
     630              :                                 }else{
     631            0 :                                         select_element(u.name(fct).c_str(), u.name(fct).c_str());
     632              :                                 }
     633              :                         }
     634              :                 }
     635              :         }
     636              : 
     637              : //      write nodal data
     638            0 :         write_nodal_values_piece(File, u, time, grid, ssGrp, dim, numVert);
     639              : 
     640              : //      write cell data
     641            0 :         write_cell_values_piece(File, u, time, grid, ssGrp, dim, numElem);
     642              : 
     643              : //      write closing tag
     644            0 :         File << VTKFileWriter::normal;
     645            0 :         File << "    </Piece>\n";
     646            0 : }
     647              : 
     648              : ////////////////////////////////////////////////////////////////////////////////
     649              : // Sizes
     650              : ////////////////////////////////////////////////////////////////////////////////
     651              : 
     652              : template <int TDim>
     653              : template <typename TElem, typename T>
     654            0 : void VTKOutput<TDim>::
     655              : count_sizes(Grid& grid, const T& iterContainer, const int si,
     656              :             int& numVert, int& numElem, int& numConn)
     657              : {
     658              : //      get reference element
     659              :         typedef typename reference_element_traits<TElem>::reference_element_type
     660              :                                                                                                                                 ref_elem_type;
     661              : 
     662              : //      number of corners of element
     663              :         static const int numCo = ref_elem_type::numCorners;
     664              : 
     665              : //      get iterators
     666              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
     667            0 :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
     668            0 :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
     669              : 
     670              : //      loop elements
     671            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
     672              :         {
     673              :         //      get the element
     674              :                 TElem *elem = *iterBegin;
     675              : 
     676              :         //      count number of elements and number of connections;
     677              :         //      handle octahedrons separately by splitting into a top and bottom pyramid
     678              :                 if(ref_elem_type::REFERENCE_OBJECT_ID != ROID_OCTAHEDRON)
     679              :                 {
     680            0 :                         ++numElem;
     681            0 :                         numConn += numCo;
     682              :                 }
     683              :                 else
     684              :                 {
     685              :                 //      counting top and bottom pyramid
     686            0 :                         numElem += 2;
     687            0 :                         numConn += 10;
     688              :                 }
     689              : 
     690              :         //      loop vertices of the element
     691            0 :                 for(int i = 0; i < numCo; ++i)
     692              :                 {
     693              :                 //      get vertex of the element
     694            0 :                         Vertex* v = GetVertex(elem,i);
     695              : 
     696              :                 //      if this vertex has already been counted, skip it
     697            0 :                         if(grid.is_marked(v)) continue;
     698              : 
     699              :                 // count vertex and mark it
     700            0 :                         ++numVert;
     701              :                         grid.mark(v);
     702              :                 }
     703              :         }
     704            0 : };
     705              : 
     706              : /**
     707              :  * Counts VTK grid elements (points, full-dim. elements and connections) in a given
     708              :  * piece of the ug grid.
     709              :  */
     710              : template <int TDim>
     711              : template <typename T>
     712            0 : void VTKOutput<TDim>::
     713              : count_piece_sizes(Grid& grid, const T& iterContainer, const SubsetGroup& ssGrp, const int dim,
     714              :                   int& numVert, int& numElem, int& numConn)
     715              : {
     716            0 :         numVert = numElem = numConn = 0;
     717              : 
     718              : //      reset all marks (we use vertex marking to avoid counting vertices twice)
     719            0 :         grid.begin_marking();
     720              : 
     721            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
     722              :         {
     723              :                 const int si = ssGrp[i];
     724            0 :                 switch(dim) // switch dimension
     725              :                 {
     726            0 :                         case 0: count_sizes<Vertex, T>(grid, iterContainer, si, numVert, numElem, numConn); break;
     727            0 :                         case 1: count_sizes<RegularEdge, T>(grid, iterContainer, si, numVert, numElem, numConn);
     728            0 :                                         count_sizes<ConstrainingEdge, T>(grid, iterContainer, si, numVert, numElem, numConn); break;
     729            0 :                         case 2: count_sizes<Triangle, T>(grid, iterContainer, si, numVert, numElem, numConn);
     730            0 :                                         count_sizes<Quadrilateral, T>(grid, iterContainer, si, numVert, numElem, numConn);
     731            0 :                                         count_sizes<ConstrainingTriangle, T>(grid, iterContainer, si, numVert, numElem, numConn);
     732            0 :                                         count_sizes<ConstrainingQuadrilateral, T>(grid, iterContainer, si, numVert, numElem, numConn); break;
     733            0 :                         case 3: count_sizes<Tetrahedron, T>(grid, iterContainer, si, numVert, numElem, numConn);
     734            0 :                                         count_sizes<Pyramid, T>(grid, iterContainer, si, numVert, numElem, numConn);
     735            0 :                                         count_sizes<Prism, T>(grid, iterContainer, si, numVert, numElem, numConn);
     736            0 :                                         count_sizes<Octahedron, T>(grid, iterContainer, si, numVert, numElem, numConn);
     737            0 :                                         count_sizes<Hexahedron, T>(grid, iterContainer, si, numVert, numElem, numConn); break;
     738            0 :                         default: UG_THROW("VTK::count_piece_sizes: Dimension " << dim <<
     739              :                                                                         " is not supported.");
     740              :                 }
     741              :         }
     742              : 
     743              : //      signal end of marking
     744            0 :         grid.end_marking();
     745            0 : }
     746              : 
     747              : ////////////////////////////////////////////////////////////////////////////////
     748              : // Points
     749              : ////////////////////////////////////////////////////////////////////////////////
     750              : 
     751              : /**
     752              :  * This method loops all elements of a subset and writes the vertex
     753              :  * coordinates to a file. All vertices of the element are written reguardless
     754              :  * if the vertex itself is contained in the subset or another. Written
     755              :  * vertices are marked and not written again.
     756              :  */
     757              : template <int TDim>
     758              : template <typename TElem, typename T>
     759            0 : void VTKOutput<TDim>::
     760              : write_points_elementwise(VTKFileWriter& File,
     761              :                          Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     762              :                          const Grid::VertexAttachmentAccessor<Attachment<MathVector<TDim> > >& aaPos,
     763              :                          Grid& grid, const T& iterContainer, const int si, int& n)
     764              : {
     765              : //      get reference element
     766              :         typedef typename reference_element_traits<TElem>::reference_element_type
     767              :                                                                                                                                 ref_elem_type;
     768              : //      get iterators
     769              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
     770            0 :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
     771            0 :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
     772            0 :         if(m_bBinary)
     773            0 :                 File << VTKFileWriter::base64_binary;
     774              :         else
     775            0 :                 File << VTKFileWriter::normal;
     776              : 
     777              : //      loop all elements of the subset
     778            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
     779              :         {
     780              :         //      get the element
     781              :                 TElem *elem = *iterBegin;
     782              : 
     783              :         //      loop vertices of the element
     784            0 :                 for(size_t i = 0; i < (size_t) ref_elem_type::numCorners; ++i)
     785              :                 {
     786              :                 //      get vertex of element
     787              :                         Vertex* v = GetVertex(elem, i);
     788              : 
     789              :                 //      if vertex has already be handled, skip it
     790            0 :                         if(grid.is_marked(v)) continue;
     791              : 
     792              :                 //      mark the vertex as processed
     793              :                         grid.mark(v);
     794              : 
     795              :                 //      number vertex
     796            0 :                         aaVrtIndex[v] = n++;
     797              : 
     798              :                 //      get position of vertex and write position to stream
     799            0 :                         write_item_to_file(File, aaPos[v]);
     800              :                 }
     801              :         }
     802            0 : }
     803              : 
     804              : /**
     805              :  * This function writes the vertices of a piece (the specified subsets) of
     806              :  * the grid to a vtk file.
     807              :  */
     808              : template <int TDim>
     809              : template <typename T>
     810            0 : void VTKOutput<TDim>::
     811              : write_points(VTKFileWriter& File,
     812              :              Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     813              :              const Grid::VertexAttachmentAccessor<Attachment<MathVector<TDim> > >& aaPos,
     814              :              Grid& grid, const T& iterContainer, const SubsetGroup& ssGrp, const int dim,
     815              :              const int numVert)
     816              : {
     817            0 :         if(!m_bWriteGrid){
     818            0 :                 return;
     819              :         }
     820              : 
     821              : //      write starting xml tag for points
     822            0 :         File << VTKFileWriter::normal;
     823            0 :         File << "      <Points>\n";
     824            0 :         File << "        <DataArray type=\"Float32\" NumberOfComponents=\"3\" format="
     825            0 :                  <<       (m_bBinary ? "\"binary\"" : "\"ascii\"") << ">\n";
     826            0 :         int n = 3*sizeof(float) * numVert;
     827            0 :         if(m_bBinary)
     828            0 :                 File << VTKFileWriter::base64_binary << n;
     829              : 
     830              : //      reset counter for vertices
     831            0 :         n = 0;
     832              : 
     833              : //      start marking of vertices
     834            0 :         grid.begin_marking();
     835              : 
     836              : //      switch dimension
     837            0 :         if(numVert > 0)
     838            0 :         for(size_t i = 0; i < ssGrp.size(); i++){
     839            0 :                 switch(dim){
     840            0 :                         case 0: write_points_elementwise<Vertex,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n); break;
     841            0 :                         case 1: write_points_elementwise<RegularEdge,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     842            0 :                                         write_points_elementwise<ConstrainingEdge,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n); break;
     843            0 :                         case 2: write_points_elementwise<Triangle,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     844            0 :                                         write_points_elementwise<Quadrilateral,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     845            0 :                                         write_points_elementwise<ConstrainingTriangle,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     846            0 :                                         write_points_elementwise<ConstrainingQuadrilateral,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n); break;
     847            0 :                         case 3: write_points_elementwise<Tetrahedron,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     848            0 :                                         write_points_elementwise<Pyramid,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     849            0 :                                         write_points_elementwise<Prism,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     850            0 :                                         write_points_elementwise<Octahedron,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n);
     851            0 :                                         write_points_elementwise<Hexahedron,T>(File, aaVrtIndex, aaPos, grid, iterContainer, ssGrp[i], n); break;
     852            0 :                         default: UG_THROW("VTK::write_points: Dimension " << dim <<
     853              :                                                 " is not supported.");
     854              :                 }
     855              :         }
     856              : 
     857              : //      signal end of marking the grid
     858            0 :         grid.end_marking();
     859              : 
     860              : //      write closing tags
     861            0 :         File << VTKFileWriter::normal;
     862            0 :         File << "\n        </DataArray>\n";
     863            0 :         File << "      </Points>\n";
     864              : }
     865              : 
     866              : ////////////////////////////////////////////////////////////////////////////////
     867              : // Cells
     868              : ////////////////////////////////////////////////////////////////////////////////
     869              : 
     870              : template <int TDim>
     871            0 : void VTKOutput<TDim>::
     872              : write_cell_subset_names(VTKFileWriter& File, MGSubsetHandler &sh)
     873              : {
     874            0 :         File << VTKFileWriter::normal;
     875            0 :         File << "      <RegionInfo Name=\"regions\">\n";
     876            0 :         for(int i = 0; i < sh.num_subsets(); ++i){
     877            0 :                 File << "        <Region Name=\"" << sh.get_subset_name(i) << "\"></Region>\n";
     878              :         }
     879            0 :         File << "      </RegionInfo>\n";
     880            0 : }
     881              : 
     882              : /**
     883              :  * This function writes the elements that are part of the specified subsets.
     884              :  */
     885              : template <int TDim>
     886              : template <typename T>
     887            0 : void VTKOutput<TDim>::
     888              : write_cells(VTKFileWriter& File,
     889              :             Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     890              :             Grid& grid, const T& iterContainer, const SubsetGroup& ssGrp, const int dim,
     891              :             const int numElem, const int numConn)
     892              : {
     893            0 :         File << VTKFileWriter::normal;
     894              : 
     895              : //      write opening tag to indicate that elements will be written
     896            0 :         File << "      <Cells>\n";
     897              : 
     898              : //      write connectivities of elements
     899            0 :         write_cell_connectivity(File, aaVrtIndex, grid, iterContainer, ssGrp, dim, numConn);
     900              : 
     901              : //      write offsets for elements (i.e. number of nodes counted up)
     902            0 :         write_cell_offsets(File, iterContainer, ssGrp, dim, numElem);
     903              : 
     904              : //      write a defined type for each cell
     905            0 :         write_cell_types(File, iterContainer, ssGrp, dim, numElem);
     906              : 
     907              : //      write closing tag
     908            0 :         File << VTKFileWriter::normal;
     909            0 :         File << "      </Cells>\n";
     910            0 : }
     911              : 
     912              : ////////////////////////////////////////////////////////////////////////////////
     913              : // Connectivity
     914              : ////////////////////////////////////////////////////////////////////////////////
     915              : 
     916              : 
     917              : template <int TDim>
     918              : template <class TElem, typename T>
     919            0 : void VTKOutput<TDim>::
     920              : write_cell_connectivity(VTKFileWriter& File,
     921              :                         Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
     922              :                         Grid& grid, const T& iterContainer, const int si)
     923              : {
     924              : //      get reference element type
     925              :         typedef typename reference_element_traits<TElem>::reference_element_type
     926              :                                                                                                                                 ref_elem_type;
     927              : 
     928              : //      get reference element id
     929              :         static const ReferenceObjectID refID = ref_elem_type::REFERENCE_OBJECT_ID;
     930              : 
     931              : //      get iterators
     932              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
     933            0 :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
     934            0 :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
     935              : 
     936            0 :         if(m_bBinary)
     937            0 :                 File << VTKFileWriter::base64_binary;
     938              :         else
     939            0 :                 File << VTKFileWriter::normal;
     940              : 
     941              : //      loop all elements
     942            0 :         for( ; iterBegin != iterEnd; iterBegin++)
     943              :         {
     944              :         //      get element
     945              :                 TElem* elem = *iterBegin;
     946              : 
     947              :         //      write ids of the element
     948              :                 if(refID != ROID_PRISM && refID != ROID_OCTAHEDRON)
     949              :                 {
     950            0 :                         for(size_t i=0; i< (size_t) ref_elem_type::numCorners; i++)
     951              :                         {
     952            0 :                                 Vertex* vert = elem->vertex(i);
     953            0 :                                 int id = aaVrtIndex[vert];
     954            0 :                                 File << id;
     955            0 :                                 if(!m_bBinary)
     956            0 :                                         File << ' ';
     957              :                         }
     958              :                 }
     959              :                 else if(refID == ROID_PRISM)
     960              :                 {
     961            0 :                         int id = aaVrtIndex[elem->vertex(0)]; File << id;
     962            0 :                         if(!m_bBinary) File << ' ';
     963            0 :                         id = aaVrtIndex[elem->vertex(2)]; File << id;
     964            0 :                         if(!m_bBinary) File << ' ';
     965            0 :                         id = aaVrtIndex[elem->vertex(1)]; File << id;
     966            0 :                         if(!m_bBinary) File << ' ';
     967            0 :                         id = aaVrtIndex[elem->vertex(3)]; File << id;
     968            0 :                         if(!m_bBinary) File << ' ';
     969            0 :                         id = aaVrtIndex[elem->vertex(5)]; File << id;
     970            0 :                         if(!m_bBinary) File << ' ';
     971            0 :                         id = aaVrtIndex[elem->vertex(4)]; File << id;
     972            0 :                         if(!m_bBinary) File << ' ';
     973              :                 }
     974              :                 //      case == ROID_OCTAHEDRON (handle by a splitting into a top and bottom pyramid)
     975              :                 else
     976              :                 {
     977              :                 //      top pyramid
     978            0 :                         int id = aaVrtIndex[elem->vertex(1)]; File << id;
     979            0 :                         if(!m_bBinary) File << ' ';
     980            0 :                         id = aaVrtIndex[elem->vertex(2)]; File << id;
     981            0 :                         if(!m_bBinary) File << ' ';
     982            0 :                         id = aaVrtIndex[elem->vertex(3)]; File << id;
     983            0 :                         if(!m_bBinary) File << ' ';
     984            0 :                         id = aaVrtIndex[elem->vertex(4)]; File << id;
     985            0 :                         if(!m_bBinary) File << ' ';
     986            0 :                         id = aaVrtIndex[elem->vertex(5)]; File << id;
     987            0 :                         if(!m_bBinary) File << ' ';
     988              : 
     989              :                 //      bottom pyramid
     990            0 :                         id = aaVrtIndex[elem->vertex(1)]; File << id;
     991            0 :                         if(!m_bBinary) File << ' ';
     992            0 :                         id = aaVrtIndex[elem->vertex(2)]; File << id;
     993            0 :                         if(!m_bBinary) File << ' ';
     994            0 :                         id = aaVrtIndex[elem->vertex(3)]; File << id;
     995            0 :                         if(!m_bBinary) File << ' ';
     996            0 :                         id = aaVrtIndex[elem->vertex(4)]; File << id;
     997            0 :                         if(!m_bBinary) File << ' ';
     998            0 :                         id = aaVrtIndex[elem->vertex(0)]; File << id;
     999            0 :                         if(!m_bBinary) File << ' ';
    1000              :                 }
    1001              :         }
    1002            0 : }
    1003              : 
    1004              : /**
    1005              :  * This method writes the 'connectivity' for each element of a subset. The
    1006              :  * connectivity are the indices of all vertex the element is formed of.
    1007              :  */
    1008              : template <int TDim>
    1009              : template <typename T>
    1010            0 : void VTKOutput<TDim>::
    1011              : write_cell_connectivity(VTKFileWriter& File,
    1012              :                         Grid::VertexAttachmentAccessor<Attachment<int> >& aaVrtIndex,
    1013              :                         Grid& grid, const T& iterContainer, const SubsetGroup& ssGrp,
    1014              :                         const int dim, const int numConn)
    1015              : {
    1016            0 :         File << VTKFileWriter::normal;
    1017              : //      write opening tag to indicate that connections will be written
    1018            0 :         File << "        <DataArray type=\"Int32\" Name=\"connectivity\" format="
    1019            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1020            0 :         int n = sizeof(int) * numConn;
    1021              : 
    1022            0 :         if(m_bBinary)
    1023            0 :                 File << VTKFileWriter::base64_binary << n;
    1024              : //      switch dimension
    1025            0 :         if(numConn > 0)
    1026            0 :         for(size_t i = 0; i < ssGrp.size(); i++){
    1027            0 :                 switch(dim)
    1028              :                 {
    1029              :                         case 0: break; // no elements -> nothing to do
    1030            0 :                         case 1: write_cell_connectivity<RegularEdge,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1031            0 :                                         write_cell_connectivity<ConstrainingEdge,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]); break;
    1032            0 :                         case 2: write_cell_connectivity<Triangle,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1033            0 :                                         write_cell_connectivity<Quadrilateral,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1034            0 :                                         write_cell_connectivity<ConstrainingTriangle,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1035            0 :                                         write_cell_connectivity<ConstrainingQuadrilateral,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]); break;
    1036            0 :                         case 3: write_cell_connectivity<Tetrahedron,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1037            0 :                                         write_cell_connectivity<Pyramid,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1038            0 :                                         write_cell_connectivity<Prism,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1039            0 :                                         write_cell_connectivity<Octahedron,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]);
    1040            0 :                                         write_cell_connectivity<Hexahedron,T>(File, aaVrtIndex, grid, iterContainer, ssGrp[i]); break;
    1041            0 :                         default: UG_THROW("VTK::write_cell_connectivity: Dimension " << dim <<
    1042              :                                                 " is not supported.");
    1043              :                 }
    1044              :         }
    1045              : 
    1046              : //      write closing tag
    1047            0 :         File << VTKFileWriter::normal;
    1048            0 :         File << "\n        </DataArray>\n";
    1049            0 : }
    1050              : 
    1051              : ////////////////////////////////////////////////////////////////////////////////
    1052              : // Offset
    1053              : ////////////////////////////////////////////////////////////////////////////////
    1054              : 
    1055              : 
    1056              : template <int TDim>
    1057              : template <class TElem, typename T>
    1058            0 : void VTKOutput<TDim>::
    1059              : write_cell_offsets(VTKFileWriter& File, const T& iterContainer, const int si, int& n)
    1060              : {
    1061              : //      get reference element
    1062              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1063              :                                                                                                                                 ref_elem_type;
    1064              : 
    1065              : //      get iterators
    1066              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
    1067            0 :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
    1068            0 :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
    1069              : 
    1070            0 :         if(m_bBinary)
    1071            0 :                 File << VTKFileWriter::base64_binary;
    1072              :         else
    1073            0 :                 File << VTKFileWriter::normal;
    1074              : 
    1075              : //      loop all elements
    1076            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    1077              :         {
    1078              :         //      handle octahedron separately by splitting into a top and bottom pyramid
    1079              :                 if(ref_elem_type::REFERENCE_OBJECT_ID != ROID_OCTAHEDRON)
    1080              :                 {
    1081              :                 //      increase counter of vertices
    1082            0 :                         n += ref_elem_type::numCorners;
    1083              : 
    1084              :                 //      write offset
    1085            0 :                         File << n;
    1086            0 :                         if(!m_bBinary)
    1087            0 :                                 File << ' ';
    1088              :                 }
    1089              :                 else
    1090              :                 {
    1091              :                 //      increase counter for top pyramid vertices
    1092            0 :                         n += 5;
    1093              : 
    1094              :                 //      write offset for top pyramid
    1095            0 :                         File << n;
    1096            0 :                         if(!m_bBinary)
    1097            0 :                                 File << ' ';
    1098              : 
    1099              :                 //      increase counter for bottom pyramid vertices
    1100            0 :                         n += 5;
    1101              : 
    1102              :                 //      write offset for bottom pyramid
    1103            0 :                         File << n;
    1104            0 :                         if(!m_bBinary)
    1105            0 :                                 File << ' ';
    1106              :                 }
    1107              :         }
    1108            0 : }
    1109              : 
    1110              : /**
    1111              :  * This method writes the 'offset' for each element of a subset.
    1112              :  */
    1113              : template <int TDim>
    1114              : template <typename T>
    1115            0 : void VTKOutput<TDim>::
    1116              : write_cell_offsets(VTKFileWriter& File, const T& iterContainer, const SubsetGroup& ssGrp,
    1117              :                    const int dim, const int numElem)
    1118              : {
    1119            0 :         File << VTKFileWriter::normal;
    1120              : //      write opening tag indicating that offsets are going to be written
    1121            0 :         File << "        <DataArray type=\"Int32\" Name=\"offsets\" format="
    1122            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1123            0 :         int n = sizeof(int) * numElem;
    1124            0 :         if(m_bBinary)
    1125            0 :                 File << VTKFileWriter::base64_binary << n;
    1126              : 
    1127            0 :         n = 0;
    1128              : //      switch dimension
    1129            0 :         if(numElem > 0)
    1130            0 :         for(size_t i = 0; i < ssGrp.size(); i++){
    1131            0 :                 switch(dim)
    1132              :                 {
    1133              :                         case 0: break; // no elements -> nothing to do
    1134            0 :                         case 1: write_cell_offsets<RegularEdge,T>(File, iterContainer, ssGrp[i], n);
    1135            0 :                                         write_cell_offsets<ConstrainingEdge,T>(File, iterContainer, ssGrp[i], n); break;
    1136            0 :                         case 2: write_cell_offsets<Triangle,T>(File, iterContainer, ssGrp[i], n);
    1137            0 :                                         write_cell_offsets<Quadrilateral,T>(File, iterContainer, ssGrp[i], n);
    1138            0 :                                         write_cell_offsets<ConstrainingTriangle,T>(File, iterContainer, ssGrp[i], n);
    1139            0 :                                         write_cell_offsets<ConstrainingQuadrilateral,T>(File, iterContainer, ssGrp[i], n); break;
    1140            0 :                         case 3: write_cell_offsets<Tetrahedron,T>(File, iterContainer, ssGrp[i], n);
    1141            0 :                                         write_cell_offsets<Pyramid,T>(File, iterContainer, ssGrp[i], n);
    1142            0 :                                         write_cell_offsets<Prism,T>(File, iterContainer, ssGrp[i], n);
    1143            0 :                                         write_cell_offsets<Octahedron,T>(File, iterContainer, ssGrp[i], n);
    1144            0 :                                         write_cell_offsets<Hexahedron,T>(File, iterContainer, ssGrp[i], n); break;
    1145            0 :                         default: UG_THROW("VTK::write_cell_offsets: Dimension " << dim <<
    1146              :                                                 " is not supported.");
    1147              :                 }
    1148              :         }
    1149              : 
    1150              : //      closing tag
    1151            0 :         File << VTKFileWriter::normal;
    1152            0 :         File << "\n        </DataArray>\n";
    1153            0 : }
    1154              : 
    1155              : ////////////////////////////////////////////////////////////////////////////////
    1156              : // Types
    1157              : ////////////////////////////////////////////////////////////////////////////////
    1158              : 
    1159              : 
    1160              : template <int TDim>
    1161              : template <class TElem, typename T>
    1162            0 : void VTKOutput<TDim>::
    1163              : write_cell_types(VTKFileWriter& File, const T& iterContainer, const int si)
    1164              : {
    1165              : //      get reference element
    1166              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1167              :                                                                                                                                 ref_elem_type;
    1168              : //      get object type
    1169              :         static const ReferenceObjectID refID = ref_elem_type::REFERENCE_OBJECT_ID;
    1170              : 
    1171              : //      type
    1172              :         char type;
    1173              : 
    1174              : //      get type, based on reference element type
    1175              :         switch(refID)
    1176              :         {
    1177              :                 case ROID_EDGE: type = (char) 3; break;
    1178              :                 case ROID_TRIANGLE: type = (char) 5; break;
    1179              :                 case ROID_QUADRILATERAL: type = (char) 9; break;
    1180              :                 case ROID_TETRAHEDRON: type = (char) 10; break;
    1181              :                 case ROID_PYRAMID: type = (char) 14; break;
    1182              :                 case ROID_PRISM: type = (char) 13; break;
    1183              :                 case ROID_OCTAHEDRON: type = (char) 14; break; // use type id == 14 (PYRAMID) as we handle an octahedron by splitting into a top and bottom pyramid
    1184              :                 case ROID_HEXAHEDRON: type = (char) 12; break;
    1185              :                 default: UG_THROW("Element Type not known.");
    1186              :         }
    1187              : 
    1188              : //      get iterators
    1189              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
    1190            0 :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
    1191            0 :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
    1192              : 
    1193            0 :         if(m_bBinary)
    1194            0 :                 File << VTKFileWriter::base64_binary;
    1195              :         else
    1196            0 :                 File << VTKFileWriter::normal;
    1197              : //      loop all elements, write type for each element to stream
    1198            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    1199              :         {
    1200              :         //      handle octahedral case separately by splitting into a top and bottom pyramid
    1201              :                 if(ref_elem_type::REFERENCE_OBJECT_ID != ROID_OCTAHEDRON)
    1202              :                 {
    1203            0 :                         if(m_bBinary)
    1204            0 :                                 File << type;
    1205              :                          else
    1206            0 :                                 File << (int) type << ' ';
    1207              :                 }
    1208              :                 else
    1209              :                 {
    1210            0 :                         if(m_bBinary)
    1211              :                         {
    1212            0 :                                 File << type; // top pyramid
    1213            0 :                                 File << type; // bottom pyramid
    1214              :                         }
    1215              :                         else
    1216              :                         {
    1217            0 :                                 File << (int) type << ' '; // top pyramid
    1218            0 :                                 File << (int) type << ' '; // bottom pyramid
    1219              :                         }
    1220              :                 }
    1221              :         }
    1222            0 : }
    1223              : 
    1224              : /**
    1225              :  * This method writes the 'type' for each element of a subset. The type is
    1226              :  * a vtk-format specified number for a given element type.
    1227              :  */
    1228              : template <int TDim>
    1229              : template <typename T>
    1230            0 : void VTKOutput<TDim>::
    1231              : write_cell_types(VTKFileWriter& File, const T& iterContainer, const SubsetGroup& ssGrp,
    1232              :                  const int dim, int numElem)
    1233              : {
    1234            0 :         File << VTKFileWriter::normal;
    1235              : //      write opening tag to indicate that types will be written
    1236            0 :         File << "        <DataArray type=\"Int8\" Name=\"types\" format="
    1237            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1238            0 :         if(m_bBinary)
    1239            0 :                 File << VTKFileWriter::base64_binary << numElem;
    1240              : 
    1241              : //      switch dimension
    1242            0 :         if(numElem > 0)
    1243            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
    1244              :         {
    1245            0 :                 switch(dim)
    1246              :                 {
    1247              :                         case 0: break; // no elements -> nothing to do
    1248            0 :                         case 1: write_cell_types<RegularEdge>(File, iterContainer, ssGrp[i]);
    1249            0 :                                         write_cell_types<ConstrainingEdge>(File, iterContainer, ssGrp[i]); break;
    1250            0 :                         case 2: write_cell_types<Triangle>(File, iterContainer, ssGrp[i]);
    1251            0 :                                         write_cell_types<Quadrilateral>(File, iterContainer, ssGrp[i]);
    1252            0 :                                         write_cell_types<ConstrainingTriangle>(File, iterContainer, ssGrp[i]);
    1253            0 :                                         write_cell_types<ConstrainingQuadrilateral>(File, iterContainer, ssGrp[i]); break;
    1254            0 :                         case 3: write_cell_types<Tetrahedron>(File, iterContainer, ssGrp[i]);
    1255            0 :                                         write_cell_types<Pyramid>(File, iterContainer, ssGrp[i]);
    1256            0 :                                         write_cell_types<Prism>(File, iterContainer, ssGrp[i]);
    1257            0 :                                         write_cell_types<Octahedron>(File, iterContainer, ssGrp[i]);
    1258            0 :                                         write_cell_types<Hexahedron>(File, iterContainer, ssGrp[i]); break;
    1259            0 :                         default: UG_THROW("VTK::write_cell_types: Dimension " << dim <<
    1260              :                                                 " is not supported.");
    1261              :                 }
    1262              :         }
    1263              : 
    1264              : //      write closing tag
    1265            0 :         File << VTKFileWriter::normal;
    1266            0 :         File << "\n        </DataArray>\n";
    1267            0 : }
    1268              : 
    1269              : ////////////////////////////////////////////////////////////////////////////////
    1270              : // Subset Indices
    1271              : ////////////////////////////////////////////////////////////////////////////////
    1272              : 
    1273              : 
    1274              : template <int TDim>
    1275              : template <class TElem, typename T>
    1276              : void VTKOutput<TDim>::
    1277              : write_cell_subsets(VTKFileWriter& File, const T& iterContainer, const int si, MGSubsetHandler& sh)
    1278              : {
    1279              : //      subset
    1280              :         int subset;
    1281              : 
    1282              : //      get iterators
    1283              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
    1284              :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
    1285              :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
    1286              : 
    1287              :         if(m_bBinary)
    1288              :                 File << VTKFileWriter::base64_binary;
    1289              :         else
    1290              :                 File << VTKFileWriter::normal;
    1291              : //      loop all elements, write type for each element to stream
    1292              :         for( ; iterBegin != iterEnd; ++iterBegin)
    1293              :         {
    1294              :                 subset = (char)sh.get_subset_index(*iterBegin);
    1295              :                 //iterContainer.get_subset_name(2);
    1296              : 
    1297              :                 if(m_bBinary){
    1298              :                         File << (char) subset << ' ';
    1299              :                 }
    1300              :                 else{
    1301              :                         File << subset << ' ';
    1302              :                 }
    1303              :         }
    1304              : }
    1305              : 
    1306              : /**
    1307              :  * This method writes the 'region' for each element of a subset. The region is
    1308              :  * the ug4 subset index for a given element.
    1309              :  */
    1310              : template <int TDim>
    1311              : template <typename T>
    1312              : void VTKOutput<TDim>::
    1313              : write_cell_subsets(VTKFileWriter& File, const T& iterContainer, const SubsetGroup& ssGrp,
    1314              :                  const int dim, const int numElem, MGSubsetHandler& sh)
    1315              : {
    1316              :         File << VTKFileWriter::normal;
    1317              : //      write opening tag to indicate that types will be written
    1318              :         File << "        <DataArray type=\"Int8\" Name=\"regions\" format="
    1319              :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1320              :         if(m_bBinary)
    1321              :                 File << VTKFileWriter::base64_binary << numElem;
    1322              : 
    1323              : //      switch dimension
    1324              :         if(numElem > 0)
    1325              :         for(size_t i = 0; i < ssGrp.size(); i++)
    1326              :         {
    1327              :                 switch(dim)
    1328              :                 {
    1329              :                         case 0: break; // no elements -> nothing to do
    1330              :                         case 1: write_cell_subsets<RegularEdge>(File, iterContainer, ssGrp[i], sh);
    1331              :                                         write_cell_subsets<ConstrainingEdge>(File, iterContainer, ssGrp[i], sh); break;
    1332              :                         case 2: write_cell_subsets<Triangle>(File, iterContainer, ssGrp[i], sh);
    1333              :                                         write_cell_subsets<Quadrilateral>(File, iterContainer, ssGrp[i], sh);
    1334              :                                         write_cell_subsets<ConstrainingTriangle>(File, iterContainer, ssGrp[i], sh);
    1335              :                                         write_cell_subsets<ConstrainingQuadrilateral>(File, iterContainer, ssGrp[i], sh); break;
    1336              :                         case 3: write_cell_subsets<Tetrahedron>(File, iterContainer, ssGrp[i], sh);
    1337              :                                         write_cell_subsets<Pyramid>(File, iterContainer, ssGrp[i], sh);
    1338              :                                         write_cell_subsets<Prism>(File, iterContainer, ssGrp[i], sh);
    1339              :                                         write_cell_subsets<Octahedron>(File, iterContainer, ssGrp[i], sh);
    1340              :                                         write_cell_subsets<Hexahedron>(File, iterContainer, ssGrp[i], sh); break;
    1341              :                         default: UG_THROW("VTK::write_cell_subsets: Dimension " << dim <<
    1342              :                                                 " is not supported.");
    1343              :                 }
    1344              :         }
    1345              : 
    1346              : //      write closing tag
    1347              :         File << VTKFileWriter::normal;
    1348              :         File << "\n        </DataArray>\n";
    1349              : }
    1350              : 
    1351              : ////////////////////////////////////////////////////////////////////////////////
    1352              : // Subset Indices
    1353              : ////////////////////////////////////////////////////////////////////////////////
    1354              : 
    1355              : 
    1356              : template <int TDim>
    1357              : template <class TElem, typename T>
    1358              : void VTKOutput<TDim>::
    1359              : write_cell_proc_ranks(VTKFileWriter& File, const T& iterContainer, const int si, MGSubsetHandler& sh)
    1360              : {
    1361              : //      subset
    1362              :         int rank = 0;
    1363              : 
    1364              : #ifdef UG_PARALLEL
    1365              :         rank = pcl::ProcRank();
    1366              : #endif
    1367              : 
    1368              : //      get iterators
    1369              :         typedef typename IteratorProvider<T>::template traits<TElem>::const_iterator const_iterator;
    1370              :         const_iterator iterBegin = IteratorProvider<T>::template begin<TElem>(iterContainer, si);
    1371              :         const_iterator iterEnd = IteratorProvider<T>::template end<TElem>(iterContainer, si);
    1372              : 
    1373              :         if(m_bBinary)
    1374              :                 File << VTKFileWriter::base64_binary;
    1375              :         else
    1376              :                 File << VTKFileWriter::normal;
    1377              : //      loop all elements, write type for each element to stream
    1378              :         for( ; iterBegin != iterEnd; ++iterBegin)
    1379              :         {
    1380              : 
    1381              :                 if(m_bBinary){
    1382              :                         File << (char) rank << ' ';
    1383              :                 }
    1384              :                 else{
    1385              :                         File << rank << ' ';
    1386              :                 }
    1387              :         }
    1388              : }
    1389              : 
    1390              : /**
    1391              :  * This method writes the proc ranks for each cell.
    1392              :  */
    1393              : template <int TDim>
    1394              : template <typename T>
    1395              : void VTKOutput<TDim>::
    1396              : write_cell_proc_ranks(VTKFileWriter& File, const T& iterContainer, const SubsetGroup& ssGrp,
    1397              :                  const int dim, const int numElem, MGSubsetHandler& sh)
    1398              : {
    1399              :         File << VTKFileWriter::normal;
    1400              : //      write opening tag to indicate that types will be written
    1401              :         File << "        <DataArray type=\"Int8\" Name=\"proc_ranks\" format="
    1402              :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1403              :         if(m_bBinary)
    1404              :                 File << VTKFileWriter::base64_binary << numElem;
    1405              : 
    1406              : //      switch dimension
    1407              :         if(numElem > 0)
    1408              :         for(size_t i = 0; i < ssGrp.size(); i++)
    1409              :         {
    1410              :                 switch(dim)
    1411              :                 {
    1412              :                         case 0: break; // no elements -> nothing to do
    1413              :                         case 1: write_cell_proc_ranks<RegularEdge>(File, iterContainer, ssGrp[i], sh);
    1414              :                                         write_cell_proc_ranks<ConstrainingEdge>(File, iterContainer, ssGrp[i], sh); break;
    1415              :                         case 2: write_cell_proc_ranks<Triangle>(File, iterContainer, ssGrp[i], sh);
    1416              :                                         write_cell_proc_ranks<Quadrilateral>(File, iterContainer, ssGrp[i], sh);
    1417              :                                         write_cell_proc_ranks<ConstrainingTriangle>(File, iterContainer, ssGrp[i], sh);
    1418              :                                         write_cell_proc_ranks<ConstrainingQuadrilateral>(File, iterContainer, ssGrp[i], sh); break;
    1419              :                         case 3: write_cell_proc_ranks<Tetrahedron>(File, iterContainer, ssGrp[i], sh);
    1420              :                                         write_cell_proc_ranks<Pyramid>(File, iterContainer, ssGrp[i], sh);
    1421              :                                         write_cell_proc_ranks<Prism>(File, iterContainer, ssGrp[i], sh);
    1422              :                                         write_cell_proc_ranks<Octahedron>(File, iterContainer, ssGrp[i], sh);
    1423              :                                         write_cell_proc_ranks<Hexahedron>(File, iterContainer, ssGrp[i], sh); break;
    1424              :                         default: UG_THROW("VTK::write_cell_proc_ranks: Dimension " << dim <<
    1425              :                                                 " is not supported.");
    1426              :                 }
    1427              :         }
    1428              : 
    1429              : //      write closing tag
    1430              :         File << VTKFileWriter::normal;
    1431              :         File << "\n        </DataArray>\n";
    1432              : }
    1433              : 
    1434              : ////////////////////////////////////////////////////////////////////////////////
    1435              : // Nodal Value
    1436              : ////////////////////////////////////////////////////////////////////////////////
    1437              : 
    1438              : template <int TDim>
    1439              : template <typename TElem, typename TFunction, typename TData>
    1440            0 : void VTKOutput<TDim>::
    1441              : write_nodal_data_elementwise(VTKFileWriter& File, TFunction& u, number time,
    1442              :                              SmartPtr<UserData<TData, TDim> > spData,
    1443              :                              Grid& grid, const int si)
    1444              : {
    1445              : //      get reference element
    1446              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1447              :                                                                                                                                 ref_elem_type;
    1448            0 :         static const ref_elem_type& refElem = Provider<ref_elem_type>::get();
    1449              :         static const size_t numCo = ref_elem_type::numCorners;
    1450              : 
    1451            0 :         if(m_bBinary)
    1452            0 :                 File << VTKFileWriter::base64_binary;
    1453              :         else
    1454            0 :                 File << VTKFileWriter::normal;
    1455              : 
    1456              : //      get iterators
    1457              :         typedef typename IteratorProvider<TFunction>::template traits<TElem>::const_iterator const_iterator;
    1458            0 :         const_iterator iterBegin = IteratorProvider<TFunction>::template begin<TElem>(u, si);
    1459            0 :         const_iterator iterEnd = IteratorProvider<TFunction>::template end<TElem>(u, si);
    1460              : 
    1461            0 :         std::vector<MathVector<TDim> > vCorner(numCo);
    1462              : 
    1463            0 :         TData vValue[numCo];
    1464            0 :         bool bNeedFct = spData->requires_grid_fct();
    1465              : 
    1466              : //      loop all elements
    1467            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    1468              :         {
    1469              :         //      get element
    1470              :                 TElem *elem = *iterBegin;
    1471              : 
    1472              :         //      update the reference mapping for the corners
    1473            0 :                 CollectCornerCoordinates(vCorner, *elem, u.domain()->position_accessor(), true);
    1474              : 
    1475              :         //      get subset
    1476              :                 int theSI = si;
    1477            0 :                 if(si < 0) theSI = u.domain()->subset_handler()->get_subset_index(elem);
    1478              : 
    1479              :         //      get local solution if needed
    1480            0 :                 if(bNeedFct)
    1481              :                 {
    1482              :                 //      create storage
    1483              :                         LocalIndices ind;
    1484              :                         LocalVector locU;
    1485              : 
    1486              :                 //      get global indices
    1487              :                         u.indices(elem, ind);
    1488              : 
    1489              :                 //      adapt local algebra
    1490            0 :                         locU.resize(ind);
    1491              : 
    1492              :                 //      read local values of u
    1493            0 :                         GetLocalVector(locU, u);
    1494              : 
    1495              :                 //      compute data
    1496              :                         try{
    1497            0 :                                 (*spData)(vValue, &vCorner[0], time, theSI, elem,
    1498              :                                                         &vCorner[0], refElem.corners(), numCo, &locU, NULL);
    1499              :                         }
    1500            0 :                         UG_CATCH_THROW("VTK::write_nodal_data_elementwise: Cannot evaluate data.");
    1501              :                 }
    1502              :                 else
    1503              :                 {
    1504              :                 //      compute data
    1505              :                         try{
    1506            0 :                                 (*spData)(vValue, &vCorner[0], time, theSI, numCo);
    1507              :                         }
    1508            0 :                         UG_CATCH_THROW("VTK::write_nodal_data_elementwise: Cannot evaluate data.");
    1509              :                 }
    1510              : 
    1511              :         //      loop vertices of element
    1512            0 :                 for(size_t co = 0; co < numCo; ++co)
    1513              :                 {
    1514              :                 //      get vertex of element
    1515              :                         Vertex* v = GetVertex(elem, co);
    1516              : 
    1517              :                 //      if vertex has been handled before, skip
    1518            0 :                         if(grid.is_marked(v)) continue;
    1519              : 
    1520              :                 //      mark as used
    1521              :                         grid.mark(v);
    1522              : 
    1523              :                 //      loop all components
    1524            0 :                         write_item_to_file(File, vValue[co]);
    1525              :                 }
    1526              :         }
    1527              : 
    1528            0 : }
    1529              : 
    1530              : /**
    1531              :  * Writes the nodal data to the vtu file.
    1532              :  */
    1533              : template <int TDim>
    1534              : template <typename TFunction, typename TData>
    1535            0 : void VTKOutput<TDim>::
    1536              : write_nodal_data(VTKFileWriter& File, TFunction& u, number time,
    1537              :                  SmartPtr<UserData<TData, TDim> > spData,
    1538              :                  const int numCmp,
    1539              :                  const std::string& name,
    1540              :                  Grid& grid, const SubsetGroup& ssGrp, const int dim, const int numVert)
    1541              : {
    1542            0 :         spData->set_function_pattern(u.function_pattern());
    1543              : 
    1544              : //      check that nodal data is possible
    1545            0 :         if(!spData->continuous())
    1546            0 :                 UG_THROW("VTK: data with name '"<<name<<"' is scheduled for nodal output,"
    1547              :                                 " but the data is not continuous. Cannot write it as nodal data.")
    1548              : 
    1549              : //      write opening tag
    1550            0 :         File << VTKFileWriter::normal;
    1551            0 :         File << "        <DataArray type=\"Float32\" Name=\""<<name<<"\" "
    1552            0 :         "NumberOfComponents=\""<<numCmp<<"\" format="
    1553            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1554              : 
    1555            0 :         int n = sizeof(float) * numVert * numCmp;
    1556            0 :         if(m_bBinary)
    1557            0 :                 File << VTKFileWriter::base64_binary << n;
    1558              : 
    1559              : //      start marking of grid
    1560            0 :         grid.begin_marking();
    1561              : 
    1562              : //      switch dimension
    1563            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
    1564            0 :         switch(dim)
    1565              :         {
    1566            0 :                 case 1: write_nodal_data_elementwise<RegularEdge,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1567            0 :                                 write_nodal_data_elementwise<ConstrainingEdge,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1568            0 :                 case 2: write_nodal_data_elementwise<Triangle,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1569            0 :                                 write_nodal_data_elementwise<Quadrilateral,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1570            0 :                                 write_nodal_data_elementwise<ConstrainingTriangle,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1571            0 :                                 write_nodal_data_elementwise<ConstrainingQuadrilateral,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1572            0 :                 case 3: write_nodal_data_elementwise<Tetrahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1573            0 :                                 write_nodal_data_elementwise<Pyramid,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1574            0 :                                 write_nodal_data_elementwise<Prism,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1575            0 :                                 write_nodal_data_elementwise<Octahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1576            0 :                                 write_nodal_data_elementwise<Hexahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1577            0 :                 default: UG_THROW("VTK::write_nodal_data: Dimension " << dim <<
    1578              :                                         " is not supported.");
    1579              :         }
    1580              : 
    1581              : //      end marking
    1582            0 :         grid.end_marking();
    1583              : 
    1584              : //      write closing tag
    1585            0 :         File << VTKFileWriter::normal;
    1586            0 :         File << "\n        </DataArray>\n";
    1587            0 : };
    1588              : 
    1589              : 
    1590              : template <int TDim>
    1591              : template <typename TElem, typename TFunction>
    1592            0 : void VTKOutput<TDim>::
    1593              : write_nodal_values_elementwise(VTKFileWriter& File, TFunction& u,
    1594              :                                const std::vector<size_t>& vFct,
    1595              :                                Grid& grid, const int si)
    1596              : {
    1597              : //      get reference element
    1598              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1599              :                                                                                                                                 ref_elem_type;
    1600            0 :         if(m_bBinary)
    1601            0 :                 File << VTKFileWriter::base64_binary;
    1602              :         else
    1603            0 :                 File << VTKFileWriter::normal;
    1604              : 
    1605              : //      index vector
    1606              :         std::vector<DoFIndex> vMultInd;
    1607              : 
    1608              : //      get iterators
    1609              :         typedef typename IteratorProvider<TFunction>::template traits<TElem>::const_iterator const_iterator;
    1610            0 :         const_iterator iterBegin = IteratorProvider<TFunction>::template begin<TElem>(u, si);
    1611            0 :         const_iterator iterEnd = IteratorProvider<TFunction>::template end<TElem>(u, si);
    1612              : 
    1613              : //      loop all elements
    1614            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    1615              :         {
    1616              :         //      get element
    1617              :                 TElem *elem = *iterBegin;
    1618              : 
    1619              :         //      loop vertices of element
    1620            0 :                 for(size_t co = 0; co < (size_t) ref_elem_type::numCorners; ++co)
    1621              :                 {
    1622              :                 //      get vertex of element
    1623              :                         Vertex* v = GetVertex(elem, co);
    1624              : 
    1625              :                 //      if vertex has been handled before, skip
    1626            0 :                         if(grid.is_marked(v)) continue;
    1627              : 
    1628              :                 //      mark as used
    1629              :                         grid.mark(v);
    1630              : 
    1631              :                 //      loop all components
    1632            0 :                         for(size_t i = 0; i < vFct.size(); ++i)
    1633              :                         {
    1634              :                         //      get multi index of vertex for the function
    1635            0 :                                 if(u.inner_dof_indices(v, vFct[i], vMultInd) != 1)
    1636            0 :                                         UG_THROW("VTK:write_nodal_values_elementwise: "
    1637              :                                                         "The function component "<<vFct[i]<<" has "<<
    1638              :                                                         vMultInd.size()<<" DoFs in a vertex of an element of subset "
    1639              :                                                         <<si<<". To write a component to vtk, exactly "
    1640              :                                                         "one DoF must be given in any vertex.");
    1641              : 
    1642              :                         //      flush stream
    1643            0 :                                 write_item_to_file(File, DoFRef(u, vMultInd[0]));
    1644              :                         }
    1645              : 
    1646              : 
    1647              : 
    1648              :                 //      fill with zeros up to 3d if vector type
    1649            0 :                         if(vFct.size() != 1) {
    1650            0 :                                 for(size_t i = vFct.size(); i < 3; ++i) {
    1651            0 :                                         write_item_to_file(File, 0.f);
    1652              :                                 }
    1653              :                         }
    1654              :                 }
    1655              :         }
    1656              : 
    1657            0 : }
    1658              : 
    1659              : template <int TDim>
    1660              : template <typename TFunction>
    1661            0 : void VTKOutput<TDim>::
    1662              : write_nodal_values(VTKFileWriter& File, TFunction& u,
    1663              :                    const std::vector<size_t>& vFct, const std::string& name,
    1664              :                    Grid& grid, const SubsetGroup& ssGrp, const int dim, const int numVert)
    1665              : {
    1666            0 :         File << VTKFileWriter::normal;
    1667              : //      write opening tag
    1668            0 :         File << "        <DataArray type=\"Float32\" Name=\""<<name<<"\" "
    1669            0 :         "NumberOfComponents=\""<<(vFct.size() == 1 ? 1 : 3)<<"\" format="
    1670            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1671              : 
    1672            0 :         int n = sizeof(float) * numVert * (vFct.size() == 1 ? 1 : 3);
    1673            0 :         if(m_bBinary)
    1674            0 :                 File << VTKFileWriter::base64_binary << n;
    1675              : 
    1676              : //      start marking of grid
    1677            0 :         grid.begin_marking();
    1678              : 
    1679              : //      switch dimension
    1680            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
    1681            0 :         switch(dim)
    1682              :         {
    1683            0 :                 case 0: write_nodal_values_elementwise<Vertex>(File, u, vFct, grid, ssGrp[i]); break;
    1684            0 :                 case 1: write_nodal_values_elementwise<RegularEdge>(File, u, vFct, grid, ssGrp[i]);
    1685            0 :                                 write_nodal_values_elementwise<ConstrainingEdge>(File, u, vFct, grid, ssGrp[i]); break;
    1686            0 :                 case 2: write_nodal_values_elementwise<Triangle>(File, u, vFct, grid, ssGrp[i]);
    1687            0 :                                 write_nodal_values_elementwise<Quadrilateral>(File, u, vFct, grid, ssGrp[i]);
    1688            0 :                                 write_nodal_values_elementwise<ConstrainingTriangle>(File, u, vFct, grid, ssGrp[i]);
    1689            0 :                                 write_nodal_values_elementwise<ConstrainingQuadrilateral>(File, u, vFct, grid, ssGrp[i]); break;
    1690            0 :                 case 3: write_nodal_values_elementwise<Tetrahedron>(File, u, vFct, grid, ssGrp[i]);
    1691            0 :                                 write_nodal_values_elementwise<Pyramid>(File, u, vFct, grid, ssGrp[i]);
    1692            0 :                                 write_nodal_values_elementwise<Prism>(File, u, vFct, grid, ssGrp[i]);
    1693            0 :                                 write_nodal_values_elementwise<Octahedron>(File, u, vFct, grid, ssGrp[i]);
    1694            0 :                                 write_nodal_values_elementwise<Hexahedron>(File, u, vFct, grid, ssGrp[i]); break;
    1695            0 :                 default: UG_THROW("VTK::write_nodal_values: Dimension " << dim <<
    1696              :                                         " is not supported.");
    1697              :         }
    1698              : 
    1699              : //      end marking
    1700            0 :         grid.end_marking();
    1701              : 
    1702              : //      write closing tag
    1703            0 :         File << VTKFileWriter::normal;
    1704            0 :         File << "\n        </DataArray>\n";
    1705            0 : };
    1706              : 
    1707              : template <int TDim>
    1708              : template <typename TFunction>
    1709            0 : void VTKOutput<TDim>::
    1710              : write_nodal_values_piece(VTKFileWriter& File, TFunction& u, number time, Grid& grid,
    1711              :                          const SubsetGroup& ssGrp, const int dim, const int numVert)
    1712              : {
    1713            0 :         if(!m_vSymbFct.empty()){
    1714            0 :                 for(std::map<std::string, std::vector<std::string> >::const_iterator iter =
    1715            0 :                                 m_vSymbFct.begin(); iter != m_vSymbFct.end(); ++iter){
    1716            0 :                         const std::vector<std::string>& symbNames = (*iter).second;
    1717            0 :                         const std::string& vtkName = (*iter).first;
    1718              : 
    1719              :                         bool bContinuous = true;
    1720            0 :                         for(size_t i = 0; i < symbNames.size(); ++i){
    1721              :                                 size_t fct = u.fct_id_by_name(symbNames[i].c_str());
    1722            0 :                                 if(!LocalFiniteElementProvider::continuous(u.local_finite_element_id(fct))){
    1723              :                                         bContinuous = false; break;
    1724              :                                 }
    1725              :                         }
    1726              : 
    1727            0 :                         if(bContinuous){
    1728            0 :                                 m_vSymbFctNodal[vtkName] = symbNames;
    1729              :                         }
    1730              :                 }
    1731              :         }
    1732              : 
    1733              : //      check if something to do
    1734            0 :         if(m_vSymbFctNodal.empty() && m_vScalarNodalData.empty() && m_vVectorNodalData.empty())
    1735              :                 return;
    1736              : 
    1737              : //      write opening tag to indicate point data
    1738            0 :         File << VTKFileWriter::normal;
    1739            0 :         File << "      <PointData>\n";
    1740              : 
    1741              : //      loop all selected symbolic names
    1742            0 :         for(std::map<std::string, std::vector<std::string> >::const_iterator iter =
    1743            0 :                         m_vSymbFctNodal.begin(); iter != m_vSymbFctNodal.end(); ++iter)
    1744              :         {
    1745              :         //      get symb function
    1746              :                 const std::vector<std::string>& symbNames = (*iter).second;
    1747            0 :                 const std::string& vtkName = (*iter).first;
    1748              : 
    1749              :         //      create function group
    1750            0 :                 std::vector<size_t> fctGrp(symbNames.size());
    1751            0 :                 for(size_t i = 0; i < symbNames.size(); ++i)
    1752            0 :                         fctGrp[i] = u.fct_id_by_name(symbNames[i].c_str());
    1753              : 
    1754              :         //      check that all functions are contained in subset
    1755              :                 bool bContained = true;
    1756            0 :                 for(size_t i = 0; i < fctGrp.size(); ++i)
    1757            0 :                         for (size_t j = 0; j < ssGrp.size(); ++j)
    1758            0 :                                 if(!u.is_def_in_subset(fctGrp[i], ssGrp[j]))
    1759              :                                         bContained = false;
    1760              : 
    1761            0 :                 if(!bContained) continue;
    1762              : 
    1763              :         //      write scalar value of this function
    1764              :                 try{
    1765            0 :                         write_nodal_values(File, u, fctGrp, vtkName, grid, ssGrp, dim, numVert);
    1766              :                 }
    1767            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed write nodal Values.");
    1768              :         }
    1769              : 
    1770              : //      loop all scalar data
    1771            0 :         for(ScalarDataIterator iter = m_vScalarNodalData.begin();
    1772            0 :                         iter != m_vScalarNodalData.end(); ++iter)
    1773              :         {
    1774              :         //      get symb function
    1775              :                 SmartPtr<UserData<number,TDim> > spData = (*iter).second;
    1776            0 :                 const std::string& vtkName = (*iter).first;
    1777              : 
    1778              :         //      write scalar value of this data
    1779              :                 try{
    1780              :                         write_nodal_data<TFunction,number>
    1781            0 :                                                         (File, u, time, spData, 1, vtkName, grid, ssGrp, dim, numVert);
    1782              :                 }
    1783            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed write nodal scalar Data.");
    1784              :         }
    1785              : 
    1786              : //      loop all vector data
    1787            0 :         for(VectorDataIterator  iter = m_vVectorNodalData.begin();
    1788            0 :                         iter != m_vVectorNodalData.end(); ++iter)
    1789              :         {
    1790              :         //      get symb function
    1791              :                 SmartPtr<UserData<MathVector<TDim>,TDim> > spData = (*iter).second;
    1792            0 :                 const std::string& vtkName = (*iter).first;
    1793              : 
    1794              :         //      write scalar value of this data
    1795              :                 try{
    1796              :                         write_nodal_data<TFunction,MathVector<TDim> >
    1797            0 :                                                         (File, u, time, spData, 3, vtkName, grid, ssGrp, dim, numVert);
    1798              :                 }
    1799            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed write nodal vector Data.");
    1800              :         }
    1801              : 
    1802              : //      loop all vector data
    1803            0 :         for(MatrixDataIterator  iter = m_vMatrixNodalData.begin();
    1804            0 :                         iter != m_vMatrixNodalData.end(); ++iter)
    1805              :         {
    1806              :         //      get symb function
    1807              :                 SmartPtr<UserData<MathMatrix<TDim,TDim>,TDim> > spData = (*iter).second;
    1808            0 :                 const std::string& vtkName = (*iter).first;
    1809              : 
    1810              :         //      write scalar value of this data
    1811              :                 try{
    1812              :                         write_nodal_data<TFunction,MathMatrix<TDim,TDim> >
    1813            0 :                                                         (File, u, time, spData, 9, vtkName, grid, ssGrp, dim, numVert);
    1814              :                 }
    1815            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed write nodal matrix Data.");
    1816              :         }
    1817              : 
    1818              : //      write closing tag
    1819            0 :         File << VTKFileWriter::normal;
    1820            0 :         File << "      </PointData>\n";
    1821              : }
    1822              : 
    1823              : 
    1824              : ////////////////////////////////////////////////////////////////////////////////
    1825              : // Cell Value
    1826              : ////////////////////////////////////////////////////////////////////////////////
    1827              : 
    1828              : template <int TDim>
    1829              : template <typename TElem, typename TFunction, typename TData>
    1830            0 : void VTKOutput<TDim>::
    1831              : write_cell_data_elementwise(VTKFileWriter& File, TFunction& u, number time,
    1832              :                              SmartPtr<UserData<TData, TDim> > spData,
    1833              :                              Grid& grid, const int si)
    1834              : {
    1835              : //      get reference element
    1836              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1837              :                                                                                                                                 ref_elem_type;
    1838              :         static const int refDim = reference_element_traits<TElem>::dim;
    1839            0 :         static const ref_elem_type& refElem = Provider<ref_elem_type>::get();
    1840              :         static const size_t numCo = ref_elem_type::numCorners;
    1841              : 
    1842            0 :         if(m_bBinary)
    1843            0 :                 File << VTKFileWriter::base64_binary;
    1844              :         else
    1845            0 :                 File << VTKFileWriter::normal;
    1846              : 
    1847              : //      get iterators
    1848              :         typedef typename IteratorProvider<TFunction>::template traits<TElem>::const_iterator const_iterator;
    1849            0 :         const_iterator iterBegin = IteratorProvider<TFunction>::template begin<TElem>(u, si);
    1850            0 :         const_iterator iterEnd = IteratorProvider<TFunction>::template end<TElem>(u, si);
    1851              : 
    1852              :         MathVector<refDim> localIP;
    1853              :         MathVector<TDim> globIP;
    1854            0 :         AveragePositions(localIP, refElem.corners(), numCo);
    1855              : 
    1856            0 :         std::vector<MathVector<TDim> > vCorner(numCo);
    1857              : 
    1858              :         TData value;
    1859            0 :         bool bNeedFct = spData->requires_grid_fct();
    1860              : 
    1861              : //      loop all elements
    1862            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    1863              :         {
    1864              :         //      get element
    1865              :                 TElem *elem = *iterBegin;
    1866              : 
    1867              :         //      update the reference mapping for the corners
    1868            0 :                 CollectCornerCoordinates(vCorner, *elem, u.domain()->position_accessor(), true);
    1869              : 
    1870              :         //      compute global integration points
    1871            0 :                 AveragePositions(globIP, &vCorner[0], numCo);
    1872              : 
    1873              :         //      get subset
    1874              :                 int theSI = si;
    1875            0 :                 if(si < 0) theSI = u.domain()->subset_handler()->get_subset_index(elem);
    1876              : 
    1877              :         //      get local solution if needed
    1878            0 :                 if(bNeedFct)
    1879              :                 {
    1880              :                 //      create storage
    1881              :                         LocalIndices ind;
    1882              :                         LocalVector locU;
    1883              : 
    1884              :                 //      get global indices
    1885              :                         u.indices(elem, ind);
    1886              : 
    1887              :                 //      adapt local algebra
    1888            0 :                         locU.resize(ind);
    1889              : 
    1890              :                 //      read local values of u
    1891            0 :                         GetLocalVector(locU, u);
    1892              : 
    1893              :                 //      compute data
    1894              :                         try{
    1895              :                                 (*spData)(value, globIP, time, theSI, elem,
    1896              :                                                         &vCorner[0], localIP, &locU);
    1897              :                         }
    1898            0 :                         UG_CATCH_THROW("VTK::write_cell_data_elementwise: Cannot evaluate data.");
    1899              :                 }
    1900              :                 else
    1901              :                 {
    1902              :                 //      compute data
    1903              :                         try{
    1904            0 :                                 (*spData)(value, globIP, time, theSI);
    1905              :                         }
    1906            0 :                         UG_CATCH_THROW("VTK::write_cell_data_elementwise: Cannot evaluate data.");
    1907              :                 }
    1908              : 
    1909              :         //      handle octahedral case separately by splitting into top and bottom pyramid with the same values
    1910              :                 if(ref_elem_type::REFERENCE_OBJECT_ID != ROID_OCTAHEDRON)
    1911              :                 {
    1912            0 :                         write_item_to_file(File, value);
    1913              :                 }
    1914              :                 else
    1915              :                 {
    1916            0 :                         write_item_to_file(File, value); // top pyramid
    1917            0 :                         write_item_to_file(File, value); // bottom pyramid
    1918              :                 }
    1919              :         }
    1920              : 
    1921            0 : }
    1922              : 
    1923              : 
    1924              : template <int TDim>
    1925              : template <typename TFunction, typename TData>
    1926            0 : void VTKOutput<TDim>::
    1927              : write_cell_data(VTKFileWriter& File, TFunction& u, number time,
    1928              :                  SmartPtr<UserData<TData, TDim> > spData,
    1929              :                  const int numCmp,
    1930              :                  const std::string& name,
    1931              :                  Grid& grid, const SubsetGroup& ssGrp, const int dim, const int numElem)
    1932              : {
    1933            0 :         spData->set_function_pattern(u.function_pattern());
    1934              : 
    1935              : //      write opening tag
    1936            0 :         File << VTKFileWriter::normal;
    1937            0 :         File << "        <DataArray type=\"Float32\" Name=\""<<name<<"\" "
    1938            0 :         "NumberOfComponents=\""<<numCmp<<"\" format="
    1939            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    1940              : 
    1941            0 :         int n = sizeof(float) * numElem * numCmp;
    1942            0 :         if(m_bBinary)
    1943            0 :                 File << VTKFileWriter::base64_binary << n;
    1944              : 
    1945              : //      switch dimension
    1946            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
    1947            0 :         switch(dim)
    1948              :         {
    1949            0 :                 case 1: write_cell_data_elementwise<RegularEdge,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1950            0 :                                 write_cell_data_elementwise<ConstrainingEdge,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1951            0 :                 case 2: write_cell_data_elementwise<Triangle,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1952            0 :                                 write_cell_data_elementwise<Quadrilateral,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1953            0 :                                 write_cell_data_elementwise<ConstrainingTriangle,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1954            0 :                                 write_cell_data_elementwise<ConstrainingQuadrilateral,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1955            0 :                 case 3: write_cell_data_elementwise<Tetrahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1956            0 :                                 write_cell_data_elementwise<Pyramid,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1957            0 :                                 write_cell_data_elementwise<Prism,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1958            0 :                                 write_cell_data_elementwise<Octahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]);
    1959            0 :                                 write_cell_data_elementwise<Hexahedron,TFunction,TData>(File, u, time, spData, grid, ssGrp[i]); break;
    1960            0 :                 default: UG_THROW("VTK::write_cell_data: Dimension " << dim <<
    1961              :                                         " is not supported.");
    1962              :         }
    1963              : 
    1964              : //      write closing tag
    1965            0 :         File << VTKFileWriter::normal;
    1966            0 :         File << "\n        </DataArray>\n";
    1967            0 : };
    1968              : 
    1969              : 
    1970              : template <int TDim>
    1971              : template <typename TElem, typename TFunction>
    1972            0 : void VTKOutput<TDim>::
    1973              : write_cell_values_elementwise(VTKFileWriter& File, TFunction& u,
    1974              :                                const std::vector<size_t>& vFct,
    1975              :                                Grid& grid, const int si)
    1976              : {
    1977              : //      get reference element
    1978              :         typedef typename reference_element_traits<TElem>::reference_element_type
    1979              :                                                                                                                                 ref_elem_type;
    1980              : 
    1981            0 :         static const ref_elem_type& refElem = Provider<ref_elem_type>::get();
    1982              :         static const ReferenceObjectID roid = ref_elem_type::REFERENCE_OBJECT_ID;
    1983              :         static const int dim = ref_elem_type::dim;
    1984              :         static const size_t numCo = ref_elem_type::numCorners;
    1985              : 
    1986              : //      index vector
    1987              :         std::vector<DoFIndex> vMultInd;
    1988              : 
    1989              : //      get iterators
    1990              :         typedef typename IteratorProvider<TFunction>::template traits<TElem>::const_iterator const_iterator;
    1991            0 :         const_iterator iterBegin = IteratorProvider<TFunction>::template begin<TElem>(u, si);
    1992            0 :         const_iterator iterEnd = IteratorProvider<TFunction>::template end<TElem>(u, si);
    1993              : 
    1994            0 :         if(m_bBinary)
    1995            0 :                 File << VTKFileWriter::base64_binary;
    1996              :         else
    1997            0 :                 File << VTKFileWriter::normal;
    1998              : 
    1999              :         MathVector<dim> localIP;
    2000            0 :         AveragePositions(localIP, refElem.corners(), numCo);
    2001              : 
    2002              : //      request for trial space
    2003              :         try{
    2004              : 
    2005              :         // avoid passing this code, since LocalShapeFunctionSet might not exist for RefElem-Type
    2006            0 :         if(iterBegin == iterEnd) return;
    2007              : 
    2008            0 :         std::vector<std::vector<number> > vvShape(vFct.size());
    2009            0 :         std::vector<size_t> vNsh(vFct.size());
    2010              : 
    2011            0 :         for(size_t f = 0; f < vFct.size(); ++f)
    2012              :         {
    2013            0 :                 const LFEID lfeID = u.local_finite_element_id(vFct[f]);
    2014              :                 const LocalShapeFunctionSet<dim>& lsfs
    2015              :                          = LocalFiniteElementProvider::get<dim>(roid, lfeID);
    2016              : 
    2017            0 :                 vNsh[f] = lsfs.num_sh();
    2018            0 :                 lsfs.shapes(vvShape[f], localIP);
    2019              :         }
    2020              : 
    2021              : //      loop all elements
    2022            0 :         for( ; iterBegin != iterEnd; ++iterBegin)
    2023              :         {
    2024              :         //      get element
    2025              :                 TElem *elem = *iterBegin;
    2026              : 
    2027              :         //      loop all components
    2028            0 :                 for(size_t f = 0; f < vFct.size(); ++f)
    2029              :                 {
    2030              :                 //      get multi index of vertex for the function
    2031            0 :                         if(u.dof_indices(elem, vFct[f], vMultInd) != vNsh[f])
    2032            0 :                                 UG_THROW("VTK:write_cell_values_elementwise: "
    2033              :                                                 "Number of shape functions for component "<<vFct[f]<<
    2034              :                                                 " does not match number of DoFs");
    2035              : 
    2036              :                         number ipVal = 0.0;
    2037            0 :                         for(size_t sh = 0; sh < vNsh[f]; ++sh)
    2038              :                         {
    2039            0 :                                 ipVal += DoFRef(u, vMultInd[sh]) * vvShape[f][sh];
    2040              :                         }
    2041              : 
    2042              :                 //      flush stream
    2043              :                         write_item_to_file(File, ipVal);
    2044              : 
    2045              :                 //      flush stream a second time in case of an octahedron as we handle it by splitting into a top and bottom pyramid
    2046              :                         if(roid == ROID_OCTAHEDRON)
    2047              :                                 write_item_to_file(File, ipVal); // bottom pyramid
    2048              :                 }
    2049              : 
    2050              :         //      fill with zeros up to 3d if vector type
    2051            0 :                 if(vFct.size() != 1){
    2052            0 :                         for(size_t i = vFct.size(); i < 3; ++i) {
    2053            0 :                                 write_item_to_file(File, 0.f);
    2054              : 
    2055              :                         //      flush stream a second time in case of an octahedron as we handle it by splitting into a top and bottom pyramid
    2056              :                                 if(roid == ROID_OCTAHEDRON)
    2057            0 :                                         write_item_to_file(File, 0.f); // bottom pyramid
    2058              :                         }
    2059              :                 }
    2060              :         }
    2061            0 :         }
    2062            0 :         UG_CATCH_THROW("VTK: Could not find Shape function Set.");
    2063              : 
    2064              : }
    2065              : 
    2066              : template <int TDim>
    2067              : template <typename TFunction>
    2068            0 : void VTKOutput<TDim>::
    2069              : write_cell_values(VTKFileWriter& File, TFunction& u,
    2070              :                    const std::vector<size_t>& vFct, const std::string& name,
    2071              :                    Grid& grid, const SubsetGroup& ssGrp, const int dim, const int numElem)
    2072              : {
    2073              : //      write opening tag
    2074            0 :         File << VTKFileWriter::normal;
    2075            0 :         File << "        <DataArray type=\"Float32\" Name=\""<<name<<"\" "
    2076            0 :         "NumberOfComponents=\""<<(vFct.size() == 1 ? 1 : 3)<<"\" format="
    2077            0 :                  <<       (m_bBinary ? "\"binary\"": "\"ascii\"") << ">\n";
    2078              : 
    2079            0 :         int n = sizeof(float) * numElem * (vFct.size() == 1 ? 1 : 3);
    2080            0 :         if(m_bBinary)
    2081            0 :                 File << VTKFileWriter::base64_binary << n;
    2082              : 
    2083              : //      switch dimension
    2084            0 :         for(size_t i = 0; i < ssGrp.size(); i++)
    2085            0 :         switch(dim)
    2086              :         {
    2087            0 :                 case 1: write_cell_values_elementwise<RegularEdge>(File, u, vFct, grid, ssGrp[i]);
    2088            0 :                                 write_cell_values_elementwise<ConstrainingEdge>(File, u, vFct, grid, ssGrp[i]); break;
    2089            0 :                 case 2: write_cell_values_elementwise<Triangle>(File, u, vFct, grid, ssGrp[i]);
    2090            0 :                                 write_cell_values_elementwise<Quadrilateral>(File, u, vFct, grid, ssGrp[i]);
    2091            0 :                                 write_cell_values_elementwise<ConstrainingTriangle>(File, u, vFct, grid, ssGrp[i]);
    2092            0 :                                 write_cell_values_elementwise<ConstrainingQuadrilateral>(File, u, vFct, grid, ssGrp[i]); break;
    2093            0 :                 case 3: write_cell_values_elementwise<Tetrahedron>(File, u, vFct, grid, ssGrp[i]);
    2094            0 :                                 write_cell_values_elementwise<Pyramid>(File, u, vFct, grid, ssGrp[i]);
    2095            0 :                                 write_cell_values_elementwise<Prism>(File, u, vFct, grid, ssGrp[i]);
    2096            0 :                                 write_cell_values_elementwise<Octahedron>(File, u, vFct, grid, ssGrp[i]);
    2097            0 :                                 write_cell_values_elementwise<Hexahedron>(File, u, vFct, grid, ssGrp[i]); break;
    2098            0 :                 default: UG_THROW("VTK::write_cell_values: Dimension " << dim <<
    2099              :                                         " is not supported.");
    2100              :         }
    2101              : 
    2102              : //      write closing tag
    2103            0 :         File << VTKFileWriter::normal;
    2104            0 :         File << "\n        </DataArray>\n";
    2105            0 : };
    2106              : 
    2107              : template <int TDim>
    2108              : template <typename TFunction>
    2109            0 : void VTKOutput<TDim>::
    2110              : write_cell_values_piece(VTKFileWriter& File, TFunction& u, number time, Grid& grid,
    2111              :                          const SubsetGroup& ssGrp, const int dim, const int numElem)
    2112              : {
    2113            0 :         if(!m_vSymbFct.empty()){
    2114            0 :                 for(std::map<std::string, std::vector<std::string> >::const_iterator iter =
    2115            0 :                                 m_vSymbFct.begin(); iter != m_vSymbFct.end(); ++iter){
    2116            0 :                         const std::vector<std::string>& symbNames = (*iter).second;
    2117            0 :                         const std::string& vtkName = (*iter).first;
    2118              : 
    2119              :                         bool bContinuous = true;
    2120            0 :                         for(size_t i = 0; i < symbNames.size(); ++i){
    2121              :                                 size_t fct = u.fct_id_by_name(symbNames[i].c_str());
    2122            0 :                                 if(!LocalFiniteElementProvider::continuous(u.local_finite_element_id(fct))){
    2123              :                                         bContinuous = false; break;
    2124              :                                 }
    2125              :                         }
    2126              : 
    2127            0 :                         if(!bContinuous){
    2128            0 :                                 m_vSymbFctElem[vtkName] = symbNames;
    2129              :                         }
    2130              :                 }
    2131              :         }
    2132              : 
    2133              : //      check if something to do
    2134            0 :         if(m_vSymbFctElem.empty() && m_vScalarElemData.empty() && m_vVectorElemData.empty())
    2135              :                 return;
    2136              : 
    2137              : //      write opening tag to indicate point data
    2138            0 :         File << VTKFileWriter::normal;
    2139            0 :         File << "      <CellData>\n";
    2140              : 
    2141              : //      loop all selected symbolic names
    2142            0 :         for(ComponentsIterator iter = m_vSymbFctElem.begin();
    2143            0 :                         iter != m_vSymbFctElem.end(); ++iter)
    2144              :         {
    2145              :         //      get symb function
    2146              :                 const std::vector<std::string>& symbNames = (*iter).second;
    2147            0 :                 const std::string& vtkName = (*iter).first;
    2148              : 
    2149              :         //      create function group
    2150            0 :                 std::vector<size_t> fctGrp(symbNames.size());
    2151            0 :                 for(size_t i = 0; i < symbNames.size(); ++i)
    2152            0 :                         fctGrp[i] = u.fct_id_by_name(symbNames[i].c_str());
    2153              : 
    2154              :         //      check that all functions are contained in subset
    2155              :                 bool bContained = true;
    2156            0 :                 for(size_t i = 0; i < fctGrp.size(); ++i)
    2157            0 :                         for(size_t j = 0; j < ssGrp.size(); ++j)
    2158            0 :                                 if(!u.is_def_in_subset(fctGrp[i], ssGrp[j]))
    2159              :                                         bContained = false;
    2160              : 
    2161            0 :                 if(!bContained) continue;
    2162              : 
    2163              :         //      write scalar value of this function
    2164              :                 try{
    2165            0 :                         write_cell_values(File, u, fctGrp, vtkName, grid, ssGrp, dim, numElem);
    2166              :                 }
    2167            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed write cell Values.");
    2168              :         }
    2169              : 
    2170              : //      loop all scalar data
    2171            0 :         for(ScalarDataIterator iter = m_vScalarElemData.begin();
    2172            0 :                         iter != m_vScalarElemData.end(); ++iter)
    2173              :         {
    2174              :         //      get symb function
    2175              :                 SmartPtr<UserData<number,TDim> > spData = (*iter).second;
    2176            0 :                 const std::string& vtkName = (*iter).first;
    2177              : 
    2178              :         //      write scalar value of this data
    2179              :                 try{
    2180              :                         write_cell_data<TFunction,number>
    2181            0 :                                                         (File, u, time, spData, 1, vtkName, grid, ssGrp, dim, numElem);
    2182              :                 }
    2183            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed to write cell scalar Data.");
    2184              :         }
    2185              : 
    2186              : //      loop all vector data
    2187            0 :         for(VectorDataIterator iter = m_vVectorElemData.begin();
    2188            0 :                         iter != m_vVectorElemData.end(); ++iter)
    2189              :         {
    2190              :         //      get symb function
    2191              :                 SmartPtr<UserData<MathVector<TDim>,TDim> > spData = (*iter).second;
    2192            0 :                 const std::string& vtkName =  (*iter).first;
    2193              : 
    2194              :         //      write scalar value of this data
    2195              :                 try{
    2196              :                         write_cell_data<TFunction,MathVector<TDim> >
    2197            0 :                                                         (File, u, time, spData, 3, vtkName, grid, ssGrp, dim, numElem);
    2198              :                 }
    2199            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed to write cell vector Data.");
    2200              :         }
    2201              : 
    2202              : //      loop all vector data
    2203            0 :         for(MatrixDataIterator iter = m_vMatrixElemData.begin();
    2204            0 :                         iter != m_vMatrixElemData.end(); ++iter)
    2205              :         {
    2206              :         //      get symb function
    2207              :                 SmartPtr<UserData<MathMatrix<TDim,TDim>,TDim> > spData = (*iter).second;
    2208            0 :                 const std::string& vtkName =  (*iter).first;
    2209              : 
    2210              :         //      write scalar value of this data
    2211              :                 try{
    2212              :                         write_cell_data<TFunction,MathMatrix<TDim,TDim> >
    2213            0 :                                                         (File, u, time, spData, 9, vtkName, grid, ssGrp, dim, numElem);
    2214              :                 }
    2215            0 :                 UG_CATCH_THROW("VTK::write_piece: Failed to write cell matrix Data.");
    2216              :         }
    2217              : 
    2218              : //      write closing tag
    2219            0 :         File << VTKFileWriter::normal;
    2220            0 :         File << "      </CellData>\n";
    2221              : }
    2222              : 
    2223              : ////////////////////////////////////////////////////////////////////////////////
    2224              : // Grouping Files
    2225              : ////////////////////////////////////////////////////////////////////////////////
    2226              : 
    2227              : template <int TDim>
    2228              : template <typename TFunction>
    2229              : void VTKOutput<TDim>::
    2230              : write_pvtu(TFunction& u, const std::string& filename,
    2231              :            int si, int step, number time)
    2232              : {
    2233              : #ifdef UG_PARALLEL
    2234              : //      File pointer
    2235              :         FILE* file;
    2236              : 
    2237              : //      file name
    2238              :         std::string name;
    2239              : 
    2240              : //      get and check number of procs (only for numProcs > 1 we write the pvtu)
    2241              :         int numProcs = pcl::NumProcs();
    2242              :         if(numProcs == 1) return;
    2243              : 
    2244              : //      check if this proc is output proc
    2245              :         bool isOutputProc = GetLogAssistant().is_output_process();
    2246              : 
    2247              : //      max subset
    2248              :         int maxSi = u.num_subsets() - 1;
    2249              : 
    2250              : //      only the master process writes this file
    2251              :         if (isOutputProc)
    2252              :         {
    2253              :         //      get name for *.pvtu file
    2254              :                 pvtu_filename(name, filename, si, maxSi, step);
    2255              : 
    2256              :         //      open file
    2257              :                 file = fopen(name.c_str(), "w");
    2258              :                 if (file == NULL)
    2259              :                         UG_THROW("VTKOutput: Cannot print to file.");
    2260              : 
    2261              :         //      Write to file
    2262              :                 fprintf(file, "<?xml version=\"1.0\"?>\n");
    2263              : 
    2264              :         //      Write comment
    2265              :                 write_comment_printf(file);
    2266              :         
    2267              :                 fprintf(file, "<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\">\n");
    2268              :                 fprintf(file, "  <Time timestep=\"%.17g\"/>\n", time);
    2269              :                 fprintf(file, "  <PUnstructuredGrid GhostLevel=\"0\">\n");
    2270              :                 fprintf(file, "    <PPoints>\n");
    2271              :                 fprintf(file, "      <PDataArray type=\"Float32\" NumberOfComponents=\"3\"/>\n");
    2272              :                 fprintf(file, "    </PPoints>\n");
    2273              : 
    2274              :         //      Node Data
    2275              :                 if(!m_vSymbFctNodal.empty() || !m_vScalarNodalData.empty() || !m_vVectorNodalData.empty())
    2276              :                 {
    2277              :                         fprintf(file, "    <PPointData>\n");
    2278              : //                      for(size_t sym = 0; sym < m_vSymbFctNodal.size(); ++sym)
    2279              :                         for(ComponentsIterator iter = m_vSymbFctNodal.begin();
    2280              :                                         iter != m_vSymbFctNodal.end(); ++iter)
    2281              :                         {
    2282              :                         //      get symb function
    2283              :                                 const std::vector<std::string>& symbNames = (*iter).second;
    2284              :                                 const std::string& vtkName = (*iter).first;
    2285              : 
    2286              :                         //      create function group
    2287              :                                 std::vector<size_t> fctGrp(symbNames.size());
    2288              :                                 for(size_t i = 0; i < symbNames.size(); ++i)
    2289              :                                         fctGrp[i] = u.fct_id_by_name(symbNames[i].c_str());
    2290              : 
    2291              :                         //      check that all functions are contained in subset
    2292              :                                 bool bContained = true;
    2293              :                                 for(size_t i = 0; i < fctGrp.size(); ++i)
    2294              :                                         if(!u.is_def_in_subset(fctGrp[i], si))
    2295              :                                                 bContained = false;
    2296              : 
    2297              :                                 if(!bContained) continue;
    2298              : 
    2299              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2300              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2301              :                                                           vtkName.c_str(), (fctGrp.size() == 1 ? 1 : 3));
    2302              :                         }
    2303              : 
    2304              :                 //      loop all scalar data
    2305              :                         for(ScalarDataIterator iter = m_vScalarNodalData.begin();
    2306              :                                         iter != m_vScalarNodalData.end(); ++iter)
    2307              :                         {
    2308              :                         //      get symb function
    2309              :                                 const std::string& vtkName = (*iter).first;
    2310              : 
    2311              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2312              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2313              :                                                           vtkName.c_str(), 1);
    2314              :                         }
    2315              : 
    2316              :                 //      loop all vector data
    2317              :                         for(VectorDataIterator iter = m_vVectorNodalData.begin();
    2318              :                                         iter != m_vVectorNodalData.end(); ++iter)
    2319              :                         {
    2320              :                         //      get symb function
    2321              :                                 const std::string& vtkName = (*iter).first;
    2322              : 
    2323              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2324              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2325              :                                                           vtkName.c_str(), 3);
    2326              :                         }
    2327              : 
    2328              :                 //      loop all matrix data
    2329              :                         for(MatrixDataIterator iter = m_vMatrixNodalData.begin();
    2330              :                                         iter != m_vMatrixNodalData.end(); ++iter)
    2331              :                         {
    2332              :                         //      get symb function
    2333              :                                 const std::string& vtkName = (*iter).first;
    2334              : 
    2335              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2336              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2337              :                                                           vtkName.c_str(), 9);
    2338              :                         }
    2339              :                         fprintf(file, "    </PPointData>\n");
    2340              :                 }
    2341              : 
    2342              :         //      Elem Data
    2343              :                 if(!m_vSymbFctElem.empty() || !m_vScalarElemData.empty() || !m_vVectorElemData.empty() || m_bWriteSubsetIndices || m_bWriteProcRanks) //TODO: cleanup
    2344              :                 {
    2345              :                         fprintf(file, "    <PCellData>\n");
    2346              : //                      for(size_t sym = 0; sym < m_vSymbFctElem.size(); ++sym)
    2347              :                         for(ComponentsIterator iter = m_vSymbFctElem.begin();
    2348              :                                         iter != m_vSymbFctElem.end(); ++iter)
    2349              :                         {
    2350              :                         //      get symb function
    2351              :                                 const std::vector<std::string>& symbNames = (*iter).second;//m_vSymbFctElem[sym].first;
    2352              :                                 const std::string& vtkName = (*iter).first;//m_vSymbFctElem[sym].second;
    2353              : 
    2354              :                         //      create function group
    2355              :                                 std::vector<size_t> fctGrp(symbNames.size());
    2356              :                                 for(size_t i = 0; i < symbNames.size(); ++i)
    2357              :                                         fctGrp[i] = u.fct_id_by_name(symbNames[i].c_str());
    2358              : 
    2359              :                         //      check that all functions are contained in subset
    2360              :                                 bool bContained = true;
    2361              :                                 for(size_t i = 0; i < fctGrp.size(); ++i)
    2362              :                                         if(!u.is_def_in_subset(fctGrp[i], si))
    2363              :                                                 bContained = false;
    2364              : 
    2365              :                                 if(!bContained) continue;
    2366              : 
    2367              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2368              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2369              :                                                           vtkName.c_str(), (fctGrp.size() == 1 ? 1 : 3));
    2370              :                         }
    2371              : 
    2372              :                 //      loop all scalar data
    2373              :                         for(ScalarDataIterator iter = m_vScalarElemData.begin();
    2374              :                                         iter != m_vScalarElemData.end(); ++iter)
    2375              :                         {
    2376              :                         //      get symb function
    2377              :                                 const std::string& vtkName = (*iter).first;
    2378              : 
    2379              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2380              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2381              :                                                           vtkName.c_str(), 1);
    2382              :                         }
    2383              : 
    2384              :  //TODO: cleanup!!
    2385              :                         if(m_bWriteSubsetIndices){
    2386              :                                 fprintf(file, "      <DataArray type=\"Int8\" Name=\"regions\" "
    2387              :                                                           "NumberOfComponents=\"1\"/>\n");
    2388              :                         }
    2389              :                         if(m_bWriteProcRanks){
    2390              :                                 fprintf(file, "      <DataArray type=\"Int8\" Name=\"proc_ranks\" "
    2391              :                                                           "NumberOfComponents=\"1\"/>\n");
    2392              :                         }
    2393              : 
    2394              :                 //      loop all vector data
    2395              :                         for(VectorDataIterator iter = m_vVectorElemData.begin();
    2396              :                                         iter != m_vVectorElemData.end(); ++iter)
    2397              :                         {
    2398              :                         //      get symb function
    2399              :                                 const std::string& vtkName = (*iter).first;
    2400              : 
    2401              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2402              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2403              :                                                           vtkName.c_str(), 3);
    2404              :                         }
    2405              : 
    2406              :                 //      loop all vector data
    2407              :                         for(MatrixDataIterator iter = m_vMatrixElemData.begin();
    2408              :                                         iter != m_vMatrixElemData.end(); ++iter)
    2409              :                         {
    2410              :                         //      get symb function
    2411              :                                 const std::string& vtkName = (*iter).first;
    2412              : 
    2413              :                                 fprintf(file, "      <PDataArray type=\"Float32\" Name=\"%s\" "
    2414              :                                                           "NumberOfComponents=\"%d\"/>\n",
    2415              :                                                           vtkName.c_str(), 9);
    2416              :                         }
    2417              :                         fprintf(file, "    </PCellData>\n");
    2418              :                 }
    2419              : 
    2420              :         //      include files from all procs
    2421              :                 for (int i = 0; i < numProcs; i++) {
    2422              :                         vtu_filename(name, filename, i, si, maxSi, step);
    2423              :                         name = FilenameWithoutPath(name);
    2424              :                         fprintf(file, "    <Piece Source=\"%s\"/>\n", name.c_str());
    2425              :                 }
    2426              : 
    2427              :         //      write closing tags
    2428              :                 fprintf(file, "  </PUnstructuredGrid>\n");
    2429              :                 fprintf(file, "</VTKFile>\n");
    2430              :                 fclose(file);
    2431              :         }
    2432              : 
    2433              :         PCL_DEBUG_BARRIER_ALL();
    2434              : #endif
    2435              : }
    2436              : 
    2437              : 
    2438              : template <int TDim>
    2439              : template <typename TFunction>
    2440            0 : void VTKOutput<TDim>::
    2441              : write_time_pvd(const char* filename, TFunction& u)
    2442              : {
    2443              : //      File
    2444              :         FILE* file;
    2445              : 
    2446              : //      filename
    2447              :         std::string name;
    2448              : 
    2449              : //      get some numbers
    2450            0 :         bool isOutputProc = GetLogAssistant().is_output_process();
    2451              :         int numProcs = 1;
    2452              : #ifdef UG_PARALLEL
    2453              :         numProcs = pcl::NumProcs();
    2454              : #endif
    2455              : 
    2456              : //      get time steps
    2457            0 :         std::vector<number>& vTimestep = m_mTimestep[filename];
    2458              : 
    2459              : //      change locale to ensure decimal . is really a .
    2460            0 :         char* oldLocale = setlocale (LC_ALL, NULL);
    2461            0 :         setlocale(LC_NUMERIC, "C");
    2462              : 
    2463            0 :         if (isOutputProc)
    2464              :         {
    2465              :         //      get file name
    2466            0 :                 pvd_filename(name, filename);
    2467              : 
    2468              :         //      open file
    2469            0 :                 file = fopen(name.c_str(), "w");
    2470            0 :                 if (file == NULL)
    2471            0 :                         UG_THROW("Cannot print to file.");
    2472              : 
    2473              :         //      Write to file
    2474              :                 fprintf(file, "<?xml version=\"1.0\"?>\n");
    2475              : 
    2476              :         //      Write comment
    2477            0 :                 write_comment_printf(file);
    2478              : 
    2479              :                 fprintf(file, "<VTKFile type=\"Collection\" version=\"0.1\">\n");
    2480              :                 fprintf(file, "  <Collection>\n");
    2481              : 
    2482              :         //      check functions
    2483              :                 bool bEverywhere = true;
    2484            0 :                 for(size_t fct = 0; fct < u.num_fct(); ++fct)
    2485              :                 {
    2486              :                 //      check if function is defined everywhere
    2487            0 :                         if(!u.is_def_everywhere(fct))
    2488              :                                 bEverywhere = false;
    2489              :                 }
    2490              : 
    2491              :         //      include files from all procs
    2492            0 :                 if(bEverywhere)
    2493              :                 {
    2494            0 :                         for(int step = 0; step < (int)vTimestep.size(); ++step)
    2495              :                         {
    2496            0 :                                 vtu_filename(name, filename, 0, -1, 0, step);
    2497              :                                 if(numProcs > 1) pvtu_filename(name, filename, -1, 0, step);
    2498              : 
    2499            0 :                                 name = FilenameWithoutPath(name);
    2500            0 :                                 fprintf(file, "  <DataSet timestep=\"%.17g\" part=\"%d\" file=\"%s\"/>\n",
    2501              :                                                         vTimestep[step], 0, name.c_str());
    2502              :                         }
    2503              :                 }
    2504              :                 else
    2505              :                 {
    2506            0 :                         for(int step = 0; step < (int)vTimestep.size(); ++step)
    2507            0 :                                 for(int si = 0; si < u.num_subsets(); ++si)
    2508              :                                 {
    2509            0 :                                         vtu_filename(name, filename, 0, si, u.num_subsets()-1, step);
    2510              :                                         if(numProcs > 1) pvtu_filename(name, filename, si, u.num_subsets()-1, step);
    2511              : 
    2512            0 :                                         name = FilenameWithoutPath(name);
    2513            0 :                                         fprintf(file, "  <DataSet timestep=\"%.17g\" part=\"%d\" file=\"%s\"/>\n",
    2514              :                                                         vTimestep[step], si, name.c_str());
    2515              :                                 }
    2516              :                 }
    2517              : 
    2518              :         //      close file
    2519              :                 fprintf(file, "  </Collection>\n");
    2520              :                 fprintf(file, "</VTKFile>\n");
    2521            0 :                 fclose(file);
    2522              :         }
    2523              : 
    2524              : // restore old locale
    2525            0 :         setlocale(LC_NUMERIC, oldLocale);
    2526              : 
    2527              :         #ifdef UG_PARALLEL
    2528              :                 PCL_DEBUG_BARRIER_ALL();
    2529              :         #endif
    2530            0 : }
    2531              : 
    2532              : 
    2533              : template <int TDim>
    2534              : template <typename TFunction>
    2535            0 : void VTKOutput<TDim>::
    2536              : write_time_processwise_pvd(const char* filename, TFunction& u)
    2537              : {
    2538              : //      File
    2539              :         FILE* file;
    2540              : 
    2541              : //      filename
    2542              :         std::string name;
    2543              : 
    2544              : //      get some numbers
    2545            0 :         bool isOutputProc = GetLogAssistant().is_output_process();
    2546              :         int numProcs = 1;
    2547              : #ifdef UG_PARALLEL
    2548              :         numProcs = pcl::NumProcs();
    2549              : #endif
    2550              : 
    2551              : //      get time steps
    2552            0 :         std::vector<number>& vTimestep = m_mTimestep[filename];
    2553              : 
    2554              : //      change locale to ensure decimal . is really a .
    2555            0 :         char* oldLocale = setlocale (LC_ALL, NULL);
    2556            0 :         setlocale(LC_NUMERIC, "C");
    2557              : 
    2558              :         if (isOutputProc && numProcs > 1)
    2559              :         {
    2560              :         //      adjust filename
    2561              :                 std::string procName = filename;
    2562              :                 procName.append("_processwise");
    2563              :                 pvd_filename(name, procName);
    2564              : 
    2565              :         //      open file
    2566              :                 file = fopen(name.c_str(), "w");
    2567              :                 if (file == NULL)
    2568              :                         UG_THROW("Cannot print to file.");
    2569              : 
    2570              :         //      Write to file
    2571              :                 fprintf(file, "<?xml version=\"1.0\"?>\n");
    2572              : 
    2573              :         //      Write comment
    2574              :                 write_comment_printf(file);
    2575              : 
    2576              :                 fprintf(file, "<VTKFile type=\"Collection\" version=\"0.1\">\n");
    2577              :                 fprintf(file, "  <Collection>\n");
    2578              : 
    2579              :         //      include files from all procs
    2580              :                 for(int step = 0; step < (int)vTimestep.size(); ++step)
    2581              :                         for (int rank = 0; rank < numProcs; rank++)
    2582              :                                 for(int si = 0; si < u.num_subsets(); ++si)
    2583              :                                 {
    2584              :                                         vtu_filename(name, filename, rank, si, u.num_subsets()-1, step);
    2585              :                                         if(numProcs > 1) pvtu_filename(name, filename, si, u.num_subsets()-1, step);
    2586              : 
    2587              :                                         name = FilenameWithoutPath(name);
    2588              :                                         fprintf(file, "  <DataSet timestep=\"%.17g\" part=\"%d\" file=\"%s\"/>\n",
    2589              :                                                 vTimestep[step], rank, name.c_str());
    2590              :                                 }
    2591              : 
    2592              :         //      end file
    2593              :                 fprintf(file, "  </Collection>\n");
    2594              :                 fprintf(file, "</VTKFile>\n");
    2595              :                 fclose(file);
    2596              :         }
    2597              : 
    2598              : // restore old locale
    2599            0 :         setlocale(LC_NUMERIC, oldLocale);
    2600              : 
    2601              :         #ifdef UG_PARALLEL
    2602              :                 PCL_DEBUG_BARRIER_ALL();
    2603              :         #endif
    2604            0 : }
    2605              : 
    2606              : 
    2607              : 
    2608              : template <int TDim>
    2609              : template <typename TFunction>
    2610            0 : void VTKOutput<TDim>::
    2611              : write_time_pvd_subset(const char* filename, TFunction& u, int si)
    2612              : {
    2613              : //      File
    2614              :         FILE* file;
    2615              : 
    2616              : //      filename
    2617              :         std::string name;
    2618              : 
    2619              : //      get some numbers
    2620            0 :         bool isOutputProc = GetLogAssistant().is_output_process();
    2621              :         int numProcs = 1;
    2622              : #ifdef UG_PARALLEL
    2623              :         numProcs = pcl::NumProcs();
    2624              : #endif
    2625              : 
    2626              : //      get time steps
    2627            0 :         std::vector<number>& vTimestep = m_mTimestep[filename];
    2628              : 
    2629              : //      change locale to ensure decimal . is really a .
    2630            0 :         char* oldLocale = setlocale (LC_ALL, NULL);
    2631            0 :         setlocale(LC_NUMERIC, "C");
    2632              : 
    2633            0 :         if (isOutputProc)
    2634              :         {
    2635              :         //      get file name
    2636            0 :                 pvd_filename(name, filename);
    2637              : 
    2638              :         //      open file
    2639            0 :                 file = fopen(name.c_str(), "w");
    2640            0 :                 if (file == NULL)
    2641            0 :                         UG_THROW("Cannot print to file.");
    2642              : 
    2643              :         //      Write to file
    2644              :                 fprintf(file, "<?xml version=\"1.0\"?>\n");
    2645              : 
    2646              :         //      Write comment
    2647            0 :                 write_comment_printf(file);
    2648              : 
    2649              :                 fprintf(file, "<VTKFile type=\"Collection\" version=\"0.1\">\n");
    2650              :                 fprintf(file, "  <Collection>\n");
    2651              : 
    2652              :         //      include files from all procs
    2653            0 :                 for(int step = 0; step < (int)vTimestep.size(); ++step)
    2654              :                 {
    2655            0 :                         vtu_filename(name, filename, 0, si, u.num_subsets()-1, step);
    2656              :                         if(numProcs > 1) pvtu_filename(name, filename, si, u.num_subsets()-1, step);
    2657              : 
    2658            0 :                         name = FilenameWithoutPath(name);
    2659            0 :                         fprintf(file, "  <DataSet timestep=\"%g\" part=\"%d\" file=\"%s\"/>\n",
    2660              :                                                 vTimestep[step], si, name.c_str());
    2661              :                 }
    2662              : 
    2663              :         //      close file
    2664              :                 fprintf(file, "  </Collection>\n");
    2665              :                 fprintf(file, "</VTKFile>\n");
    2666            0 :                 fclose(file);
    2667              :         }
    2668              : 
    2669              : // restore old locale
    2670            0 :         setlocale(LC_NUMERIC, oldLocale);
    2671              : 
    2672              :         #ifdef UG_PARALLEL
    2673              :                 PCL_DEBUG_BARRIER_ALL();
    2674              :         #endif
    2675            0 : }
    2676              : 
    2677              : }
    2678              : 
    2679              : 
        

Generated by: LCOV version 2.0-1