PLaSK library
Loading...
Searching...
No Matches
generator_rectangular.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program 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
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__GENERATOR_RECTANGULAR_H
15#define PLASK__GENERATOR_RECTANGULAR_H
16
17#include "mesh.hpp"
18#include "rectangular.hpp"
20
21namespace plask {
22
29PLASK_API shared_ptr<OrderedAxis> makeGeometryGrid1D(const shared_ptr<GeometryObjectD<2>>& geometry, double split=0.);
30
37PLASK_API shared_ptr<RectangularMesh<2>> makeGeometryGrid(const shared_ptr<GeometryObjectD<2>>& geometry, double split=0.);
38
45PLASK_API shared_ptr<RectangularMesh<3>> makeGeometryGrid(const shared_ptr<GeometryObjectD<3>>& geometry, double split=0.);
46
52inline shared_ptr<OrderedAxis> makeGeometryGrid1D(const shared_ptr<GeometryD<2>>& geometry)
53{
54 return makeGeometryGrid1D(geometry->getChild());
55}
56
63{
64 return makeGeometryGrid(geometry->getChild());
65}
66
73{
74 return makeGeometryGrid(geometry->getChild());
75}
76
82PLASK_API shared_ptr<OrderedAxis> refineAxis(const shared_ptr<MeshAxis>& axis, double spacing);
83
88
89 protected:
90
91 bool split;
92
93 public:
94
96 OrderedMesh1DSimpleGenerator(bool split=false): split(split) {}
97
98 shared_ptr<MeshD<1>> generate(const shared_ptr<GeometryObjectD<2>>& geometry) override;
99};
100
101
106
107 protected:
108
109 bool split;
110
111 public:
112
114 RectangularMesh2DSimpleGenerator(bool split=false): split(split) {}
115
116 shared_ptr<MeshD<2>> generate(const shared_ptr<GeometryObjectD<2>>& geometry) override;
117};
118
123
124 protected:
125
126 bool split;
127
128 public:
129
131 RectangularMesh3DSimpleGenerator(bool split=false): split(split) {}
132
133 shared_ptr<MeshD<3>> generate(const shared_ptr<GeometryObjectD<3>>& geometry) override;
134};
135
136
137
143
145 double spacing;
146
147 public:
148
153 OrderedMesh1DRegularGenerator(double spacing, bool split=false):
154 OrderedMesh1DSimpleGenerator(split), spacing(spacing) {}
155
156 shared_ptr<MeshD<1>> generate(const shared_ptr<GeometryObjectD<2>>& geometry) override;
157};
158
159
165
167 double spacing0, spacing1;
168
169 public:
170
175 RectangularMesh2DRegularGenerator(double spacing, bool split=false):
176 RectangularMesh2DSimpleGenerator(split), spacing0(spacing), spacing1(spacing) {}
177
183 RectangularMesh2DRegularGenerator(double spacing0, double spacing1, bool split=false):
184 RectangularMesh2DSimpleGenerator(split), spacing0(spacing0), spacing1(spacing1) {}
185
186 shared_ptr<MeshD<2>> generate(const shared_ptr<GeometryObjectD<2>>& geometry) override;
187};
188
194
196 double spacing0, spacing1, spacing2;
197
198 public:
199
204 RectangularMesh3DRegularGenerator(double spacing, bool split=false):
205 RectangularMesh3DSimpleGenerator(split), spacing0(spacing), spacing1(spacing), spacing2(spacing) {}
206
213 RectangularMesh3DRegularGenerator(double spacing0, double spacing1, double spacing2, bool split=false):
214 RectangularMesh3DSimpleGenerator(split), spacing0(spacing0), spacing1(spacing1), spacing2(spacing2) {}
215
216 shared_ptr<MeshD<3>> generate(const shared_ptr<GeometryObjectD<3>>& geometry) override;
217};
218
219
220
225
226 shared_ptr<MeshGeneratorD<1>> horizontal_generator;
227
228 public:
229
234 horizontal_generator(source) {}
235
236 shared_ptr<MeshD<2>> generate(const shared_ptr<GeometryObjectD<2>>& geometry) override;
237};
238
239
240
244template <int dim>
246
248 using MeshGeneratorD<dim>::DIM;
249
250 typedef std::map<std::pair<weak_ptr<const GeometryObjectD<DIM>>,PathHints>, std::set<double>> Refinements;
251
252 double aspect;
253
254 Refinements refinements[dim];
255
256 shared_ptr<OrderedAxis> getAxis(shared_ptr<OrderedAxis> axis, const shared_ptr<GeometryObjectD<DIM>>& geometry, size_t dir);
257
258 virtual shared_ptr<OrderedAxis> processAxis(shared_ptr<OrderedAxis> axis, const shared_ptr<GeometryObjectD<DIM>>& geometry, size_t dir) = 0;
259
260 virtual const char* name() = 0;
261
262 void fromXML(XMLReader&, Manager&);
263
264 std::pair<double, double> getMinMax(const shared_ptr<OrderedAxis>& axis);
265
266 void divideLargestSegment(shared_ptr<OrderedAxis> axis);
267
272
273 shared_ptr<MeshD<dim>> generate(const shared_ptr<GeometryObjectD<DIM>>& geometry) override;
274
276 double getAspect() const { return aspect; }
277
279 void setAspect(double value) {
280 if (value != 0. && value < 2.)
281 throw BadInput("divideGenerator", "maximum aspect must be larger than 2");
282 aspect = value;
283 this->fireChanged();
284 }
285
288 const Refinements& getRefinements(typename Primitive<DIM>::Direction direction) const {
289 assert(size_t(direction) <= dim);
290 return refinements[size_t(direction)];
291 }
292
300 void addRefinement(typename Primitive<DIM>::Direction direction, const weak_ptr<const GeometryObjectD<DIM>>& object, const PathHints& path, double position) {
301 auto key = std::make_pair(object, path);
302 assert(size_t(direction) <= dim);
303 refinements[size_t(direction)][key].insert(position);
304 this->fireChanged();
305 }
306
313 void addRefinement(typename Primitive<DIM>::Direction direction, const weak_ptr<const GeometryObjectD<DIM>>& object, double position) {
314 addRefinement(direction, object, PathHints(), position);
315 }
316
323 void addRefinement(typename Primitive<DIM>::Direction direction, const Path& path, double position) {
324 addRefinement(direction, dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path), position);
325 }
326
333 void addRefinement(typename Primitive<DIM>::Direction direction, const GeometryObject::Subtree& subtree, double position) {
334 auto path = subtree.getLastPath();
335 addRefinement(direction, dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path), position);
336 }
337
345 void removeRefinement(typename Primitive<DIM>::Direction direction, const weak_ptr<const GeometryObjectD<DIM>>& object, const PathHints& path, double position) {
346 auto key = std::make_pair(object, path);
347 assert(size_t(direction) <= dim);
348 auto ref = refinements[size_t(direction)].find(key);
349 if (ref == refinements[size_t(direction)].end()) throw BadInput("RectangularMeshDivideGenerator", "there are no refinements for specified geometry object.");
350 auto oposition = ref->second.find(position);
351 if (oposition == ref->second.end()) throw BadInput("RectangularMeshDivideGenerator", "specified geometry object does not have refinements at {0}.", *oposition);
352 ref->second.erase(oposition);
353 if (ref->second.empty()) refinements[size_t(direction)].erase(ref);
354 this->fireChanged();
355 }
356
363 void removeRefinement(typename Primitive<DIM>::Direction direction, const weak_ptr<const GeometryObjectD<DIM>>& object, double position) {
364 removeRefinement(direction, object, PathHints(), position);
365 }
366
373 void removeRefinement(typename Primitive<DIM>::Direction direction, const Path& path, double position) {
374 removeRefinement(direction, dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path), position);
375 }
376
383 void removeRefinement(typename Primitive<DIM>::Direction direction, const GeometryObject::Subtree& subtree, double position) {
384 auto path = subtree.getLastPath();
385 removeRefinement(direction, dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path), position);
386 }
387
393 void removeRefinements(const weak_ptr<const GeometryObjectD<DIM>>& object, const PathHints& path=PathHints()) {
394 auto key = std::make_pair(object, path);
395 bool found = false;
396 for (size_t i = 0; i != dim; ++i) {
397 auto ref = refinements[i].find(key);
398 if (ref != refinements[i].end()) {
399 found = true;
400 refinements[i].erase(ref);
401 }
402 }
403 if (found) this->fireChanged();
404 else writelog(LOG_WARNING, "RectangularMeshDivideGenerator: There are no refinements for specified geometry object");
405 }
406
411 refinements[0].clear();
412 refinements[1].clear();
413 this->fireChanged();
414 }
415
420 void removeRefinements(const Path& path) {
421 removeRefinements(dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path));
422 }
423
429 auto path = subtree.getLastPath();
430 removeRefinements(dynamic_pointer_cast<const GeometryObjectD<DIM>>(path.back()), PathHints(path));
431 }
432
433};
434
438
442
443
446template <int dim>
448
450 using MeshGeneratorD<dim>::DIM;
451
452 size_t pre_divisions[dim];
453 size_t post_divisions[dim];
454
456
457 shared_ptr<OrderedAxis> processAxis(shared_ptr<OrderedAxis> axis, const shared_ptr<GeometryObjectD<DIM>>& geometry, size_t dir) override;
458
459 const char* name() override { return "DivideGenerator"; }
460
461 template <int fd>
463
468 {
469 for (int i = 0; i != dim; ++i) {
470 pre_divisions[i] = 1;
471 post_divisions[i] = 1;
472 }
473 }
474
476 inline size_t getPreDivision(typename Primitive<DIM>::Direction direction) const {
477 assert(size_t(direction) <= dim);
478 return pre_divisions[size_t(direction)];
479 }
480
482 inline void setPreDivision(typename Primitive<DIM>::Direction direction, size_t div) {
483 assert(size_t(direction) <= dim);
484 pre_divisions[size_t(direction)] = div;
485 this->fireChanged();
486 }
487
489 inline size_t getPostDivision(typename Primitive<DIM>::Direction direction) const {
490 assert(size_t(direction) <= dim);
491 return post_divisions[size_t(direction)];
492 }
493
495 inline void setPostDivision(typename Primitive<DIM>::Direction direction, size_t div) {
496 assert(size_t(direction) <= dim);
497 post_divisions[size_t(direction)] = div;
498 this->fireChanged();
499 }
500
502 inline bool getGradual(size_t dir) const {
503 assert(dir <= dim);
504 return (gradual >> dir) & 1;
505 }
506
508 inline void setGradual(size_t dir, bool value) {
509 assert(dir <= dim);
510 gradual &= ~(1 << dir);
511 if (value) gradual |= 1 << dir;
512 this->fireChanged();
513 }
514
516 inline bool getGradual(typename Primitive<DIM>::Direction direction) const {
517 return getGradual(size_t(direction));
518 }
519
521 inline void setGradual(typename Primitive<DIM>::Direction direction, bool value) {
522 setGradual(size_t(direction), value);
523 }
524
525};
526
530
531
532
535template <int dim>
537
539 using MeshGeneratorD<dim>::DIM;
540
541 double finestep[dim];
542 double maxstep[dim];
543 double factor[dim];
544
545 shared_ptr<OrderedAxis> processAxis(shared_ptr<OrderedAxis> axis, const shared_ptr<GeometryObjectD<DIM>>& geometry, size_t dir) override;
546
547 const char* name() override { return "SmoothGenerator"; }
548
549 template <int fd>
551
554
556 inline double getFineStep(typename Primitive<DIM>::Direction direction) const {
557 assert(size_t(direction) <= dim);
558 return finestep[size_t(direction)];
559 }
560
562 inline void setFineStep(typename Primitive<DIM>::Direction direction, double value) {
563 assert(size_t(direction) <= dim);
564 finestep[size_t(direction)] = value;
565 this->fireChanged();
566 }
567
569 inline double getMaxStep(typename Primitive<DIM>::Direction direction) const {
570 assert(size_t(direction) <= dim);
571 return maxstep[size_t(direction)];
572 }
573
575 inline void setMaxStep(typename Primitive<DIM>::Direction direction, double value) {
576 assert(size_t(direction) <= dim);
577 maxstep[size_t(direction)] = value;
578 this->fireChanged();
579 }
580
582 inline double getFactor(typename Primitive<DIM>::Direction direction) const {
583 assert(size_t(direction) <= dim);
584 return factor[size_t(direction)];
585 }
586
588 inline void setFactor(typename Primitive<DIM>::Direction direction, double value) {
589 assert(size_t(direction) <= dim);
590 if (value < 1.) throw BadInput("SmoothGenerator", "increase factor for axis {:d} cannot be smaller than 1", size_t(direction));
591 factor[size_t(direction)] = value;
592 this->fireChanged();
593 }
594};
595
599
603
604} // namespace plask
605
606#endif // PLASK__GENERATOR_RECTANGULAR_H