LCOV - code coverage report
Current view: top level - ugbase/lib_disc/function_spaces - grid_function_util.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 369 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 610 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              : #ifndef __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_UTIL__
      34              : #define __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_UTIL__
      35              : 
      36              : #include <vector>
      37              : #include <string>
      38              : #include <cmath>  // for isinf, isnan
      39              : #include <boost/function.hpp>
      40              : 
      41              : 
      42              : #include "common/util/file_util.h"
      43              : 
      44              : #include "lib_algebra/cpu_algebra/sparsematrix_print.h"
      45              : #include "lib_algebra/operator/interface/matrix_operator.h"
      46              : #include "lib_algebra/operator/debug_writer.h"
      47              : #include "lib_algebra/operator/vector_writer.h"
      48              : #include "lib_algebra/common/matrixio/matrix_io_mtx.h"
      49              : #include "lib_algebra/common/connection_viewer_output.h"
      50              : #include "lib_algebra/common/csv_gnuplot_output.h"
      51              : #include "lib_disc/io/vtkoutput.h"
      52              : #include "lib_disc/spatial_disc/constraints/constraint_interface.h"
      53              : #include "lib_disc/dof_manager/dof_distribution.h"
      54              : #include "lib_disc/spatial_disc/user_data/user_data.h"
      55              : #include "lib_disc/common/groups_util.h"
      56              : #include "lib_disc/common/geometry_util.h"
      57              : #include "lib_disc/function_spaces/integrate.h"
      58              : #include "lib_grid/algorithms/debug_util.h"  // for ElementDebugInfo
      59              : #include "lib_grid/tools/periodic_boundary_manager.h"
      60              : 
      61              : #include "grid_function.h"
      62              : #include "dof_position_util.h"
      63              : 
      64              : #ifdef UG_PARALLEL
      65              : #include "pcl/pcl.h"
      66              : #endif
      67              : 
      68              : namespace ug {
      69              : 
      70              : #ifndef isnan
      71              : using boost::math::isnan;
      72              : #endif
      73              : 
      74              : #ifndef isinf
      75              : using boost::math::isinf;
      76              : #endif
      77              : 
      78              : 
      79              : template <typename TBaseElem, typename TGridFunction>
      80            0 : static void ScaleGFOnElems
      81              : (
      82              :         ConstSmartPtr<DoFDistribution> dd,
      83              :         SmartPtr<TGridFunction> vecOut,
      84              :         ConstSmartPtr<TGridFunction> vecIn,
      85              :         const std::vector<number>& vScale
      86              : )
      87              : {
      88              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
      89              :         std::vector<DoFIndex> vInd;
      90              : 
      91              :         try
      92              :         {
      93              :                 // iterate all elements (including SHADOW_RIM_COPY!)
      94            0 :                 iter = dd->template begin<TBaseElem>(SurfaceView::ALL);
      95            0 :                 iterEnd = dd->template end<TBaseElem>(SurfaceView::ALL);
      96            0 :                 for (; iter != iterEnd; ++iter)
      97              :                 {
      98            0 :                         for (size_t fi = 0; fi < dd->num_fct(); ++fi)
      99              :                         {
     100            0 :                                 size_t nInd = dd->inner_dof_indices(*iter, fi, vInd);
     101              : 
     102              :                                 // remember multi indices
     103            0 :                                 for (size_t dof = 0; dof < nInd; ++dof)
     104            0 :                                         DoFRef(*vecOut, vInd[dof]) = vScale[fi] * DoFRef(*vecIn, vInd[dof]);
     105              :                         }
     106              :                 }
     107              :         }
     108            0 :         UG_CATCH_THROW("Error while scaling vector.")
     109            0 : }
     110              : 
     111              : 
     112              : /**
     113              :  * \brief Scales all functions contained in a grid function.
     114              :  *
     115              :  *      Each function has a separate scaling factor.
     116              :  *
     117              :  * \param scaledVecOut    the scaled grid function (output)
     118              :  * \param vecIn           the original grid function (input)
     119              :  * \param scalingFactors  vector of scales for each of the composite functions
     120              :  */
     121              : template <typename TGridFunction>
     122            0 : void ScaleGF
     123              : (
     124              :         SmartPtr<TGridFunction> scaledVecOut,
     125              :         ConstSmartPtr<TGridFunction> vecIn,
     126              :         const std::vector<number>& scalingFactors
     127              : )
     128              : {
     129              :         // check that the correct numbers of scaling factors are given
     130              :         size_t n = scalingFactors.size();
     131            0 :         UG_COND_THROW(n != vecIn->num_fct(), "Number of scaling factors (" << n << ") "
     132              :                         "does not match number of functions given in dimless vector (" << vecIn->num_fct() << ").");
     133              : 
     134              :         // check that input and output vectors have the same number of components and dofs
     135            0 :         UG_COND_THROW(n != scaledVecOut->num_fct(), "Input and output vectors do not have "
     136              :                         "the same number of functions (" << n << " vs. " << scaledVecOut->num_fct() << ").");
     137            0 :         for (size_t fct = 0; fct < n; ++fct)
     138              :         {
     139            0 :                 UG_COND_THROW(vecIn->num_dofs(fct) != scaledVecOut->num_dofs(fct),
     140              :                                 "Input and output vectors do not have the same number of DoFs for function " << fct
     141              :                                 << " (" << vecIn->num_dofs(fct) << " vs. " << scaledVecOut->num_dofs(fct) << ").");
     142              :         }
     143              : 
     144              :         ConstSmartPtr<DoFDistribution> dd = vecIn->dof_distribution();
     145              : 
     146            0 :         if (dd->max_dofs(VERTEX))
     147            0 :                 ScaleGFOnElems<Vertex, TGridFunction>(dd, scaledVecOut, vecIn, scalingFactors);
     148            0 :         if (dd->max_dofs(EDGE))
     149            0 :                 ScaleGFOnElems<Edge, TGridFunction>(dd, scaledVecOut, vecIn, scalingFactors);
     150            0 :         if (dd->max_dofs(FACE))
     151            0 :                 ScaleGFOnElems<Face, TGridFunction>(dd, scaledVecOut, vecIn, scalingFactors);
     152            0 :         if (dd->max_dofs(VOLUME))
     153            0 :                 ScaleGFOnElems<Volume, TGridFunction>(dd, scaledVecOut, vecIn, scalingFactors);
     154            0 : }
     155              : 
     156              : 
     157              : 
     158              : 
     159              : ////////////////////////////////////////////////////////////////////////////////
     160              : //      AverageComponent
     161              : ////////////////////////////////////////////////////////////////////////////////
     162              : 
     163              : /**
     164              :  * Subtracts a given value from all DoFs of a given grid function associated with
     165              :  * a given element type.
     166              :  *
     167              :  * \tparam TGridFunction        grid function type
     168              :  * \tparam TBaseElem            type of the elements the DoFs are associated with
     169              :  */
     170              : template<typename TGridFunction, typename TBaseElem>
     171            0 : void SubtractValueFromComponent(SmartPtr<TGridFunction> spGF, size_t fct, number sub)
     172              : {
     173              :         typedef TGridFunction GF;
     174              :         typedef typename GF::template traits<TBaseElem>::const_iterator iter_type;
     175              : 
     176              :         iter_type iter = spGF->template begin<TBaseElem>();
     177              :         iter_type iterEnd = spGF->template end<TBaseElem>();
     178              : 
     179            0 :         PeriodicBoundaryManager* pbm = spGF->domain()->grid()->periodic_boundary_manager();
     180              : 
     181              : //  loop elems
     182              :         std::vector<DoFIndex> vMultInd;
     183            0 :         for(; iter != iterEnd; ++iter)
     184              :         {
     185              :         //      get element
     186              :                 TBaseElem* elem = *iter;
     187              : 
     188              :         //      skip periodic ghosts
     189            0 :                 if (pbm && pbm->is_slave(elem)) continue;
     190              : 
     191              :         //  get global indices
     192              :                 spGF->inner_dof_indices(elem, fct, vMultInd);
     193              : 
     194              :         //      sum up value
     195            0 :                 for(size_t i = 0; i < vMultInd.size(); ++i)
     196              :                 {
     197            0 :                         DoFRef(*spGF, vMultInd[i]) -= sub;
     198              :                 }
     199              :         }
     200            0 : }
     201              : 
     202              : /**
     203              :  * Subtracts the average of a given grid function (computed by taking into account
     204              :  * the shape functions), shifted by the value of 'mean', from all the DoFs of this
     205              :  * grid function. Typically, it should result in a grid function with the average
     206              :  * equal to 'mean'.
     207              :  *
     208              :  * \remark Note that mean is not the desired average but the one multiplied by the area of the domain.
     209              :  *
     210              :  * \tparam TGridFunction        type of the grid function
     211              :  */
     212              : template<typename TGridFunction>
     213            0 : void AdjustMeanValue
     214              : (
     215              :         SmartPtr<TGridFunction> spGF, ///< the grid function
     216              :         const std::vector<std::string>& vCmp, ///< the component to adjust the average for
     217              :         number mean ///< the desired mean value
     218              : )
     219              : {
     220              :         typedef TGridFunction GF;
     221              :         PROFILE_FUNC_GROUP("gmg");
     222              : 
     223            0 :         if(vCmp.empty())
     224            0 :                 return;
     225              : 
     226            0 :         if(spGF.invalid())
     227            0 :                 UG_THROW("AverageComponent: expects a valid GridFunction.");
     228              : 
     229              :         ConstSmartPtr<DoFDistributionInfo> ddinfo =
     230            0 :                                                                 spGF->approx_space()->dof_distribution_info();
     231              : 
     232              : //      compute integral of components
     233            0 :         const number area = Integral(1.0, spGF);
     234            0 :         std::vector<number> vIntegral(vCmp.size(), 0.0);
     235            0 :         for(size_t f = 0; f < vCmp.size(); f++){
     236              :                 const size_t fct = spGF->fct_id_by_name(vCmp[f].c_str());
     237            0 :                 vIntegral[f] = Integral(spGF, vCmp[f].c_str(), NULL, ddinfo->lfeid(fct).order());
     238              :         }
     239              : 
     240              : //      subtract value
     241            0 :         for(size_t f = 0; f < vCmp.size(); f++)
     242              :         {
     243            0 :                 const number sub = (vIntegral[f] - mean) / area;
     244              :                 const size_t fct = spGF->fct_id_by_name(vCmp[f].c_str());
     245              : 
     246            0 :                 if(ddinfo->max_fct_dofs(fct, VERTEX)) SubtractValueFromComponent<GF, Vertex>(spGF, fct, sub);
     247            0 :                 if(ddinfo->max_fct_dofs(fct, EDGE)) SubtractValueFromComponent<GF, Edge>(spGF, fct, sub);
     248            0 :                 if(ddinfo->max_fct_dofs(fct, FACE)) SubtractValueFromComponent<GF, Face>(spGF, fct, sub);
     249            0 :                 if(ddinfo->max_fct_dofs(fct, VOLUME)) SubtractValueFromComponent<GF, Volume>(spGF, fct, sub);
     250              :         }
     251            0 : }
     252              : 
     253              : /**
     254              :  * Subtracts the average of a given grid function (computed by taking into account
     255              :  * the shape functions) from all the DoFs of this grid function. Typically, it
     256              :  * should result in a grid function with the zero average.
     257              :  *
     258              :  * \tparam TGridFunction        type of the grid function
     259              :  */
     260              : template<typename TGridFunction>
     261            0 : void AdjustMeanValue(SmartPtr<TGridFunction> spGF, const std::vector<std::string>& vCmp)
     262              : {
     263            0 :         AdjustMeanValue(spGF, vCmp, 0.0);
     264            0 : }
     265              : 
     266              : /**
     267              :  * Subtracts the average of a given grid function (computed by taking into account
     268              :  * the shape functions) from all the DoFs of this grid function. Typically, it
     269              :  * should result in a grid function with the zero average.
     270              :  *
     271              :  * \tparam TGridFunction        type of the grid function
     272              :  */
     273              : template<typename TGridFunction>
     274            0 : void AdjustMeanValue(SmartPtr<TGridFunction> spGF, const std::string& fcts)
     275              : {
     276            0 :         AdjustMeanValue(spGF, TokenizeTrimString(fcts), 0.0);
     277            0 : }
     278              : 
     279              : /**
     280              :  * Subtracts the average of a given grid function (computed by taking into account
     281              :  * the shape functions), shifted by the value of 'mean', from all the DoFs of this
     282              :  * grid function. Typically, it should result in a grid function with the average
     283              :  * equal to 'mean'.
     284              :  *
     285              :  * \remark Note that mean is not the desired average but the one multiplied by the area of the domain.
     286              :  *
     287              :  * \tparam TGridFunction        type of the grid function
     288              :  */
     289              : template<typename TGridFunction>
     290            0 : void AdjustMeanValue(SmartPtr<TGridFunction> spGF, const std::string& fcts, number mean)
     291              : {
     292            0 :         AdjustMeanValue(spGF, TokenizeTrimString(fcts), mean);
     293            0 : }
     294              : 
     295              : ////////////////////////////////////////////////////////////////////////////////
     296              : //      Summing up components
     297              : ////////////////////////////////////////////////////////////////////////////////
     298              : 
     299              : /**
     300              :  * Sums values of a grid function at all given elements (like vertices)
     301              :  *
     302              :  * \tparam TGridFunction        the grid function type
     303              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     304              :  */
     305              : template <typename TGridFunction, typename TBaseElem>
     306            0 : number SumGFValuesAt
     307              : (
     308              :         TGridFunction * u, ///< the grid function
     309              :         size_t fct ///< index of the function
     310              : )
     311              : {
     312              :         typedef typename TGridFunction::template traits<TBaseElem>::const_iterator t_elem_iter;
     313              :         
     314              :         std::vector<DoFIndex> ind;
     315              :         number sum (1);
     316              :         
     317              :         sum = 0;
     318              : //      Loop the elements in the subset
     319            0 :         for (t_elem_iter vi = u->template begin<TBaseElem> ();
     320            0 :                                 vi != u->template end<TBaseElem> (); ++vi)
     321              :         {
     322              :                 TBaseElem * vert = *vi;
     323              :                 
     324              :         //      indices at this element
     325              :                 u->inner_dof_indices (vert, fct, ind);
     326              :                 
     327            0 :                 if (ind.size () != 1)
     328            0 :                         UG_THROW ("SumGFValuesAt: The function must be scalar!");
     329              :         
     330              :         //      add the contribution
     331            0 :                 sum += DoFRef (*u, ind [0]);
     332              :         }
     333              :         
     334              : #ifdef UG_PARALLEL
     335              :         pcl::ProcessCommunicator procComm;
     336              :         sum = procComm.allreduce (sum, PCL_RO_SUM);
     337              : #endif
     338              :         
     339            0 :         return sum;
     340              : }
     341              : 
     342              : /**
     343              :  * Sums values of a grid function at all given elements (like vertices).
     344              :  *
     345              :  * This version takes symbolic data.
     346              :  *
     347              :  * \tparam TGridFunction        the grid function type
     348              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     349              :  */
     350              : template <typename TGridFunction, typename TBaseElem>
     351            0 : number SumGFValuesAt
     352              : (
     353              :         TGridFunction * u, ///< the grid function
     354              :         const char * fct_names ///< index of the function
     355              : )
     356              : {
     357              : //      Get the function index
     358              :         std::vector<std::string> vfctNames;
     359            0 :         TokenizeString (fct_names, vfctNames);
     360            0 :         if (vfctNames.size () != 1)
     361            0 :                 UG_THROW ("SumGFValuesAt: Exactly one function name must be specified.");
     362            0 :         FunctionGroup fctGroup (u->function_pattern ());
     363            0 :         fctGroup.add (vfctNames [0]);
     364              : 
     365              : //      Compute the sum
     366            0 :         return SumGFValuesAt<TGridFunction, TBaseElem> (u, fctGroup[0]);
     367            0 : }
     368              : 
     369              : /**
     370              :  * Sums values of a grid function at given elements (like vertices) in given subsets
     371              :  *
     372              :  * \tparam TGridFunction        the grid function type
     373              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     374              :  */
     375              : template <typename TGridFunction, typename TBaseElem>
     376            0 : number SumGFValuesAt
     377              : (
     378              :         TGridFunction * u, ///< the grid function
     379              :         size_t fct, ///< index of the function
     380              :         SubsetGroup & ssGroup ///< the subsets
     381              : )
     382              : {
     383              :         typedef typename TGridFunction::template traits<TBaseElem>::const_iterator t_elem_iter;
     384              :         
     385              :         std::vector<DoFIndex> ind;
     386              :         number sum (1);
     387              :         
     388              : //      Loop the selected subsets
     389              :         sum = 0;
     390            0 :         for (size_t i = 0; i < ssGroup.size (); i++)
     391              :         {
     392              :                 int ssi = ssGroup [i];
     393              :                 
     394              :         //      Loop the elements in the subset
     395            0 :                 for (t_elem_iter vi = u->template begin<TBaseElem> (ssi);
     396            0 :                                         vi != u->template end<TBaseElem> (ssi); ++vi)
     397              :                 {
     398              :                     TBaseElem * vert = *vi;
     399              :                     
     400              :                 //      indices at this element
     401              :                         u->inner_dof_indices (vert, fct, ind);
     402              :                         
     403            0 :                         if (ind.size () != 1)
     404            0 :                                 UG_THROW ("SumGFValuesAt: The function must be scalar!");
     405              :                 
     406              :                 //      add the contribution
     407            0 :                         sum += DoFRef (*u, ind [0]);
     408              :                 }
     409              :         }
     410              :         
     411              : #ifdef UG_PARALLEL
     412              :         pcl::ProcessCommunicator procComm;
     413              :         sum = procComm.allreduce (sum, PCL_RO_SUM);
     414              : #endif
     415              :         
     416            0 :         return sum;
     417              : }
     418              : 
     419              : /**
     420              :  * Sums values of a grid function at given elements (like vertices) in given subsets.
     421              :  *
     422              :  * This version takes symbolic data.
     423              :  *
     424              :  * \tparam TGridFunction        the grid function type
     425              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     426              :  */
     427              : template <typename TGridFunction, typename TBaseElem>
     428            0 : number SumGFValuesAt
     429              : (
     430              :         TGridFunction * u, ///< the grid function
     431              :         const char * fct_names, ///< index of the function
     432              :         const char * subset_names ///< the subsets
     433              : )
     434              : {
     435              : //      Get the function index
     436              :         std::vector<std::string> vfctNames;
     437            0 :         TokenizeString (fct_names, vfctNames);
     438            0 :         if (vfctNames.size () != 1)
     439            0 :                 UG_THROW ("SumGFValuesAt: Exactly one function name must be specified.");
     440            0 :         FunctionGroup fctGroup (u->function_pattern ());
     441            0 :         fctGroup.add (vfctNames [0]);
     442              : 
     443              : //      Get the subset indices
     444              :         std::vector<std::string> vssNames;
     445            0 :         TokenizeString (subset_names, vssNames);
     446            0 :         SubsetGroup ssGroup (u->domain()->subset_handler ());
     447            0 :         ssGroup.add (vssNames);
     448              :         
     449              : //      Compute the sum
     450            0 :         return SumGFValuesAt<TGridFunction, TBaseElem> (u, fctGroup[0], ssGroup);
     451            0 : }
     452              : 
     453              : ////////////////////////////////////////////////////////////////////////////////
     454              : //      Checking components for nan and inf
     455              : ////////////////////////////////////////////////////////////////////////////////
     456              : 
     457              : /**
     458              :  * Checks values of a grid function at given elements (like vertices) for nan and inf
     459              :  *
     460              :  * \tparam TGridFunction        the grid function type
     461              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     462              :  */
     463              : template <typename TGridFunction, typename TBaseElem>
     464            0 : bool CheckGFforNaN
     465              : (
     466              :         const TGridFunction * u, ///< the grid function
     467              :         size_t fct ///< index of the function
     468              : )
     469              : {
     470              :         typedef typename TGridFunction::template traits<TBaseElem>::const_iterator t_elem_iter;
     471              :         
     472              :         std::vector<DoFIndex> ind;
     473              :         
     474              : //      Loop the elements in the subset
     475            0 :         for (t_elem_iter vi = u->template begin<TBaseElem> ();
     476            0 :                                 vi != u->template end<TBaseElem> (); ++vi)
     477              :         {
     478              :                 TBaseElem * vert = *vi;
     479              :                 
     480              :         //      indices at this element
     481              :                 u->inner_dof_indices (vert, fct, ind);
     482              :                 
     483            0 :                 if (ind.size () != 1)
     484            0 :                         UG_THROW ("CheckGFforNaN: The function must be scalar!");
     485              :         
     486              :         //      check the value
     487            0 :                 number value = DoFRef (*u, ind [0]);
     488            0 :                 if (isnan (value))
     489              :                 {
     490            0 :                         int si = u->domain()->subset_handler()->get_subset_index (vert);
     491            0 :                         UG_LOG ("nan at index " << ind [0] << ", grid data idx " << vert->grid_data_index ());
     492            0 :                         if (si >= 0)
     493            0 :                                 UG_LOG (", subset " << u->domain()->subset_handler()->get_subset_name (si))
     494            0 :                         UG_LOG ('\n');
     495            0 :                         return true;
     496              :                 }
     497            0 :                 if (isinf (value))
     498              :                 {
     499            0 :                         int si = u->domain()->subset_handler()->get_subset_index (vert);
     500            0 :                         UG_LOG ("inf at index " << ind [0] << ", grid data idx " << vert->grid_data_index ());
     501            0 :                         if (si >= 0)
     502            0 :                                 UG_LOG (", subset " << u->domain()->subset_handler()->get_subset_name (si))
     503            0 :                         UG_LOG ('\n');
     504              :                         return true;
     505              :                 }
     506              :         }
     507              :         
     508            0 :         return false;
     509              : }
     510              : 
     511              : /**
     512              :  * Checks values of a grid function at given elements (like vertices) for nan and inf
     513              :  *
     514              :  * This version takes symbolic data.
     515              :  *
     516              :  * \tparam TGridFunction        the grid function type
     517              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     518              :  */
     519              : template <typename TGridFunction, typename TBaseElem>
     520            0 : bool CheckGFforNaN
     521              : (
     522              :         const TGridFunction * u, ///< the grid function
     523              :         const char * fct_names ///< names of the functions
     524              : )
     525              : {
     526              : //      Get the function index
     527              :         std::vector<std::string> vfctNames;
     528            0 :         TokenizeString (fct_names, vfctNames);
     529            0 :         FunctionGroup fctGroup (u->function_pattern ());
     530            0 :         for (size_t i = 0; i < vfctNames.size (); i++)
     531            0 :                 fctGroup.add (vfctNames [i]);
     532              : 
     533              : //      Check the functions
     534              :         bool result = false;
     535            0 :         for (size_t i = 0; i < vfctNames.size (); i++)
     536              :         {
     537              :                 UG_LOG ("Checking " << vfctNames[i] << " ... ");
     538            0 :                 if (CheckGFforNaN<TGridFunction, TBaseElem> (u, fctGroup[i]))
     539              :                         result = true;
     540              :                 else
     541              :                         UG_LOG ("OK\n");
     542              :         }
     543            0 :         return result;
     544            0 : }
     545              : 
     546              : /**
     547              :  * Checks values of a grid function at given elements (like vertices) for nan and inf
     548              :  *
     549              :  * This version takes a function group.
     550              :  *
     551              :  * \tparam TGridFunction        the grid function type
     552              :  * \tparam TBaseElem            the given element type (like 'Vertex')
     553              :  */
     554              : template <typename TGridFunction, typename TBaseElem>
     555              : bool CheckGFforNaN
     556              : (
     557              :         const TGridFunction * u, ///< the grid function
     558              :         const FunctionGroup & fctGroup ///< names of the functions
     559              : )
     560              : {
     561              : //      Check the functions
     562              :         bool result = false;
     563              :         for (size_t i = 0; i < fctGroup.size (); i++)
     564              :         {
     565              :                 UG_LOG ("Checking fct #" << i << " ... ");
     566              :                 if (CheckGFforNaN<TGridFunction, TBaseElem> (u, fctGroup[i]))
     567              :                         result = true;
     568              :                 else
     569              :                         UG_LOG ("OK\n");
     570              :         }
     571              :         return result;
     572              : }
     573              : 
     574              : // //////////////////////////////////////////////////////////////////////////////
     575              : //      Check values are within bounds
     576              : // //////////////////////////////////////////////////////////////////////////////
     577              : template <typename TGridFunction, typename TBaseElem>
     578            0 : bool CheckGFValuesWithinBounds
     579              : (
     580              :         ConstSmartPtr<TGridFunction> u, ///< the grid function
     581              :         size_t cmp,  ///< the function component to be checked
     582              :         number lowerBnd,
     583              :         number upperBnd
     584              : )
     585              : {
     586              :         typedef typename TGridFunction::template traits<TBaseElem>::const_iterator elem_it;
     587              : 
     588              :         bool ret = true;
     589              : 
     590              :         // loop the elements in the subset
     591              :         std::vector<DoFIndex> vDI;
     592              :         elem_it it = u->template begin<TBaseElem>();
     593              :         elem_it itEnd = u->template end<TBaseElem>();
     594            0 :         for (; it != itEnd; ++it)
     595              :         {
     596              :                 TBaseElem* elem = *it;
     597              : 
     598              :                 // loop indices at this element
     599              :                 const size_t nInd = u->inner_dof_indices(elem, cmp, vDI, true);
     600            0 :                 for (size_t i = 0; i < nInd; ++i)
     601              :                 {
     602              :                         const number& val = DoFRef(*u, vDI[i]);
     603            0 :                         if (val < lowerBnd || val > upperBnd)
     604              :                         {
     605            0 :                                 UG_LOG_ALL_PROCS("Function value for component " << cmp << " (" << val << ") "
     606              :                                         "is outside the specified range [" << lowerBnd << ", " << upperBnd << "] "
     607              :                                         "at " << ElementDebugInfo(*u->domain()->grid(), elem) << std::endl);
     608              :                                 ret = false;
     609              :                         }
     610              :                 }
     611              :         }
     612              : 
     613              : #ifdef UG_PARALLEL
     614              :         if (pcl::NumProcs() > 1)
     615              :         {
     616              :                 pcl::ProcessCommunicator pc;
     617              :                 int retInt = ret;
     618              :                 ret = pc.allreduce(retInt, PCL_RO_BAND);
     619              :         }
     620              : #endif
     621              : 
     622            0 :         return ret;
     623              : }
     624              : 
     625              : template <typename TGridFunction>
     626            0 : bool CheckGFValuesWithinBounds
     627              : (
     628              :         ConstSmartPtr<TGridFunction> u, ///< the grid function
     629              :         size_t cmp,  ///< the function component to be checked
     630              :         number lowerBnd,
     631              :         number upperBnd
     632              : )
     633              : {
     634              :         bool ret = true;
     635            0 :         if (u->max_fct_dofs(cmp, 0))
     636            0 :                 ret = ret && CheckGFValuesWithinBounds<TGridFunction, Vertex>(u, cmp, lowerBnd, upperBnd);
     637            0 :         if (u->max_fct_dofs(cmp, 1))
     638            0 :                 ret = ret && CheckGFValuesWithinBounds<TGridFunction, Edge>(u, cmp, lowerBnd, upperBnd);
     639            0 :         if (u->max_fct_dofs(cmp, 2))
     640            0 :                 ret = ret && CheckGFValuesWithinBounds<TGridFunction, Face>(u, cmp, lowerBnd, upperBnd);
     641            0 :         if (u->max_fct_dofs(cmp, 3))
     642            0 :                 ret = ret && CheckGFValuesWithinBounds<TGridFunction, Volume>(u, cmp, lowerBnd, upperBnd);
     643              : 
     644            0 :         return ret;
     645              : }
     646              : 
     647              : template <typename TGridFunction>
     648            0 : bool CheckGFValuesWithinBounds
     649              : (
     650              :         ConstSmartPtr<TGridFunction> u, ///< the grid function
     651              :         const char* fctNames,  ///< the functions to be checked
     652              :         number lowerBnd,
     653              :         number upperBnd
     654              : )
     655              : {
     656              :         std::vector<std::string> vFctNames;
     657            0 :         TokenizeTrimString (fctNames, vFctNames);
     658            0 :         FunctionGroup fctGroup (u->function_pattern());
     659              :         const size_t nFct = vFctNames.size();
     660            0 :         for (size_t f = 0; f < nFct; ++f)
     661              :         {
     662            0 :                 try {fctGroup.add(vFctNames[f]);}
     663            0 :                 UG_CATCH_THROW("Could not add function " << vFctNames[f] << " to function group.");
     664              :         }
     665              : 
     666              :         bool ret = true;
     667              :         const size_t fctGrpSz = fctGroup.size();
     668            0 :         for (size_t f = 0; f < fctGrpSz; ++f)
     669            0 :                 ret = ret && CheckGFValuesWithinBounds(u, fctGroup[f], lowerBnd, upperBnd);
     670              : 
     671            0 :         return ret;
     672            0 : }
     673              : 
     674              : 
     675              : 
     676              : 
     677              : ////////////////////////////////////////////////////////////////////////////////
     678              : //      Writing algebra
     679              : ////////////////////////////////////////////////////////////////////////////////
     680              : 
     681              : template<typename TDomain>
     682            0 : void WriteAlgebraIndices(std::string name, ConstSmartPtr<TDomain> domain,  ConstSmartPtr<DoFDistribution> dd)
     683              : {
     684              :         PROFILE_FUNC_GROUP("debug");
     685              : 
     686              : #ifdef UG_PARALLEL
     687              :         name = ConnectionViewer::GetParallelName(name, dd->layouts()->proc_comm());
     688              : #endif
     689              : 
     690              :         std::vector<size_t> fctIndex;
     691              :         std::vector<std::string> fctNames;
     692              : 
     693            0 :         ExtractAlgebraIndices<TDomain>(domain, dd, fctIndex);
     694              : 
     695              :         size_t numFct = dd->num_fct();
     696            0 :         if(numFct <= 1) return;
     697              : 
     698            0 :         fctNames.resize(numFct);
     699            0 :         for(size_t i=0; i<numFct; i++)
     700            0 :                 fctNames[i] = dd->name(i);
     701              : 
     702            0 :         name.append(".indices");
     703            0 :         std::fstream file(name.c_str(), std::ios::out);
     704              : 
     705              :         //std::cout << "name is " << name << "\n";
     706            0 :         file << "NUMDOF " << fctNames.size() << "\n";
     707            0 :         for(size_t i=0; i<numFct; i++)
     708            0 :                 file << fctNames[i] << "\n";
     709              : 
     710            0 :         for(size_t i=0; i<fctIndex.size(); i++)
     711            0 :                 file << fctIndex[i] << "\n";
     712            0 : }
     713              : 
     714              : template<class TFunction>
     715            0 : void WriteMatrixToConnectionViewer(const char *filename,
     716              :                 const typename TFunction::algebra_type::matrix_type &A,
     717              :                 const TFunction &u) {
     718              : 
     719              :         PROFILE_FUNC_GROUP("debug");
     720              : //      check name
     721            0 :         if ( !FileTypeIs( filename, ".mat") ) {
     722            0 :                 UG_THROW( "Only '.mat' format supported for matrices, but"
     723              :                           " filename is '" << filename << "'." );
     724              :         }
     725              : 
     726              : //      position array
     727              :         const static int dim = TFunction::domain_type::dim;
     728              :         std::vector<MathVector<dim> > vPos;
     729            0 :         ExtractPositions(u, vPos);
     730              : 
     731              : //      write matrix
     732            0 :         if(vPos.empty())
     733            0 :                 ConnectionViewer::WriteMatrixPar( filename, A, (MathVector<dim>*)NULL, dim );
     734              :         else
     735            0 :                 ConnectionViewer::WriteMatrixPar( filename, A, &vPos[0], dim );
     736              : 
     737            0 :         WriteAlgebraIndices(filename, u.domain(),u.dof_distribution());
     738              : 
     739            0 : }
     740              : 
     741              : template<typename TGridFunction>
     742            0 : void SaveMatrixForConnectionViewer(
     743              :                 TGridFunction& u,
     744              :                 MatrixOperator<typename TGridFunction::algebra_type::matrix_type,
     745              :                                 typename TGridFunction::vector_type>& A,
     746              :                 const char* filename) {
     747              :         PROFILE_FUNC_GROUP("debug");
     748              : //      forward
     749            0 :         WriteMatrixToConnectionViewer(filename, A.get_matrix(), u);
     750            0 : }
     751              : 
     752              : /**
     753              :  * \brief Save the assembled matrix of a matrix operator to MatrixMarket format
     754              :  * 
     755              :  * \param[in] filename name of the file; must end on '<tt>.mtx</tt>'
     756              :  * \param[in] A matrix operator of with \c CPUAlgebra matrix
     757              :  * \param[in] comment optional comment for the header of the MTX file
     758              :  * 
     759              :  * \note Until now only CPUAlgebra matrices are supported.
     760              :  */
     761              : // TODO extend MatrixIO to support other than CPUAlgebra
     762            0 : inline void SaveMatrixToMTX( const char *filename,
     763              :                 MatrixOperator< CPUAlgebra::matrix_type, CPUAlgebra::vector_type >& A,
     764              :                 std::string comment="%Generated with ug4." ) {
     765              :         PROFILE_FUNC_GROUP("debug");
     766              : 
     767              :         // check name
     768            0 :         if ( !FileTypeIs( filename, ".mtx" ) ) {
     769            0 :                 UG_THROW( "Please use '.mtx' as file extension for MatrixMarket exchange files."
     770              :                           " (Filename is '" << filename << "')" );
     771              :         }
     772              :         
     773              :         // automatically detect the file mode to use
     774            0 :         MatrixIO::OpenMode openMode = (FileExists( filename )) ? MatrixIO::EXISTING : MatrixIO::NEW;
     775              :         
     776              :         // create MatrixIO object for handling the export
     777            0 :         MatrixIOMtx mtx( filename, openMode );
     778            0 :         mtx.write_from( A.get_matrix(), comment );
     779            0 : }
     780              : 
     781              : template<class TFunction>
     782            0 : void WriteVectorToConnectionViewer(const char *filename,
     783              :                 const typename TFunction::algebra_type::vector_type &b,
     784              :                 const TFunction &u,
     785              :                 const typename TFunction::algebra_type::vector_type *pCompareVec = NULL) {
     786              :         PROFILE_FUNC_GROUP("debug");
     787              : //      check name
     788            0 :         if ( !FileTypeIs( filename, ".vec") ) {
     789            0 :                 UG_THROW( "Only '.vec' format supported for vectors, but"
     790              :                           " filename is '" << filename << "'." );
     791              :         }
     792              : 
     793              : //      get positions of vertices
     794              :         const static int dim = TFunction::domain_type::dim;
     795              :         std::vector<MathVector<dim> > vPos;
     796            0 :         ExtractPositions(u, vPos);
     797              : 
     798              : //      write vector
     799            0 :         ConnectionViewer::WriteVectorPar( filename, b, &vPos[0], dim, pCompareVec);
     800            0 :         WriteAlgebraIndices(filename, u.domain(),u.dof_distribution());
     801            0 : }
     802              : 
     803              : template<class TFunction>
     804            0 : void WriteVectorToConnectionViewer(
     805              :                 const char *filename,
     806              :                 const typename TFunction::algebra_type::matrix_type &A,
     807              :                 const typename TFunction::algebra_type::vector_type &b,
     808              :                 const TFunction &u,
     809              :                 const typename TFunction::algebra_type::vector_type *pCompareVec = NULL) {
     810              :         PROFILE_FUNC_GROUP("debug");
     811              : //      get dimension
     812              :         const static int dim = TFunction::domain_type::dim;
     813              : 
     814              : //      check name
     815            0 :         if ( !FileTypeIs( filename, ".vec") ) {
     816            0 :                 UG_THROW( "Only '.vec' format supported for vectors." );
     817              :         }
     818              : 
     819              : //      get positions of vertices
     820              :         std::vector<MathVector<dim> > positions;
     821            0 :         ExtractPositions(u, positions);
     822              : 
     823              : //      write vector
     824            0 :         ConnectionViewer::WriteVectorPar( filename, A, b, &positions[0], dim, pCompareVec );
     825            0 : }
     826              : 
     827              : template<typename TGridFunction>
     828            0 : void SaveVectorForConnectionViewer(TGridFunction& b, const char* filename) {
     829            0 :         WriteVectorToConnectionViewer(filename, b, b);
     830            0 : }
     831              : 
     832              : template<typename TGridFunction>
     833            0 : void SaveVectorDiffForConnectionViewer(TGridFunction& b, TGridFunction& bCompare, const char* filename) {
     834            0 :         WriteVectorToConnectionViewer(filename, b, b, &bCompare);
     835            0 : }
     836              : 
     837              : template<typename TGridFunction>
     838            0 : void SaveVectorForConnectionViewer(
     839              :                 TGridFunction& u,
     840              :                 MatrixOperator<typename TGridFunction::algebra_type::matrix_type,
     841              :                                 typename TGridFunction::vector_type>& A,
     842              :                 const char* filename) {
     843            0 :         WriteVectorToConnectionViewer(filename, A.get_matrix(), u, u);
     844            0 : }
     845              : 
     846              : template<typename TGridFunction>
     847            0 : void SaveVectorDiffForConnectionViewer(
     848              :                 TGridFunction& u,
     849              :                 TGridFunction& compareVec,
     850              :                 MatrixOperator<typename TGridFunction::algebra_type::matrix_type,
     851              :                                 typename TGridFunction::vector_type>& A,
     852              :                 const char* filename) {
     853              : //      forward
     854            0 :         WriteVectorToConnectionViewer(filename, A.get_matrix(), u, u, &compareVec);
     855            0 : }
     856              : 
     857              : // from connection_viewer_input.h
     858              : // with additional checks
     859              : template<typename vector_type>
     860            0 : bool ReadVector(std::string filename, vector_type &vec,int dim)
     861              : {
     862            0 :     Progress p;
     863            0 :         std::cout << " Reading std::vector from " <<  filename << "... ";
     864            0 :         std::fstream matfile(filename.c_str(), std::ios::in);
     865            0 :         if(matfile.is_open() == false) { std::cout << "failed.\n"; return false; }
     866              : 
     867            0 :         int version=-1, dimension=-1, gridsize;
     868              : 
     869            0 :         matfile >> version;
     870            0 :         matfile >> dimension;
     871            0 :         matfile >> gridsize;
     872              : 
     873              :         assert(version == 1);
     874              :         assert(dimension == dim);
     875              :         // todo check positions and not just size
     876              :         assert(gridsize == (int)vec.size());
     877              :         
     878              : 
     879            0 :         PROGRESS_START(prog, gridsize*2, "ReadVector " << dimension << "d from " << filename << " , " << gridsize << " x " << gridsize);
     880            0 :         for(int i=0; i<gridsize; i++)
     881              :         {
     882            0 :                 if(i%100) { PROGRESS_UPDATE(prog, i); }
     883            0 :                 if(matfile.eof())
     884              :                 {
     885            0 :                         std::cout << " failed.\n";
     886              :                         assert(0);
     887            0 :                         return false;
     888              :                 }
     889              :                 double x, y, z;
     890              :                 matfile >> x >> y;
     891            0 :                 if(dimension==3) matfile >> z;
     892              :         }
     893              : 
     894              :         int printStringsInWindow;
     895            0 :         matfile >> printStringsInWindow;
     896              : 
     897              :         // vec.resize(gridsize);
     898              :         bool bEOF = matfile.eof();
     899            0 :         while(!bEOF)
     900              :         {
     901              :                 int from, to; double value;
     902            0 :                 char c = matfile.peek();
     903            0 :                 if(c == -1 || c == 'c' || c == 'v' || matfile.eof())
     904              :                         break;
     905              : 
     906            0 :                 matfile >> from >> to >> value;
     907              :                 assert(from == to);
     908            0 :                 vec[from] = value;
     909            0 :                 if(from%100) { PROGRESS_UPDATE(prog, from); }
     910              :                 bEOF = matfile.eof();
     911              :         }
     912              :         return true;
     913            0 : }
     914              : 
     915              : // load vector that has been saved in connection viewer format and write it
     916              : // into grid function
     917              : template<typename TGridFunction>
     918            0 : void LoadVector(TGridFunction& u,const char* filename){
     919              :         PROFILE_FUNC();
     920              :         typename TGridFunction::algebra_type::vector_type b;
     921              :         b.resize(u.num_indices());
     922            0 :         ReadVector(filename,b,TGridFunction::dim);
     923            0 :         u.assign(b);
     924            0 : }
     925              : 
     926              : // Same as before, but for comma separated value (CSV)
     927              : template<class TFunction>
     928            0 : void WriteVectorCSV(const char *filename,
     929              :                 const typename TFunction::algebra_type::vector_type &b,
     930              :                 const TFunction &u) {
     931              :         PROFILE_FUNC_GROUP("debug");
     932              : //      get dimension
     933              :         const static int dim = TFunction::domain_type::dim;
     934              : 
     935              : //      check name
     936            0 :         if ( !FileTypeIs( filename, ".csv") ) {
     937            0 :                 UG_THROW( "Only '.csv' format supported for vectors, but"
     938              :                           " filename is '" << filename << "'." );
     939              :         }
     940              : 
     941              : //      extended filename
     942              : //      add p000X extension in parallel
     943              : #ifdef UG_PARALLEL
     944              :         std::string name(filename);
     945              :         size_t iExtPos = name.find_last_of(".");
     946              :         name.resize(iExtPos);
     947              :         int rank = pcl::ProcRank();
     948              :         char ext[20]; snprintf(ext, 20, "_p%05d.csv", rank);
     949              :         name.append(ext);
     950              : #endif
     951              : 
     952              : //      get positions of vertices
     953              :         std::vector<MathVector<dim> > positions;
     954            0 :         ExtractPositions(u, positions);
     955              : 
     956              : //      write vector
     957            0 :         WriteVectorCSV( filename, b, &positions[0], dim );
     958            0 : }
     959              : 
     960              : template<typename TGridFunction>
     961            0 : void SaveVectorCSV(TGridFunction& b, const char* filename) {
     962              :         PROFILE_FUNC();
     963            0 :         WriteVectorCSV(filename, b, b);
     964            0 : }
     965              : 
     966              : /**
     967              :  * \brief Calculates the average of the pointwise difference of two functions on given subset
     968              :  * \details Iterates over all vertices of given subset, calculates difference
     969              :  *   of \c fct1 and \c fct2 and computes arithmetic mean of the differences at
     970              :  *   all vertices (grid points).
     971              :  * \note \c fct1 and \c fct2 must both be defined on \c subset !
     972              :  * \param[in] spGridFct GridFunction holding functions \c fct1 and \c fct2 defined on subset \c subset
     973              :  * \param[in] subset name of the subset to compare on
     974              :  * \param[in] fct1 name of the first function
     975              :  * \param[in] fct2 name of the second function
     976              :  * \return arithmetic average of the pointwise differences of \c fct1 and \c fct2 on
     977              :  *   all vertices of \c subset
     978              :  */
     979              : template<typename TDomain, typename TAlgebra>
     980            0 : number AverageFunctionDifference(
     981              :                 SmartPtr< GridFunction<TDomain, TAlgebra> > spGridFct,
     982              :                 std::string subset, std::string fct1, std::string fct2 )
     983              : {
     984              :         PROFILE_FUNC();
     985              :         // get subset index
     986              :         size_t subSetID = spGridFct->subset_id_by_name( subset.c_str() );
     987              : 
     988              :         // get function indices
     989              :         size_t fct1ID = spGridFct->fct_id_by_name( fct1.c_str() );
     990              :         size_t fct2ID = spGridFct->fct_id_by_name( fct2.c_str() );
     991              : 
     992              :         // create space for sum of difference
     993              :         number sum = 0.0;
     994              :         size_t numElements = 0;
     995              : 
     996              :         // loop over all vertices in given subset and compare values of fct1 and fct2
     997              :         typedef typename GridFunction<TDomain, TAlgebra>::template traits<Vertex>::const_iterator gridFctIterator;
     998            0 :         for( gridFctIterator iter = spGridFct->template begin<Vertex>((int)subSetID); 
     999            0 :                iter != spGridFct->template end<Vertex>((int)subSetID); ++iter ) {
    1000              :                 // get dof_indices for the two functions on given subset
    1001              :                 std::vector< DoFIndex > indFct1, indFct2;
    1002              :                 spGridFct->template dof_indices<Vertex>( *iter, fct1ID, indFct1 );
    1003              :                 spGridFct->template dof_indices<Vertex>( *iter, fct2ID, indFct2 );
    1004              : 
    1005              :                 // calculate the difference between the two functions at this grid point
    1006            0 :                 sum += DoFRef( *spGridFct, indFct1[0] ) - DoFRef( *spGridFct, indFct2[0] );
    1007            0 :                 numElements++;
    1008              :         }
    1009              :         
    1010              :         // return overal arithmetic average of differences
    1011            0 :         return sum / numElements;
    1012              : }
    1013              : 
    1014              : 
    1015              : ////////////////////////////////////////////////////////////////////////////////
    1016              : //      Grid Function Debug Writer
    1017              : ////////////////////////////////////////////////////////////////////////////////
    1018              : 
    1019              : template<typename TDomain, typename TAlgebra>
    1020              : class GridFunctionDebugWriter: public IDebugWriter<TAlgebra>
    1021              : {
    1022              :         ///     dimension
    1023              :         static const int dim = TDomain::dim;
    1024              : 
    1025              : public:
    1026              :         ///     type of matrix
    1027              :         typedef TAlgebra algebra_type;
    1028              : 
    1029              :         ///     type of vector
    1030              :         typedef typename algebra_type::vector_type vector_type;
    1031              : 
    1032              :         ///     type of matrix
    1033              :         typedef typename algebra_type::matrix_type matrix_type;
    1034              : 
    1035              :         ///     type of approximation space
    1036              :         typedef ApproximationSpace<TDomain> approximation_space_type;
    1037              : 
    1038              :         typedef IDebugWriter<TAlgebra> super;
    1039              :         using super::get_base_dir;
    1040              : 
    1041              : public:
    1042              :         ///     Constructor
    1043            0 :         GridFunctionDebugWriter(
    1044              :                         SmartPtr<ApproximationSpace<TDomain> > spApproxSpace) :
    1045            0 :                         m_spApproxSpace(spApproxSpace), bConnViewerOut(
    1046            0 :                                         true), bConnViewerIndices(false), bVTKOut(true), m_printConsistent(true)
    1047              :         {
    1048            0 :                 IVectorDebugWriter<vector_type>::m_currentDim = dim;
    1049              :                 reset();
    1050            0 :         }
    1051              : 
    1052            0 :         virtual ~GridFunctionDebugWriter() {};
    1053              : 
    1054              :         ///     sets the grid level
    1055            0 :         void set_grid_level(const GridLevel& gridLevel) {
    1056            0 :                 m_glFrom = gridLevel; m_glTo = gridLevel;
    1057            0 :         }
    1058              : 
    1059              :         ///     sets the grid level
    1060              :         void set_grid_levels(const GridLevel& glFrom, const GridLevel& glTo) {
    1061            0 :                 m_glFrom = glFrom; m_glTo = glTo;
    1062              :         }
    1063              : 
    1064              :         ///     returns current grid level
    1065            0 :         GridLevel grid_level() const {return m_glFrom;}
    1066              : 
    1067              :         ///     sets to toplevel on surface
    1068            0 :         void reset() {
    1069              :                 set_grid_level(GridLevel(GridLevel::TOP, GridLevel::SURFACE));
    1070            0 :         }
    1071              : 
    1072              : 
    1073              :         ///     sets if writing to vtk
    1074            0 :         void set_vtk_output(bool b) {bVTKOut = b;}
    1075              : 
    1076              :         ///     sets if writing to conn viewer
    1077            0 :         void set_conn_viewer_output(bool b) {bConnViewerOut = b;}
    1078              : 
    1079              :         /// sets if .indices file is written or conn viewer
    1080            0 :         void set_conn_viewer_indices(bool b) { bConnViewerIndices = b; }
    1081              : 
    1082              :         ///     sets if data shall be made consistent before printing
    1083            0 :         void set_print_consistent(bool b) {m_printConsistent = b;}
    1084              : 
    1085              :         ///     write vector
    1086            0 :         virtual void write_vector(const vector_type& vec, const char* filename) {
    1087              :                 //      write to conn viewer
    1088            0 :                 if (bConnViewerOut)
    1089            0 :                         write_vector_to_conn_viewer(vec, filename);
    1090              : 
    1091              :                 //      write to vtk
    1092            0 :                 if (bVTKOut)
    1093            0 :                         write_vector_to_vtk(vec, filename);
    1094            0 :         }
    1095              : 
    1096            0 :         virtual void update_positions()
    1097              :         {
    1098            0 :                 extract_positions(m_glFrom);
    1099            0 :         }
    1100              : 
    1101              :         ///     write matrix
    1102            0 :         virtual void write_matrix(const matrix_type& mat, const char* filename) {
    1103              :                 PROFILE_FUNC_GROUP("debug");
    1104              :                 //      something to do ?
    1105            0 :                 if (!bConnViewerOut)
    1106            0 :                         return;
    1107              : 
    1108            0 :                 update_positions();
    1109              : 
    1110              :                 std::string name;
    1111            0 :                 this->compose_file_path (name);
    1112              :                 name += filename;
    1113              : 
    1114            0 :                 if ( !FileTypeIs( filename, ".mat" ) ) {
    1115            0 :                         UG_THROW( "Only '.mat' format supported for matrices, but"
    1116              :                                   " filename is '" << filename << "'." );
    1117              :                 }
    1118              : 
    1119              :                 //      write to file
    1120            0 :                 write_algebra_indices_CV(name);
    1121              :                 if(m_glFrom == m_glTo){
    1122            0 :                         if(mat.num_rows() != mat.num_cols())
    1123            0 :                                 UG_THROW("DebugWriter: grid level the same, but non-square matrix.");
    1124              : 
    1125            0 :                         const std::vector<MathVector<dim> >& vPos = this->template get_positions<dim>();
    1126            0 :                         if(vPos.empty())
    1127            0 :                                 ConnectionViewer::WriteMatrixPar(name.c_str(), mat,(MathVector<dim>*)NULL, dim);
    1128              :                         else
    1129            0 :                                 ConnectionViewer::WriteMatrixPar(name.c_str(), mat, &vPos[0], dim);
    1130              :                 }
    1131              :                 else{
    1132            0 :                         const std::vector<MathVector<dim> >& vFromPos = this->template get_positions<dim>();
    1133              : 
    1134              :                         std::vector<MathVector<dim> > vToPos;
    1135            0 :                         ExtractPositions<TDomain>(m_spApproxSpace->domain(),
    1136            0 :                                                   m_spApproxSpace->dof_distribution(m_glTo),
    1137              :                                                   vToPos);
    1138              : 
    1139            0 :                         if(mat.num_cols() == vFromPos.size() && mat.num_rows() == vToPos.size())
    1140              :                         {
    1141            0 :                                 ConnectionViewer::WriteMatrixPar(name, mat, vFromPos, vToPos, dim);
    1142              :                         }
    1143              :                         else{
    1144            0 :                                 UG_THROW("GridFunctionDebugWriter: Wrong size of matrix for writing"
    1145              :                                                 "matrix ("<<m_glTo<<" x "<<m_glFrom<<"), that would be a ("
    1146              :                                                 <<vToPos.size()<<" x "<<vFromPos.size()<<") matrix. But "
    1147              :                                                 "passed matrix of size ("<<mat.num_rows()<<" x "
    1148              :                                                 <<mat.num_cols()<<").");
    1149              :                         }
    1150            0 :                 }
    1151              :         }
    1152              : 
    1153              : protected:
    1154              : 
    1155            0 :         void write_algebra_indices_CV(std::string name)
    1156              :         {
    1157            0 :                 if(bConnViewerIndices)
    1158            0 :                         WriteAlgebraIndices<TDomain>(name, m_spApproxSpace->domain(), m_spApproxSpace->dof_distribution(m_glFrom));
    1159            0 :         }
    1160              : 
    1161              :         ///     reads the positions
    1162            0 :         void extract_positions(const GridLevel& gridLevel) {
    1163              :                 //      extract positions for this grid function
    1164              :                 std::vector<MathVector<dim> >& vPos =
    1165              :                                 this->template positions<dim>();
    1166              : 
    1167              :                 vPos.clear();
    1168            0 :                 ExtractPositions<TDomain>(
    1169              :                                 m_spApproxSpace->domain(),
    1170              :                                 m_spApproxSpace->dof_distribution(gridLevel),
    1171              :                                 vPos);
    1172            0 :         }
    1173              : 
    1174              :         ///     write vector
    1175            0 :         virtual void write_vector_to_conn_viewer(const vector_type& vec,
    1176              :                         const char* filename)
    1177              :         {
    1178              :                 PROFILE_FUNC_GROUP("debug");
    1179            0 :                 update_positions();
    1180              : 
    1181              :                 std::string name;
    1182            0 :                 this->compose_file_path (name);
    1183              :                 name += filename;
    1184              : 
    1185            0 :                 if ( !FileTypeIs( filename, ".vec" ) ) {
    1186            0 :                         UG_THROW( "Only '.vec' format supported for vectors, but"
    1187              :                                   " filename is '" << name << "'.");
    1188              :                 }
    1189              : 
    1190              :                 //      write
    1191            0 :                 write_algebra_indices_CV(filename);
    1192              :                 const std::vector<MathVector<dim> >& vPos =
    1193            0 :                                 this->template get_positions<dim>();
    1194            0 :                 if(vPos.empty())
    1195            0 :                         ConnectionViewer::WriteVectorPar(name.c_str(), vec, (MathVector<dim>*)NULL, dim);
    1196              :                 else
    1197            0 :                         ConnectionViewer::WriteVectorPar(name.c_str(), vec, &vPos[0], dim);
    1198            0 :         }
    1199              : 
    1200            0 :         void write_vector_to_vtk(const vector_type& vec, const char* filename) {
    1201              :                 PROFILE_FUNC_GROUP("debug");
    1202              :                 //      check name
    1203              : 
    1204              :                 std::string name;
    1205            0 :                 this->compose_file_path (name);
    1206              :                 name += filename;
    1207              : 
    1208              :                 typedef GridFunction<TDomain, TAlgebra> TGridFunction;
    1209            0 :                 TGridFunction vtkFunc(
    1210              :                                 m_spApproxSpace,
    1211            0 :                                 m_spApproxSpace->dof_distribution(m_glFrom));
    1212            0 :                 vtkFunc.resize_values(vec.size());
    1213            0 :                 vtkFunc.assign(vec);
    1214            0 :                 VTKOutput<dim> out;
    1215            0 :                 out.print(name.c_str(), vtkFunc, m_printConsistent);
    1216            0 :         }
    1217              : 
    1218              : protected:
    1219              :         //      underlying approximation space
    1220              :         SmartPtr<approximation_space_type> m_spApproxSpace;
    1221              : 
    1222              :         //      flag if write to conn viewer
    1223              :         bool bConnViewerOut;
    1224              :         bool bConnViewerIndices;
    1225              : 
    1226              :         //      flag if write to vtk
    1227              :         bool bVTKOut;
    1228              : 
    1229              :         //      flag if data shall be made consistent before printing
    1230              :         bool m_printConsistent;
    1231              : 
    1232              :         //      current grid level
    1233              :         GridLevel m_glFrom, m_glTo;
    1234              : };
    1235              : 
    1236              : ////////////////////////////////////////////////////////////////////////////////
    1237              : //      Grid Function Position Provider
    1238              : ////////////////////////////////////////////////////////////////////////////////
    1239              : 
    1240              : template<typename TGridFunction>
    1241              : class GridFunctionPositionProvider: public IPositionProvider<
    1242              :                 TGridFunction::domain_type::dim> {
    1243              : public:
    1244              :         ///     Constructor
    1245            0 :         GridFunctionPositionProvider() :
    1246            0 :                         m_pGridFunc(NULL) {
    1247              :         }
    1248            0 :         GridFunctionPositionProvider(const TGridFunction& u) :
    1249            0 :                         m_pGridFunc(&u) {
    1250              :         }
    1251            0 :         void set_reference_grid_function(const TGridFunction& u) {
    1252            0 :                 m_pGridFunc = &u;
    1253            0 :         }
    1254              : 
    1255            0 :         virtual bool get_positions(
    1256              :                         std::vector<MathVector<TGridFunction::domain_type::dim> >&vec) {
    1257              :                 UG_ASSERT(m_pGridFunc != NULL,
    1258              :                                 "provide a grid function with set_reference_grid_function");
    1259            0 :                 ExtractPositions(*m_pGridFunc, vec);
    1260            0 :                 return true;
    1261              :         }
    1262              : 
    1263              : protected:
    1264              :         const TGridFunction *m_pGridFunc;
    1265              : };
    1266              : 
    1267              : ////////////////////////////////////////////////////////////////////////////////
    1268              : //      Grid Function Vector Writer
    1269              : ////////////////////////////////////////////////////////////////////////////////
    1270              : 
    1271              : template<typename TGridFunction, typename TVector>
    1272              : class GridFunctionVectorWriter: public IVectorWriter<TVector> {
    1273              : public:
    1274              :         typedef typename TVector::value_type value_type;
    1275              :         typedef typename TGridFunction::domain_type domain_type;
    1276              :         typedef TVector vector_type;
    1277              : 
    1278              : public:
    1279              :         ///     Constructor
    1280            0 :         GridFunctionVectorWriter() :
    1281            0 :                         m_pGridFunc(NULL) {
    1282              :         }
    1283              : 
    1284            0 :         void set_user_data(SmartPtr<UserData<number, domain_type::dim> > userData) {
    1285            0 :                 m_userData = userData;
    1286            0 :         }
    1287              : 
    1288            0 :         void set_reference_grid_function(const TGridFunction& u) {
    1289            0 :                 m_pGridFunc = &u;
    1290            0 :         }
    1291              : 
    1292              :         /*virtual double calculate(MathVector<3> &v, double time)
    1293              :          {
    1294              :          }*/
    1295              : 
    1296            0 :         virtual bool update(vector_type &vec) {
    1297              :                 PROFILE_FUNC_GROUP("debug");
    1298              :                 UG_ASSERT(m_pGridFunc != NULL,
    1299              :                                 "provide a grid function with set_reference_grid_function");
    1300              :                 UG_ASSERT(m_userData.valid(), "provide user data with set_user_data");
    1301              : 
    1302            0 :                 const TGridFunction &u = *m_pGridFunc;
    1303              : 
    1304              :                 //      get position accessor
    1305              : 
    1306              :                 const typename domain_type::position_accessor_type& aaPos =
    1307            0 :                                 u.domain()->position_accessor();
    1308              : 
    1309              :                 //      number of total dofs
    1310            0 :                 int nr = u.num_indices();
    1311              : 
    1312              :                 //      resize positions
    1313            0 :                 vec.resize(nr);
    1314              : 
    1315              :                 typedef typename TGridFunction::template traits<Vertex>::const_iterator const_iterator;
    1316              : 
    1317              :                 //      loop all subsets
    1318            0 :                 for (int si = 0; si < u.num_subsets(); ++si) {
    1319              :                         //      loop all vertices
    1320              :                         const_iterator iter = u.template begin<Vertex>(si);
    1321              :                         const_iterator iterEnd = u.template end<Vertex>(si);
    1322              : 
    1323            0 :                         for (; iter != iterEnd; ++iter) {
    1324              :                                 //      get vertex
    1325              :                                 Vertex* v = *iter;
    1326              : 
    1327              :                                 //      algebra indices vector
    1328              :                                 std::vector<size_t> ind;
    1329              : 
    1330              :                                 //      load indices associated with vertex
    1331              :                                 u.inner_algebra_indices(v, ind);
    1332              : 
    1333              :                                 number t = 0.0;
    1334              : 
    1335              :                                 number d;
    1336            0 :                                 (*m_userData)(d, aaPos[v], t, si);
    1337              : 
    1338              :                                 //      write
    1339            0 :                                 for (size_t i = 0; i < ind.size(); ++i) {
    1340            0 :                                         const size_t index = ind[i];
    1341            0 :                                         for (size_t alpha = 0; alpha < GetSize(vec[index]); ++alpha)
    1342            0 :                                                 BlockRef(vec[index], alpha) = d;
    1343              :                                 }
    1344              :                         }
    1345              :                 }
    1346            0 :                 return true;
    1347              :         }
    1348              : 
    1349              : protected:
    1350              :         const TGridFunction *m_pGridFunc;
    1351              :         SmartPtr<UserData<number, domain_type::dim> > m_userData;
    1352              : };
    1353              : 
    1354              : ////////////////////////////////////////////////////////////////////////////////
    1355              : //      Grid Function Vector Writer Dirichlet 0
    1356              : ////////////////////////////////////////////////////////////////////////////////
    1357              : 
    1358              : template<typename TGridFunction>
    1359              : class GridFunctionVectorWriterDirichlet0: public IVectorWriter<
    1360              :                 typename TGridFunction::algebra_type::vector_type> {
    1361              : public:
    1362              :         typedef typename TGridFunction::domain_type domain_type;
    1363              : 
    1364              :         typedef typename TGridFunction::approximation_space_type approximation_space_type;
    1365              : 
    1366              :         typedef typename TGridFunction::algebra_type algebra_type;
    1367              :         typedef typename algebra_type::vector_type vector_type;
    1368              :         typedef typename vector_type::value_type value_type;
    1369              : 
    1370              : public:
    1371              :         ///     Constructor
    1372            0 :         GridFunctionVectorWriterDirichlet0() :
    1373            0 :                         m_pApproxSpace(NULL), m_spPostProcess(NULL), m_level(-1) {
    1374              :         }
    1375              : 
    1376            0 :         void set_level(size_t level) {
    1377            0 :                 m_level = level;
    1378            0 :         }
    1379              : 
    1380            0 :         void init(SmartPtr<IConstraint<algebra_type> > pp,
    1381              :                         approximation_space_type& approxSpace) {
    1382            0 :                 m_spPostProcess = pp;
    1383            0 :                 m_pApproxSpace = &approxSpace;
    1384            0 :         }
    1385              : 
    1386              :         /*virtual double calculate(MathVector<3> &v, double time)
    1387              :          {
    1388              :          }*/
    1389              : 
    1390            0 :         virtual bool update(vector_type &vec) {
    1391              :                 PROFILE_FUNC_GROUP("debug");
    1392              :                 UG_ASSERT(m_spPostProcess.valid(), "provide a post process with init");
    1393              :                 UG_ASSERT(m_pApproxSpace != NULL, "provide approximation space init");
    1394              : 
    1395              :                 size_t numDoFs = 0;
    1396              :                 GridLevel gl;
    1397            0 :                 if (m_level == (size_t) -1) {
    1398            0 :                         numDoFs = m_pApproxSpace->dof_distribution(GridLevel(GridLevel::TOP, GridLevel::SURFACE))->num_indices();
    1399            0 :                         gl = GridLevel();
    1400              :                 } else {
    1401              :                         numDoFs =
    1402            0 :                                         m_pApproxSpace->dof_distribution(GridLevel(m_level, GridLevel::LEVEL, true))->num_indices();
    1403            0 :                         gl = GridLevel(m_level, GridLevel::LEVEL);
    1404              :                 }
    1405              :                 vec.resize(numDoFs);
    1406              :                 vec.set(1.0);
    1407              : 
    1408            0 :                 m_spPostProcess->adjust_defect(vec, vec, m_pApproxSpace->dof_distribution(gl), CT_DIRICHLET);
    1409              : 
    1410            0 :                 return true;
    1411              :         }
    1412              : 
    1413              : protected:
    1414              :         approximation_space_type * m_pApproxSpace;
    1415              :         SmartPtr<IConstraint<algebra_type> > m_spPostProcess;
    1416              :         size_t m_level;
    1417              : };
    1418              : 
    1419              : } // end namespace ug
    1420              : 
    1421              : #endif /* __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_UTIL__ */
        

Generated by: LCOV version 2.0-1