LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/user_data/common_user_data - dim_dim_user_data.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 143 0
Test Date: 2025-11-12 02:41:53 Functions: 0.0 % 78 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Dmitry Logashenko
       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              : /*
      34              :  * Classes for user data that compute normals or project vectors to low-dimensional
      35              :  * subsets. Note that these classes are mainly implemented for visualization purposes
      36              :  * and cannot be used for coupling.
      37              :  */
      38              : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__ONC_USER_DATA__
      39              : #define __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__ONC_USER_DATA__
      40              : 
      41              : #include <vector>
      42              : 
      43              : // ug4 headers
      44              : #include "common/common.h"
      45              : #include "common/math/ugmath.h"
      46              : #include "lib_grid/grid_objects/grid_dim_traits.h"
      47              : #include "lib_disc/domain_traits.h"
      48              : #include "lib_disc/domain_util.h"
      49              : #include "lib_disc/common/geometry_util.h"
      50              : #include "lib_disc/reference_element/reference_mapping_provider.h"
      51              : #include "lib_disc/spatial_disc/user_data/std_user_data.h"
      52              : 
      53              : namespace ug {
      54              : 
      55              : /// Projection to the outer normal for a given vector user data
      56              : /**
      57              :  * This class implements the UserData for evaluation of the normal component of vectors
      58              :  * computed by the other user data object. The normal component is evaluation only for
      59              :  * WDim-1-dimensional subsets - sides of WDim-dimensional elements.
      60              :  *
      61              :  * ToDo: Note that the LocalVector provided for the evaluate function is not properly
      62              :  * used. Thus, the passed UserData objects should not use it.
      63              :  *
      64              :  */
      65              : template <typename TDomain>
      66              : class OutNormCmp
      67              :         : public StdUserData<OutNormCmp<TDomain>, MathVector<TDomain::dim>, TDomain::dim, void, UserData<MathVector<TDomain::dim>, TDomain::dim, void> >
      68              : {
      69              : ///     the world dimension
      70              :         static const int dim = TDomain::dim;
      71              :         
      72              : ///     the domain type
      73              :         typedef TDomain domain_type;
      74              :         
      75              : ///     the grid type
      76              :         typedef typename TDomain::grid_type grid_type;
      77              :         
      78              : ///     the original data type
      79              :         typedef MathVector<dim> vec_type;
      80              :         
      81              : ///     the original data
      82              :         SmartPtr<UserData<vec_type, dim, void> > m_spData;
      83              :         
      84              : ///     the domain
      85              :         SmartPtr<domain_type> m_spDomain;
      86              :         
      87              : ///     the subset group for the inner part
      88              :         SubsetGroup m_ssGrp;
      89              :         
      90              : public:
      91              : 
      92              : ///     constructor
      93            0 :         OutNormCmp
      94              :         (
      95              :                 SmartPtr<domain_type> spDomain, ///< the domain
      96              :                 SmartPtr<UserData<vec_type, dim, void> > spData, ///< the original data
      97              :                 const char * ss_names ///< the subsets
      98              :         )
      99            0 :         :       m_spData (spData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     100              :         {
     101              :         // Parse the subset names:
     102              :                 std::vector<std::string> vssNames;
     103              :                 try
     104              :                 {
     105            0 :                         TokenizeString (ss_names, vssNames);
     106            0 :                         for (size_t k = 0; k < vssNames.size (); k++)
     107            0 :                                 RemoveWhitespaceFromString (vssNames [k]);
     108              :                         m_ssGrp.clear ();
     109            0 :                         m_ssGrp.add (vssNames);
     110            0 :                 } UG_CATCH_THROW ("SubsetIndicatorUserData: Failed to parse subset names.");
     111            0 :         }
     112              :         
     113              : ///     constructor
     114            0 :         OutNormCmp
     115              :         (
     116              :                 SmartPtr<domain_type> spDomain, ///< the domain
     117              :                 SmartPtr<UserData<vec_type, dim, void> > spData ///< the original data
     118              :         )
     119            0 :         :       m_spData (spData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     120            0 :         {}
     121              :         
     122              : ///     Indicator functions are discontinuous
     123            0 :         virtual bool continuous () const {return false;}
     124              : 
     125              : ///     Returns true to get the grid element in the evaluation routine
     126            0 :         virtual bool requires_grid_fct () const {return m_spData->requires_grid_fct ();}
     127              :         // Remark: Note that actually we have not enought data for that. This dependence is neglected.
     128              : 
     129              : ///     Evaluator
     130              :         template <int refDim>
     131            0 :         inline void evaluate
     132              :         (
     133              :                 vec_type vValue[],
     134              :                 const MathVector<dim> vGlobIP [],
     135              :                 number time,
     136              :                 int si,
     137              :                 GridObject * elem,
     138              :                 const MathVector<dim> vCornerCoords [],
     139              :                 const MathVector<refDim> vLocIP [],
     140              :                 const size_t nip,
     141              :                 LocalVector * u,
     142              :                 const MathMatrix<refDim, dim> * vJT = NULL
     143              :         ) const
     144              :         {
     145              :                 if (refDim == dim)
     146              :                 {
     147            0 :                         (* m_spData) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
     148            0 :                         return;
     149              :                 }
     150              :                 if (refDim != dim - 1)
     151              :                 {
     152            0 :                         UG_THROW ("OutNormCmp: Wrong dimensionality of the subset.");
     153              :                 }
     154              :                 
     155              :         //      Get the full-dim. element associated with the given side
     156              :                 typedef typename grid_dim_traits<dim>::grid_base_object fd_elem_type;
     157              :                 fd_elem_type * fd_elem = NULL;
     158              :                 int fd_si = -1;
     159              :                 
     160              :                 typedef typename Grid::traits<fd_elem_type>::secure_container fd_elem_secure_container_type;
     161              :                 fd_elem_secure_container_type fd_elem_list;
     162            0 :                 grid_type& grid = * (grid_type*) (m_spDomain->grid().get ());
     163            0 :                 grid.associated_elements (fd_elem_list, elem);
     164              :                 
     165            0 :                 if (m_ssGrp.empty ()) // no subsets specified; we assume, elem should be the bnd of the whole domain
     166              :                 {
     167            0 :                         if (fd_elem_list.size () == 1)
     168              :                         {
     169              :                                 fd_elem = fd_elem_list[0];
     170            0 :                                 fd_si = m_spDomain->subset_handler()->get_subset_index (fd_elem);
     171              :                         }
     172              :                         // otherwise this is no boundary of the domain and we return 0
     173              :                 }
     174              :                 else
     175              :                 {
     176            0 :                         for (size_t k = 0; k < fd_elem_list.size (); k++)
     177              :                         {
     178              :                                 fd_elem_type * e = fd_elem_list[k];
     179            0 :                                 int e_si = m_ssGrp.subset_handler()->get_subset_index (e);
     180            0 :                                 if (m_ssGrp.contains (e_si))
     181              :                                 {
     182            0 :                                         if (fd_elem != NULL) // i.e. e is already the second one
     183              :                                         { // this is no boundary of the subset; return 0
     184              :                                                 fd_elem = NULL;
     185              :                                                 break;
     186              :                                         }
     187              :                                         fd_elem = e;
     188              :                                         fd_si = e_si;
     189              :                                 }
     190              :                         }
     191              :                 }
     192            0 :                 if (fd_elem == NULL)
     193              :                 { // this is no bondary, return 0
     194            0 :                         for (size_t ip = 0; ip < nip; ip++) vValue[ip] = 0;
     195              :                         return;
     196              :                 }
     197              :                 
     198              :         //      Get the coordinates of the corners of the full-dim. element
     199            0 :                 std::vector<MathVector<dim> > fd_elem_corner_coords (domain_traits<dim>::MaxNumVerticesOfElem);
     200            0 :                 CollectCornerCoordinates (fd_elem->base_object_id (), fd_elem_corner_coords,
     201              :                         *fd_elem, *m_spDomain, true);
     202              :                 
     203              :         //      Convert the local ip coordinates (use the global coordinates as they are the same)
     204            0 :                 const ReferenceObjectID fd_roid = fd_elem->reference_object_id ();
     205              :                 DimReferenceMapping<dim, dim> & fd_map
     206              :                         = ReferenceMappingProvider::get<dim, dim> (fd_roid, fd_elem_corner_coords);
     207            0 :                 std::vector<MathVector<dim> > fd_loc_ip (nip);
     208            0 :                 for (size_t ip = 0; ip < nip; ip++)
     209            0 :                         fd_map.global_to_local(fd_loc_ip[ip], vGlobIP[ip]);
     210              :         
     211              :         //      Call the original UserData, get the vectors
     212            0 :                 (* m_spData) (vValue, vGlobIP, time, fd_si, fd_elem, &(fd_elem_corner_coords[0]),
     213              :                         &(fd_loc_ip[0]), nip, u);
     214              :                 //TODO: Note that u is here a dummy parameter: We do not have enough data for it.
     215              :         
     216              :         //      Project the vectors
     217            0 :                 const ReferenceObjectID roid = elem->reference_object_id ();
     218              :                 DimReferenceMapping<refDim, dim> & map
     219              :                         = ReferenceMappingProvider::get<refDim, dim> (roid, vCornerCoords);
     220            0 :                 for (size_t ip = 0; ip < nip; ip++)
     221              :                 {
     222              :                         MathMatrix<dim, refDim> J;
     223            0 :                         MathVector<dim> p (vValue[ip]);
     224              :                         
     225            0 :                         map.jacobian (J, vLocIP[ip]);
     226            0 :                         OrthogProjectVec (p, J);                        
     227              :                         vValue[ip] -= p;
     228              :                 }
     229              :         };
     230              :         
     231              : ///     This function should not be used
     232            0 :         void operator()
     233              :         (
     234              :                 vec_type & vValue,
     235              :                 const MathVector<dim> & globIP,
     236              :                 number time,
     237              :                 int si
     238              :         )
     239              :         const
     240              :         {
     241            0 :                 UG_THROW("OutNormCmp: Element required for evaluation, but not passed. Cannot evaluate.");
     242              :         }
     243              : 
     244              : ///     This function should not be used
     245            0 :         void operator()
     246              :         (
     247              :                 vec_type vValue [],
     248              :                 const MathVector<dim> vGlobIP [],
     249              :                 number time,
     250              :                 int si,
     251              :                 const size_t nip
     252              :         ) const
     253              :         {
     254            0 :                 UG_THROW("OutNormCmp: Element required for evaluation, but not passed. Cannot evaluate.");
     255              :         }
     256              : 
     257              : };
     258              : 
     259              : /// Scaled projection to the outer normal for a given vector user data
     260              : /**
     261              :  * This class implements the UserData for evaluation of the normal component of vectors
     262              :  * computed by the other user data object. The normal component is evaluation only for
     263              :  * WDim-1-dimensional subsets - sides of WDim-dimensional elements. It is scaled by
     264              :  * a furthe (scalar) UserData.
     265              :  *
     266              :  * ToDo: Note that the LocalVector provided for the evaluate function is not properly
     267              :  * used. Thus, the passed UserData objects should not use it.
     268              :  *
     269              :  */
     270              : template <typename TDomain>
     271              : class ScaledOutNormCmp
     272              :         : public StdUserData<ScaledOutNormCmp<TDomain>, MathVector<TDomain::dim>, TDomain::dim, void, UserData<MathVector<TDomain::dim>, TDomain::dim, void> >
     273              : {
     274              : ///     the world dimension
     275              :         static const int dim = TDomain::dim;
     276              :         
     277              : ///     the domain type
     278              :         typedef TDomain domain_type;
     279              :         
     280              : ///     the grid type
     281              :         typedef typename TDomain::grid_type grid_type;
     282              :         
     283              : ///     the original data type
     284              :         typedef MathVector<dim> vec_type;
     285              :         
     286              : ///     the original vector field data
     287              :         SmartPtr<UserData<vec_type, dim, void> > m_spVecData;
     288              :         
     289              : ///     the scaling data
     290              :         SmartPtr<UserData<number, dim, void> > m_spScalData;
     291              :         
     292              : ///     the domain
     293              :         SmartPtr<domain_type> m_spDomain;
     294              :         
     295              : ///     the subset group for the inner part
     296              :         SubsetGroup m_ssGrp;
     297              :         
     298              : public:
     299              : 
     300              : ///     constructor
     301            0 :         ScaledOutNormCmp
     302              :         (
     303              :                 SmartPtr<domain_type> spDomain, ///< the domain
     304              :                 SmartPtr<UserData<number, dim, void> > spScalData, ///< the scaling data
     305              :                 SmartPtr<UserData<vec_type, dim, void> > spVecData, ///< the original vector field data
     306              :                 const char * ss_names ///< the subsets
     307              :         )
     308            0 :         :       m_spVecData (spVecData), m_spScalData (spScalData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     309              :         {
     310              :         // Parse the subset names:
     311              :                 std::vector<std::string> vssNames;
     312              :                 try
     313              :                 {
     314            0 :                         TokenizeString (ss_names, vssNames);
     315            0 :                         for (size_t k = 0; k < vssNames.size (); k++)
     316            0 :                                 RemoveWhitespaceFromString (vssNames [k]);
     317              :                         m_ssGrp.clear ();
     318            0 :                         m_ssGrp.add (vssNames);
     319            0 :                 } UG_CATCH_THROW ("SubsetIndicatorUserData: Failed to parse subset names.");
     320            0 :         }
     321              :         
     322              : ///     constructor
     323            0 :         ScaledOutNormCmp
     324              :         (
     325              :                 SmartPtr<domain_type> spDomain, ///< the domain
     326              :                 SmartPtr<UserData<number, dim, void> > spScalData, ///< the scaling data
     327              :                 SmartPtr<UserData<vec_type, dim, void> > spVecData ///< the original vector field data
     328              :         )
     329            0 :         :       m_spVecData (spVecData), m_spScalData (spScalData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     330            0 :         {}
     331              :         
     332              : ///     Indicator functions are discontinuous
     333            0 :         virtual bool continuous () const {return false;}
     334              : 
     335              : ///     Returns true to get the grid element in the evaluation routine
     336            0 :         virtual bool requires_grid_fct () const {return m_spVecData->requires_grid_fct () || m_spScalData->requires_grid_fct ();}
     337              :         // Remark: Note that actually we have not enought data for that. This dependence is neglected.
     338              : 
     339              : ///     Evaluator
     340              :         template <int refDim>
     341            0 :         inline void evaluate
     342              :         (
     343              :                 vec_type vValue[],
     344              :                 const MathVector<dim> vGlobIP [],
     345              :                 number time,
     346              :                 int si,
     347              :                 GridObject * elem,
     348              :                 const MathVector<dim> vCornerCoords [],
     349              :                 const MathVector<refDim> vLocIP [],
     350              :                 const size_t nip,
     351              :                 LocalVector * u,
     352              :                 const MathMatrix<refDim, dim> * vJT = NULL
     353              :         ) const
     354              :         {
     355              :                 if (refDim == dim)
     356              :                 {
     357            0 :                         std::vector<number> scaling (nip);
     358            0 :                         (* m_spVecData) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
     359            0 :                         (* m_spScalData) (&(scaling[0]), vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
     360            0 :                         for (size_t ip = 0; ip < nip; ip++)
     361            0 :                                 vValue[ip] *= scaling[ip];
     362              :                         return;
     363            0 :                 }
     364              :                 if (refDim != dim - 1)
     365              :                 {
     366            0 :                         UG_THROW ("ScaledOutNormCmp: Wrong dimensionality of the subset.");
     367              :                 }
     368              :                 
     369              :         //      Get the full-dim. element associated with the given side
     370              :                 typedef typename grid_dim_traits<dim>::grid_base_object fd_elem_type;
     371              :                 fd_elem_type * fd_elem = NULL;
     372              :                 int fd_si = -1;
     373              :                 
     374              :                 typedef typename Grid::traits<fd_elem_type>::secure_container fd_elem_secure_container_type;
     375              :                 fd_elem_secure_container_type fd_elem_list;
     376            0 :                 grid_type& grid = * (grid_type*) (m_spDomain->grid().get ());
     377            0 :                 grid.associated_elements (fd_elem_list, elem);
     378              :                 
     379            0 :                 if (m_ssGrp.empty ()) // no subsets specified; we assume, elem should be the bnd of the whole domain
     380              :                 {
     381            0 :                         if (fd_elem_list.size () == 1)
     382              :                         {
     383              :                                 fd_elem = fd_elem_list[0];
     384            0 :                                 fd_si = m_spDomain->subset_handler()->get_subset_index (fd_elem);
     385              :                         }
     386              :                         // otherwise this is no boundary of the domain and we return 0
     387              :                 }
     388              :                 else
     389              :                 {
     390            0 :                         for (size_t k = 0; k < fd_elem_list.size (); k++)
     391              :                         {
     392              :                                 fd_elem_type * e = fd_elem_list[k];
     393            0 :                                 int e_si = m_ssGrp.subset_handler()->get_subset_index (e);
     394            0 :                                 if (m_ssGrp.contains (e_si))
     395              :                                 {
     396            0 :                                         if (fd_elem != NULL) // i.e. e is already the second one
     397              :                                         { // this is no boundary of the subset; return 0
     398              :                                                 fd_elem = NULL;
     399              :                                                 break;
     400              :                                         }
     401              :                                         fd_elem = e;
     402              :                                         fd_si = e_si;
     403              :                                 }
     404              :                         }
     405              :                 }
     406            0 :                 if (fd_elem == NULL)
     407              :                 { // this is no bondary, return 0
     408            0 :                         for (size_t ip = 0; ip < nip; ip++) vValue[ip] = 0;
     409              :                         return;
     410              :                 }
     411              :                 
     412              :         //      Get the coordinates of the corners of the full-dim. element
     413            0 :                 std::vector<MathVector<dim> > fd_elem_corner_coords (domain_traits<dim>::MaxNumVerticesOfElem);
     414            0 :                 CollectCornerCoordinates (fd_elem->base_object_id (), fd_elem_corner_coords,
     415              :                         *fd_elem, *m_spDomain, true);
     416              :                 
     417              :         //      Convert the local ip coordinates (use the global coordinates as they are the same)
     418            0 :                 const ReferenceObjectID fd_roid = fd_elem->reference_object_id ();
     419              :                 DimReferenceMapping<dim, dim> & fd_map
     420              :                         = ReferenceMappingProvider::get<dim, dim> (fd_roid, fd_elem_corner_coords);
     421            0 :                 std::vector<MathVector<dim> > fd_loc_ip (nip);
     422            0 :                 for (size_t ip = 0; ip < nip; ip++)
     423            0 :                         fd_map.global_to_local(fd_loc_ip[ip], vGlobIP[ip]);
     424              :         
     425              :         //      Call the original UserData, get the vectors
     426            0 :                 std::vector<number> scaling (nip);
     427            0 :                 (* m_spVecData) (vValue, vGlobIP, time, fd_si, fd_elem, &(fd_elem_corner_coords[0]),
     428              :                         &(fd_loc_ip[0]), nip, u);
     429            0 :                 (* m_spScalData) (&(scaling[0]), vGlobIP, time, fd_si, fd_elem, &(fd_elem_corner_coords[0]),
     430              :                         &(fd_loc_ip[0]), nip, u);
     431              :                 //TODO: Note that u is here a dummy parameter: We do not have enough data for it.
     432              :         
     433              :         //      Scale and project the vectors
     434            0 :                 const ReferenceObjectID roid = elem->reference_object_id ();
     435              :                 DimReferenceMapping<refDim, dim> & map
     436              :                         = ReferenceMappingProvider::get<refDim, dim> (roid, vCornerCoords);
     437            0 :                 for (size_t ip = 0; ip < nip; ip++)
     438              :                 {
     439            0 :                         vValue[ip] *= scaling[ip];
     440              :                         
     441              :                         MathMatrix<dim, refDim> J;
     442              :                         MathVector<dim> p (vValue[ip]);
     443              :                         
     444            0 :                         map.jacobian (J, vLocIP[ip]);
     445            0 :                         OrthogProjectVec (p, J);                        
     446              :                         vValue[ip] -= p;
     447              :                 }
     448            0 :         };
     449              :         
     450              : ///     This function should not be used
     451            0 :         void operator()
     452              :         (
     453              :                 vec_type & vValue,
     454              :                 const MathVector<dim> & globIP,
     455              :                 number time,
     456              :                 int si
     457              :         )
     458              :         const
     459              :         {
     460            0 :                 UG_THROW("ScaledOutNormCmp: Element required for evaluation, but not passed. Cannot evaluate.");
     461              :         }
     462              : 
     463              : ///     This function should not be used
     464            0 :         void operator()
     465              :         (
     466              :                 vec_type vValue [],
     467              :                 const MathVector<dim> vGlobIP [],
     468              :                 number time,
     469              :                 int si,
     470              :                 const size_t nip
     471              :         ) const
     472              :         {
     473            0 :                 UG_THROW("ScaledOutNormCmp: Element required for evaluation, but not passed. Cannot evaluate.");
     474              :         }
     475              : 
     476              : };
     477              : 
     478              : /// Scaled flux for a given vector user data
     479              : /**
     480              :  * This class implements the UserData for evaluation of the flux of a vector field
     481              :  * computed by the other user data object. The flux is evaluation only for
     482              :  * WDim-1-dimensional subsets - sides of WDim-dimensional elements. It is scaled by
     483              :  * a furthe (scalar) UserData.
     484              :  *
     485              :  * ToDo: Note that the LocalVector provided for the evaluate function is not properly
     486              :  * used. Thus, the passed UserData objects should not use it.
     487              :  *
     488              :  */
     489              : template <typename TDomain>
     490              : class ScaledFluxData
     491              :         : public StdUserData<ScaledFluxData<TDomain>, number, TDomain::dim, void, UserData<number, TDomain::dim, void> >
     492              : {
     493              : ///     the world dimension
     494              :         static const int dim = TDomain::dim;
     495              :         
     496              : ///     the domain type
     497              :         typedef TDomain domain_type;
     498              :         
     499              : ///     the grid type
     500              :         typedef typename TDomain::grid_type grid_type;
     501              :         
     502              : ///     the original data type
     503              :         typedef MathVector<dim> vec_type;
     504              :         
     505              : ///     the original vector field data
     506              :         SmartPtr<UserData<vec_type, dim, void> > m_spVecData;
     507              :         
     508              : ///     the scaling data
     509              :         SmartPtr<UserData<number, dim, void> > m_spScalData;
     510              :         
     511              : ///     the domain
     512              :         SmartPtr<domain_type> m_spDomain;
     513              :         
     514              : ///     the subset group for the inner part
     515              :         SubsetGroup m_ssGrp;
     516              :         
     517              : public:
     518              : 
     519              : ///     constructor
     520            0 :         ScaledFluxData
     521              :         (
     522              :                 SmartPtr<domain_type> spDomain, ///< the domain
     523              :                 SmartPtr<UserData<number, dim, void> > spScalData, ///< the scaling data
     524              :                 SmartPtr<UserData<vec_type, dim, void> > spVecData, ///< the original vector field data
     525              :                 const char * ss_names ///< the subsets
     526              :         )
     527            0 :         :       m_spVecData (spVecData), m_spScalData (spScalData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     528              :         {
     529              :         // Parse the subset names:
     530              :                 std::vector<std::string> vssNames;
     531              :                 try
     532              :                 {
     533            0 :                         TokenizeString (ss_names, vssNames);
     534            0 :                         for (size_t k = 0; k < vssNames.size (); k++)
     535            0 :                                 RemoveWhitespaceFromString (vssNames [k]);
     536              :                         m_ssGrp.clear ();
     537            0 :                         m_ssGrp.add (vssNames);
     538            0 :                 } UG_CATCH_THROW ("SubsetIndicatorUserData: Failed to parse subset names.");
     539            0 :         }
     540              :         
     541              : ///     constructor
     542            0 :         ScaledFluxData
     543              :         (
     544              :                 SmartPtr<domain_type> spDomain, ///< the domain
     545              :                 SmartPtr<UserData<number, dim, void> > spScalData, ///< the scaling data
     546              :                 SmartPtr<UserData<vec_type, dim, void> > spVecData ///< the original vector field data
     547              :         )
     548            0 :         :       m_spVecData (spVecData), m_spScalData (spScalData), m_spDomain (spDomain), m_ssGrp (spDomain->subset_handler ())
     549            0 :         {}
     550              :         
     551              : ///     Indicator functions are discontinuous
     552            0 :         virtual bool continuous () const {return false;}
     553              : 
     554              : ///     Returns true to get the grid element in the evaluation routine
     555            0 :         virtual bool requires_grid_fct () const {return m_spVecData->requires_grid_fct () || m_spScalData->requires_grid_fct ();}
     556              :         // Remark: Note that actually we have not enought data for that. This dependence is neglected.
     557              : 
     558              : ///     Evaluator
     559              :         template <int refDim>
     560            0 :         inline void evaluate
     561              :         (
     562              :                 number vValue[],
     563              :                 const MathVector<dim> vGlobIP [],
     564              :                 number time,
     565              :                 int si,
     566              :                 GridObject * elem,
     567              :                 const MathVector<dim> vCornerCoords [],
     568              :                 const MathVector<refDim> vLocIP [],
     569              :                 const size_t nip,
     570              :                 LocalVector * u,
     571              :                 const MathMatrix<refDim, dim> * vJT = NULL
     572              :         ) const
     573              :         {
     574              :                 if (refDim != dim - 1)
     575              :                 {
     576            0 :                         UG_THROW ("ScaledFluxData: Wrong dimensionality of the subset.");
     577              :                 }
     578              :                 
     579              :         //      Get the full-dim. element associated with the given side
     580              :                 typedef typename grid_dim_traits<dim>::grid_base_object fd_elem_type;
     581              :                 fd_elem_type * fd_elem = NULL;
     582              :                 int fd_si = -1;
     583              :                 
     584              :                 typedef typename Grid::traits<fd_elem_type>::secure_container fd_elem_secure_container_type;
     585              :                 fd_elem_secure_container_type fd_elem_list;
     586            0 :                 grid_type& grid = * (grid_type*) (m_spDomain->grid().get ());
     587            0 :                 grid.associated_elements (fd_elem_list, elem);
     588              :                 
     589            0 :                 if (m_ssGrp.empty ()) // no subsets specified; we assume, elem should be the bnd of the whole domain
     590              :                 {
     591            0 :                         if (fd_elem_list.size () == 1)
     592              :                         {
     593              :                                 fd_elem = fd_elem_list[0];
     594            0 :                                 fd_si = m_spDomain->subset_handler()->get_subset_index (fd_elem);
     595              :                         }
     596              :                         // otherwise this is no boundary of the domain and we return 0
     597              :                 }
     598              :                 else
     599              :                 {
     600            0 :                         for (size_t k = 0; k < fd_elem_list.size (); k++)
     601              :                         {
     602              :                                 fd_elem_type * e = fd_elem_list[k];
     603            0 :                                 int e_si = m_ssGrp.subset_handler()->get_subset_index (e);
     604            0 :                                 if (m_ssGrp.contains (e_si))
     605              :                                 {
     606            0 :                                         if (fd_elem != NULL) // i.e. e is already the second one
     607              :                                         { // this is no boundary of the subset; return 0
     608              :                                                 fd_elem = NULL;
     609              :                                                 break;
     610              :                                         }
     611              :                                         fd_elem = e;
     612              :                                         fd_si = e_si;
     613              :                                 }
     614              :                         }
     615              :                 }
     616            0 :                 if (fd_elem == NULL)
     617              :                 { // this is no bondary, return 0
     618            0 :                         for (size_t ip = 0; ip < nip; ip++) vValue[ip] = 0;
     619              :                         return;
     620              :                 }
     621              :                 
     622              :         //      Get the coordinates of the corners of the full-dim. element
     623            0 :                 std::vector<MathVector<dim> > fd_elem_corner_coords (domain_traits<dim>::MaxNumVerticesOfElem);
     624            0 :                 CollectCornerCoordinates (fd_elem->base_object_id (), fd_elem_corner_coords,
     625              :                         *fd_elem, *m_spDomain, true);
     626              :                 
     627              :         //      Convert the local ip coordinates (use the global coordinates as they are the same)
     628            0 :                 const ReferenceObjectID fd_roid = fd_elem->reference_object_id ();
     629              :                 DimReferenceMapping<dim, dim> & fd_map
     630              :                         = ReferenceMappingProvider::get<dim, dim> (fd_roid, fd_elem_corner_coords);
     631            0 :                 std::vector<MathVector<dim> > fd_loc_ip (nip);
     632            0 :                 for (size_t ip = 0; ip < nip; ip++)
     633            0 :                         fd_map.global_to_local(fd_loc_ip[ip], vGlobIP[ip]);
     634              :         
     635              :         //      Get the normal to the face:
     636              :                 MathVector<dim> normal;
     637            0 :                 ElementNormal<dim> (elem->reference_object_id (), normal, vCornerCoords);
     638            0 :                 VecScale (normal, normal, 1 / VecLength (normal));
     639            0 :                 for (size_t co = 0; co < fd_elem->num_vertices (); co++)
     640              :                 {
     641              :                         MathVector<dim> s_vec;
     642              :                         VecSubtract (s_vec, fd_elem_corner_coords[co], vCornerCoords[0]);
     643            0 :                         if (VecDot (s_vec, normal) > 1e-12 * VecLength (s_vec))
     644              :                         {       // this is the inner normal, invert its direction
     645              :                                 VecScale (normal, normal, -1);
     646            0 :                                 break;
     647              :                         }
     648              :                 }
     649              :                 
     650              :         //      Call the original UserData, get the vectors
     651            0 :                 std::vector<MathVector<dim> > vecfield (nip);
     652            0 :                 std::vector<number> scaling (nip);
     653            0 :                 (* m_spVecData) (&(vecfield[0]), vGlobIP, time, fd_si, fd_elem, &(fd_elem_corner_coords[0]),
     654              :                         &(fd_loc_ip[0]), nip, u);
     655            0 :                 (* m_spScalData) (&(scaling[0]), vGlobIP, time, fd_si, fd_elem, &(fd_elem_corner_coords[0]),
     656              :                         &(fd_loc_ip[0]), nip, u);
     657              :                 //TODO: Note that u is here a dummy parameter: We do not have enough data for it.
     658              :         
     659              :         //      Scale and project the vectors
     660            0 :                 for (size_t ip = 0; ip < nip; ip++)
     661            0 :                         vValue[ip] = scaling[ip] * VecDot (vecfield[ip], normal);
     662            0 :         };
     663              :         
     664              : ///     This function should not be used
     665            0 :         void operator()
     666              :         (
     667              :                 number & vValue,
     668              :                 const MathVector<dim> & globIP,
     669              :                 number time,
     670              :                 int si
     671              :         )
     672              :         const
     673              :         {
     674            0 :                 UG_THROW("ScaledFluxData: Element required for evaluation, but not passed. Cannot evaluate.");
     675              :         }
     676              : 
     677              : ///     This function should not be used
     678            0 :         void operator()
     679              :         (
     680              :                 number vValue [],
     681              :                 const MathVector<dim> vGlobIP [],
     682              :                 number time,
     683              :                 int si,
     684              :                 const size_t nip
     685              :         ) const
     686              :         {
     687            0 :                 UG_THROW("ScaledFluxData: Element required for evaluation, but not passed. Cannot evaluate.");
     688              :         }
     689              : 
     690              : };
     691              : 
     692              : } // end namespace ug
     693              : 
     694              : #endif // __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__ONC_USER_DATA__
     695              : 
     696              : /* End of File */
        

Generated by: LCOV version 2.0-1