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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Michael Lampe
       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              :  * Singular sources and sinks for the FV discretizations: Implementation of the functions
      35              :  */
      36              : 
      37              : // ug4 headers
      38              : #include "lib_grid/algorithms/ray_element_intersection_util.h"
      39              : #include "lib_disc/reference_element/reference_element_util.h"
      40              : 
      41              : namespace ug{
      42              : 
      43              : /**
      44              :  * Test whether a source/sink point corresponds to a given corner of the element.
      45              :  * Note that \c TElem must specify the dimensionality of the element. Thus,
      46              :  * \c GridObject is not a proper type for \c TElem. It should be at least
      47              :  * \c Edge, \c Face, \c Volume or derived classes.
      48              :  */
      49              : template <int dim, typename TData>
      50              : template <typename TElem, typename TAAPos, typename TFVGeom>
      51            0 : bool FVPointSourceOrSink<dim, TData>::corresponds_to
      52              : (
      53              :         TElem* elem, ///< the element
      54              :         Grid& grid, ///< the grid
      55              :         TAAPos& aaPos, ///< position of the vertices
      56              :         const TFVGeom& geo, ///< FV geometry (initialized for 'elem')
      57              :         size_t co ///< corner to get the contribution for
      58              : )
      59              : {
      60              : // restrict point to element
      61            0 :         if (!ContainsPoint(elem, point, aaPos))
      62              :                 return false;
      63              : 
      64              : // restrict point to scv
      65            0 :         for (size_t i = 0; i < geo.num_scvf(); i++)
      66              :         {
      67              :                 const typename TFVGeom::SCVF& scvf = geo.scvf(i);
      68              :                 MathVector<dim> d;
      69              :                 VecSubtract(d, point, scvf.global_ip());
      70            0 :                 if (scvf.from() == co)
      71              :                 {
      72            0 :                         if (VecDot(d, scvf.normal()) >= 0.0)
      73            0 :                                 return false;
      74              :                 }
      75            0 :                 else if (scvf.to() == co)
      76              :                 {
      77            0 :                         if (VecDot(d, scvf.normal()) < 0.0)
      78              :                                 return false;
      79              :                 }
      80              :         }
      81              :         return true;
      82              : };
      83              : 
      84              : /**
      85              :  * Test whether a line source/sink corresponds to a given corner of an element.
      86              :  * If yes, the function returns true and sets ls and le to the beginning and the
      87              :  * end of the subsegment of the source/sink.
      88              :  *
      89              :  * Note that \c TElem must specify the dimensionality of the element. Thus,
      90              :  * \c GridObject is not a proper type for \c TElem. It should be at least
      91              :  * \c Edge, \c Face, \c Volume or derived classes.
      92              :  *
      93              :  * \todo This function works only for there is only one scv per corner. This is not true for pyramids!
      94              :  */
      95              : template <int dim, typename TData>
      96              : template <typename TElem, typename TAAPos, typename TFVGeom>
      97            0 : bool FVLineSourceOrSink<dim, TData>::corresponds_to
      98              : (
      99              :         TElem* elem, ///< [in] the element
     100              :         Grid& grid, ///< [in] the grid
     101              :         TAAPos& aaPos, ///< [in] position of the vertices
     102              :         const TFVGeom& geo, ///< [in] FV geometry (initialized for 'elem')
     103              :         size_t co, ///< [in] corner to get the contribution for
     104              :         MathVector<dim>& ls, ///< [out] beginning of the subsegment
     105              :         MathVector<dim>& le ///< [out] end of the subsegment
     106              : )
     107              : {
     108              : //      get the dimensionality of the element
     109            0 :         int elem_dim = ReferenceElementDimension(elem->reference_object_id());
     110              : 
     111              : //      restrict line segment to element (so that ls and le are the intersection points with its sides)
     112              :         ls = point1;
     113              :         le = point2;
     114              :         MathVector<dim> dir;
     115              :         number lambda_min, lambda_max;
     116              :         VecSubtract(dir, le, ls);
     117            0 :         if (!RayElementIntersection(lambda_min, lambda_max, ls, dir, elem, grid, aaPos))
     118              :                 return false;
     119              :         
     120            0 :         if (elem_dim == dim) // full-dimensional element, two different points
     121              :         {
     122              :         // extend the ends of the segment to the sides of the element
     123            0 :                 if (ContainsPoint(elem, ls, aaPos))
     124            0 :                         lambda_min = 0.0;
     125            0 :                 if (ContainsPoint(elem, le, aaPos))
     126            0 :                         lambda_max = 1.0;
     127              :         
     128              :         // skip the segment if its line cuts the element before or after the segment
     129            0 :                 if (lambda_min < 0.0 || lambda_max > 1.0)
     130            0 :                         return false;
     131              :         
     132              :         // compute the corrected ends
     133              :                 VecScaleAdd(le, 1.0, ls, lambda_max, dir);
     134              :                 VecScaleAdd(ls, 1.0, ls, lambda_min, dir);
     135              : 
     136              :         //      restrict line segment to scv (so that ls and le are the intersection points with the sides of the scv)
     137              :                 MathVector<dim> p;
     138            0 :                 for (size_t i = 0; i < geo.num_scvf(); i++)
     139              :                 {
     140              :                         const typename TFVGeom::SCVF& scvf = geo.scvf(i);
     141              :                         number d_min, d_max, lambda;
     142            0 :                         if (scvf.from() == co)
     143              :                         {
     144              :                                 VecSubtract(p, ls, scvf.global_ip());
     145              :                                 d_min = VecDot(p, scvf.normal());
     146              :                                 VecSubtract(p, le, scvf.global_ip());
     147              :                                 d_max = VecDot(p, scvf.normal());
     148            0 :                                 if (d_min*d_max < 0.0)
     149              :                                 {
     150            0 :                                         lambda = fabs(d_min)/(fabs(d_min)+fabs(d_max));
     151            0 :                                         VecScaleAdd(p, 1.0-lambda, ls, lambda, le);
     152            0 :                                         if (d_max > 0.0)
     153              :                                                 le = p;
     154              :                                         else
     155              :                                                 ls = p;
     156              :                                 }
     157            0 :                                 else if (d_min > 0.0) // if so than d_max >= 0, too
     158              :                                         return false;
     159              :                         }
     160            0 :                         else if (scvf.to() == co)
     161              :                         {
     162              :                                 VecSubtract(p, ls, scvf.global_ip());
     163              :                                 d_min = VecDot(p, scvf.normal());
     164              :                                 VecSubtract(p, le, scvf.global_ip());
     165              :                                 d_max = VecDot(p, scvf.normal());
     166            0 :                                 if (d_min*d_max < 0.0)
     167              :                                 {
     168            0 :                                         lambda = fabs(d_min)/(fabs(d_min)+fabs(d_max));
     169            0 :                                         VecScaleAdd(p, 1.0-lambda, ls, lambda, le);
     170            0 :                                         if (d_max < 0.0)
     171              :                                                 le = p;
     172              :                                         else
     173              :                                                 ls = p;
     174              :                                 }
     175            0 :                                 else if (d_min < 0.0) // if so than d_max <= 0, too
     176              :                                         return false;
     177              :                         }
     178              :                 }
     179              :         }
     180            0 :         else if (elem_dim + 1 == dim) // low-dimensional element, we accept only one point
     181              :         {
     182              :         // skip the segment if its line cuts the element before or after the segment
     183            0 :                 if (lambda_min < 0.0 || lambda_max > 1.0)
     184              :                         return false;
     185              :                 
     186              :         //      exclude the case the the line in the plane
     187            0 :                 if (std::fabs (lambda_max - lambda_min) > SMALL)
     188            0 :                         UG_THROW ("FVLineSourceOrSink: Line source or sink lyes in a low-dimensional element!");
     189              : 
     190              :         //      check if the point is in the scv
     191              :                 VecScaleAdd(ls, 1.0, point1, lambda_min, dir);
     192            0 :                 for (size_t i = 0; i < geo.num_scvf(); i++)
     193              :                 {
     194              :                         const typename TFVGeom::SCVF& scvf = geo.scvf(i);
     195              :                         MathVector<dim> d;
     196              :                         VecSubtract(d, ls, scvf.global_ip());
     197            0 :                         if (scvf.from() == co)
     198              :                         {
     199            0 :                                 if (VecDot(d, scvf.normal()) > 0.0)
     200            0 :                                         return false;
     201              :                         }
     202            0 :                         else if (scvf.to() == co)
     203              :                         {
     204            0 :                                 if (VecDot(d, scvf.normal()) < 0.0)
     205              :                                         return false;
     206              :                         }
     207              :                 }
     208              :                 le = ls;
     209              :         }
     210              :         else
     211            0 :                 UG_THROW ("FVLineSourceOrSink: Dimension mismatch with a grid element!");
     212              :         
     213            0 :         return true;
     214              : };
     215              : 
     216              : /**
     217              :  * Finds the proper point source or sink starting with a given index
     218              :  */
     219              : template <int dim, typename TPointData, typename TLineData>
     220              : template <typename TElem, typename TAAPos, typename TFVGeom>
     221            0 : void FVSingularSourcesAndSinks<dim, TPointData, TLineData>::point_iterator<TElem, TAAPos, TFVGeom>::next_sss
     222              : (
     223              :         size_t index ///< index to start the search with
     224              : )
     225              : {
     226            0 :         for (m_index = index; m_index < m_sss->num_points (); m_index++)
     227              :         {
     228              :                 point_sss_type * pnt_sss = m_sss->ListP[m_index].get();
     229            0 :                 if (! m_elem_bbox.contains_point (pnt_sss->position ())) // a quick test
     230            0 :                         continue;
     231            0 :                 if (pnt_sss->corresponds_to (m_elem, m_grid, m_aaPos, m_geo, m_co))
     232              :                         break;
     233              :         }
     234            0 : };
     235              : 
     236              : /**
     237              :  * Finds the proper point source or sink starting with a given index
     238              :  */
     239              : template <int dim, typename TPointData, typename TLineData>
     240              : template <typename TElem, typename TAAPos, typename TFVGeom>
     241            0 : void FVSingularSourcesAndSinks<dim, TPointData, TLineData>::line_iterator<TElem, TAAPos, TFVGeom>::next_sss
     242              : (
     243              :         size_t index, ///< index to start the search with
     244              :         MathVector<dim>& ls, ///< the 1st of the intersection points with the bnd of the scv
     245              :         MathVector<dim>& le ///< the 2nd of the intersection points with the bnd of the scv
     246              : )
     247              : {
     248            0 :         for (m_index = index; m_index < m_sss->num_lines (); m_index++)
     249              :         {
     250              :                 line_sss_type * line_sss = m_sss->ListL[m_index].get();
     251            0 :                 if (! m_elem_bbox.overlaps_line (line_sss->from_position (), line_sss->to_position ())) // a quick test
     252            0 :                         continue;
     253            0 :                 if (line_sss->corresponds_to (m_elem, m_grid, m_aaPos, m_geo, m_co, ls, le))
     254              :                         break;
     255              :         }
     256            0 : };
     257              : 
     258              : } // end of namespace ug
     259              : 
     260              : /* End of File */
        

Generated by: LCOV version 2.0-1