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 : #ifndef LIBMESH_SPHERE_H 21 : #define LIBMESH_SPHERE_H 22 : 23 : // Local includes 24 : #include "libmesh/surface.h" 25 : #include "libmesh/libmesh.h" 26 : 27 : // C++ includes 28 : #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC 29 : #include <cmath> 30 : 31 : namespace libMesh 32 : { 33 : 34 : /** 35 : * This class defines a sphere. It also computes coordinate 36 : * transformations between cartesian \f$ (x, y, z) \f$ 37 : * and spherical \f$ (r, \theta, \phi) \f$ coordinates. 38 : * The spherical coordinates are valid in the ranges: 39 : * 40 : * - \f$ 0 \le r < \infty \f$ 41 : * - \f$ 0 \le \theta < \pi \f$ 42 : * - \f$ 0 \le \phi < 2\pi \f$ 43 : * 44 : * The coordinates are related as follows: 45 : * \f$ \phi \f$ is the angle in the xy plane 46 : * starting with 0. from the positive x axis, 47 : * \f$ \theta \f$ is measured against the positive 48 : * z axis. 49 : * \verbatim 50 : * 51 : * \ | Z 52 : * \theta| 53 : * \ | . 54 : * \ | . 55 : * \ | . 56 : * \ | . 57 : * \|. 58 : * --------------+---------.--------- 59 : * /|\ . Y 60 : * /phi\ . 61 : * / | \ . 62 : * / | \ . 63 : * /.........\ 64 : * / | 65 : * X / 66 : * \endverbatim 67 : * 68 : * \author Benjamin S. Kirk, Daniel Dreyer 69 : * \date 2002-2007 70 : * \brief A geometric object representing a sphere. 71 : */ 72 68 : class Sphere : public Surface 73 : { 74 : public: 75 : 76 : /** 77 : * Dummy Constructor. 78 : */ 79 : Sphere (); 80 : 81 : /** 82 : * Constructs a sphere of radius r centered at c. 83 : */ 84 : Sphere (const Point & c, const Real r); 85 : 86 : /** 87 : * Constructs a sphere connecting four points. 88 : */ 89 : Sphere (const Point &, const Point &, const Point &, const Point &); 90 : 91 : /** 92 : * Copy-constructor. 93 : */ 94 : Sphere (const Sphere & other_sphere); 95 : 96 : /** 97 : * Destructor. Does nothing at the moment. 98 : */ 99 : ~Sphere (); 100 : 101 : /** 102 : * Defines a sphere of radius r centered at c. 103 : */ 104 : void create_from_center_radius (const Point & c, const Real r); 105 : 106 : /** 107 : * \returns \p true if other_sphere intersects this sphere, 108 : * false otherwise. 109 : */ 110 : bool intersects (const Sphere & other_sphere) const; 111 : 112 : /** 113 : * \returns The distance between the surface of this sphere and 114 : * another sphere. 115 : */ 116 : Real distance (const Sphere & other_sphere) const; 117 : 118 : /** 119 : * \returns \p true if the point p is above the surface, 120 : * false otherwise. 121 : */ 122 : virtual bool above_surface (const Point & p) const override; 123 : 124 : /** 125 : * \returns \p true if the point p is below the surface, 126 : * false otherwise. 127 : */ 128 : virtual bool below_surface (const Point & p) const override; 129 : 130 : /** 131 : * \returns \p true if the point p is on the surface, 132 : * false otherwise. 133 : * 134 : * \note The definition of "on the surface" really means "very 135 : * close" to account for roundoff error. 136 : */ 137 : virtual bool on_surface (const Point & p) const override; 138 : 139 : /** 140 : * \returns The closest point on the surface to point p. 141 : */ 142 : virtual Point closest_point (const Point & p) const override; 143 : 144 : /** 145 : * \returns A unit vector normal to the surface at 146 : * point p. 147 : */ 148 : virtual Point unit_normal (const Point & p) const override; 149 : 150 : /** 151 : * \returns The radius of the sphere. 152 : */ 153 34290 : Real radius() const { return _rad; } 154 : 155 : /** 156 : * \returns The radius of the sphere as a writable reference. 157 : */ 158 68 : Real & radius() { return _rad; } 159 : 160 : /** 161 : * \returns The center of the sphere. 162 : */ 163 34290 : const Point & center() const { return _cent; } 164 : 165 : /** 166 : * \returns The center of the sphere. 167 : */ 168 34 : Point & center() { return _cent; } 169 : 170 : /** 171 : * \returns The spherical coordinates for the 172 : * cartesian coordinates \p cart. 173 : */ 174 : virtual Point surface_coords (const Point & cart) const override; 175 : 176 : /** 177 : * \returns The cartesian coordinates for the 178 : * spherical coordinates \p sph. 179 : */ 180 : virtual Point world_coords (const Point & sph) const override; 181 : 182 : 183 : private: 184 : 185 : /** 186 : * The center of the sphere. 187 : */ 188 : Point _cent; 189 : 190 : /** 191 : * The radius of the sphere. 192 : */ 193 : Real _rad; 194 : }; 195 : 196 : 197 : 198 : // ------------------------------------------------------------ 199 : // Sphere inline functions 200 : inline 201 0 : Point Sphere::surface_coords (const Point & cart) const 202 : { 203 : #if LIBMESH_DIM > 2 204 : // constant translation in the origin 205 0 : const Point c (cart-this->center()); 206 : 207 : // phi: special care, so that it gives 0..2pi results 208 0 : const Real phi = std::atan2(c(1), c(0)); 209 : 210 : return Point(/* radius */ c.norm(), 211 0 : /* theta */ std::atan2( std::sqrt( c(0)*c(0) + c(1)*c(1) ), c(2) ), 212 0 : /* phi */ ( (phi < 0) ? 2.*libMesh::pi+phi : phi ) ); 213 : #else 214 : libmesh_ignore(cart); 215 : libmesh_not_implemented(); 216 : #endif 217 : } 218 : 219 : 220 : 221 : inline 222 0 : Point Sphere::world_coords (const Point & sph) const 223 : { 224 0 : const Real r = sph(0); 225 0 : const Real theta = sph(1); 226 0 : const Real phi = sph(2); 227 : 228 : // constant translation out of the origin 229 0 : return Point (/* x */ r*std::sin(theta)*std::cos(phi) + this->center()(0), 230 0 : /* y */ r*std::sin(theta)*std::sin(phi) + this->center()(1), 231 0 : /* z */ r*std::cos(theta) + this->center()(2)); 232 : } 233 : 234 : 235 : 236 : } // namespace libMesh 237 : 238 : 239 : #endif // LIBMESH_SPHERE_H