Class documentation of Concepts

Loading...
Searching...
No Matches
sphereCell.hh
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
15namespace concepts {
16
17 //************************************************ SphereMapping ***
18
22 Real radius_;
23 Real3d center_;
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 {
60 return mapping_.center_ + mapping_.radius_*
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);
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:
112 SphericalSurface& cntr_;
113
115 std::vector<Quad2d*> chld_;
116
118 SphereMapping mapping_;
119
120 };
121
122
123 //************************************************************* Sphere3d ***
124
130 class Sphere3d : public Cell {
131 public:
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 {
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);
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 {
212 return mapping_.radius_*mapping_.radius_*
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:
223 Sphere& cntr_;
224
226 SphereMapping mapping_;
227
228 };
229
230}
231
232#endif // SPHERECELL_HH
std::ostream & info(std::ostream &os) const override
Returns information in an output stream.
Real3d elemMap(const Real3d &coord_local) const override
Element map from point local coordinates in 3D.
Sphere & connector() const override
Returns the connector.
Real3d inverseElemMap(const Real3d &coord_global) const
Real3d elemMap(const Real coord_local) const override
Element map from point local coordinates in 1D.
Quad2d * child(uint i) override
Real3d elemMap(const Real2d &coord_local) const override
Element map from point local coordinates in 2D.
const Cell * child(uint i) const override
Real3d elemMap(const Real3d &coord_local) const override
Element map from point local coordinates in 3D.
Definition sphereCell.hh:55
Real3d elemMap(const Real2d &coord_local) const override
Element map from point local coordinates in 2D.
Definition sphereCell.hh:52
SphericalSurface & connector() const override
Returns the connector.
Definition sphereCell.hh:46
Quad2d * child(uint i) override
const Quad2d * child(uint i) const override
std::ostream & info(std::ostream &os) const override
Returns information in an output stream.
Real2d inverseElemMap(const Real3d &coord_global) const
Definition sphereCell.hh:66
Real3d elemMap(const Real coord_local) const override
Element map from point local coordinates in 1D.
Definition sphereCell.hh:48
#define conceptsAssert(cond, exc)
#define DEBUGL(doit, msg)
Definition debug.hh:40
double Real
Definition typedefs.hh:39
Set< F > makeSet(uint n, const F &first,...)
Definition set.hh:320