sphereCell.hh

Go to the documentation of this file.
1 #ifndef SPHERECELL_HH
2 #define SPHERECELL_HH
3 
4 #include "sphereTopology.hh"
5 #include "geometry/cell2D.hh"
6 #include <cmath>
7 #include <random>
8 
9 
10 #define CONCEPTS_SPHERECELL_D 1
11 
12 
14 
15 namespace concepts {
16 
17  //************************************************ SphereMapping ***
18 
21  struct SphereMapping {
24  };
25 
26  //************************************************ SphericalSurface3d ***
27 
33  class SphericalSurface3d : public Cell {
34  public:
36  Real radius,
37  Real3d center );
38 
39  ~SphericalSurface3d() override;
40 
41  const Quad2d* child(uint i) const override;
42  Quad2d* child(uint i) override;
43 
44  inline bool hasChildren() const { return chld_.size() > 0; }
45 
46  SphericalSurface& connector() const override { return cntr_;}
47 
48  inline Real3d elemMap( const Real coord_local) const override {
49  throw concepts::MissingFeature("elementMap with one-dimensional coord cannot be called.");
50  }
51 
52  inline Real3d elemMap( const Real2d& coord_local ) const override {
53  return elemMap(coord_local[0],coord_local[1]);
54  }
55  inline Real3d elemMap( const Real3d& coord_local ) const override {
56  return elemMap(coord_local[0],coord_local[1]);
57  }
58 
59  inline Real3d elemMap( const Real& theta, const Real& phi ) const {
61  Real3d( std::cos(phi)*std::sin(theta),
62  std::sin(phi)*std::sin(theta),
63  std::cos(theta) );
64  }
65 
66  inline Real2d inverseElemMap( const Real3d& coord_global ) const {
67  Real3d sphericalCoord = 1./mapping_.radius_*(coord_global-mapping_.center_);
68  conceptsAssert( std::abs(sphericalCoord.l2()-1) < 1e3*std::numeric_limits<Real>::epsilon(),
69  Assertion() );
70  Real phi = std::atan2(sphericalCoord[1],sphericalCoord[0]);
71  if(phi < 0.) phi += 2*3.14159265358979323846264338328;
73  Real theta = 0.;
74  if( std::abs(sphericalCoord[2]) < 0.5 )
75  theta = std::acos(sphericalCoord[2]);
76  else {
77  theta = std::asin( (std::abs(sphericalCoord[0]) > std::abs(sphericalCoord[1]) ?
78  sphericalCoord[0]/std::cos(phi) :
79  sphericalCoord[1]/std::sin(phi)) );
80  if(sphericalCoord[2] < 0.)
81  theta = 3.14159265358979323846264338328 - theta;
82  }
83  if( std::abs(sphericalCoord[2]-1.) < 1e1*std::numeric_limits<concepts::Real>::epsilon()
84  || std::abs(sphericalCoord[2]+1.) < 1e1*std::numeric_limits<concepts::Real>::epsilon()) {
85  static std::default_random_engine engine_;
86  static std::uniform_real_distribution<concepts::Real> distribution_(0.,2.*3.14159265358979323846264338328);
87  phi = distribution_(engine_);
88  }
89  if( std::isnan( theta ) ) {
90  if(std::abs(sphericalCoord[2]-1.)<1e1*std::numeric_limits<concepts::Real>::epsilon())
91  theta = 1e1*std::numeric_limits<concepts::Real>::epsilon();
92  else if(std::abs(sphericalCoord[2]+1.)<1e1*std::numeric_limits<concepts::Real>::epsilon())
93  theta = 3.14159265358979323846264338328-1e1*std::numeric_limits<concepts::Real>::epsilon();
94  }
95  conceptsAssert(phi >= 0. && phi <= 2*3.14159265358979323846264338328,Assertion());
96  conceptsAssert(theta >= 0. && theta <= 3.14159265358979323846264338328,Assertion());
97  conceptsAssert(!std::isnan(phi) && !std::isnan(theta),Assertion());
98  return Real2d( theta, phi/*std::acos(sphericalCoord[2]),
99  std::atan2(sphericalCoord[1],sphericalCoord[0])*/ );
100  }
101 
102  inline Real jacobianDeterminant( const Real2d& coord_local ) const {
103  return mapping_.radius_*mapping_.radius_*std::sin(coord_local[0]); }
104 
105  Real getRadius() const { return mapping_.radius_; }
106 
107  Real3d getCenter() const { return mapping_.center_; }
108 
109  std::ostream& info(std::ostream& os) const override;
110  private:
113 
115  std::vector<Quad2d*> chld_;
116 
119 
120  };
121 
122 
123  //************************************************************* Sphere3d ***
124 
130  class Sphere3d : public Cell {
131  public:
132  Sphere3d( Sphere& cntr,
133  Real radius,
134  Real3d center );
135 
136  ~Sphere3d() override;
137 
138  const Cell* child(uint i) const override;
139  Quad2d* child(uint i) override;
140 
141  inline bool hasChildren() const { return false; }
142 
143  Sphere& connector() const override { return cntr_;}
144 
145  inline Real3d elemMap( const Real coord_local ) const override {
146  throw concepts::MissingFeature("elementMap with one-dimensional coord cannot be called.");
147  }
148 
149  inline Real3d elemMap( const Real2d& coord_local ) const override {
150  throw concepts::MissingFeature("elementMap with two-dimensional coord cannot be called.");
151  }
152 
153  inline Real3d elemMap( const Real3d& coord_local ) const override {
154  return elemMap(coord_local[0],coord_local[1],coord_local[2]);
155  }
156 
157  inline Real3d elemMap( const Real& radius, const Real& theta, const Real& phi ) const {
158  return mapping_.center_ + mapping_.radius_*radius*
159  Real3d( std::cos(phi)*std::sin(theta),
160  std::sin(phi)*std::sin(theta),
161  std::cos(theta) );
162  }
163 
164  inline Real3d inverseElemMap( const Real3d& coord_global ) const {
165  Real3d sphericalCoord = 1./mapping_.radius_*(coord_global-mapping_.center_);
166  const Real radius = sphericalCoord.l2();
167  conceptsAssert(!std::isnan(radius),Assertion());
168  conceptsAssert( std::abs(sphericalCoord.l2()-radius) < 1e2*std::numeric_limits<Real>::epsilon(),
169  Assertion() );
170  sphericalCoord *= 1./radius;
171  Real phi = std::atan2(sphericalCoord[1],sphericalCoord[0]);
172  if(std::isnan(phi)) DEBUGL(1,"Phi is nan for spherical coordinates (" << sphericalCoord[0] << ","
173  << sphericalCoord[1] << "," << sphericalCoord[2] << ")");
174  if(phi < 0.) phi += 2*3.14159265358979323846264338328;
176  Real theta = 0.;
177  if( std::abs(sphericalCoord[2]) < 0.5 )
178  theta = std::acos(sphericalCoord[2]);
179  else {
180  theta = std::asin( (std::abs(sphericalCoord[0]) > std::abs(sphericalCoord[1]) ?
181  sphericalCoord[0]/std::cos(phi) :
182  sphericalCoord[1]/std::sin(phi)) );
183  if(sphericalCoord[2] < 0.)
184  theta = 3.14159265358979323846264338328 - theta;
185  }
186  if( std::abs(sphericalCoord[2]-1.) < 1e1*std::numeric_limits<concepts::Real>::epsilon()
187  || std::abs(sphericalCoord[2]+1.) < 1e1*std::numeric_limits<concepts::Real>::epsilon()) {
188  static std::default_random_engine engine_;
189  static std::uniform_real_distribution<concepts::Real> distribution_(0.,2.*3.14159265358979323846264338328);
190  phi = distribution_(engine_);
191  conceptsAssert(phi <= 2.*3.14159265358979323846264338328,Assertion());
192  }
193  if( std::isnan( theta ) ) {
194  if(std::abs(sphericalCoord[2]-1.)<1e1*std::numeric_limits<concepts::Real>::epsilon())
195  theta = 1e1*std::numeric_limits<concepts::Real>::epsilon();
196  else if(std::abs(sphericalCoord[2]+1.)<1e1*std::numeric_limits<concepts::Real>::epsilon())
197  theta = 3.14159265358979323846264338328-1e1*std::numeric_limits<concepts::Real>::epsilon();
198  }
199  if ( !(phi >= 0. && phi <= 2*3.14159265358979323846264338328) ) {
200  DEBUGL(1,"Phi value out of range: " << phi << ".");
201  conceptsAssert(false,Assertion());
202  }
203  conceptsAssert(phi >= 0. && phi <= 2*3.14159265358979323846264338328,Assertion());
204  conceptsAssert(theta >= 0. && theta <= 2.*3.14159265358979323846264338328,Assertion());
205  conceptsAssert(!std::isnan(phi) && !std::isnan(theta),Assertion());
206  return Real3d( radius,
207  theta,
208  phi );
209  }
210 
211  inline Real jacobianDeterminant( const Real3d& coord_local ) const {
213  coord_local[0]*coord_local[0]*std::sin(coord_local[1]); }
214 
215  Real getRadius() const { return mapping_.radius_; }
216 
217  Real3d getCenter() const { return mapping_.center_; }
218 
219  std::ostream& info(std::ostream& os) const override;
220 
221  private:
224 
227 
228  };
229 
230 }
231 
232 #endif // SPHERECELL_HH
SphereMapping mapping_
Geometric embedding.
Definition: sphereCell.hh:226
A 2D cell: quadrilateral.
Definition: cell2D.hh:378
Real3d elemMap(const Real coord_local) const override
Element map from point local coordinates in 1D.
Definition: sphereCell.hh:145
std::ostream & info(std::ostream &os) const override
Returns information in an output stream.
Real jacobianDeterminant(const Real2d &coord_local) const
Definition: sphereCell.hh:102
Geometric spherical surface element.
Definition: sphereCell.hh:33
Real getRadius() const
Definition: sphereCell.hh:215
Quad2d * child(uint i) override
Returns a pointer to the ith child.
Real3d elemMap(const Real coord_local) const override
Element map from point local coordinates in 1D.
Definition: sphereCell.hh:48
Real3d elemMap(const Real2d &coord_local) const override
Element map from point local coordinates in 2D.
Definition: sphereCell.hh:52
Point< Real, 2 > Real2d
A cell in a mesh consist of topological information (neighbours, connectivity, orientation) and geome...
Definition: cell.hh:39
std::vector< Quad2d * > chld_
Child cells.
Definition: sphereCell.hh:115
#define conceptsAssert(cond, exc)
Assert that a certain condition is fulfilled.
Definition: exceptions.hh:394
Topological spherical surface connector.
Point< Real, 3 > Real3d
Geometric sphere.
Definition: sphereCell.hh:21
Real3d inverseElemMap(const Real3d &coord_global) const
Definition: sphereCell.hh:164
#define DEBUGL(doit, msg)
Sphere & connector() const override
Returns the connector.
Definition: sphereCell.hh:143
Real3d getCenter() const
Definition: sphereCell.hh:217
Exception class for assertions.
Definition: exceptions.hh:258
Real l2() const
Returns the Euclidian norm of the vector.
SphericalSurface & cntr_
Topology.
Definition: sphereCell.hh:112
Sphere & cntr_
Topology.
Definition: sphereCell.hh:223
std::ostream & info(std::ostream &os) const override
Returns information in an output stream.
const Cell * child(uint i) const override
Returns a pointer to the ith child.
Real jacobianDeterminant(const Real3d &coord_local) const
Definition: sphereCell.hh:211
uint abs(const uint &v)
Definition: operations.hh:95
~Sphere3d() override
SphericalSurface & connector() const override
Returns the connector.
Definition: sphereCell.hh:46
Topological sphere connector.
Exception class to express a missing feature.
Definition: exceptions.hh:206
Quad2d * child(uint i) override
Returns a pointer to the ith child.
Real3d elemMap(const Real3d &coord_local) const override
Element map from point local coordinates in 3D.
Definition: sphereCell.hh:153
Sphere3d(Sphere &cntr, Real radius, Real3d center)
Real3d elemMap(const Real2d &coord_local) const override
Element map from point local coordinates in 2D.
Definition: sphereCell.hh:149
Real2d inverseElemMap(const Real3d &coord_global) const
Definition: sphereCell.hh:66
const Quad2d * child(uint i) const override
Returns a pointer to the ith child.
Geometric sphere element.
Definition: sphereCell.hh:130
bool hasChildren() const
Definition: sphereCell.hh:141
Real3d elemMap(const Real &theta, const Real &phi) const
Definition: sphereCell.hh:59
SphereMapping mapping_
Geometric embedding.
Definition: sphereCell.hh:118
Real3d elemMap(const Real &radius, const Real &theta, const Real &phi) const
Definition: sphereCell.hh:157
SphericalSurface3d(SphericalSurface &cntr, Real radius, Real3d center)
Real3d elemMap(const Real3d &coord_local) const override
Element map from point local coordinates in 3D.
Definition: sphereCell.hh:55
double Real
Type normally used for a floating point number.
Definition: typedefs.hh:36
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich