LCOV - code coverage report
Current view: top level - src/geom - sphere.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 21 77 27.3 %
Date: 2025-08-19 19:27:09 Functions: 5 14 35.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : // C++ includes
      21             : #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
      22             : #include <cmath> // for std::abs
      23             : 
      24             : 
      25             : // Local includes
      26             : #include "libmesh/tensor_value.h"
      27             : #include "libmesh/sphere.h"
      28             : 
      29             : namespace libMesh
      30             : {
      31             : 
      32             : 
      33             : 
      34             : // ------------------------------------------------------------
      35             : // Sphere class member functions
      36           0 : Sphere::Sphere () :
      37           0 :   _rad(-1.)
      38             : {
      39           0 : }
      40             : 
      41             : 
      42             : 
      43        1074 : Sphere::Sphere (const Point & c,
      44        1074 :                 const Real r)
      45             : {
      46          34 :   libmesh_assert_greater (r, 0.);
      47             : 
      48        1074 :   this->create_from_center_radius (c, r);
      49        1074 : }
      50             : 
      51             : 
      52             : 
      53           0 : Sphere::Sphere (const Sphere & other_sphere) :
      54           0 :   Surface()
      55             : {
      56           0 :   this->create_from_center_radius (other_sphere.center(),
      57             :                                    other_sphere.radius());
      58           0 : }
      59             : 
      60             : 
      61             : 
      62           0 : Sphere::Sphere(const Point & pa,
      63             :                const Point & pb,
      64             :                const Point & pc,
      65           0 :                const Point & pd)
      66             : {
      67             : #if LIBMESH_DIM > 2
      68           0 :   Point pad = pa - pd;
      69           0 :   Point pbd = pb - pd;
      70           0 :   Point pcd = pc - pd;
      71             : 
      72           0 :   TensorValue<Real> T(pad,pbd,pcd);
      73             : 
      74           0 :   Real D = T.det();
      75             : 
      76             :   // The points had better not be coplanar
      77           0 :   libmesh_assert_greater (std::abs(D), 1e-12);
      78             : 
      79           0 :   Real e = 0.5*(pa.norm_sq() - pd.norm_sq());
      80           0 :   Real f = 0.5*(pb.norm_sq() - pd.norm_sq());
      81           0 :   Real g = 0.5*(pc.norm_sq() - pd.norm_sq());
      82             : 
      83           0 :   TensorValue<Real> T1(e,pad(1),pad(2),
      84           0 :                        f,pbd(1),pbd(2),
      85           0 :                        g,pcd(1),pcd(2));
      86           0 :   Real sx = T1.det()/D;
      87             : 
      88           0 :   TensorValue<Real> T2(pad(0),e,pad(2),
      89           0 :                        pbd(0),f,pbd(2),
      90           0 :                        pcd(0),g,pcd(2));
      91           0 :   Real sy = T2.det()/D;
      92             : 
      93           0 :   TensorValue<Real> T3(pad(0),pad(1),e,
      94           0 :                        pbd(0),pbd(1),f,
      95           0 :                        pcd(0),pcd(1),g);
      96           0 :   Real sz = T3.det()/D;
      97             : 
      98           0 :   Point c(sx,sy,sz);
      99           0 :   Real r = (c-pa).norm();
     100             : 
     101           0 :   this->create_from_center_radius(c,r);
     102             : #else // LIBMESH_DIM > 2
     103             :   libmesh_ignore(pa, pb, pc, pd);
     104             :   libmesh_not_implemented();
     105             : #endif
     106           0 : }
     107             : 
     108             : 
     109             : 
     110        1006 : Sphere::~Sphere () = default;
     111             : 
     112             : 
     113             : 
     114        1074 : void Sphere::create_from_center_radius (const Point & c, const Real r)
     115             : {
     116        1074 :   this->center() = c;
     117        1074 :   this->radius() = r;
     118             : 
     119          34 :   libmesh_assert_greater (this->radius(), 0.);
     120        1074 : }
     121             : 
     122             : 
     123             : 
     124           0 : bool Sphere::intersects (const Sphere & other_sphere) const
     125             : {
     126           0 :   return distance(other_sphere) < 0 ? true : false;
     127             : }
     128             : 
     129             : 
     130             : 
     131           0 : Real Sphere::distance (const Sphere & other_sphere) const
     132             : {
     133           0 :   libmesh_assert_greater ( this->radius(), 0. );
     134           0 :   libmesh_assert_greater ( other_sphere.radius(), 0. );
     135             : 
     136           0 :   const Real the_distance = (this->center() - other_sphere.center()).norm();
     137             : 
     138           0 :   return the_distance - (this->radius() + other_sphere.radius());
     139             : }
     140             : 
     141             : 
     142             : 
     143           0 : bool Sphere::above_surface (const Point & p) const
     144             : {
     145           0 :   libmesh_assert_greater (this->radius(), 0.);
     146             : 
     147             :   // create a vector from the center to the point.
     148           0 :   const Point w = p - this->center();
     149             : 
     150           0 :   if (w.norm() > this->radius())
     151           0 :     return true;
     152             : 
     153           0 :   return false;
     154             : }
     155             : 
     156             : 
     157             : 
     158           0 : bool Sphere::below_surface (const Point & p) const
     159             : {
     160           0 :   libmesh_assert_greater (this->radius(), 0.);
     161             : 
     162           0 :   return ( !this->above_surface (p) );
     163             : }
     164             : 
     165             : 
     166             : 
     167           0 : bool Sphere::on_surface (const Point & p) const
     168             : {
     169           0 :   libmesh_assert_greater (this->radius(), 0.);
     170             : 
     171             :   // Create a vector from the center to the point.
     172           0 :   const Point w = p - this->center();
     173             : 
     174             :   // if the size of that vector is the same as the radius() then
     175             :   // the point is on the surface.
     176           0 :   if (std::abs(w.norm() - this->radius()) < 1.e-10)
     177           0 :     return true;
     178             : 
     179           0 :   return false;
     180             : }
     181             : 
     182             : 
     183             : 
     184      259586 : Point Sphere::closest_point (const Point & p) const
     185             : {
     186       11430 :   libmesh_assert_greater (this->radius(), 0.);
     187             : 
     188             :   // get the normal from the surface in the direction
     189             :   // of p
     190      259586 :   Point normal = this->unit_normal (p);
     191             : 
     192             :   // The closest point on the sphere is in the direction
     193             :   // of the normal a distance r from the center.
     194       22860 :   const Point cp = this->center() + normal*this->radius();
     195             : 
     196      271016 :   return cp;
     197             : }
     198             : 
     199             : 
     200             : 
     201      259586 : Point Sphere::unit_normal (const Point & p) const
     202             : {
     203       11430 :   libmesh_assert_greater (this->radius(), 0.);
     204             : 
     205       11430 :   libmesh_assert_not_equal_to (p, this->center());
     206             : 
     207             :   // Create a vector from the center to the point
     208       11430 :   Point n = p - this->center();
     209             : 
     210      259586 :   return n.unit();
     211             : }
     212             : 
     213             : } // namespace libMesh

Generated by: LCOV version 1.14