libMesh
sphere.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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
37  _rad(-1.)
38 {
39 }
40 
41 
42 
43 Sphere::Sphere (const Point & c,
44  const Real r)
45 {
46  libmesh_assert_greater (r, 0.);
47 
48  this->create_from_center_radius (c, r);
49 }
50 
51 
52 
53 Sphere::Sphere (const Sphere & other_sphere) :
54  Surface()
55 {
56  this->create_from_center_radius (other_sphere.center(),
57  other_sphere.radius());
58 }
59 
60 
61 
62 Sphere::Sphere(const Point & pa,
63  const Point & pb,
64  const Point & pc,
65  const Point & pd)
66 {
67 #if LIBMESH_DIM > 2
68  Point pad = pa - pd;
69  Point pbd = pb - pd;
70  Point pcd = pc - pd;
71 
72  TensorValue<Real> T(pad,pbd,pcd);
73 
74  Real D = T.det();
75 
76  // The points had better not be coplanar
77  libmesh_assert_greater (std::abs(D), 1e-12);
78 
79  Real e = 0.5*(pa.norm_sq() - pd.norm_sq());
80  Real f = 0.5*(pb.norm_sq() - pd.norm_sq());
81  Real g = 0.5*(pc.norm_sq() - pd.norm_sq());
82 
83  TensorValue<Real> T1(e,pad(1),pad(2),
84  f,pbd(1),pbd(2),
85  g,pcd(1),pcd(2));
86  Real sx = T1.det()/D;
87 
88  TensorValue<Real> T2(pad(0),e,pad(2),
89  pbd(0),f,pbd(2),
90  pcd(0),g,pcd(2));
91  Real sy = T2.det()/D;
92 
93  TensorValue<Real> T3(pad(0),pad(1),e,
94  pbd(0),pbd(1),f,
95  pcd(0),pcd(1),g);
96  Real sz = T3.det()/D;
97 
98  Point c(sx,sy,sz);
99  Real r = (c-pa).norm();
100 
101  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 }
107 
108 
109 
110 Sphere::~Sphere () = default;
111 
112 
113 
115 {
116  this->center() = c;
117  this->radius() = r;
118 
119  libmesh_assert_greater (this->radius(), 0.);
120 }
121 
122 
123 
124 bool Sphere::intersects (const Sphere & other_sphere) const
125 {
126  return distance(other_sphere) < 0 ? true : false;
127 }
128 
129 
130 
131 Real Sphere::distance (const Sphere & other_sphere) const
132 {
133  libmesh_assert_greater ( this->radius(), 0. );
134  libmesh_assert_greater ( other_sphere.radius(), 0. );
135 
136  const Real the_distance = (this->center() - other_sphere.center()).norm();
137 
138  return the_distance - (this->radius() + other_sphere.radius());
139 }
140 
141 
142 
143 bool Sphere::above_surface (const Point & p) const
144 {
145  libmesh_assert_greater (this->radius(), 0.);
146 
147  // create a vector from the center to the point.
148  const Point w = p - this->center();
149 
150  if (w.norm() > this->radius())
151  return true;
152 
153  return false;
154 }
155 
156 
157 
158 bool Sphere::below_surface (const Point & p) const
159 {
160  libmesh_assert_greater (this->radius(), 0.);
161 
162  return ( !this->above_surface (p) );
163 }
164 
165 
166 
167 bool Sphere::on_surface (const Point & p) const
168 {
169  libmesh_assert_greater (this->radius(), 0.);
170 
171  // Create a vector from the center to the point.
172  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  if (std::abs(w.norm() - this->radius()) < 1.e-10)
177  return true;
178 
179  return false;
180 }
181 
182 
183 
185 {
186  libmesh_assert_greater (this->radius(), 0.);
187 
188  // get the normal from the surface in the direction
189  // of p
190  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  const Point cp = this->center() + normal*this->radius();
195 
196  return cp;
197 }
198 
199 
200 
201 Point Sphere::unit_normal (const Point & p) const
202 {
203  libmesh_assert_greater (this->radius(), 0.);
204 
205  libmesh_assert_not_equal_to (p, this->center());
206 
207  // Create a vector from the center to the point
208  Point n = p - this->center();
209 
210  return n.unit();
211 }
212 
213 } // namespace libMesh
virtual bool above_surface(const Point &p) const override
Definition: sphere.C:143
auto norm() const -> decltype(std::norm(T()))
Definition: type_vector.h:929
This class defines a sphere.
Definition: sphere.h:72
The libMesh namespace provides an interface to certain functionality in the library.
virtual Point closest_point(const Point &p) const override
Definition: sphere.C:184
const Point & center() const
Definition: sphere.h:163
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:57
TypeVector< T > unit() const
Definition: type_vector.h:1120
void libmesh_ignore(const Args &...)
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_vector.h:948
virtual bool on_surface(const Point &p) const override
Definition: sphere.C:167
Real distance(const Sphere &other_sphere) const
Definition: sphere.C:131
virtual Point unit_normal(const Point &p) const override
Definition: sphere.C:201
Sphere()
Dummy Constructor.
Definition: sphere.C:36
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
~Sphere()
Destructor.
void create_from_center_radius(const Point &c, const Real r)
Defines a sphere of radius r centered at c.
Definition: sphere.C:114
The base class for all "surface" related geometric objects.
Definition: surface.h:42
Real radius() const
Definition: sphere.h:153
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual bool below_surface(const Point &p) const override
Definition: sphere.C:158
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
bool intersects(const Sphere &other_sphere) const
Definition: sphere.C:124