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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "dof_position_util.h"
      34              : #include "approximation_space.h"
      35              : #include "lib_disc/domain.h"
      36              : #include "lib_disc/domain_util.h"
      37              : #include "lib_disc/domain_traits.h"
      38              : 
      39              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      40              : #include "lib_disc/local_finite_element/local_dof_set.h"
      41              : #include "lib_disc/reference_element/reference_mapping_provider.h"
      42              : #include "lib_disc/reference_element/reference_element_util.h"
      43              : 
      44              : namespace ug{
      45              : 
      46              : ////////////////////////////////////////////////////////////////////////////////
      47              : //      DoFPositions
      48              : ////////////////////////////////////////////////////////////////////////////////
      49              : 
      50              : template <int refDim, int dim>
      51            0 : bool InnerDoFPositionElem(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
      52              :                       const std::vector<MathVector<dim> >& vVertPos, const LFEID& lfeID)
      53              : {
      54              : //      get local dof set
      55              :         const DimLocalDoFSet<refDim>& lds =
      56            0 :                                         LocalFiniteElementProvider::get_dofs<refDim>(roid, lfeID);
      57              : 
      58              : //      create a reference mapping
      59              :          DimReferenceMapping<refDim,dim>& map =
      60              :                                         ReferenceMappingProvider::get<refDim,dim>(roid, vVertPos);
      61              : 
      62              : //      clear pos
      63              :         vPos.clear();
      64              : 
      65              : //      bool flag if position is exact, or no exact position available for shapes
      66              :         bool bExact = true;
      67              : 
      68              : //      loop all shape functions
      69            0 :         for(size_t sh = 0; sh < lds.num_sh(); ++sh)
      70              :         {
      71              :         //      check if dof in interior
      72            0 :                 if(lds.local_dof(sh).dim() != refDim) continue;
      73              : 
      74              :         //      get local position
      75              :                 MathVector<refDim> locPos;
      76            0 :                 bExact &= lds.position(sh, locPos);
      77              : 
      78              :         //      map to global position
      79              :                 MathVector<dim> globPos;
      80            0 :                 map.local_to_global(globPos, locPos);
      81              : 
      82              :         //      add
      83            0 :                 vPos.push_back(globPos);
      84              :         }
      85              : 
      86              : //      return if positions are given exactly
      87            0 :         return bExact;
      88              : };
      89              : 
      90              : template <int dim>
      91            0 : bool InnerDoFPositionVertex(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
      92              :                             const std::vector<MathVector<dim> >& vVertPos, const LFEID& lfeID)
      93              : {
      94              :         UG_ASSERT(vVertPos.size() == 1, "Vertex should have only on inner Vertex");
      95              : 
      96              : //      get local dof set
      97            0 :         const CommonLocalDoFSet& lds = LocalFiniteElementProvider::get_dofs(lfeID);
      98              : 
      99              : //      clear pos
     100              :         vPos.clear();
     101              : 
     102              : //      loop all shape functions
     103            0 :         for(int sh = 0; sh < lds.num_dof(ROID_VERTEX); ++sh)
     104            0 :                 vPos.push_back(vVertPos[0]);
     105              : 
     106              : //      return if positions are given exactly
     107            0 :         return true;
     108              : };
     109              : 
     110              : 
     111              : template <int dim>
     112            0 : bool InnerDoFPosition(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
     113              :                       const std::vector<MathVector<dim> >& vCornerCoord, const LFEID& lfeID)
     114              : {
     115            0 :         switch(ReferenceElementDimension(roid))
     116              :         {
     117            0 :                 case VERTEX: return InnerDoFPositionVertex<dim>(vPos, roid, vCornerCoord, lfeID);
     118            0 :                 case EDGE:   return InnerDoFPositionElem<1,dim>(vPos, roid, vCornerCoord, lfeID);
     119            0 :                 case FACE:   return InnerDoFPositionElem<2,dim>(vPos, roid, vCornerCoord, lfeID);
     120            0 :                 case VOLUME: return InnerDoFPositionElem<3,dim>(vPos, roid, vCornerCoord, lfeID);
     121            0 :                 default: UG_THROW("Base Object type not found.");
     122              :         }
     123              : }
     124              : 
     125              : template <typename TDomain>
     126            0 : bool InnerDoFPosition(std::vector<MathVector<TDomain::dim> >& vPos, GridObject* elem,
     127              :                       const TDomain& domain, const LFEID& lfeID)
     128              : {
     129              : //      reference object id
     130            0 :         const ReferenceObjectID roid = elem->reference_object_id();
     131              : 
     132              : //      get the vertices
     133              :         std::vector<MathVector<TDomain::dim> > vVertPos;
     134            0 :         switch(elem->base_object_id())
     135              :         {
     136              :                 case VERTEX: CollectCornerCoordinates(vVertPos, *static_cast<Vertex*>(elem), domain, true); break;
     137              :                 case EDGE: CollectCornerCoordinates(vVertPos, *static_cast<Edge*>(elem), domain, true); break;
     138              :                 case FACE: CollectCornerCoordinates(vVertPos, *static_cast<Face*>(elem), domain, true); break;
     139              :                 case VOLUME: CollectCornerCoordinates(vVertPos, *static_cast<Volume*>(elem), domain, true); break;
     140            0 :                 default: UG_THROW("Base Object type not found.");
     141              :         }
     142              : 
     143              : //      forward
     144            0 :         return InnerDoFPosition<TDomain::dim>(vPos, roid, vVertPos, lfeID);
     145            0 : }
     146              : 
     147              : 
     148              : 
     149              : template <int refDim, int dim>
     150            0 : bool DoFPositionElem(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
     151              :                  const std::vector<MathVector<dim> >& vVertPos, const LFEID& lfeID)
     152              : {
     153              : //      get local shape function set
     154              :         const DimLocalDoFSet<refDim>& lds
     155            0 :                                         = LocalFiniteElementProvider::get_dofs<refDim>(roid, lfeID);
     156              : 
     157              : //      create a reference mapping
     158              :         const DimReferenceMapping<refDim,dim>& map =
     159              :                                         ReferenceMappingProvider::get<refDim,dim>(roid, vVertPos);
     160              : 
     161              : //      clear pos
     162            0 :         vPos.resize(lds.num_sh());
     163              : 
     164              : //      bool flag if position is exact, or no exact position available for shapes
     165              :         bool bExact = true;
     166              : 
     167              : //      loop all shape functions
     168            0 :         for(size_t sh = 0; sh < lds.num_sh(); ++sh)
     169              :         {
     170              :         //      get local position
     171              :                 MathVector<refDim> locPos;
     172            0 :                 bExact &= lds.position(sh, locPos);
     173              : 
     174              :         //      map to global position
     175            0 :                 map.local_to_global(vPos[sh], locPos);
     176              :         }
     177              : 
     178              : //      return if positions are given exactly
     179            0 :         return bExact;
     180              : };
     181              : 
     182              : template <int dim>
     183            0 : bool DoFPositionVertex(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
     184              :                        const std::vector<MathVector<dim> >& vVertPos, const LFEID& lfeID)
     185              : {
     186              : //      get local dof set
     187            0 :         const CommonLocalDoFSet& lds = LocalFiniteElementProvider::get_dofs(lfeID);
     188              : 
     189              : //      clear pos
     190              :         vPos.clear();
     191              : 
     192              : //      loop all shape functions
     193            0 :         for(size_t co = 0; co < vVertPos.size(); ++co)
     194            0 :                 for(int sh = 0; sh < lds.num_dof(ROID_VERTEX); ++sh)
     195            0 :                 vPos.push_back(vVertPos[co]);
     196              : 
     197              : //      return if positions are given exactly
     198            0 :         return true;
     199              : };
     200              : 
     201              : template <int dim>
     202            0 : bool DoFPosition(std::vector<MathVector<dim> >& vPos, const ReferenceObjectID roid,
     203              :                  const std::vector<MathVector<dim> >& vCornerCoord, const LFEID& lfeID)
     204              : {
     205            0 :         switch(ReferenceElementDimension(roid))
     206              :         {
     207            0 :                 case VERTEX: return DoFPositionVertex<dim>(vPos, roid, vCornerCoord, lfeID);
     208            0 :                 case EDGE:   return DoFPositionElem<1,dim>(vPos, roid, vCornerCoord, lfeID);
     209            0 :                 case FACE:   return DoFPositionElem<2,dim>(vPos, roid, vCornerCoord, lfeID);
     210            0 :                 case VOLUME: return DoFPositionElem<3,dim>(vPos, roid, vCornerCoord, lfeID);
     211            0 :                 default: UG_THROW("Base Object type not found.");
     212              :         }
     213              : }
     214              : 
     215              : template <typename TDomain>
     216            0 : bool DoFPosition(std::vector<MathVector<TDomain::dim> >& vPos, GridObject* elem,
     217              :                  const TDomain& domain, const LFEID& lfeID)
     218              : {
     219              : //      reference object id
     220            0 :         const ReferenceObjectID roid = elem->reference_object_id();
     221              : 
     222              : //      get the vertices
     223              :         std::vector<MathVector<TDomain::dim> > vVertPos;
     224            0 :         switch(elem->base_object_id())
     225              :         {
     226              :                 case VERTEX: CollectCornerCoordinates(vVertPos, *static_cast<Vertex*>(elem), domain, true); break;
     227              :                 case EDGE: CollectCornerCoordinates(vVertPos, *static_cast<Edge*>(elem), domain, true); break;
     228              :                 case FACE: CollectCornerCoordinates(vVertPos, *static_cast<Face*>(elem), domain, true); break;
     229              :                 case VOLUME: CollectCornerCoordinates(vVertPos, *static_cast<Volume*>(elem), domain, true); break;
     230            0 :                 default: UG_THROW( "Base Object type not found.");
     231              :         }
     232              : 
     233              : //      forward
     234            0 :         return DoFPosition<TDomain::dim>(vPos, roid, vVertPos, lfeID);
     235            0 : }
     236              : 
     237              : 
     238              : ////////////////////////////////////////////////////////////////////////////////
     239              : //      ShapesAtGlobalPosition
     240              : ////////////////////////////////////////////////////////////////////////////////
     241              : 
     242              : template <int dim>
     243            0 : void ShapesAtGlobalPositionVertex(std::vector<std::vector<number> >& vvShape,
     244              :                                   const std::vector<MathVector<dim> >& vGlobPos,
     245              :                                   const LFEID& lfeID)
     246              : {
     247              : //      get local position of DoF
     248            0 :         std::vector<MathVector<0> > vLocPos(vGlobPos.size(), 0.0);
     249              : 
     250              : //      evaluate coarse shape fct at fine local point
     251              :         try{
     252              :                 const LocalShapeFunctionSet<0>& lsfs =
     253              :                                 LocalFiniteElementProvider::get<0>(ROID_VERTEX, lfeID);
     254            0 :                 lsfs.shapes(vvShape, vLocPos);
     255              :         }
     256            0 :         UG_CATCH_THROW("ShapesAtGlobalPosition: Cannot evalute shapes.")
     257            0 : }
     258              : 
     259              : template <int refDim, int dim>
     260            0 : void ShapesAtGlobalPositionElem(std::vector<std::vector<number> >& vvShape,
     261              :                                 const std::vector<MathVector<dim> >& vGlobPos,
     262              :                                 const ReferenceObjectID roid,
     263              :                                 const std::vector<MathVector<dim> >& vCornerCoord,
     264              :                                 const LFEID& lfeID)
     265              : {
     266              : //      get local position of DoF
     267            0 :         std::vector<MathVector<refDim> > vLocPos(vGlobPos.size(), 0.0);
     268              :         try{
     269              :                 DimReferenceMapping<refDim, dim>& map =
     270              :                                 ReferenceMappingProvider::get<refDim, dim>(roid, vCornerCoord);
     271            0 :                 map.global_to_local(vLocPos, vGlobPos);
     272              :         }
     273            0 :         UG_CATCH_THROW("ShapesAtGlobalPosition: Cannot find elem-local Positions.");
     274              : 
     275              : //      evaluate coarse shape fct at fine local point
     276              :         try{
     277              :                 const LocalShapeFunctionSet<refDim>& lsfs =
     278              :                                 LocalFiniteElementProvider::get<refDim>(roid, lfeID);
     279            0 :                 lsfs.shapes(vvShape, vLocPos);
     280              :         }
     281            0 :         UG_CATCH_THROW("ShapesAtGlobalPosition: Cannot evalute shapes.")
     282            0 : }
     283              : 
     284              : template <int dim>
     285            0 : void ShapesAtGlobalPosition(std::vector<std::vector<number> >& vvShape,
     286              :                            const std::vector<MathVector<dim> >& vGlobPos,
     287              :                            const ReferenceObjectID roid,
     288              :                            const std::vector<MathVector<dim> >& vCornerCoord,
     289              :                            const LFEID& lfeID)
     290              : {
     291            0 :         switch(ReferenceElementDimension(roid))
     292              :         {
     293            0 :                 case VERTEX: return ShapesAtGlobalPositionVertex<dim>(vvShape, vGlobPos, lfeID);
     294            0 :                 case EDGE:   return ShapesAtGlobalPositionElem<1,dim>(vvShape, vGlobPos, roid, vCornerCoord, lfeID);
     295            0 :                 case FACE:   return ShapesAtGlobalPositionElem<2,dim>(vvShape, vGlobPos, roid, vCornerCoord, lfeID);
     296            0 :                 case VOLUME: return ShapesAtGlobalPositionElem<3,dim>(vvShape, vGlobPos, roid, vCornerCoord, lfeID);
     297            0 :                 default: UG_THROW("Base Object type not found.");
     298              :         }
     299              : }
     300              : 
     301              : template <typename TDomain>
     302            0 : void ShapesAtGlobalPosition(std::vector<std::vector<number> >& vvShape,
     303              :                            const std::vector<MathVector<TDomain::dim> >& vGlobPos,
     304              :                            GridObject* elem, const TDomain& domain, const LFEID& lfeID)
     305              : {
     306            0 :         const int baseDim = elem->base_object_id();
     307            0 :         if(baseDim == VERTEX)
     308            0 :                 return ShapesAtGlobalPositionVertex<TDomain::dim>(vvShape, vGlobPos, lfeID);
     309              : 
     310              : //      get the vertices
     311              :         std::vector<MathVector<TDomain::dim> > vCornerCoord;
     312            0 :         switch(baseDim)
     313              :         {
     314              :                 case EDGE: CollectCornerCoordinates(vCornerCoord, *static_cast<Edge*>(elem), domain, true); break;
     315              :                 case FACE: CollectCornerCoordinates(vCornerCoord, *static_cast<Face*>(elem), domain, true); break;
     316              :                 case VOLUME: CollectCornerCoordinates(vCornerCoord, *static_cast<Volume*>(elem), domain, true); break;
     317            0 :                 default: UG_THROW( "Base Object type not found.");
     318              :         }
     319              : 
     320              : //      reference object id
     321            0 :         const ReferenceObjectID roid = elem->reference_object_id();
     322              : 
     323              : //      forward
     324            0 :         return ShapesAtGlobalPosition<TDomain::dim>(vvShape, vGlobPos, roid, vCornerCoord, lfeID);
     325            0 : }
     326              : 
     327              : 
     328              : ////////////////////////////////////////////////////////////////////////////////
     329              : //      Extract Positions
     330              : ////////////////////////////////////////////////////////////////////////////////
     331              : 
     332              : template <typename TDomain>
     333            0 : void ExtractPositionsVertex(ConstSmartPtr<TDomain> domain,
     334              :                             ConstSmartPtr<DoFDistribution> dd,
     335              :                             std::vector<MathVector<TDomain::dim> >& vPos)
     336              : {
     337              : //      get position accessor
     338              :         const typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
     339              : 
     340              : //      iterator
     341              :         typename DoFDistribution::traits<Vertex>::const_iterator iter, iterEnd;
     342              : 
     343              : //      algebra indices vector
     344              :         std::vector<size_t> ind;
     345              : 
     346              : //      get iterators
     347            0 :         iter = dd->begin<Vertex>(SurfaceView::ALL);
     348            0 :         iterEnd = dd->end<Vertex>(SurfaceView::ALL);
     349              : 
     350              : //      loop all vertices
     351            0 :         for(;iter != iterEnd; ++iter)
     352              :         {
     353              :         //      get vertex
     354              :                 Vertex* v = *iter;
     355              : 
     356              :         //      load indices associated with vertex
     357            0 :                 dd->inner_algebra_indices(v, ind);
     358              : 
     359              :         //      write position
     360            0 :                 for(size_t i = 0; i < ind.size(); ++i)
     361              :                 {
     362            0 :                         const size_t index = ind[i];
     363              :                         vPos[index] = aaPos[v];
     364              :                 }
     365              :         }
     366            0 : }
     367              : 
     368              : template <typename TDomain, typename TBaseElem>
     369            0 : void ExtractPositionsElem(ConstSmartPtr<TDomain> domain,
     370              :                           ConstSmartPtr<DoFDistribution> dd,
     371              :                           std::vector<MathVector<TDomain::dim> >& vPos)
     372              : {
     373              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     374              : 
     375              : //      vector for positions
     376              :         std::vector<MathVector<TDomain::dim> > vElemPos;
     377              : 
     378              : //      algebra indices vector
     379              :         std::vector<DoFIndex> ind;
     380              : 
     381              : //      loop all subsets
     382            0 :         for(int si = 0; si < dd->num_subsets(); ++si)
     383              :         {
     384              :         //      get iterators
     385            0 :                 iter = dd->begin<TBaseElem>(si, SurfaceView::ALL);
     386            0 :                 iterEnd = dd->end<TBaseElem>(si, SurfaceView::ALL);
     387              : 
     388              :         //      loop all elements
     389            0 :                 for(;iter != iterEnd; ++iter)
     390              :                 {
     391              :                 //      get vertex
     392              :                         TBaseElem* elem = *iter;
     393              : 
     394              :                 //      loop all functions
     395            0 :                         for(size_t fct = 0; fct < dd->num_fct(); ++fct)
     396              :                         {
     397              :                         //      skip non-used function
     398            0 :                                 if(!dd->is_def_in_subset(fct,si)) continue;
     399              : 
     400              :                         //      load indices associated with element function
     401            0 :                                 dd->inner_dof_indices(elem, fct, ind);
     402              : 
     403              :                         //      load positions associated with element and function
     404            0 :                                 InnerDoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
     405              :                                                  dd->local_finite_element_id(fct));
     406              : 
     407              :                         //      check correct size
     408              :                                 UG_ASSERT(ind.size() == vElemPos.size(), "Num MultiIndex ("<<ind.size()
     409              :                                                   <<") and Num Position ("<<vElemPos.size()<<") must match."
     410              :                                                  "GeomObject dim="<<geometry_traits<TBaseElem>::BASE_OBJECT_ID);
     411              : 
     412              :                         //      write position
     413            0 :                                 for(size_t sh = 0; sh < ind.size(); ++sh)
     414              :                                 {
     415            0 :                                         const size_t index = ind[sh][0];
     416              :                                         vPos[index] = vElemPos[sh];
     417              :                                 }
     418              :                         }
     419              :                 }
     420              :         }
     421            0 : }
     422              : 
     423              : template <typename TDomain>
     424            0 : void ExtractPositions(ConstSmartPtr<TDomain> domain,
     425              :                       ConstSmartPtr<DoFDistribution> dd,
     426              :                       std::vector<MathVector<TDomain::dim> >& vPos)
     427              : {
     428              : //      number of total dofs
     429            0 :         int nr = dd->num_indices();
     430              : 
     431              : //      resize positions
     432            0 :         vPos.resize(nr);
     433              : 
     434              : //      extract for all element types
     435            0 :         if(dd->max_dofs(VERTEX)) ExtractPositionsVertex<TDomain>(domain, dd, vPos);
     436            0 :         if(dd->max_dofs(EDGE)) ExtractPositionsElem<TDomain, Edge>(domain, dd, vPos);
     437            0 :         if(dd->max_dofs(FACE)) ExtractPositionsElem<TDomain, Face>(domain, dd, vPos);
     438            0 :         if(dd->max_dofs(VOLUME)) ExtractPositionsElem<TDomain, Volume>(domain, dd, vPos);
     439            0 : }
     440              : 
     441              : 
     442              : template <typename TDomain, typename TBaseElem>
     443            0 : void ExtractAlgebraIndices2(ConstSmartPtr<TDomain> domain,
     444              :                   ConstSmartPtr<DoFDistribution> dd,
     445              :                   std::vector<size_t>& fctIndex)
     446              : {
     447              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     448              : 
     449              : //      algebra indices vector
     450              :         std::vector<size_t> ind;
     451              : 
     452              : //      loop all subsets
     453            0 :         for(int si = 0; si < dd->num_subsets(); ++si)
     454              :         {
     455              :         //      get iterators
     456            0 :                 iter = dd->begin<TBaseElem>(si, SurfaceView::ALL);
     457            0 :                 iterEnd = dd->end<TBaseElem>(si, SurfaceView::ALL);
     458              : 
     459              :         //      loop all elements
     460            0 :                 for(;iter != iterEnd; ++iter)
     461              :                 {
     462              :                 //      get element
     463              :                         TBaseElem* elem = *iter;
     464              : 
     465              :                 //      loop all functions
     466            0 :                         for(size_t fct = 0; fct < dd->num_fct(); ++fct)
     467              :                         {
     468              :                         //      skip non-used function
     469            0 :                                 if(!dd->is_def_in_subset(fct,si)) continue;
     470              : 
     471              :                         //      load indices associated with element function
     472            0 :                                 dd->inner_algebra_indices_for_fct(elem, ind, true, fct);
     473              : 
     474            0 :                                 for(size_t sh = 0; sh < ind.size(); ++sh)
     475              :                                 {
     476            0 :                                         const size_t index = ind[sh];
     477            0 :                                         if(index < fctIndex.size())
     478            0 :                                                 fctIndex[index] = fct;
     479              :                                 }
     480              :                         }
     481              :                 }
     482              :         }
     483            0 : }
     484              : 
     485              : 
     486              : template <typename TDomain>
     487            0 : void ExtractAlgebraIndices(ConstSmartPtr<TDomain> domain,
     488              :                       ConstSmartPtr<DoFDistribution> dd,
     489              :                       std::vector<size_t> &fctIndex)
     490              : {
     491              : //      number of total dofs
     492            0 :         int nr = dd->num_indices();
     493              : 
     494              : //      resize positions
     495            0 :         fctIndex.resize(nr);
     496              : 
     497              : //      extract for all element types
     498            0 :         if(dd->max_dofs(VERTEX)) ExtractAlgebraIndices2<TDomain, Vertex>(domain, dd, fctIndex);
     499            0 :         if(dd->max_dofs(EDGE)) ExtractAlgebraIndices2<TDomain, Edge>(domain, dd, fctIndex);
     500            0 :         if(dd->max_dofs(FACE)) ExtractAlgebraIndices2<TDomain, Face>(domain, dd, fctIndex);
     501            0 :         if(dd->max_dofs(VOLUME)) ExtractAlgebraIndices2<TDomain, Volume>(domain, dd, fctIndex);
     502            0 : }
     503              : 
     504              : 
     505              : ////////////////////////////////////////////////////////////////////////////////
     506              : //      Extract (Positions, Index) Pairs
     507              : ////////////////////////////////////////////////////////////////////////////////
     508              : 
     509              : template <typename TDomain>
     510            0 : void ExtractPositionsVertex(ConstSmartPtr<TDomain> domain,
     511              :                             ConstSmartPtr<DoFDistribution> dd,
     512              :                             std::vector<std::pair<MathVector<TDomain::dim>, size_t> >& vPosPair)
     513              : {
     514              : //      get position accessor
     515              :         const typename TDomain::position_accessor_type& aaPos = domain->position_accessor();
     516              : 
     517              : //      resize positions
     518            0 :         vPosPair.resize(dd->num_indices());
     519              : 
     520              :         typedef DoFDistribution::traits<Vertex>::const_iterator const_iterator;
     521              : 
     522              : //      loop all vertices
     523              :         const_iterator iter = dd->begin<Vertex>(SurfaceView::ALL);
     524              :         const_iterator iterEnd = dd->end<Vertex>(SurfaceView::ALL);
     525              : 
     526              : //      algebra indices vector
     527              :         std::vector<size_t> ind;
     528              : 
     529            0 :         for(;iter != iterEnd; ++iter)
     530              :         {
     531              :         //      get vertex
     532              :                 Vertex* v = *iter;
     533              : 
     534              :         //      load indices associated with vertex
     535            0 :                 dd->inner_algebra_indices(v, ind);
     536              : 
     537              :         //      write position and index
     538            0 :                 for(size_t i = 0; i < ind.size(); ++i)
     539              :                 {
     540            0 :                         const size_t index = ind[i];
     541              :                         vPosPair[index].first = aaPos[v];
     542            0 :                         vPosPair[index].second = index;
     543              :                 }
     544              :         }
     545            0 : }
     546              : 
     547              : 
     548              : template <typename TDomain, typename TBaseElem>
     549            0 : void ExtractPositionsElem(ConstSmartPtr<TDomain> domain,
     550              :                           ConstSmartPtr<DoFDistribution> dd,
     551              :                           std::vector<std::pair<MathVector<TDomain::dim>, size_t> >& vPosPair)
     552              : {
     553              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     554              : 
     555              : //      vector for positions
     556              :         std::vector<MathVector<TDomain::dim> > vElemPos;
     557              : 
     558              : //      algebra indices vector
     559              :         std::vector<DoFIndex> ind;
     560              : 
     561              : //      loop all subsets
     562            0 :         for(int si = 0; si < dd->num_subsets(); ++si)
     563              :         {
     564              :         //      get iterators
     565            0 :                 iter = dd->begin<TBaseElem>(si, SurfaceView::ALL);
     566            0 :                 iterEnd = dd->end<TBaseElem>(si, SurfaceView::ALL);
     567              : 
     568              :         //      loop all elements
     569            0 :                 for(;iter != iterEnd; ++iter)
     570              :                 {
     571              :                 //      get vertex
     572              :                         TBaseElem* elem = *iter;
     573              : 
     574              :                 //      loop all functions
     575            0 :                         for(size_t fct = 0; fct < dd->num_fct(); ++fct)
     576              :                         {
     577              :                         //      skip non-used function
     578            0 :                                 if(!dd->is_def_in_subset(fct,si)) continue;
     579              : 
     580              :                         //      load indices associated with element function
     581            0 :                                 dd->inner_dof_indices(elem, fct, ind);
     582              : 
     583              :                         //      load positions associated with element and function
     584            0 :                                 InnerDoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
     585              :                                                  dd->local_finite_element_id(fct));
     586              : 
     587              :                         //      check correct size
     588              :                                 UG_ASSERT(ind.size() == vElemPos.size(), "Num MultiIndex ("<<ind.size()
     589              :                                                   <<") and Num Position ("<<vElemPos.size()<<") must match."
     590              :                                                  "GeomObject dim="<<geometry_traits<TBaseElem>::BASE_OBJECT_ID);
     591              : 
     592              :                         //      write position
     593            0 :                                 for(size_t sh = 0; sh < ind.size(); ++sh)
     594              :                                 {
     595            0 :                                         const size_t index = ind[sh][0];
     596              :                                         vPosPair[index].first = vElemPos[sh];
     597            0 :                                         vPosPair[index].second = index;
     598              : 
     599              :                                 }
     600              :                         }
     601              :                 }
     602              :         }
     603            0 : }
     604              : 
     605              : template <typename TDomain>
     606            0 : void ExtractPositions(ConstSmartPtr<TDomain> domain,
     607              :                       ConstSmartPtr<DoFDistribution> dd,
     608              :                       std::vector<std::pair<MathVector<TDomain::dim>, size_t> >& vPosPair)
     609              : {
     610              : //      number of total dofs
     611            0 :         int nr = dd->num_indices();
     612              : 
     613              : //      resize positions
     614            0 :         vPosPair.resize(nr);
     615              : 
     616              : //      extract for all element types
     617            0 :         if(dd->max_dofs(VERTEX)) ExtractPositionsVertex<TDomain>(domain, dd, vPosPair);
     618            0 :         if(dd->max_dofs(EDGE)) ExtractPositionsElem<TDomain, Edge>(domain, dd, vPosPair);
     619            0 :         if(dd->max_dofs(FACE)) ExtractPositionsElem<TDomain, Face>(domain, dd, vPosPair);
     620            0 :         if(dd->max_dofs(VOLUME)) ExtractPositionsElem<TDomain, Volume>(domain, dd, vPosPair);
     621            0 : }
     622              : 
     623              : ////////////////////////////////////////////////////////////////////////////////
     624              : //      Extract (Positions, Index) Pairs for a single component
     625              : ////////////////////////////////////////////////////////////////////////////////
     626              : 
     627              : 
     628              : template <typename TDomain, typename TBaseElem>
     629            0 : void ExtractPositionsElem(ConstSmartPtr<TDomain> domain,
     630              :                           ConstSmartPtr<DoFDistribution> dd,
     631              :                           const size_t fct,
     632              :                           std::vector<std::pair<MathVector<TDomain::dim>, size_t> >& vPosPair)
     633              : {
     634              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     635              : 
     636              : //      vector for positions
     637              :         std::vector<MathVector<TDomain::dim> > vElemPos;
     638              : 
     639              : //      algebra indices vector
     640              :         std::vector<DoFIndex> ind;
     641              : 
     642              : //      a pair
     643              :         std::pair<MathVector<TDomain::dim>, size_t> pair;
     644              : 
     645              : //      loop all subsets
     646            0 :         for(int si = 0; si < dd->num_subsets(); ++si)
     647              :         {
     648              :         //      get iterators
     649            0 :                 iter = dd->begin<TBaseElem>(si, SurfaceView::ALL);
     650            0 :                 iterEnd = dd->end<TBaseElem>(si, SurfaceView::ALL);
     651              : 
     652              :         //      skip non-used function
     653            0 :                 if(!dd->is_def_in_subset(fct,si)) continue;
     654              : 
     655              :         //      loop all elements
     656            0 :                 for(;iter != iterEnd; ++iter)
     657              :                 {
     658              :                 //      get vertex
     659              :                         TBaseElem* elem = *iter;
     660              : 
     661              :                 //      load indices associated with element function
     662            0 :                         dd->inner_dof_indices(elem, fct, ind);
     663              : 
     664              :                 //      load positions associated with element and function
     665            0 :                         InnerDoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
     666              :                                                          dd->local_finite_element_id(fct));
     667              : 
     668              :                 //      check correct size
     669              :                         UG_ASSERT(ind.size() == vElemPos.size(), "Num MultiIndex ("<<ind.size()
     670              :                                           <<") and Num Position ("<<vElemPos.size()<<") must match."
     671              :                                          "GeomObject dim="<<geometry_traits<TBaseElem>::BASE_OBJECT_ID);
     672              : 
     673              :                 //      write position
     674            0 :                         for(size_t sh = 0; sh < ind.size(); ++sh)
     675              :                         {
     676            0 :                                 const size_t index = ind[sh][0];
     677              : 
     678              :                                 pair.first = vElemPos[sh];
     679            0 :                                 pair.second = index;
     680              : 
     681            0 :                                 vPosPair.push_back(pair);
     682              :                         }
     683              :                 }
     684              :         }
     685            0 : }
     686              : 
     687              : template <typename TDomain>
     688            0 : void ExtractPositions(ConstSmartPtr<TDomain> domain,
     689              :                       ConstSmartPtr<DoFDistribution> dd,
     690              :                       const size_t fct,
     691              :                       std::vector<std::pair<MathVector<TDomain::dim>, size_t> >& vPosPair)
     692              : {
     693              : //      resize positions
     694              :         vPosPair.clear();
     695              : 
     696              : //      extract for all element types
     697            0 :         if(dd->max_dofs(VERTEX)) ExtractPositionsElem<TDomain, Vertex>(domain, dd, fct, vPosPair);
     698            0 :         if(dd->max_dofs(EDGE)) ExtractPositionsElem<TDomain, Edge>(domain, dd, fct, vPosPair);
     699            0 :         if(dd->max_dofs(FACE)) ExtractPositionsElem<TDomain, Face>(domain, dd, fct, vPosPair);
     700            0 :         if(dd->max_dofs(VOLUME)) ExtractPositionsElem<TDomain, Volume>(domain, dd, fct, vPosPair);
     701            0 : }
     702              : 
     703              : ////////////////////////////////////////////////////////////////////////////////
     704              : //      Checks correct DoF Positions
     705              : ////////////////////////////////////////////////////////////////////////////////
     706              : 
     707              : template <typename TDomain, typename TBaseElem>
     708            0 : bool CheckDoFElem(ConstSmartPtr<TDomain> domain,
     709              :                   ConstSmartPtr<DoFDistribution> dd,
     710              :                   std::vector<MathVector<TDomain::dim> >& vPos)
     711              : {
     712              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     713              : 
     714              :         bool bRes = true;
     715              : 
     716              : //      vector for positions
     717              :         std::vector<MathVector<TDomain::dim> > vElemPos;
     718              : 
     719              : //      algebra indices vector
     720              :         std::vector<DoFIndex> ind;
     721              : 
     722              : //      loop all subsets
     723            0 :         for(int si = 0; si < dd->num_subsets(); ++si)
     724              :         {
     725              :         //      get iterators
     726            0 :                 iter = dd->begin<TBaseElem>(si, SurfaceView::ALL);
     727            0 :                 iterEnd = dd->end<TBaseElem>(si, SurfaceView::ALL);
     728              : 
     729              :         //      loop all elements
     730            0 :                 for(;iter != iterEnd; ++iter)
     731              :                 {
     732              :                 //      get element
     733              :                         TBaseElem* elem = *iter;
     734              : 
     735              :                 //      loop all functions
     736            0 :                         for(size_t fct = 0; fct < dd->num_fct(); ++fct)
     737              :                         {
     738              :                         //      skip non-used function
     739            0 :                                 if(!dd->is_def_in_subset(fct,si)) continue;
     740              : 
     741              :                         //      load indices associated with element function
     742            0 :                                 dd->inner_dof_indices(elem, fct, ind);
     743              : 
     744              :                         //      load positions associated with element and function
     745            0 :                                 InnerDoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
     746              :                                                  dd->local_finite_element_id(fct));
     747              : 
     748              :                                 bool bWrite = false;
     749            0 :                                 for(size_t sh = 0; sh < ind.size(); ++sh)
     750              :                                 {
     751            0 :                                         size_t index = ind[sh][0];
     752              : 
     753            0 :                                         if(vPos[index] != MathVector<TDomain::dim>(-1)){
     754            0 :                                                         if(VecDistance(vPos[index], vElemPos[sh]) < 1e-10) continue;
     755              : 
     756            0 :                                                 if(!bWrite)
     757              :                                                         UG_LOG(" **** inner_multi_index (start) ******\n")
     758              :                                                 bWrite = true;
     759              :                                                 bRes = false;
     760            0 :                                                 UG_LOG("CheckDoFPositions "<<sh<<": inner_dof_indices: index: "
     761              :                                                        <<index<<" at "<<vElemPos[sh]<<", but previously: "
     762              :                                                        <<vPos[index]<<"\n");
     763              :                                         }
     764              : 
     765              :                                         vPos[index] = vElemPos[sh];
     766              : 
     767              :                                 }
     768              : 
     769            0 :                                 if(bWrite){
     770              :                                         std::vector<MathVector<TDomain::dim> > vVertPos;
     771              :                                         CollectCornerCoordinates(vVertPos, elem, *domain, true);
     772            0 :                                         UG_LOG("From Elem "<<elem<<" ("<<elem->reference_object_id()<<"):\n")
     773            0 :                                         for(size_t i = 0; i < vVertPos.size(); ++i)
     774            0 :                                                 UG_LOG("with corner "<<i<<": "<<vVertPos[i]<<"\n");
     775              :                                         UG_LOG(" **** inner_multi_index (end) ******\n")
     776            0 :                                 }
     777              : 
     778              :                                  /////////////////////////
     779              :                                 //      load indices associated with element function
     780            0 :                                         dd->dof_indices(elem, fct, ind);
     781              : 
     782              :                                 //      load positions associated with element and function
     783            0 :                                         DoFPosition(vElemPos, elem, *(const_cast<TDomain*>(domain.get())),
     784              :                                                          dd->local_finite_element_id(fct));
     785              : 
     786              :                                 //      write position
     787              :                                         bWrite = false;
     788            0 :                                         for(size_t sh = 0; sh < ind.size(); ++sh)
     789              :                                         {
     790            0 :                                                 size_t index = ind[sh][0];
     791              : 
     792            0 :                                                 if(vPos[index] != MathVector<TDomain::dim>(-1)){
     793            0 :                                                         if(VecDistance(vPos[index], vElemPos[sh]) < 1e-10) continue;
     794              : 
     795            0 :                                                         if(!bWrite)
     796              :                                                                 UG_LOG(" **** multi_index (start) ******\n")
     797              :                                                         bWrite = true;
     798              :                                                         bRes = false;
     799            0 :                                                         UG_LOG("CheckDoFPositions "<<sh<<": dof_indices: index: "
     800              :                                                                    <<index<<" at "<<vElemPos[sh]<<", but previously: "
     801              :                                                                    <<vPos[index]<<"\n");
     802              :                                                 }
     803              : 
     804              :                                                 vPos[index] = vElemPos[sh];
     805              :                                         }
     806              : 
     807            0 :                                         if(bWrite){
     808              :                                                 std::vector<MathVector<TDomain::dim> > vVertPos;
     809              :                                                 CollectCornerCoordinates(vVertPos, elem, *domain, true);
     810            0 :                                                 UG_LOG("From Elem "<<elem<<" ("<<elem->reference_object_id()<<"):\n")
     811            0 :                                                 for(size_t i = 0; i < vVertPos.size(); ++i)
     812            0 :                                                         UG_LOG("with corner "<<i<<": "<<vVertPos[i]<<"\n");
     813              :                                                 UG_LOG(" **** multi_index (end) ******\n")
     814            0 :                                         }
     815              :                         }
     816              :                 }
     817              :         }
     818              : 
     819            0 :         return bRes;
     820            0 : }
     821              : 
     822              : template <typename TDomain>
     823            0 : bool CheckDoFPositions(ConstSmartPtr<TDomain> domain,
     824              :                        ConstSmartPtr<DoFDistribution> dd)
     825              : {
     826              : //      number of total dofs
     827            0 :         int nr = dd->num_indices();
     828            0 :         std::vector<MathVector<TDomain::dim> > vPos(nr, -1);
     829              : 
     830              : //      extract for all element types
     831              :         bool bRes = true;
     832            0 :         if(dd->max_dofs(VERTEX)) bRes &= CheckDoFElem<TDomain, Vertex>(domain, dd, vPos);
     833            0 :         if(dd->max_dofs(EDGE)) bRes &= CheckDoFElem<TDomain, Edge>(domain, dd, vPos);
     834            0 :         if(dd->max_dofs(FACE)) bRes &= CheckDoFElem<TDomain, Face>(domain, dd, vPos);
     835            0 :         if(dd->max_dofs(VOLUME)) bRes &= CheckDoFElem<TDomain, Volume>(domain, dd, vPos);
     836            0 :         return bRes;
     837            0 : }
     838              : 
     839              : #ifdef UG_DIM_1
     840              : template bool InnerDoFPosition<Domain1d>(std::vector<MathVector<1> >& vPos, GridObject* elem, const Domain1d& domain, const LFEID& lfeID);
     841              : template bool InnerDoFPosition<1>(std::vector<MathVector<1> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<1> >& vCornerCoord, const LFEID& lfeID);
     842              : template bool DoFPosition<Domain1d>(std::vector<MathVector<1> >& vPos, GridObject* elem, const Domain1d& domain, const LFEID& lfeID);
     843              : template bool DoFPosition<1>(std::vector<MathVector<1> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<1> >& vCornerCoord, const LFEID& lfeID);
     844              : template void ExtractPositions(ConstSmartPtr<Domain1d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<MathVector<Domain1d::dim> >& vPos);
     845              : template void ExtractPositions(ConstSmartPtr<Domain1d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<std::pair<MathVector<Domain1d::dim>, size_t> >& vPos);
     846              : template void ExtractPositions(ConstSmartPtr<Domain1d> domain, ConstSmartPtr<DoFDistribution> dd, const size_t fct, std::vector<std::pair<MathVector<Domain1d::dim>, size_t> >& vPos);
     847              : template bool CheckDoFPositions(ConstSmartPtr<Domain1d> domain, ConstSmartPtr<DoFDistribution> dd);
     848              : template void ExtractAlgebraIndices<Domain1d>(ConstSmartPtr<Domain1d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<size_t> &fctIndex);
     849              : template void ShapesAtGlobalPosition<1>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<1> >& vGlobPos, const ReferenceObjectID roid,const std::vector<MathVector<1> >& vCornerCoord, const LFEID& lfeID);
     850              : template void ShapesAtGlobalPosition<Domain1d>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<1> >& vGlobPos,GridObject* elem, const Domain1d& domain, const LFEID& lfeID);
     851              : #endif
     852              : #ifdef UG_DIM_2
     853              : template bool InnerDoFPosition<Domain2d>(std::vector<MathVector<2> >& vPos, GridObject* elem, const Domain2d& domain, const LFEID& lfeID);
     854              : template bool InnerDoFPosition<2>(std::vector<MathVector<2> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<2> >& vCornerCoord, const LFEID& lfeID);
     855              : template bool DoFPosition<Domain2d>(std::vector<MathVector<2> >& vPos, GridObject* elem, const Domain2d& domain, const LFEID& lfeID);
     856              : template bool DoFPosition<2>(std::vector<MathVector<2> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<2> >& vCornerCoord, const LFEID& lfeID);
     857              : template void ExtractPositions(ConstSmartPtr<Domain2d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<MathVector<Domain2d::dim> >& vPos);
     858              : template void ExtractPositions(ConstSmartPtr<Domain2d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<std::pair<MathVector<Domain2d::dim>, size_t> >& vPos);
     859              : template void ExtractPositions(ConstSmartPtr<Domain2d> domain, ConstSmartPtr<DoFDistribution> dd, const size_t fct, std::vector<std::pair<MathVector<Domain2d::dim>, size_t> >& vPos);
     860              : template bool CheckDoFPositions(ConstSmartPtr<Domain2d> domain, ConstSmartPtr<DoFDistribution> dd);
     861              : template void ExtractAlgebraIndices<Domain2d>(ConstSmartPtr<Domain2d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<size_t> &fctIndex);
     862              : template void ShapesAtGlobalPosition<2>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<2> >& vGlobPos, const ReferenceObjectID roid,const std::vector<MathVector<2> >& vCornerCoord, const LFEID& lfeID);
     863              : template void ShapesAtGlobalPosition<Domain2d>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<2> >& vGlobPos,GridObject* elem, const Domain2d& domain, const LFEID& lfeID);
     864              : #endif
     865              : #ifdef UG_DIM_3
     866              : template bool InnerDoFPosition<Domain3d>(std::vector<MathVector<3> >& vPos, GridObject* elem, const Domain3d& domain, const LFEID& lfeID);
     867              : template bool InnerDoFPosition<3>(std::vector<MathVector<3> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<3> >& vCornerCoord, const LFEID& lfeID);
     868              : template bool DoFPosition<Domain3d>(std::vector<MathVector<3> >& vPos, GridObject* elem, const Domain3d& domain, const LFEID& lfeID);
     869              : template bool DoFPosition<3>(std::vector<MathVector<3> >& vPos, const ReferenceObjectID roid,const std::vector<MathVector<3> >& vCornerCoord, const LFEID& lfeID);
     870              : template void ExtractPositions(ConstSmartPtr<Domain3d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<MathVector<Domain3d::dim> >& vPos);
     871              : template void ExtractPositions(ConstSmartPtr<Domain3d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<std::pair<MathVector<Domain3d::dim>, size_t> >& vPos);
     872              : template void ExtractPositions(ConstSmartPtr<Domain3d> domain, ConstSmartPtr<DoFDistribution> dd, const size_t fct, std::vector<std::pair<MathVector<Domain3d::dim>, size_t> >& vPos);
     873              : template bool CheckDoFPositions(ConstSmartPtr<Domain3d> domain, ConstSmartPtr<DoFDistribution> dd);
     874              : template void ExtractAlgebraIndices<Domain3d>(ConstSmartPtr<Domain3d> domain, ConstSmartPtr<DoFDistribution> dd, std::vector<size_t> &fctIndex);
     875              : template void ShapesAtGlobalPosition<3>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<3> >& vGlobPos, const ReferenceObjectID roid,const std::vector<MathVector<3> >& vCornerCoord, const LFEID& lfeID);
     876              : template void ShapesAtGlobalPosition<Domain3d>(std::vector<std::vector<number> >& vvShape, const std::vector<MathVector<3> >& vGlobPos,GridObject* elem, const Domain3d& domain, const LFEID& lfeID);
     877              : #endif
     878              : 
     879              : } // end namespace ug
        

Generated by: LCOV version 2.0-1