libMesh
sphere.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 
111 {
112 }
113 
114 
115 
117 {
118  this->center() = c;
119  this->radius() = r;
120 
121  libmesh_assert_greater (this->radius(), 0.);
122 }
123 
124 
125 
126 bool Sphere::intersects (const Sphere & other_sphere) const
127 {
128  return distance(other_sphere) < 0 ? true : false;
129 }
130 
131 
132 
133 Real Sphere::distance (const Sphere & other_sphere) const
134 {
135  libmesh_assert_greater ( this->radius(), 0. );
136  libmesh_assert_greater ( other_sphere.radius(), 0. );
137 
138  const Real the_distance = (this->center() - other_sphere.center()).norm();
139 
140  return the_distance - (this->radius() + other_sphere.radius());
141 }
142 
143 
144 
145 bool Sphere::above_surface (const Point & p) const
146 {
147  libmesh_assert_greater (this->radius(), 0.);
148 
149  // create a vector from the center to the point.
150  const Point w = p - this->center();
151 
152  if (w.norm() > this->radius())
153  return true;
154 
155  return false;
156 }
157 
158 
159 
160 bool Sphere::below_surface (const Point & p) const
161 {
162  libmesh_assert_greater (this->radius(), 0.);
163 
164  return ( !this->above_surface (p) );
165 }
166 
167 
168 
169 bool Sphere::on_surface (const Point & p) const
170 {
171  libmesh_assert_greater (this->radius(), 0.);
172 
173  // Create a vector from the center to the point.
174  const Point w = p - this->center();
175 
176  // if the size of that vector is the same as the radius() then
177  // the point is on the surface.
178  if (std::abs(w.norm() - this->radius()) < 1.e-10)
179  return true;
180 
181  return false;
182 }
183 
184 
185 
187 {
188  libmesh_assert_greater (this->radius(), 0.);
189 
190  // get the normal from the surface in the direction
191  // of p
192  Point normal = this->unit_normal (p);
193 
194  // The closest point on the sphere is in the direction
195  // of the normal a distance r from the center.
196  const Point cp = this->center() + normal*this->radius();
197 
198  return cp;
199 }
200 
201 
202 
203 Point Sphere::unit_normal (const Point & p) const
204 {
205  libmesh_assert_greater (this->radius(), 0.);
206 
207  libmesh_assert_not_equal_to (p, this->center());
208 
209  // Create a vector from the center to the point
210  Point n = p - this->center();
211 
212  return n.unit();
213 }
214 
215 } // namespace libMesh
libMesh::Sphere::below_surface
virtual bool below_surface(const Point &p) const override
Definition: sphere.C:160
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Surface
The base class for all "surface" related geometric objects.
Definition: surface.h:42
libMesh::Sphere
This class defines a sphere.
Definition: sphere.h:72
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::TypeVector::norm_sq
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_vector.h:986
libMesh::Sphere::above_surface
virtual bool above_surface(const Point &p) const override
Definition: sphere.C:145
libMesh::Sphere::closest_point
virtual Point closest_point(const Point &p) const override
Definition: sphere.C:186
libMesh::libmesh_ignore
void libmesh_ignore(const Args &...)
Definition: libmesh_common.h:526
libMesh::Sphere::radius
Real radius() const
Definition: sphere.h:153
libMesh::Sphere::on_surface
virtual bool on_surface(const Point &p) const override
Definition: sphere.C:169
libMesh::TensorValue
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
Definition: exact_solution.h:53
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::Sphere::unit_normal
virtual Point unit_normal(const Point &p) const override
Definition: sphere.C:203
libMesh::Sphere::~Sphere
~Sphere()
Destructor.
Definition: sphere.C:110
libMesh::Sphere::distance
Real distance(const Sphere &other_sphere) const
Definition: sphere.C:133
libMesh::Sphere::create_from_center_radius
void create_from_center_radius(const Point &c, const Real r)
Defines a sphere of radius r centered at c.
Definition: sphere.C:116
libMesh::TypeVector::unit
TypeVector< T > unit() const
Definition: type_vector.h:1158
std::norm
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Sphere::intersects
bool intersects(const Sphere &other_sphere) const
Definition: sphere.C:126
libMesh::TypeVector::norm
auto norm() const -> decltype(std::norm(T()))
Definition: type_vector.h:955
libMesh::Sphere::center
const Point & center() const
Definition: sphere.h:163
libMesh::Sphere::Sphere
Sphere()
Dummy Constructor.
Definition: sphere.C:36
libMesh::TypeTensor::det
T det() const
Definition: type_tensor.h:1328