FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
circle.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <kernel/geometry/atlas/chart.hpp>
9
10namespace FEAT
11{
12 namespace Geometry
13 {
14 namespace Atlas
15 {
18 {
20 static constexpr bool is_explicit = true;
22 static constexpr bool is_implicit = true;
24 static constexpr int world_dim = 2;
26 static constexpr int param_dim = 1;
27 };
28
49 template<typename Mesh_>
50 class Circle :
51 public ChartCRTP<Circle<Mesh_>, Mesh_, CircleTraits>
52 {
53 public:
62
63 protected:
74
75 public:
85 explicit Circle(CoordType mid_x, CoordType mid_y, CoordType radius) :
86 _radius(radius),
87 _have_domain(false),
88 _trafo_a(0.0),
89 _trafo_b(0.0)
90 {
91 XASSERTM(radius > CoordType(0), "invalid circle radius");
92 _midpoint[0] = mid_x;
93 _midpoint[1] = mid_y;
94 }
95
109 explicit Circle(CoordType mid_x, CoordType mid_y, CoordType radius,
110 CoordType param_l, CoordType param_r) :
111 _radius(radius),
112 _have_domain(true),
113 _trafo_a(-param_l),
114 _trafo_b((CoordType(2) * Math::pi<CoordType>()) / (param_r - param_l))
115 {
116 XASSERTM(radius > CoordType(0), "invalid circle radius");
117 _midpoint[0] = mid_x;
118 _midpoint[1] = mid_y;
119 }
120
121 // use default copy ctor; this one is required by the MeshExtruder !
122 Circle(const Circle&) = default;
123
125 virtual bool can_explicit() const override
126 {
127 return _have_domain;
128 }
129
131 virtual void transform(const WorldPoint& origin, const WorldPoint& angles, const WorldPoint& offset) override
132 {
133 // create rotation matrix
135 rot.set_rotation_2d(angles(0));
136
137 // transform midpoint
138 WorldPoint tmp;
139 tmp = _midpoint - origin;
140 _midpoint.set_mat_vec_mult(rot, tmp) += offset;
141
142 // transform domain
143 if(_have_domain)
144 _trafo_a += angles(0);
145 }
146
154 void project_point(WorldPoint& point) const
155 {
156 WorldPoint grad_dist(point - _midpoint);
157 CoordType distance(grad_dist.norm_euclid());
158
159 if(distance < Math::eps<CoordType>())
160 {
161 grad_dist(0) = _radius;
162 point += grad_dist;
163 }
164 else
165 {
166 point = _midpoint + (_radius / distance)*grad_dist;
167 }
168 }
169
172 {
173 return Math::abs(compute_signed_dist(point));
174 }
175
177 CoordType compute_dist(const WorldPoint& point, WorldPoint& grad_dist) const
178 {
179 WorldPoint projected(point);
180 project_point(projected);
181
182 grad_dist = (projected - point);
183 CoordType my_dist(grad_dist.norm_euclid());
184 grad_dist.normalize();
185
186 return my_dist;
187 }
188
191 {
192 return _radius - (point - _midpoint).norm_euclid();
193 }
194
196 CoordType compute_signed_dist(const WorldPoint& point, WorldPoint& grad_dist) const
197 {
198 WorldPoint projected(point);
199 project_point(projected);
200
201 CoordType my_dist(_radius - (point - _midpoint).norm_euclid());
202
203 if(my_dist < Math::eps<CoordType>())
204 {
205 grad_dist = (_midpoint - point);
206 }
207 else
208 {
209 grad_dist = (point - projected)*Math::signum(my_dist);
210 }
211
212 grad_dist.normalize();
213
214 return my_dist;
215 }
216
218 void project_meshpart(Mesh_& mesh, const MeshPart<Mesh_>& meshpart) const
219 {
220 auto& vtx = mesh.get_vertex_set();
221 const auto& target_vtx = meshpart.template get_target_set<0>();
222
223 for(Index i(0); i < meshpart.get_num_entities(0); ++i)
224 {
225 project_point(reinterpret_cast<WorldPoint&>(vtx[target_vtx[i]]));
226 }
227 }
228
239 void map_param(WorldPoint& point, const ParamPoint& param) const
240 {
241 // transform parameter to interval [0, 2*pi)
242 CoordType x = (param[0] + _trafo_a) * _trafo_b;
243 point[0] = this->_midpoint[0] + this->_radius * Math::cos(x);
244 point[1] = this->_midpoint[1] + this->_radius * Math::sin(x);
245 }
246
248 virtual String get_type() const override
249 {
250 return "circle";
251 }
252
254 virtual void write(std::ostream& os, const String& sindent) const override
255 {
256 os << sindent << "<Circle";
257 os << " radius=\"" << this->_radius << "\"";
258 os << " midpoint=\"" << this->_midpoint[0] << " " << this->_midpoint[1] << "\"";
259 // reconstruct domain from trafo
260 if(_have_domain)
261 {
262 CoordType param_l(-_trafo_a);
263 CoordType param_r(param_l + CoordType(2) * Math::pi<CoordType>() / _trafo_b);
264 os << " domain=\"" << param_l << " " << param_r << "\"";
265 }
266 os << " />\n";
267 }
268 }; // class Circle
269
270 template<typename Mesh_, typename ChartReturn_ = ChartBase<Mesh_>>
272 public Xml::MarkupParser
273 {
274 private:
275 typedef Circle<Mesh_> ChartType;
276 typedef typename ChartType::CoordType CoordType;
277 std::unique_ptr<ChartReturn_>& _chart;
278
279 public:
280 explicit CircleChartParser(std::unique_ptr<ChartReturn_>& chart) :
281 _chart(chart)
282 {
283 }
284
285 virtual bool attribs(std::map<String,bool>& attrs) const override
286 {
287 attrs.emplace("radius", true);
288 attrs.emplace("midpoint", true);
289 attrs.emplace("domain", false);
290 return true;
291 }
292
293 virtual void create(
294 int iline,
295 const String& sline,
296 const String&,
297 const std::map<String, String>& attrs,
298 bool) override
299 {
300 CoordType radius = CoordType(0);
301 CoordType mid_x = CoordType(0);
302 CoordType mid_y = CoordType(0);
303 CoordType dom_0 = CoordType(0);
304 CoordType dom_1 = CoordType(1);
305 bool have_domain(false);
306
307 // try to parse the radius
308 if(!attrs.find("radius")->second.parse(radius))
309 throw Xml::GrammarError(iline, sline, "Failed to parse circle radius");
310 if(radius < CoordType(1E-5))
311 throw Xml::GrammarError(iline, sline, "Invalid circle radius");
312
313 // try to parse midpoint
314 std::deque<String> mids = attrs.find("midpoint")->second.split_by_whitespaces();
315 if(mids.size() != std::size_t(2))
316 throw Xml::GrammarError(iline, sline, "Invalid circle midpoint string");
317 if(!mids.front().parse(mid_x) || !mids.back().parse(mid_y))
318 throw Xml::GrammarError(iline, sline, "'Failed to parse circle midpoint");
319
320 // do we have a domain?
321 auto it = attrs.find("domain");
322 if(it != attrs.end())
323 {
324 have_domain = true;
325 std::deque<String> doms = it->second.split_by_whitespaces();
326 if(doms.size() != std::size_t(2))
327 throw Xml::GrammarError(iline, sline, "Invalid circle domain string");
328 if(!doms.front().parse(dom_0) || !doms.back().parse(dom_1))
329 throw Xml::GrammarError(iline, sline, "'Failed to parse circle domain");
330 }
331
332 // everything seems fine, let's create the chart then
333 if(have_domain)
334 _chart.reset(new ChartType(mid_x, mid_y, radius, dom_0, dom_1));
335 else
336 _chart.reset(new ChartType(mid_x, mid_y, radius));
337 }
338
339 virtual void close(int, const String&) override
340 {
341 }
342
343 virtual bool content(int, const String&) override
344 {
345 return false;
346 }
347
348 virtual std::shared_ptr<Xml::MarkupParser> markup(int, const String&, const String&) override
349 {
350 return nullptr;
351 }
352 }; // class CircleChartParser<...>
353 } // namespace Atlas
354 } // namespace Geometry
355} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Chart CRTP base-class template.
Definition: chart.hpp:354
virtual void close(int, const String &) override
Closes this markup parser node.
Definition: circle.hpp:339
virtual std::shared_ptr< Xml::MarkupParser > markup(int, const String &, const String &) override
Called to process a child markup node.
Definition: circle.hpp:348
virtual bool attribs(std::map< String, bool > &attrs) const override
Specifies the mandatory and optional attributes.
Definition: circle.hpp:285
virtual void create(int iline, const String &sline, const String &, const std::map< String, String > &attrs, bool) override
Creates this markup parser node.
Definition: circle.hpp:293
virtual bool content(int, const String &) override
Called to process a content line.
Definition: circle.hpp:343
Circle chart class template.
Definition: circle.hpp:52
CoordType _trafo_b
Right parametrization domain boundary.
Definition: circle.hpp:73
Circle(CoordType mid_x, CoordType mid_y, CoordType radius)
Creates a Circle chart for implicit adaption.
Definition: circle.hpp:85
CoordType _trafo_a
Left parametrization domain boundary.
Definition: circle.hpp:71
virtual String get_type() const override
Writes the type as String.
Definition: circle.hpp:248
CoordType compute_signed_dist(const WorldPoint &point, WorldPoint &grad_dist) const
Definition: circle.hpp:196
virtual void transform(const WorldPoint &origin, const WorldPoint &angles, const WorldPoint &offset) override
Definition: circle.hpp:131
Circle(CoordType mid_x, CoordType mid_y, CoordType radius, CoordType param_l, CoordType param_r)
Creates a Circle chart for both implicit and explicit adaption.
Definition: circle.hpp:109
CoordType compute_dist(const WorldPoint &point, WorldPoint &grad_dist) const
Definition: circle.hpp:177
CoordType compute_dist(const WorldPoint &point) const
Computes the distance of a point to this chart.
Definition: circle.hpp:171
ChartCRTP< Circle< Mesh_ >, Mesh_, CircleTraits > BaseClass
The CRTP base class.
Definition: circle.hpp:55
CoordType _radius
the circle's radius
Definition: circle.hpp:67
virtual bool can_explicit() const override
Definition: circle.hpp:125
WorldPoint _midpoint
the circle's midpoint
Definition: circle.hpp:65
BaseClass::WorldPoint WorldPoint
Vector type for world points, aka image points.
Definition: circle.hpp:59
CoordType compute_signed_dist(const WorldPoint &point) const
Definition: circle.hpp:190
BaseClass::CoordType CoordType
Floating point type.
Definition: circle.hpp:57
BaseClass::ParamPoint ParamPoint
Vector type for parametrization points, aka domain points.
Definition: circle.hpp:61
void project_meshpart(Mesh_ &mesh, const MeshPart< Mesh_ > &meshpart) const
Definition: circle.hpp:218
bool _have_domain
Specifies whether the circle mapping has a domain.
Definition: circle.hpp:69
virtual void write(std::ostream &os, const String &sindent) const override
Writes the Chart into a stream in XML format.
Definition: circle.hpp:254
void project_point(WorldPoint &point) const
Projects a single world point.
Definition: circle.hpp:154
void map_param(WorldPoint &point, const ParamPoint &param) const
Maps a single parameter point.
Definition: circle.hpp:239
Class template for partial meshes.
Definition: mesh_part.hpp:90
Index get_num_entities(int dim) const
Returns the number of entities.
Definition: mesh_part.hpp:311
String class implementation.
Definition: string.hpp:46
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_rotation_2d(T_ angle)
Sets this matrix to a 2D rotation matrix.
Tiny Vector class template.
Xml grammar error class.
XML Markup Parser interface.
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ sin(T_ x)
Returns the sine of a value.
Definition: math.hpp:344
T_ signum(T_ x)
Returns the sign of a value.
Definition: math.hpp:250
T_ cos(T_ x)
Returns the cosine of a value.
Definition: math.hpp:386
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
Circle chart traits.
Definition: circle.hpp:18
static constexpr int world_dim
this is a 2D object
Definition: circle.hpp:24
static constexpr bool is_explicit
we support explicit map
Definition: circle.hpp:20
static constexpr bool is_implicit
we support implicit projection
Definition: circle.hpp:22
static constexpr int param_dim
we have 1D parameters
Definition: circle.hpp:26