LCOV - code coverage report
Current view: top level - ugbase/lib_grid/refinement/projectors - elliptic_cylinder_projector.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 111 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 27 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2016:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Markus Breit
       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 "elliptic_cylinder_projector.h"
      34              : 
      35              : #include "common/math/misc/math_util.h"
      36              : #include "refinement_projector.h"
      37              : 
      38              : 
      39              : namespace ug {
      40              : 
      41              : 
      42            0 : EllipticCylinderProjector::EllipticCylinderProjector()
      43              : : m_center(0, 0, 0),
      44              :   m_cylinder_axis(0, 0, 1),
      45              :   m_ellipse_axis1(1, 0, 0),
      46              :   m_ellipse_axis2(0, 1, 0),
      47            0 :   m_radius(-1),
      48            0 :   m_influenceRadius(-1),
      49              :   m_ellipseNormal(0, 0, 1),
      50            0 :   m_a(1.0),
      51            0 :   m_b(1.0)
      52            0 : {}
      53              : 
      54              : 
      55            0 : EllipticCylinderProjector::EllipticCylinderProjector
      56              : (
      57              :         const vector3& center,
      58              :         const vector3& cylAxis,
      59              :         const vector3& ellipseAxis1,
      60              :         const vector3& ellipseAxis2
      61            0 : )
      62              : : m_center(center),
      63              :   m_cylinder_axis(cylAxis),
      64              :   m_ellipse_axis1(ellipseAxis1),
      65              :   m_ellipse_axis2(ellipseAxis2),
      66            0 :   m_radius(-1),
      67            0 :   m_influenceRadius(-1),
      68            0 :   m_a(VecLength(ellipseAxis1)),
      69            0 :   m_b(VecLength(ellipseAxis2))
      70              : {
      71            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
      72            0 : }
      73              : 
      74              : 
      75            0 : EllipticCylinderProjector::EllipticCylinderProjector
      76              : (
      77              :         const vector3& center,
      78              :         const vector3& cylAxis,
      79              :         const vector3& ellipseAxis1,
      80              :         const vector3& ellipseAxis2,
      81              :         number radius
      82            0 : )
      83              : : m_center(center),
      84              :   m_cylinder_axis(cylAxis),
      85              :   m_ellipse_axis1(ellipseAxis1),
      86              :   m_ellipse_axis2(ellipseAxis2),
      87            0 :   m_radius(radius),
      88            0 :   m_influenceRadius(-1),
      89            0 :   m_a(VecLength(ellipseAxis1)),
      90            0 :   m_b(VecLength(ellipseAxis2))
      91              : {
      92              :         UG_LOGN("Constructor5");
      93            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
      94            0 : }
      95              : 
      96              : 
      97            0 : EllipticCylinderProjector::EllipticCylinderProjector
      98              : (
      99              :         const vector3& center,
     100              :         const vector3& cylAxis,
     101              :         const vector3& ellipseAxis1,
     102              :         const vector3& ellipseAxis2,
     103              :         number radius,
     104              :         number influenceRadius
     105            0 : )
     106              : : m_center(center),
     107              :   m_cylinder_axis(cylAxis),
     108              :   m_ellipse_axis1(ellipseAxis1),
     109              :   m_ellipse_axis2(ellipseAxis2),
     110            0 :   m_radius(radius),
     111            0 :   m_influenceRadius(influenceRadius),
     112            0 :   m_a(VecLength(ellipseAxis1)),
     113            0 :   m_b(VecLength(ellipseAxis2))
     114              : {
     115            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
     116            0 : }
     117              : 
     118              : 
     119            0 : EllipticCylinderProjector::EllipticCylinderProjector
     120              : (
     121              :         SPIGeometry3d geometry,
     122              :         const vector3& center,
     123              :         const vector3& cylAxis,
     124              :         const vector3& ellipseAxis1,
     125              :         const vector3& ellipseAxis2,
     126              :         number radius,
     127              :         number influenceRadius
     128            0 : )
     129              : : RefinementProjector(geometry),
     130              :   m_center(center),
     131              :   m_cylinder_axis(cylAxis),
     132              :   m_ellipse_axis1(ellipseAxis1),
     133              :   m_ellipse_axis2(ellipseAxis2),
     134            0 :   m_radius(radius),
     135            0 :   m_influenceRadius(influenceRadius),
     136            0 :   m_a(VecLength(ellipseAxis1)),
     137            0 :   m_b(VecLength(ellipseAxis2))
     138              : {
     139            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
     140            0 : }
     141              : 
     142              : 
     143            0 : EllipticCylinderProjector::~EllipticCylinderProjector()
     144            0 : {}
     145              : 
     146              : 
     147              : 
     148            0 : void EllipticCylinderProjector::set_center(const vector3& center)
     149              : {
     150              :         m_center = center;
     151            0 : }
     152              : 
     153            0 : const vector3& EllipticCylinderProjector::center() const
     154              : {
     155            0 :         return m_center;
     156              : }
     157              : 
     158              : 
     159            0 : void EllipticCylinderProjector::set_cylinder_axis(const vector3& axis)
     160              : {
     161              :         m_cylinder_axis = axis;
     162            0 : }
     163              : 
     164            0 : const vector3& EllipticCylinderProjector::cylinder_axis() const
     165              : {
     166            0 :         return m_cylinder_axis;
     167              : }
     168              : 
     169              : 
     170            0 : void EllipticCylinderProjector::set_ellipse_axis1(const vector3& axis)
     171              : {
     172              :         m_ellipse_axis1 = axis;
     173            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
     174            0 :         m_a = VecLength(axis);
     175            0 : }
     176              : 
     177            0 : const vector3& EllipticCylinderProjector::ellipse_axis1() const
     178              : {
     179            0 :         return m_ellipse_axis1;
     180              : }
     181              : 
     182              : 
     183            0 : void EllipticCylinderProjector::set_ellipse_axis2(const vector3& axis)
     184              : {
     185              :         m_ellipse_axis2 = axis;
     186            0 :         VecCross(m_ellipseNormal, m_ellipse_axis1, m_ellipse_axis2);
     187            0 :         m_b = VecLength(axis);
     188            0 : }
     189              : 
     190            0 : const vector3& EllipticCylinderProjector::ellipse_axis2() const
     191              : {
     192            0 :         return m_ellipse_axis2;
     193              : }
     194              : 
     195              : 
     196            0 : void EllipticCylinderProjector::set_radius(number radius)
     197              : {
     198            0 :         m_radius = radius;
     199            0 : }
     200              : 
     201            0 : number EllipticCylinderProjector::radius() const
     202              : {
     203            0 :         return m_radius;
     204              : }
     205              : 
     206              : 
     207            0 : void EllipticCylinderProjector::set_influence_radius(number influenceRadius)
     208              : {
     209            0 :         m_influenceRadius = influenceRadius;
     210            0 : }
     211              : 
     212            0 : number EllipticCylinderProjector::influence_radius() const
     213              : {
     214            0 :         return m_influenceRadius;
     215              : }
     216              : 
     217              : 
     218              : 
     219            0 : number EllipticCylinderProjector::new_vertex(Vertex* vrt, Edge* parent)
     220              : {
     221            0 :         return perform_projection(vrt, parent);
     222              : }
     223              : 
     224            0 : number EllipticCylinderProjector::new_vertex(Vertex* vrt, Face* parent)
     225              : {
     226            0 :         return perform_projection(vrt, parent);
     227              : }
     228              : 
     229            0 : number EllipticCylinderProjector::new_vertex(Vertex* vrt, Volume* parent)
     230              : {
     231            0 :         return perform_projection(vrt, parent);
     232              : }
     233              : 
     234              : 
     235              : 
     236            0 : number EllipticCylinderProjector::radial_ellipse_coord(const vector3& v)
     237              : {
     238              :         // project coordinates along cylinder axis to ellipse plane
     239              :         vector3 proj2Ellipse;
     240              :         number dummy;
     241            0 :         RayPlaneIntersection(proj2Ellipse, dummy, v, m_cylinder_axis, m_center, m_ellipseNormal);
     242              : 
     243              :         // get x and y coordinates
     244            0 :         const number x = VecDot(m_ellipse_axis1, proj2Ellipse) / m_a;
     245            0 :         const number y = VecDot(m_ellipse_axis2, proj2Ellipse) / m_b;
     246              : 
     247            0 :         return sqrt(x*x/(m_a*m_a) + y*y/(m_b*m_b));
     248              : }
     249              : 
     250              : 
     251            0 : number EllipticCylinderProjector::scale_point_to_radius(vector3& vIO, number r)
     252              : {
     253              :         // project coordinates along cylinder axis to ellipse plane
     254              :         vector3 proj2Ellipse;
     255              :         number dummy;
     256            0 :         RayPlaneIntersection(proj2Ellipse, dummy, vIO, m_cylinder_axis, m_center, m_ellipseNormal);
     257              : 
     258              :         VecSubtract(vIO, vIO, proj2Ellipse);
     259              : 
     260              :         // current radius
     261            0 :         const number x = VecDot(m_ellipse_axis1, proj2Ellipse) / m_a;
     262            0 :         const number y = VecDot(m_ellipse_axis2, proj2Ellipse) / m_b;
     263            0 :         const number rcur = sqrt(x*x/(m_a*m_a) + y*y/(m_b*m_b));
     264              : 
     265              :         // scale and undo projection
     266            0 :         if (rcur > SMALL * r)
     267            0 :                 VecScaleAdd(vIO, 1.0, vIO, r / rcur, proj2Ellipse);
     268              :         else
     269              :                 // if current position is in the center of the cylinder, leave it there
     270              :                 VecAdd(vIO, vIO, m_center);
     271              : 
     272            0 :         return rcur;
     273              : }
     274              : 
     275              : 
     276              : template <class TElem>
     277            0 : number EllipticCylinderProjector::perform_projection(Vertex* vrt, TElem* parent)
     278              : {
     279              :         // General method:
     280              :         // The "radius" of all parent vertices is averaged
     281              :         // and used for the radius of the projected child.
     282              :         // The (Cartesian) coordinates of all parents are averaged.
     283              :         // The resulting coordinates are scaled around the axis
     284              :         // within the ellipse plane to reach the previously determined radius.
     285              :         // TODO: It might be better to also average arc lengths and axial coords of parents
     286              :         //       and project the child to averaged radius, arc length and axial coords.
     287              : 
     288              :         // average parent vertex positions and radii
     289            0 :         typename TElem::ConstVertexArray vrts = parent->vertices();
     290            0 :         const size_t numVrts = parent->num_vertices();
     291              : 
     292            0 :         if (numVrts == 0)
     293              :         {
     294            0 :                 set_pos(vrt, vector3(0, 0, 0));
     295            0 :                 return 1;
     296              :         }
     297              : 
     298              :         number avgR = 0;
     299              :         vector3 proj(0, 0, 0);
     300            0 :         for (size_t i = 0; i < numVrts; ++i)
     301              :         {
     302            0 :                 const vector3& p = pos(vrts[i]);
     303            0 :                 avgR += radial_ellipse_coord(p);
     304              :                 proj += p;
     305              :         }
     306            0 :         avgR /= numVrts;
     307            0 :         VecScale(proj, proj, 1.0 / numVrts);
     308              : 
     309              :         // move averaged position to new radius
     310            0 :         const number curR = scale_point_to_radius(proj, avgR);
     311              :         set_pos(vrt, proj);
     312              : 
     313            0 :         if (m_influenceRadius > 0)
     314              :         {
     315            0 :                 if (m_radius > m_influenceRadius)
     316              :                 {
     317            0 :                         const number dist = m_radius - m_influenceRadius;
     318            0 :                         return clip<number>((curR - m_influenceRadius) / dist, 0, 1);
     319              :                 }
     320            0 :                 else if (m_radius >= 0)
     321              :                 {
     322            0 :                         const number dist = m_influenceRadius - m_radius;
     323            0 :                         if (dist > 0)
     324            0 :                                 return clip<number>(1 - (curR - m_radius) / dist, 0, 1);
     325            0 :                         return curR < m_radius ? 1 : 0;
     326              :                 }
     327              :                 else
     328            0 :                         return clip<number>(1 - curR / m_influenceRadius, 0, 1);
     329              :         }
     330              : 
     331              :         return 1;
     332              : }
     333              : 
     334              : 
     335              : } // namespace ug
        

Generated by: LCOV version 2.0-1