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 "
plask/geometry/path.hpp
"
19
#include "
rectangular.hpp
"
20
21
namespace
plask
{
22
29
template
<
int
dim>
30
PLASK_API
shared_ptr<OrderedAxis>
makeGeometryAxis
(
const
shared_ptr<
GeometryObjectD<dim>
>& geometry,
31
Primitive<3>::Direction
dir
,
32
double
split = 0.);
33
40
PLASK_API
shared_ptr<OrderedAxis>
makeGeometryGrid1D
(
const
shared_ptr<
GeometryObjectD<2>
>& geometry,
double
split = 0.);
41
48
PLASK_API
shared_ptr<RectangularMesh<2>
>
makeGeometryGrid
(
const
shared_ptr<
GeometryObjectD<2>
>& geometry,
double
split = 0.);
49
56
PLASK_API
shared_ptr<RectangularMesh<3>
>
makeGeometryGrid
(
const
shared_ptr<
GeometryObjectD<3>
>& geometry,
double
split = 0.);
57
63
inline
shared_ptr<OrderedAxis>
makeGeometryGrid1D
(
const
shared_ptr<
GeometryD<2>
>& geometry) {
64
return
makeGeometryGrid1D
(geometry->getChild());
65
}
66
72
inline
shared_ptr<RectangularMesh<2>
>
makeGeometryGrid
(
const
shared_ptr<
GeometryD<2>
>& geometry) {
73
return
makeGeometryGrid
(geometry->getChild());
74
}
75
81
inline
shared_ptr<RectangularMesh<3>
>
makeGeometryGrid
(
const
shared_ptr<
GeometryD<3>
>& geometry) {
82
return
makeGeometryGrid
(geometry->getChild());
83
}
84
90
PLASK_API
shared_ptr<OrderedAxis>
refineAxis
(
const
shared_ptr<MeshAxis>& axis,
double
spacing);
91
95
struct
PLASK_API
OrderedMesh1DSimpleGenerator
:
public
MeshGeneratorD
<1> {
96
protected
:
97
bool
split
;
98
99
public
:
101
OrderedMesh1DSimpleGenerator
(
bool
split =
false
) : split(split) {}
102
103
shared_ptr<MeshD<1>
> generate(
const
shared_ptr<
GeometryObjectD<2>
>& geometry)
override
;
104
};
105
109
struct
PLASK_API
RectangularMesh2DSimpleGenerator
:
public
MeshGeneratorD
<2> {
110
protected
:
111
bool
split
;
112
113
public
:
115
RectangularMesh2DSimpleGenerator
(
bool
split =
false
) : split(split) {}
116
117
shared_ptr<MeshD<2>
> generate(
const
shared_ptr<
GeometryObjectD<2>
>& geometry)
override
;
118
};
119
123
struct
PLASK_API
RectangularMesh3DSimpleGenerator
:
public
MeshGeneratorD
<3> {
124
protected
:
125
bool
split
;
126
127
public
:
129
RectangularMesh3DSimpleGenerator
(
bool
split =
false
) : split(split) {}
130
131
shared_ptr<MeshD<3>
> generate(
const
shared_ptr<
GeometryObjectD<3>
>& geometry)
override
;
132
};
133
138
class
PLASK_API
OrderedMesh1DRegularGenerator
:
public
OrderedMesh1DSimpleGenerator
{
140
double
spacing;
141
142
public
:
147
OrderedMesh1DRegularGenerator
(
double
spacing,
bool
split =
false
) :
OrderedMesh1DSimpleGenerator
(split), spacing(spacing) {}
148
149
shared_ptr<MeshD<1>
> generate(
const
shared_ptr<
GeometryObjectD<2>
>& geometry)
override
;
150
};
151
156
class
PLASK_API
RectangularMesh2DRegularGenerator
:
public
RectangularMesh2DSimpleGenerator
{
158
double
spacing0, spacing1;
159
160
public
:
165
RectangularMesh2DRegularGenerator
(
double
spacing,
bool
split =
false
)
166
:
RectangularMesh2DSimpleGenerator
(split), spacing0(spacing), spacing1(spacing) {}
167
173
RectangularMesh2DRegularGenerator
(
double
spacing0,
double
spacing1,
bool
split =
false
)
174
:
RectangularMesh2DSimpleGenerator
(split), spacing0(spacing0), spacing1(spacing1) {}
175
176
shared_ptr<MeshD<2>
> generate(
const
shared_ptr<
GeometryObjectD<2>
>& geometry)
override
;
177
};
178
183
struct
PLASK_API
RectangularMesh3DRegularGenerator
:
public
RectangularMesh3DSimpleGenerator
{
185
double
spacing0
, spacing1, spacing2;
186
187
public
:
192
RectangularMesh3DRegularGenerator
(
double
spacing,
bool
split =
false
)
193
:
RectangularMesh3DSimpleGenerator
(split), spacing0(spacing), spacing1(spacing), spacing2(spacing) {}
194
201
RectangularMesh3DRegularGenerator
(
double
spacing0,
double
spacing1,
double
spacing2,
bool
split =
false
)
202
:
RectangularMesh3DSimpleGenerator
(split), spacing0(spacing0), spacing1(spacing1), spacing2(spacing2) {}
203
204
shared_ptr<MeshD<3>
> generate(
const
shared_ptr<
GeometryObjectD<3>
>& geometry)
override
;
205
};
206
210
class
PLASK_API
RectangularMesh2DFrom1DGenerator
:
public
MeshGeneratorD
<2> {
211
shared_ptr<MeshGeneratorD<1>
> horizontal_generator;
212
213
public
:
217
RectangularMesh2DFrom1DGenerator
(
const
shared_ptr<
MeshGeneratorD<1>
>& source) : horizontal_generator(source) {}
218
219
shared_ptr<MeshD<2>
> generate(
const
shared_ptr<
GeometryObjectD<2>
>& geometry)
override
;
220
};
221
225
template
<
int
dim>
struct
PLASK_API
RectangularMeshRefinedGenerator
:
public
MeshGeneratorD
<dim> {
226
typedef
typename
Rectangular_t<dim>::Rectilinear
GeneratedMeshType
;
227
using
MeshGeneratorD
<dim>::DIM;
228
229
typedef
std::map<std::pair<weak_ptr<const GeometryObjectD<DIM>>,
PathHints
>, std::set<double>>
Refinements
;
230
231
double
aspect
;
232
233
Refinements
refinements[dim];
234
235
shared_ptr<OrderedAxis>
getAxis(
shared_ptr<OrderedAxis>
axis,
const
shared_ptr<
GeometryObjectD<DIM>
>& geometry,
size_t
dir
);
236
237
virtual
shared_ptr<OrderedAxis>
processAxis
(
shared_ptr<OrderedAxis>
axis,
238
const
shared_ptr<
GeometryObjectD<DIM>
>& geometry,
239
size_t
dir
) = 0;
240
241
virtual
const
char
*
name
() = 0;
242
243
void
fromXML(
XMLReader
&,
Manager
&);
244
245
std::pair<double, double> getMinMax(
const
shared_ptr<OrderedAxis>
& axis);
246
247
void
divideLargestSegment(
shared_ptr<OrderedAxis>
axis);
248
252
RectangularMeshRefinedGenerator
() : aspect(0) {}
253
254
shared_ptr<MeshD<dim>
>
generate
(
const
shared_ptr<
GeometryObjectD<DIM>
>& geometry)
override
;
255
257
double
getAspect
()
const
{
return
aspect; }
258
260
void
setAspect
(
double
value) {
261
if
(value != 0. && value < 2.)
throw
BadInput
(
"divideGenerator"
,
"maximum aspect must be larger than 2"
);
262
aspect = value;
263
this->fireChanged();
264
}
265
268
const
Refinements
&
getRefinements
(
typename
Primitive<DIM>::Direction
direction)
const
{
269
assert
(
size_t
(direction) <= dim);
270
return
refinements[size_t(direction)];
271
}
272
280
void
addRefinement
(
typename
Primitive<DIM>::Direction
direction,
281
const
weak_ptr<
const
GeometryObjectD<DIM>
>&
object
,
282
const
PathHints
& path,
283
double
position) {
284
auto
key = std::make_pair(
object
, path);
285
assert
(
size_t
(direction) <= dim);
286
refinements[size_t(direction)][key].insert(position);
287
this->fireChanged();
288
}
289
296
void
addRefinement
(
typename
Primitive<DIM>::Direction
direction,
297
const
weak_ptr<
const
GeometryObjectD<DIM>
>&
object
,
298
double
position) {
299
addRefinement(direction,
object
,
PathHints
(), position);
300
}
301
308
void
addRefinement
(
typename
Primitive<DIM>::Direction
direction,
const
Path
& path,
double
position) {
309
addRefinement(direction, dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.
back
()),
PathHints
(path), position);
310
}
311
318
void
addRefinement
(
typename
Primitive<DIM>::Direction
direction,
const
GeometryObject::Subtree
&
subtree
,
double
position) {
319
auto
path =
subtree
.getLastPath();
320
addRefinement(direction, dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.back()),
PathHints
(path), position);
321
}
322
330
void
removeRefinement
(
typename
Primitive<DIM>::Direction
direction,
331
const
weak_ptr<
const
GeometryObjectD<DIM>
>&
object
,
332
const
PathHints
& path,
333
double
position) {
334
auto
key = std::make_pair(
object
, path);
335
assert
(
size_t
(direction) <= dim);
336
auto
ref = refinements[size_t(direction)].find(key);
337
if
(ref == refinements[
size_t
(direction)].end())
338
throw
BadInput
(
"RectangularMeshDivideGenerator"
,
"there are no refinements for specified geometry object."
);
339
auto
oposition
= ref->second.find(position);
340
if
(
oposition
== ref->second.end())
341
throw
BadInput
(
"RectangularMeshDivideGenerator"
,
"specified geometry object does not have refinements at {0}."
,
342
*
oposition
);
343
ref->second.erase(
oposition
);
344
if
(ref->second.empty()) refinements[size_t(direction)].erase(ref);
345
this->fireChanged();
346
}
347
354
void
removeRefinement
(
typename
Primitive<DIM>::Direction
direction,
355
const
weak_ptr<
const
GeometryObjectD<DIM>
>&
object
,
356
double
position) {
357
removeRefinement(direction,
object
,
PathHints
(), position);
358
}
359
366
void
removeRefinement
(
typename
Primitive<DIM>::Direction
direction,
const
Path
& path,
double
position) {
367
removeRefinement(direction, dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.
back
()),
PathHints
(path), position);
368
}
369
376
void
removeRefinement
(
typename
Primitive<DIM>::Direction
direction,
const
GeometryObject::Subtree
&
subtree
,
double
position) {
377
auto
path =
subtree
.getLastPath();
378
removeRefinement(direction, dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.back()),
PathHints
(path), position);
379
}
380
386
void
removeRefinements
(
const
weak_ptr<
const
GeometryObjectD<DIM>
>&
object
,
const
PathHints
& path =
PathHints
()) {
387
auto
key = std::make_pair(
object
, path);
388
bool
found
=
false
;
389
for
(
size_t
i = 0; i != dim; ++i) {
390
auto
ref = refinements[i].find(key);
391
if
(ref != refinements[i].end()) {
392
found
=
true
;
393
refinements[i].erase(ref);
394
}
395
}
396
if
(
found
)
397
this->fireChanged();
398
else
399
writelog
(
LOG_WARNING
,
"RectangularMeshDivideGenerator: There are no refinements for specified geometry object"
);
400
}
401
405
void
clearRefinements
() {
406
refinements[0].clear();
407
refinements[1].clear();
408
this->fireChanged();
409
}
410
415
void
removeRefinements
(
const
Path
& path) {
416
removeRefinements(dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.
back
()),
PathHints
(path));
417
}
418
423
void
removeRefinements
(
const
GeometryObject::Subtree
&
subtree
) {
424
auto
path =
subtree
.getLastPath();
425
removeRefinements(dynamic_pointer_cast<
const
GeometryObjectD<DIM>
>(path.back()),
PathHints
(path));
426
}
427
};
428
429
template
<>
430
shared_ptr<MeshD<1>
>
RectangularMeshRefinedGenerator<1>::generate
(
const
boost::shared_ptr<
plask::GeometryObjectD<2>
>& geometry);
431
template
<>
432
shared_ptr<MeshD<2>
>
RectangularMeshRefinedGenerator<2>::generate
(
const
boost::shared_ptr<
plask::GeometryObjectD<2>
>& geometry);
433
template
<>
434
shared_ptr<MeshD<3>
>
RectangularMeshRefinedGenerator<3>::generate
(
const
boost::shared_ptr<
plask::GeometryObjectD<3>
>& geometry);
435
436
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshRefinedGenerator<1>
)
437
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshRefinedGenerator<2>
)
438
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshRefinedGenerator<3>
)
439
440
443
template
<
int
dim>
struct
PLASK_API
RectangularMeshDivideGenerator
:
public
RectangularMeshRefinedGenerator
<dim> {
444
typedef
typename
Rectangular_t<dim>::Rectilinear
GeneratedMeshType
;
445
using
MeshGeneratorD
<dim>::DIM;
446
447
size_t
pre_divisions[dim];
448
size_t
post_divisions[dim];
449
450
char
gradual
;
451
452
shared_ptr<OrderedAxis>
processAxis(
shared_ptr<OrderedAxis>
axis,
453
const
shared_ptr<
GeometryObjectD<DIM>
>& geometry,
454
size_t
dir
)
override
;
455
456
const
char
*
name
()
override
{
return
"DivideGenerator"
; }
457
458
template
<
int
fd>
friend
shared_ptr<MeshGenerator>
readRectangularDivideGenerator
(
XMLReader
&,
Manager
&);
459
463
RectangularMeshDivideGenerator
() : gradual(7) {
464
for
(
int
i = 0; i != dim; ++i) {
465
pre_divisions[i] = 1;
466
post_divisions[i] = 1;
467
}
468
}
469
471
inline
size_t
getPreDivision
(
typename
Primitive<DIM>::Direction
direction)
const
{
472
assert
(
size_t
(direction) <= dim);
473
return
pre_divisions[size_t(direction)];
474
}
475
477
inline
void
setPreDivision
(
typename
Primitive<DIM>::Direction
direction,
size_t
div
) {
478
assert
(
size_t
(direction) <= dim);
479
pre_divisions[size_t(direction)] =
div
;
480
this->fireChanged();
481
}
482
484
inline
size_t
getPostDivision
(
typename
Primitive<DIM>::Direction
direction)
const
{
485
assert
(
size_t
(direction) <= dim);
486
return
post_divisions[size_t(direction)];
487
}
488
490
inline
void
setPostDivision
(
typename
Primitive<DIM>::Direction
direction,
size_t
div
) {
491
assert
(
size_t
(direction) <= dim);
492
post_divisions[size_t(direction)] =
div
;
493
this->fireChanged();
494
}
495
497
inline
bool
getGradual
(
size_t
dir
)
const
{
498
assert
(
dir
<= dim);
499
return
(gradual >>
dir
) & 1;
500
}
501
503
inline
void
setGradual
(
size_t
dir
,
bool
value) {
504
assert
(
dir
<= dim);
505
gradual &= ~(1 <<
dir
);
506
if
(value) gradual |= 1 <<
dir
;
507
this->fireChanged();
508
}
509
511
inline
bool
getGradual
(
typename
Primitive<DIM>::Direction
direction)
const
{
return
getGradual
(
size_t
(direction)); }
512
514
inline
void
setGradual
(
typename
Primitive<DIM>::Direction
direction,
bool
value) {
setGradual
(
size_t
(direction), value); }
515
};
516
517
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshDivideGenerator<1>
)
518
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshDivideGenerator<2>
)
519
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshDivideGenerator<3>
)
520
521
524
template
<
int
dim>
struct
PLASK_API
RectangularMeshSmoothGenerator
:
public
RectangularMeshRefinedGenerator
<dim> {
525
typedef
typename
Rectangular_t<dim>::Rectilinear
GeneratedMeshType
;
526
using
MeshGeneratorD
<dim>::DIM;
527
528
double
finestep[dim];
529
double
maxstep[dim];
530
double
factor[dim];
531
532
shared_ptr<OrderedAxis>
processAxis(
shared_ptr<OrderedAxis>
axis,
533
const
shared_ptr<
GeometryObjectD<DIM>
>& geometry,
534
size_t
dir
)
override
;
535
536
const
char
*
name
()
override
{
return
"SmoothGenerator"
; }
537
538
template
<
int
fd>
friend
shared_ptr<MeshGenerator>
readRectangularSmoothGenerator
(
XMLReader
&,
Manager
&);
539
541
RectangularMeshSmoothGenerator
();
542
544
inline
double
getFineStep
(
typename
Primitive<DIM>::Direction
direction)
const
{
545
assert
(
size_t
(direction) <= dim);
546
return
finestep[size_t(direction)];
547
}
548
550
inline
void
setFineStep
(
typename
Primitive<DIM>::Direction
direction,
double
value) {
551
assert
(
size_t
(direction) <= dim);
552
finestep[size_t(direction)] = value;
553
this->fireChanged();
554
}
555
557
inline
double
getMaxStep
(
typename
Primitive<DIM>::Direction
direction)
const
{
558
assert
(
size_t
(direction) <= dim);
559
return
maxstep[size_t(direction)];
560
}
561
563
inline
void
setMaxStep
(
typename
Primitive<DIM>::Direction
direction,
double
value) {
564
assert
(
size_t
(direction) <= dim);
565
maxstep[size_t(direction)] = value;
566
this->fireChanged();
567
}
568
570
inline
double
getFactor
(
typename
Primitive<DIM>::Direction
direction)
const
{
571
assert
(
size_t
(direction) <= dim);
572
return
factor[size_t(direction)];
573
}
574
576
inline
void
setFactor
(
typename
Primitive<DIM>::Direction
direction,
double
value) {
577
assert
(
size_t
(direction) <= dim);
578
if
(value < 1.)
579
throw
BadInput
(
"SmoothGenerator"
,
"increase factor for axis {:d} cannot be smaller than 1"
,
size_t
(direction));
580
factor[size_t(direction)] = value;
581
this->fireChanged();
582
}
583
};
584
585
template
<>
RectangularMeshSmoothGenerator<1>::RectangularMeshSmoothGenerator
();
586
template
<>
RectangularMeshSmoothGenerator<2>::RectangularMeshSmoothGenerator
();
587
template
<>
RectangularMeshSmoothGenerator<3>::RectangularMeshSmoothGenerator
();
588
589
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshSmoothGenerator<1>
)
590
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshSmoothGenerator<2>
)
591
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
RectangularMeshSmoothGenerator<3>
)
592
593
}
// namespace plask
594
595
#endif
// PLASK__GENERATOR_RECTANGULAR_H
plask
mesh
generator_rectangular.hpp
Generated by
1.9.8