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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2014-2017:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Arne Naegel
       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__METRIC_SPACES_H_
      34              : #define __H__UG__LIB_DISC__FUNCTION_SPACE__METRIC_SPACES_H_
      35              : 
      36              : // C++ includes
      37              : #include <vector>
      38              : #include <cmath>
      39              : 
      40              : // UG includes
      41              : #include "common/common.h"
      42              : #include "common/util/smart_pointer.h"
      43              : 
      44              : #include "lib_algebra/lib_algebra.h"
      45              : #include "lib_algebra/operator/debug_writer.h"
      46              : 
      47              : #include "lib_disc/function_spaces/integrate.h"
      48              : #include "lib_disc/function_spaces/grid_function.h"
      49              : #include "lib_disc/function_spaces/grid_function_user_data.h"
      50              : #include "lib_disc/function_spaces/integrate.h"
      51              : 
      52              : #include "lib_disc/spatial_disc/user_data/linker/darcy_velocity_linker.h"  // required for Darcy velocity linker
      53              : 
      54              : namespace ug {
      55              : /// Abstract base class for (algebraic) vectors
      56              : template<typename TVector>
      57              : class IBanachSpace
      58              : {
      59              : 
      60              : public:
      61              :         virtual ~IBanachSpace() {}
      62              : 
      63              :         /// euclidean norm (default)
      64              :         virtual double norm(TVector &x)
      65              :         { return x.norm(); }
      66              : 
      67              :         virtual double distance(TVector& x, TVector& y)
      68              :         {
      69              :                 SmartPtr<TVector> delta = x.clone();
      70              :                 *delta -= y;
      71              :                 return norm(*delta);
      72              :         }
      73              : 
      74              : };
      75              : 
      76              : 
      77              : 
      78              : /// Abstract base class for grid functions
      79              : template<typename TGridFunction>
      80              : class IGridFunctionSpace  :
      81              :                 public IBanachSpace<typename TGridFunction::vector_type>
      82              : {
      83              : 
      84              : public:
      85              :         typedef typename TGridFunction::vector_type vector_type;
      86              :         typedef TGridFunction grid_function_type;
      87              : 
      88              :         /// DTOR
      89              :         virtual ~IGridFunctionSpace() {}
      90              : 
      91              :         /// norm (for grid functions)
      92              :         virtual double norm(TGridFunction& x) = 0;
      93              :         virtual double norm2(TGridFunction& x) = 0;
      94              : 
      95              :         // { return x.norm(); }
      96              : 
      97              :         /// distance (for grid functions)
      98              :         virtual double distance(TGridFunction& x, TGridFunction& y) = 0;
      99              :         virtual double distance2(TGridFunction& x, TGridFunction& y) = 0;
     100              :         /*{
     101              :                 SmartPtr<TGridFunction> delta = x.clone();
     102              :                 *delta -= y;
     103              :                 return norm(*delta);
     104              :         }*/
     105              : 
     106              :         /// OVERRIDE norm (for vectors)
     107            0 :         virtual double norm(vector_type &x)
     108              :         {
     109            0 :                 TGridFunction* gfX=dynamic_cast< TGridFunction*>(&x);
     110              :                 UG_ASSERT(gfX!=NULL, "Huhh: GridFunction required!");
     111            0 :                 return norm(*gfX);
     112              :         }
     113              : 
     114              :         /// OVERRIDE distance (for vectors)
     115            0 :         virtual double distance(vector_type &x, vector_type &y)
     116            0 :         { return distance(static_cast<TGridFunction &>(x), static_cast<TGridFunction &>(y)); }
     117              : 
     118            0 :         virtual double scaling() const
     119            0 :         { return 1.0; }
     120              : 
     121              :         virtual std::string config_string() const
     122              :          { return std::string("IGridFunctionSpace"); }
     123              : };
     124              : 
     125              : template<typename TGridFunction>
     126              : class AlgebraicSpace : public IGridFunctionSpace<TGridFunction>
     127              : {
     128              :         typedef typename TGridFunction::vector_type vector_type;
     129              :         virtual ~AlgebraicSpace() {}
     130              : 
     131              :         virtual double norm(TGridFunction& x)
     132              :         {return x.norm();}
     133              : 
     134              :         virtual double norm2(TGridFunction& x)
     135              :         { double n = this->norm(x); return n*n; }
     136              : 
     137              :         virtual double distance(TGridFunction& x, TGridFunction& y)
     138              :         { SmartPtr<TGridFunction> delta = x.clone(); *delta -= y; return delta->norm(); }
     139              : 
     140              :         virtual double distance2(TGridFunction& x, TGridFunction& y)
     141              :         { double d = this->distance(x,y);; return d*d;}
     142              : };
     143              : 
     144              : 
     145              : 
     146              : /** Auxiliary class for providing weights*/
     147              : template <typename W>
     148            0 : class IObjectWithWeights
     149              : {
     150              : public:
     151              :         typedef W weight_type;
     152              : 
     153              :         IObjectWithWeights()
     154              :         : m_spWeight(SPNULL) {}
     155              : 
     156              :         IObjectWithWeights(ConstSmartPtr<weight_type> spW)
     157              :         : m_spWeight(spW) {}
     158              : 
     159              :         /// for weighted norms
     160            0 :         void set_weight(ConstSmartPtr<weight_type> spWeight)
     161            0 :         { m_spWeight = spWeight; }
     162              : 
     163            0 :         ConstSmartPtr<weight_type> get_weight()
     164            0 :         { return m_spWeight; }
     165              : 
     166              : protected:
     167              :         ConstSmartPtr<weight_type> m_spWeight;
     168              : };
     169              : 
     170              : 
     171              : /** Auxiliary class for time dependence - SHOULD be replaced by product space*/
     172              : /*
     173              : class ITimeData {
     174              : 
     175              : public:
     176              :         virtual ~ITimeData() {};
     177              : 
     178              :         /// characteristic time
     179              :         virtual void update_time_data(number dt) = 0;
     180              : 
     181              :         virtual bool is_time_dependent() const
     182              :         { return false; }
     183              : 
     184              : };
     185              : 
     186              : */
     187              : 
     188              : //! Estimate the error (based on the difference between two grid functions)
     189              : template <typename TGridFunction>
     190              : class IComponentSpace :
     191              :                 public IGridFunctionSpace<TGridFunction>
     192              : {
     193              : protected:
     194              :         std::string m_fctNames;
     195              :         const char* m_ssNames;
     196              :         int m_quadorder;
     197              :         //bool m_opposite;
     198              :         //number m_thickness;
     199              :         //std::string m_type; 
     200              : 
     201              : public:
     202              :         typedef IGridFunctionSpace<TGridFunction> base_type;
     203              :         static const int dim=TGridFunction::dim;
     204              : 
     205            0 :         IComponentSpace(const char *fctNames)
     206            0 :         : m_fctNames(fctNames), m_ssNames(NULL), m_quadorder(3){}
     207              : 
     208            0 :         IComponentSpace(const char *fctNames, int order)
     209            0 :         : m_fctNames(fctNames), m_ssNames(NULL), m_quadorder(order) {}
     210              : 
     211            0 :         IComponentSpace(const char *fctNames, const char* ssNames, int order)
     212            0 :         : m_fctNames(fctNames), m_ssNames(ssNames), m_quadorder(order){}
     213              : 
     214            0 :         virtual ~IComponentSpace() {};
     215              : 
     216              :         // per convention, norm must return sqrt of norm2
     217            0 :         virtual double norm(TGridFunction& uFine)
     218            0 :         { return sqrt(norm2(uFine)); }
     219              : 
     220              :         // per convention, distance must return sqrt of distance2
     221            0 :         virtual double distance(TGridFunction& uFine, TGridFunction& uCoarse)
     222            0 :         { return sqrt(distance2(uFine, uCoarse)); }
     223              : 
     224              :         virtual double norm2(TGridFunction& uFine)  = 0;
     225              :         virtual double distance2(TGridFunction& uFine, TGridFunction& uCoarse)  = 0;
     226              : 
     227              :         std::string function_name(){return m_fctNames;}
     228              : 
     229              :         //void set_opposite(bool opposite){m_opposite=opposite;}
     230              : 
     231              : public:
     232              :         /// print config string
     233            0 :         virtual std::string config_string() const
     234              :         {
     235            0 :                 std::stringstream ss;
     236              : 
     237            0 :                 if (this->m_ssNames)
     238            0 :                 ss << this->m_fctNames << ", " << this->m_ssNames << ", " << this->m_quadorder
     239            0 :                         << ", type=" << std::endl;
     240              : 
     241              :                 else
     242            0 :                         ss << this->m_fctNames << ",  (no name), " << this->m_quadorder
     243            0 :                                                 << ", type=" << std::endl;
     244            0 :                 return ss.str();
     245            0 :         }
     246              : 
     247              : };
     248              : 
     249              : 
     250              : /// Computes simple vector (2-)norm from grid function DoFs which belong to either of the
     251              : /// subsets and either of the functions supplied in the constructor.
     252              : template <typename TGridFunction>
     253              : class GridFunctionComponentSpace
     254              : : public IComponentSpace<TGridFunction>
     255              : {
     256              :         public:
     257              :                 GridFunctionComponentSpace(const char* fctNames)
     258            0 :                 : IComponentSpace<TGridFunction>(fctNames) {}
     259              : 
     260              :                 GridFunctionComponentSpace(const char* fctNames, const char* ssNames)
     261            0 :                 : IComponentSpace<TGridFunction>(fctNames, ssNames, 1) {}
     262              : 
     263            0 :                 virtual ~GridFunctionComponentSpace() {};
     264              : 
     265            0 :                 virtual double norm2(TGridFunction& uFine)
     266              :                 {
     267            0 :                         ConstSmartPtr<DoFDistribution> dd = uFine.dof_distribution();
     268              : 
     269              :                         // find function indices
     270            0 :                         FunctionGroup fg(dd->function_pattern());
     271            0 :                         try {fg.add(TokenizeTrimString(this->m_fctNames));}
     272            0 :                         UG_CATCH_THROW("Could not convert function names to function indices.");
     273              : 
     274              :                         // find subset indices
     275            0 :                         SubsetGroup sg(dd->subset_handler());
     276            0 :                         if (this->m_ssNames)
     277              :                         {
     278            0 :                                 try {sg.add(TokenizeTrimString(this->m_ssNames));}
     279            0 :                                 UG_CATCH_THROW("Could not convert subset names to subset indices.");
     280              :                         }
     281              :                         else
     282            0 :                                 sg.add_all();
     283              : 
     284              : 
     285              :                         // loop subsets
     286            0 :                         number sum = 0.0;
     287              :                         const size_t sgSz = sg.size();
     288            0 :                         for (size_t i = 0; i < sgSz; ++i)
     289              :                         {
     290              :                                 int si = sg[i];
     291            0 :                                 if (dd->max_dofs(VERTEX, si)) add_norm_values<Vertex>(sum, uFine, dd, sg[i], fg);
     292            0 :                                 if (dd->max_dofs(EDGE, si)) add_norm_values<Edge>(sum, uFine, dd, sg[i], fg);
     293            0 :                                 if (dd->max_dofs(FACE, si)) add_norm_values<Face>(sum, uFine, dd, sg[i], fg);
     294            0 :                                 if (dd->max_dofs(VOLUME, si)) add_norm_values<Volume>(sum, uFine, dd, sg[i], fg);
     295              :                         }
     296              : 
     297              : #ifdef UG_PARALLEL
     298              :                         if (pcl::NumProcs() > 1)
     299              :                         {
     300              :                                 pcl::ProcessCommunicator pc;
     301              :                                 sum = pc.allreduce(sum, PCL_RO_SUM);
     302              :                         }
     303              : #endif
     304              : 
     305            0 :                         return sum;
     306              :                 }
     307              : 
     308            0 :                 virtual double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     309              :                 {
     310            0 :                         ConstSmartPtr<DoFDistribution> dd = uFine.dof_distribution();
     311            0 :                         UG_COND_THROW(dd != uCoarse.dof_distribution(),
     312              :                                 "GridFunctionComponentSpace::distance2: GF1 DoF distro is not the same as for GF2.\n"
     313              :                                 "This case is not implemented.");
     314              : 
     315              :                         // find function indices
     316            0 :                         FunctionGroup fg(dd->function_pattern());
     317            0 :                         try {fg.add(TokenizeTrimString(this->m_fctNames));}
     318            0 :                         UG_CATCH_THROW("Could not convert function names to function indices.");
     319              : 
     320              :                         // find subset indices
     321            0 :                         SubsetGroup sg(dd->subset_handler());
     322            0 :                         if (this->m_ssNames)
     323              :                         {
     324            0 :                                 try {sg.add(TokenizeTrimString(this->m_ssNames));}
     325            0 :                                 UG_CATCH_THROW("Could not convert subset names to subset indices.");
     326              :                         }
     327              :                         else
     328            0 :                                 sg.add_all();
     329              : 
     330              : 
     331              :                         // loop subsets
     332            0 :                         number sum = 0.0;
     333              :                         const size_t sgSz = sg.size();
     334            0 :                         for (size_t i = 0; i < sgSz; ++i)
     335              :                         {
     336              :                                 int si = sg[i];
     337            0 :                                 if (dd->max_dofs(VERTEX, si)) add_distance_values<Vertex>(sum, uFine, uCoarse, dd, sg[i], fg);
     338            0 :                                 if (dd->max_dofs(EDGE, si)) add_distance_values<Edge>(sum, uFine, uCoarse, dd, sg[i], fg);
     339            0 :                                 if (dd->max_dofs(FACE, si)) add_distance_values<Face>(sum, uFine, uCoarse, dd, sg[i], fg);
     340            0 :                                 if (dd->max_dofs(VOLUME, si)) add_distance_values<Volume>(sum, uFine, uCoarse, dd, sg[i], fg);
     341              :                         }
     342              : 
     343              : #ifdef UG_PARALLEL
     344              :                         if (pcl::NumProcs() > 1)
     345              :                         {
     346              :                                 pcl::ProcessCommunicator pc;
     347              :                                 sum = pc.allreduce(sum, PCL_RO_SUM);
     348              :                         }
     349              : #endif
     350              : 
     351            0 :                         return sum;
     352              :                 }
     353              : 
     354              :         private:
     355              :                 template <typename TBaseElem>
     356            0 :                 void add_distance_values
     357              :                 (
     358              :                         number& sum,
     359              :                         const TGridFunction& uFine,
     360              :                         const TGridFunction& uCoarse,
     361              :                         ConstSmartPtr<DoFDistribution> dd,
     362              :                         int si,
     363              :                         const FunctionGroup& fg
     364              :                 ) const
     365              :                 {
     366            0 :                         const SurfaceView& sv = *dd->surface_view();
     367            0 :                         const MultiGrid& mg = *dd->multi_grid();
     368              : 
     369            0 :                         const number nFct = fg.size();
     370              : 
     371              :                         // iterate all elements (including SHADOW_RIM_COPY!)
     372              :                         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     373            0 :                         iter = dd->template begin<TBaseElem>(si, SurfaceView::ALL);
     374            0 :                         iterEnd = dd->template end<TBaseElem>(si, SurfaceView::ALL);
     375              :                         std::vector<DoFIndex> vInd;
     376            0 :                         for (; iter != iterEnd; ++iter)
     377              :                         {
     378              :                                 TBaseElem* elem = *iter;
     379            0 :                                 if (sv.is_contained(elem, dd->grid_level(), SurfaceView::SHADOW_RIM_COPY))
     380              :                                 {
     381            0 :                                         if (mg.num_children<TBaseElem>(elem) > 0)
     382              :                                         {
     383              :                                                 TBaseElem* child = mg.get_child<TBaseElem>(elem, 0);
     384            0 :                                                 if (sv.is_contained(child, dd->grid_level(), SurfaceView::SURFACE_RIM))
     385            0 :                                                         continue;
     386              :                                         }
     387              :                                 }
     388              : 
     389            0 :                                 for (size_t fi = 0; fi < nFct; ++fi)
     390              :                                 {
     391            0 :                                         dd->inner_dof_indices(elem, fg[fi], vInd);
     392              : 
     393              :                                         const size_t nDof = vInd.size();
     394            0 :                                         for (size_t dof = 0; dof < nDof; ++dof)
     395              :                                         {
     396            0 :                                                 const number tmp = DoFRef(uFine, vInd[dof]) - DoFRef(uCoarse, vInd[dof]);
     397            0 :                                                 sum += tmp*tmp;
     398              :                                         }
     399              :                                 }
     400              :                         }
     401              :                         // note: no duplicate additions possible
     402            0 :                 }
     403              : 
     404              :                 template <typename TBaseElem>
     405            0 :                 void add_norm_values
     406              :                 (
     407              :                         number& sum,
     408              :                         const TGridFunction& uFine,
     409              :                         ConstSmartPtr<DoFDistribution> dd,
     410              :                         int si,
     411              :                         const FunctionGroup& fg
     412              :                 ) const
     413              :                 {
     414            0 :                         const SurfaceView& sv = *dd->surface_view();
     415            0 :                         const MultiGrid& mg = *dd->multi_grid();
     416              : 
     417            0 :                         const number nFct = fg.size();
     418              : 
     419              :                         // iterate all elements (including SHADOW_RIM_COPY!)
     420              :                         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     421            0 :                         iter = dd->template begin<TBaseElem>(si, SurfaceView::ALL);
     422            0 :                         iterEnd = dd->template end<TBaseElem>(si, SurfaceView::ALL);
     423              :                         std::vector<DoFIndex> vInd;
     424            0 :                         for (; iter != iterEnd; ++iter)
     425              :                         {
     426              :                                 TBaseElem* elem = *iter;
     427            0 :                                 if (sv.is_contained(elem, dd->grid_level(), SurfaceView::SHADOW_RIM_COPY))
     428              :                                 {
     429            0 :                                         if (mg.num_children<TBaseElem>(elem) > 0)
     430              :                                         {
     431              :                                                 TBaseElem* child = mg.get_child<TBaseElem>(elem, 0);
     432            0 :                                                 if (sv.is_contained(child, dd->grid_level(), SurfaceView::SURFACE_RIM))
     433            0 :                                                         continue;
     434              :                                         }
     435              :                                 }
     436              : 
     437            0 :                                 for (size_t fi = 0; fi < nFct; ++fi)
     438              :                                 {
     439            0 :                                         dd->inner_dof_indices(elem, fg[fi], vInd);
     440              : 
     441              :                                         const size_t nDof = vInd.size();
     442            0 :                                         for (size_t dof = 0; dof < nDof; ++dof)
     443              :                                         {
     444            0 :                                                 const number tmp = DoFRef(uFine, vInd[dof]);
     445            0 :                                                 sum += tmp*tmp;
     446              :                                         }
     447              :                                 }
     448              :                         }
     449              :                         // note: no duplicate additions possible
     450            0 :                 }
     451              : };
     452              : 
     453              : 
     454              : 
     455              : //! Wrapper class for time dependence.
     456              : template <typename TGridFunction>
     457              : class TimeDependentSpace :
     458              :                 public IGridFunctionSpace<TGridFunction>
     459              : {
     460              : public:
     461              :         typedef IGridFunctionSpace<TGridFunction> base_type;
     462              :         typedef IComponentSpace<TGridFunction> comp_space_type;
     463              : 
     464              :         /// time dependent CTOR
     465              :         TimeDependentSpace(SmartPtr<comp_space_type> spSpace, number tScale)
     466              :         : m_spSpatialSpace(spSpace), m_tScale(tScale) {};
     467              : 
     468              :         /// DTOR
     469              :         virtual ~TimeDependentSpace() {};
     470              : 
     471              :         using base_type::norm;
     472              :         using base_type::distance;
     473              :         using base_type::scaling;
     474              : 
     475              :         /// scaling (OVERRIDE)
     476              :         double scaling() const
     477              :         { return (m_spSpatialSpace->scaling()*m_tScale); }
     478              : 
     479              :         /// characteristic time
     480              :         void update_time_data(number tScale)
     481            0 :         {  m_tScale = tScale; }
     482              : 
     483              :         /// print config string
     484              :         std::string config_string() const
     485              :         {
     486              :                 std::stringstream ss;
     487              :                 ss << "TimeDependentSpace for " <<  std::endl;
     488              :                 ss <<  m_spSpatialSpace->config_string() << std::endl;
     489              :                 return ss.str();
     490              :         }
     491              : 
     492              : protected:
     493              :         SmartPtr<comp_space_type> m_spSpatialSpace;
     494              :         number m_tScale;
     495              : };
     496              : 
     497              : 
     498              : /** Evaluates difference between two grid functions in L2 norm */
     499              : template <typename TGridFunction>
     500              : class L2ComponentSpace :
     501              :                 public IComponentSpace<TGridFunction>,
     502              :                 public IObjectWithWeights<typename L2DistIntegrand<TGridFunction>::weight_type >
     503              : {
     504              : public:
     505              :         typedef IComponentSpace<TGridFunction> base_type;
     506              :         typedef typename L2DistIntegrand<TGridFunction>::weight_type weight_type;
     507              :         typedef IObjectWithWeights<weight_type> weighted_obj_type;
     508              : 
     509              :         /// CTOR
     510            0 :         L2ComponentSpace(const char *fctNames)
     511            0 :         : base_type(fctNames), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))) {};
     512              : 
     513            0 :         L2ComponentSpace(const char *fctNames, int order)
     514            0 :         : base_type(fctNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))) {};
     515              : 
     516            0 :         L2ComponentSpace(const char *fctNames,  int order, double weight, const char* ssNames=0)
     517            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(weight))) {};
     518              : 
     519            0 :         L2ComponentSpace(const char *fctNames, int order, ConstSmartPtr<weight_type> spWeight, const char* ssNames=0)
     520            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight) {};
     521              : 
     522              :         /// DTOR
     523            0 :         ~L2ComponentSpace() {};
     524              : 
     525              :         using IComponentSpace<TGridFunction>::norm;
     526              :         using IComponentSpace<TGridFunction>::distance;
     527              : 
     528              :         /// for weighted norms
     529              :         using weighted_obj_type::set_weight;
     530              :         using weighted_obj_type::get_weight;
     531              :         using weighted_obj_type::m_spWeight;
     532              : 
     533              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     534            0 :         double norm2(TGridFunction& uFine)
     535            0 :         { return L2Norm2(uFine, base_type::m_fctNames.c_str(), base_type::m_quadorder, base_type::m_ssNames, weighted_obj_type::m_spWeight); }
     536              : 
     537              :         /// \copydoc IComponentSpace<TGridFunction>::distance
     538            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     539            0 :         { return L2Distance2(uFine, base_type::m_fctNames.c_str(), uCoarse, base_type::m_fctNames.c_str(),
     540            0 :                 base_type::m_quadorder, base_type::m_ssNames, weighted_obj_type::m_spWeight);}
     541              : 
     542              : 
     543              : 
     544              : };
     545              : 
     546              : /** Evaluates difference between two grid functions in L2 norm */
     547              : template <typename TGridFunction>
     548              : class L2QuotientSpace :
     549              :                 public IComponentSpace<TGridFunction>,
     550              :                 public IObjectWithWeights<typename L2DistIntegrand<TGridFunction>::weight_type >
     551              : {
     552              : public:
     553              :         typedef IComponentSpace<TGridFunction> base_type;
     554              :         typedef typename L2DistIntegrand<TGridFunction>::weight_type weight_type;
     555              :         typedef IObjectWithWeights<weight_type> weighted_obj_type;
     556              : 
     557              :         /// CTOR
     558            0 :         L2QuotientSpace(const char *fctNames)
     559            0 :         : base_type(fctNames), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))) {};
     560              : 
     561            0 :         L2QuotientSpace(const char *fctNames, int order)
     562            0 :         : base_type(fctNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))) {};
     563              : 
     564            0 :         L2QuotientSpace(const char *fctNames,  int order, double weight, const char* ssNames=0)
     565            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(weight))) {};
     566              : 
     567            0 :         L2QuotientSpace(const char *fctNames, int order, ConstSmartPtr<weight_type> spWeight, const char* ssNames=0)
     568            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight) {};
     569              : 
     570              :         /// DTOR
     571            0 :         ~L2QuotientSpace() {};
     572              : 
     573              :         using IComponentSpace<TGridFunction>::norm;
     574              :         using IComponentSpace<TGridFunction>::distance;
     575              : 
     576              :         /// for weighted norms
     577              :         using weighted_obj_type::set_weight;
     578              :         using weighted_obj_type::get_weight;
     579              :         using weighted_obj_type::m_spWeight;
     580              : 
     581              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     582            0 :         double norm2(TGridFunction& u)
     583              :         {
     584              :                 typedef ConstUserNumber<TGridFunction::dim> MyConstUserData;
     585              :                 typedef SmartPtr<UserData<number, TGridFunction::dim> > SPUserData;
     586              : 
     587            0 :                 SPUserData spConst= make_sp(new MyConstUserData(1.0));
     588            0 :                 number Meas = Integral(spConst, u, base_type::m_ssNames, 0.0, 1, "best");
     589            0 :                 number uAvg = Integral(u,  base_type::m_fctNames.c_str(), base_type::m_ssNames, base_type::m_quadorder);
     590              : 
     591            0 :                 std::cerr << "Average:=" << uAvg <<"/" << Meas << " = " << uAvg/Meas << std::endl;
     592            0 :                 SPUserData spAvg = make_sp(new MyConstUserData(uAvg/Meas));
     593            0 :                 double qnorm = L2Error(spAvg, u, base_type::m_fctNames.c_str(), 0.0, base_type::m_quadorder, base_type::m_ssNames);
     594              : 
     595            0 :                 return qnorm*qnorm;
     596              :         }
     597              : 
     598              :         /// \copydoc IComponentSpace<TGridFunction>::distance
     599            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     600              :         {
     601              :                 typedef ConstUserNumber<TGridFunction::dim> MyConstUserData;
     602              :                 typedef SmartPtr<UserData<number, TGridFunction::dim> > SPUserData;
     603              : 
     604            0 :                 SPUserData spConst= make_sp(new MyConstUserData(1.0));
     605            0 :                 number Meas = Integral(spConst, uFine, base_type::m_ssNames, 0.0, 1, "best");
     606            0 :                 number avgFine = Integral(uFine, base_type::m_fctNames.c_str(), base_type::m_ssNames, base_type::m_quadorder);
     607            0 :                 number avgCoarse = Integral(uCoarse, base_type::m_fctNames.c_str(), base_type::m_ssNames, base_type::m_quadorder);
     608              : 
     609            0 :                 std::cerr << "Average:=(" << avgFine << "-" << avgCoarse<<")/" << Meas << " = " << (avgFine-avgCoarse)/Meas << std::endl;
     610            0 :                 return L2Distance2(uFine, base_type::m_fctNames.c_str(),
     611              :                                                   uCoarse, base_type::m_fctNames.c_str(),
     612              :                                                   base_type::m_quadorder, base_type::m_ssNames, weighted_obj_type::m_spWeight,
     613            0 :                                                   (avgFine-avgCoarse)/Meas);
     614              :         }
     615              : 
     616              : 
     617              : 
     618              : };
     619              : 
     620              : 
     621              : /** Evaluates distance between two grid functions in H1 semi-norm */
     622              : template <typename TGridFunction>
     623              : class H1SemiComponentSpace
     624              : : public IComponentSpace<TGridFunction>,
     625              :   public IObjectWithWeights<typename H1SemiDistIntegrand<TGridFunction>::weight_type >
     626              : {
     627              : public:
     628              :         typedef IComponentSpace<TGridFunction> base_type;
     629              :         typedef typename H1SemiDistIntegrand<TGridFunction>::weight_type weight_type;
     630              :         typedef IObjectWithWeights<weight_type> weighted_obj_type;
     631              : 
     632              : 
     633            0 :         H1SemiComponentSpace(const char *fctNames)
     634            0 :         : base_type(fctNames), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(1.0))) {};
     635              : 
     636            0 :         H1SemiComponentSpace(const char *fctNames, int order)
     637            0 :         : base_type(fctNames, order), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(1.0))) {};
     638              : 
     639            0 :         H1SemiComponentSpace(const char *fctNames, int order, number weight, const char* ssNames=0)
     640            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(weight)))  {};
     641              : 
     642            0 :         H1SemiComponentSpace(const char *fctNames, int order, ConstSmartPtr<weight_type> spWeight, const char* ssNames=0)
     643            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight) {};
     644              : 
     645            0 :         H1SemiComponentSpace(const char *fctNames, int order, const char* ssNames, ConstSmartPtr<weight_type> spWeight)
     646            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight) {};
     647              : 
     648              :         /// DTOR
     649            0 :         ~H1SemiComponentSpace() {};
     650              : 
     651              : 
     652              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     653              :         /// \copydoc IComponentSpace<TGridFunction>::distance
     654              :         using IComponentSpace<TGridFunction>::norm;
     655              :         using IComponentSpace<TGridFunction>::distance;
     656              : 
     657              :         /// \copydoc IComponentSpace<TGridFunction>::norm2
     658            0 :         double norm2(TGridFunction& uFine)
     659            0 :         { return H1SemiNorm2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), base_type::m_quadorder, NULL, weighted_obj_type::m_spWeight); }
     660              : 
     661              :         /// \copydoc IComponentSpace<TGridFunction>::distance2
     662            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     663            0 :         { return H1SemiDistance2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), uCoarse, base_type::m_fctNames.c_str(), base_type::m_quadorder, m_spWeight); }
     664              : 
     665              :         /// for weighted norms
     666              :         using weighted_obj_type::set_weight;
     667              :         using weighted_obj_type::get_weight;
     668              :         using weighted_obj_type::m_spWeight;
     669              : 
     670              : };
     671              : 
     672              : 
     673              : 
     674              : /*
     675              : //! Evaluates distance w.r.t kinetic energy
     676              : template <typename TGridFunction>
     677              : class KineticEnergyComponentSpace
     678              : : public IComponentSpace<TGridFunction>,
     679              :   public IObjectWithWeights<typename L2Integrand<TGridFunction>::weight_type >
     680              : {
     681              : public:
     682              :         typedef IComponentSpace<TGridFunction> base_type;
     683              :         typedef typename L2Integrand<TGridFunction>::weight_type weight_type;
     684              :         typedef IObjectWithWeights<weight_type> weighted_obj_type;
     685              :         typedef DarcyVelocityLinker<TGridFunction::dim> velocity_type;
     686              : 
     687              : 
     688              :         KineticEnergyComponentSpace(SmartPtr<velocity_type> spVelocity, const char *fctNames)
     689              :         : base_type(fctNames), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))), m_spVelocity(spVelocity) {};
     690              : 
     691              :         KineticEnergyComponentSpace(SmartPtr<velocity_type> spVelocity, const char *fctNames, int order)
     692              :         : base_type(fctNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(1.0))), m_spVelocity(spVelocity)  {};
     693              : 
     694              :         KineticEnergyComponentSpace(SmartPtr<velocity_type> spVelocity, const char *fctNames, int order, number weight, const char* ssNames=0)
     695              :         : base_type(fctNames, ssNames, order), weighted_obj_type(make_sp(new ConstUserNumber<TGridFunction::dim>(weight))), m_spVelocity(spVelocity)   {};
     696              : 
     697              :         KineticEnergyComponentSpace(SmartPtr<velocity_type> spVelocity, const char *fctNames, int order, ConstSmartPtr<weight_type> spWeight, const char* ssNames=0)
     698              :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight), m_spVelocity(spVelocity)  {};
     699              : 
     700              :         KineticEnergyComponentSpace(SmartPtr<velocity_type> spVelocity, const char *fctNames, int order, const char* ssNames, ConstSmartPtr<weight_type> spWeight)
     701              :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight), m_spVelocity(spVelocity) {};
     702              : 
     703              :         /// DTOR
     704              :         ~KineticEnergyComponentSpace() {};
     705              : 
     706              : 
     707              :         using IComponentSpace<TGridFunction>::m_quadorder;
     708              :         using IComponentSpace<TGridFunction>::norm;
     709              :         using IComponentSpace<TGridFunction>::distance;
     710              : 
     711              :         /// \copydoc IComponentSpace<TGridFunction>::norm2
     712              :         double norm2(TGridFunction& u)
     713              :         {
     714              :                 const char* subsets = NULL;
     715              :                 UserDataIntegrandSq<MathVector<TGridFunction::dim>, TGridFunction> integrand2(m_spVelocity, &u, 0.0);
     716              :                 return IntegrateSubsets(integrand2, u, subsets, m_quadorder);
     717              :         }
     718              : 
     719              :         /// \copydoc IComponentSpace<TGridFunction>::distance2
     720              :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     721              :         {
     722              :                 // UG_THROW("Not implemented!");
     723              :                 const char* subsets = NULL;
     724              :                 UserDataDistIntegrandSq<MathVector<TGridFunction::dim>, TGridFunction> integrand2(m_spVelocity, uFine, 0, uCoarse, 0);
     725              :                 return IntegrateSubsets(integrand2, uFine, subsets, m_quadorder);
     726              :         }
     727              : 
     728              :         /// for weighted norms
     729              :         using weighted_obj_type::set_weight;
     730              :         using weighted_obj_type::get_weight;
     731              :         using weighted_obj_type::m_spWeight;
     732              : 
     733              :         void set_velocity(SmartPtr<velocity_type> spVelocity)
     734              :         { m_spVelocity = spVelocity;}
     735              : 
     736              : protected:
     737              :         SmartPtr<velocity_type> m_spVelocity;
     738              : 
     739              : };
     740              : */
     741              : 
     742              : //!
     743              : /** Evaluates distance between two grid functions in H1 semi-norm */
     744              : template <typename TGridFunction>
     745              : class H1EnergyComponentSpace
     746              : : public IComponentSpace<TGridFunction>,
     747              :   public IObjectWithWeights<typename H1EnergyDistIntegrand<TGridFunction>::weight_type >
     748              : {
     749              : public:
     750              :         typedef IComponentSpace<TGridFunction> base_type;
     751              :         typedef typename H1SemiDistIntegrand<TGridFunction>::weight_type weight_type;
     752              :         typedef IObjectWithWeights<weight_type> weighted_obj_type;
     753              :         // typedef DarcyVelocityLinker<TGridFunction::dim> velocity_type;
     754              :         static const int dim = TGridFunction::dim;
     755              :         typedef UserData<MathVector<dim>, dim> velocity_type;
     756              : 
     757            0 :         H1EnergyComponentSpace(const char *fctNames)
     758            0 :         : base_type(fctNames), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(1.0))), m_spVelocity(SPNULL) {};
     759              : 
     760            0 :         H1EnergyComponentSpace(const char *fctNames, int order)
     761            0 :         : base_type(fctNames, order), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(1.0))), m_spVelocity(SPNULL) {};
     762              : 
     763            0 :         H1EnergyComponentSpace(const char *fctNames, int order, number weight, const char* ssNames=0)
     764            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(make_sp(new ConstUserMatrix<TGridFunction::dim>(weight))), m_spVelocity(SPNULL)  {};
     765              : 
     766            0 :         H1EnergyComponentSpace(const char *fctNames, int order, ConstSmartPtr<weight_type> spWeight, const char* ssNames=0)
     767            0 :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight), m_spVelocity(SPNULL) {};
     768              : 
     769              :         /*H1EnergyComponentSpace(const char *fctNames, int order, const char* ssNames, ConstSmartPtr<weight_type> spWeight)
     770              :         : base_type(fctNames, ssNames, order), weighted_obj_type(spWeight), m_spVelocity(SPNULL) {};*/
     771              : 
     772              :         /// DTOR
     773            0 :         ~H1EnergyComponentSpace() {};
     774              : 
     775              : 
     776              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     777              :         /// \copydoc IComponentSpace<TGridFunction>::distance
     778              :         using IComponentSpace<TGridFunction>::norm;
     779              :         using IComponentSpace<TGridFunction>::distance;
     780              :  
     781              :         /// \copydoc IComponentSpace<TGridFunction>::norm2
     782            0 :         double norm2(TGridFunction& uFine)
     783              :         {
     784            0 :                 if (m_spVelocity.valid()) {
     785              :                         //const char* subsets = NULL; // [q^2]
     786            0 :                         UserDataIntegrandSq<MathVector<TGridFunction::dim>, TGridFunction> integrand2(m_spVelocity, &uFine, 0.0);
     787            0 :                         return IntegrateSubsets(integrand2, uFine, base_type::m_ssNames, base_type::m_quadorder);
     788              :                 } else {
     789            0 :                         return H1EnergyNorm2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), base_type::m_quadorder, base_type::m_ssNames, weighted_obj_type::m_spWeight);
     790              :                 }
     791              :         }
     792              : 
     793              :         /// \copydoc IComponentSpace<TGridFunction>::distance2
     794            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     795            0 :         { return H1EnergyDistance2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), uCoarse, base_type::m_fctNames.c_str(), base_type::m_quadorder,base_type::m_ssNames, weighted_obj_type::m_spWeight); }
     796              : 
     797              :         /// for weighted norms
     798              :         using weighted_obj_type::set_weight;
     799              :         using weighted_obj_type::get_weight;
     800              : 
     801            0 :         void set_velocity(SmartPtr<velocity_type> spVelocity)
     802            0 :         { m_spVelocity = spVelocity;}
     803              : 
     804              : protected:
     805              :                 SmartPtr<velocity_type> m_spVelocity;
     806              : 
     807              : };
     808              : 
     809              : /** Defines a H1 space for single component */
     810              : template <typename TGridFunction>
     811              : class H1ComponentSpace :
     812              :                 public IComponentSpace<TGridFunction>
     813              : {
     814              : public:
     815              :         typedef IComponentSpace<TGridFunction> base_type;
     816              : 
     817            0 :         H1ComponentSpace(const char *fctNames) : base_type(fctNames) {};
     818            0 :         H1ComponentSpace(const char *fctNames, int order) : base_type(fctNames, order) {};
     819            0 :         H1ComponentSpace(const char *fctNames,  const char* ssNames, int order) : base_type(fctNames, ssNames, order) {};
     820            0 :         ~H1ComponentSpace() {};
     821              : 
     822              :         using IComponentSpace<TGridFunction>::norm;
     823              :         using IComponentSpace<TGridFunction>::distance;
     824              : 
     825              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     826            0 :         double norm2(TGridFunction& uFine)
     827            0 :         { return H1Norm2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), base_type::m_quadorder, base_type::m_ssNames); }
     828              : 
     829              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     830            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     831            0 :         { return H1Distance2<TGridFunction>(uFine, base_type::m_fctNames.c_str(), uCoarse, base_type::m_fctNames.c_str(), base_type::m_quadorder, base_type::m_ssNames); }
     832              : 
     833              : };
     834              : 
     835              : 
     836              : 
     837              : //! Defines a composite space, (i.e., additive composition from other spaces)
     838              : /*! Employs a l2-type extension: \| u \|^2 := \sum_I \sigma_I \| u \|_I^2
     839              :  *  TODO: Merge with ApproximationSpace?
     840              :  * */
     841              : template <typename TGridFunction>
     842              : class CompositeSpace : public IGridFunctionSpace<TGridFunction>
     843              : {
     844              : public:
     845              :         typedef IGridFunctionSpace<TGridFunction> base_type;
     846              :         typedef IComponentSpace<TGridFunction> obj_type;
     847              :         typedef TimeDependentSpace<TGridFunction> time_dependent_obj_type;
     848              :         typedef std::pair<SmartPtr<obj_type>, number> weighted_obj_type;
     849              : 
     850            0 :         CompositeSpace() {};
     851              :         // virtual ~CompositeSpace() {};
     852              : 
     853              :         using base_type::norm;
     854              :         using base_type::distance;
     855              : 
     856              :         /// \copydoc IComponentSpace<TGridFunction>::norm
     857            0 :         double norm(TGridFunction& uFine)
     858            0 :         { return(sqrt(norm2(uFine))); }
     859              : 
     860              :         /// \copydoc IComponentSpace<TGridFunction>::norm2
     861            0 :         double norm2(TGridFunction& uFine)
     862              :         {
     863              :                 number unorm2 = 0.0;
     864            0 :                 for (typename std::vector<weighted_obj_type>::iterator it = m_spWeightedSubspaces.begin();
     865            0 :                                 it!= m_spWeightedSubspaces.end(); ++it)
     866              :                 {
     867            0 :                         double snorm2 = it->first->norm2(uFine);
     868            0 :                         unorm2 += it->second * snorm2;                                               // scaling
     869            0 :                         UG_LOG("composite-norm2:\t" << snorm2 << "\t*\t" << it->second
     870              :                                         << "\t=\t" << it->second * snorm2 << std::endl);
     871              :                 }
     872              :                 UG_LOG("composite-norm2-final:\t" << unorm2 << std::endl);
     873            0 :                 return unorm2;
     874              :         }
     875              : 
     876              :         /// \copydoc IComponentSpace<TGridFunction>::distance2
     877            0 :         double distance2(TGridFunction& uFine, TGridFunction& uCoarse)
     878              :         {
     879              :                 number unorm2 = 0.0;
     880            0 :                 for (typename std::vector<weighted_obj_type>::iterator it = m_spWeightedSubspaces.begin();
     881            0 :                                         it!= m_spWeightedSubspaces.end(); ++it)
     882              :                 {
     883            0 :                         double sdist2 = it->first->distance2(uFine, uCoarse);
     884            0 :                         unorm2 += it->second * sdist2; // scaling
     885            0 :                         UG_LOG("composite-dist2:\t" << sdist2 << "\t*\t" << it->second
     886              :                                         << "\t=\t" << it->second * sdist2 << std::endl);
     887              :                 }
     888              :                 UG_LOG("composite-dist2-final:\t" << unorm2 << std::endl);
     889            0 :                 return unorm2;
     890              :         }
     891              : 
     892              :         /// \copydoc IComponentSpace<TGridFunction>::distance2
     893            0 :         double distance(TGridFunction& uFine, TGridFunction& uCoarse)
     894            0 :         { return sqrt(distance2(uFine, uCoarse)); }
     895              : 
     896              :         /// add space to composite (with weight 1.0)
     897            0 :         void add(SmartPtr<obj_type> spSubSpace)
     898            0 :         { m_spWeightedSubspaces.push_back(std::make_pair(spSubSpace, 1.0)); }
     899              : 
     900              :         /// add space to composite (with variable weight)
     901            0 :         void add(SmartPtr<obj_type> spSubSpace, number sigma)
     902            0 :         { m_spWeightedSubspaces.push_back(std::make_pair(spSubSpace, sigma)); }
     903              : 
     904              :         /// print config string                                                                                                                                                                              
     905            0 :         std::string config_string() const
     906              :         {
     907            0 :             std::stringstream ss;
     908              :             ss << "CompositeSpace:" << std::endl;
     909              : 
     910            0 :             for (typename std::vector<weighted_obj_type>::const_iterator it = m_spWeightedSubspaces.begin();
     911            0 :                         it!= m_spWeightedSubspaces.end(); ++it)
     912            0 :             { ss << it->first->config_string(); }
     913              : 
     914            0 :             return ss.str();
     915            0 :         }
     916              : 
     917              : 
     918              :         //! Forward update to all members
     919            0 :         void update_time_data(number t)
     920              :         {
     921            0 :                 for (typename std::vector<weighted_obj_type>::iterator it = m_spWeightedSubspaces.begin();
     922            0 :                         it!= m_spWeightedSubspaces.end(); ++it)
     923              :                 {
     924            0 :                         SmartPtr<time_dependent_obj_type> spSpaceT = it->first.template cast_dynamic<time_dependent_obj_type> ();
     925            0 :                         if (spSpaceT.valid()) spSpaceT->update_time_data(t);
     926              :                 }
     927            0 :         }
     928              : 
     929              :         //! Check, if any object is time-dependent.
     930            0 :         bool is_time_dependent() const
     931              :         {
     932            0 :                 for (typename std::vector<weighted_obj_type>::const_iterator it = m_spWeightedSubspaces.begin();
     933            0 :                                 it!= m_spWeightedSubspaces.end(); ++it)
     934              :                 {
     935            0 :                         SmartPtr<time_dependent_obj_type> spSpaceT = it->first.template cast_dynamic<time_dependent_obj_type>();
     936            0 :                         if (spSpaceT.valid()) return true;
     937              :                 }
     938              :                 return false;
     939              :         }
     940              : 
     941              :         const std::vector<weighted_obj_type> &get_subspaces() const
     942              :         { return m_spWeightedSubspaces; }
     943              : 
     944              : protected:
     945              :         std::vector<weighted_obj_type> m_spWeightedSubspaces;
     946              : 
     947              : };
     948              : 
     949              : /*
     950              : template <typename TGridFunction>
     951              : class TimeDependentCompositeSpace
     952              :         : public CompositeSpace<TGridFunction>, public ITimeDependentSpace<TGridFunction>
     953              : {
     954              : protected:
     955              :         using CompositeSpace<TGridFunction>::m_spSubspaces;
     956              : 
     957              : public:
     958              :         typedef typename IComponentSpace<TGridFunction> obj_type;
     959              : 
     960              : 
     961              :         /// add spaces to composite
     962              :         void add(SmartPtr<obj_type> spSubSpace)
     963              :         { m_spSubspaces.push_back(make_sp(new ITimeDependentSpace(spSubSpace))); }
     964              : 
     965              :         //! Forward update to all members
     966              :         void update_time_data(number t)
     967              :         {
     968              :                 for (typename std::vector<SmartPtr<obj_type> >::iterator it = m_spSubspaces.begin();
     969              :                         it!= m_spSubspaces.end(); ++it)
     970              :                 { if ((*it)->is_time_dependent()) (*it)->update_time_data(t); }
     971              :         }
     972              : 
     973              :         //! Check, if all objects are time-dependent.
     974              :         bool is_time_dependent() const
     975              :         {
     976              :                 for (typename std::vector<SmartPtr<obj_type> >::const_iterator it = m_spSubspaces.begin();
     977              :                                 it!= m_spSubspaces.end(); ++it)
     978              :                 { if ((*it)->is_time_dependent()) return true; }
     979              :                 return false;
     980              :         }
     981              : };
     982              : 
     983              :  */
     984              : 
     985              : } // namespace ug
     986              : #endif
        

Generated by: LCOV version 2.0-1