PLaSK library
Loading...
Searching...
No Matches
complex_fem_solver.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) 2023 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 SOLVERS_ELECTRICAL_CAPACITANCE_COMPLEX_FEM_SOLVER_HPP
15
#define SOLVERS_ELECTRICAL_CAPACITANCE_COMPLEX_FEM_SOLVER_HPP
16
17
#include <
plask/plask.hpp
>
18
#include <
plask/common/fem/fem_solver.hpp
>
19
20
#include "
complex_gauss_matrix.hpp
"
21
22
namespace
plask
{
namespace
electrical {
namespace
capacitance {
23
25
enum
ComplexFemMatrixAlgorithm
{
26
ALGORITHM_GAUSS
,
27
ALGORITHM_ITERATIVE
28
};
29
30
template
<
typename
SpaceT,
typename
MeshT>
struct
ComplexFemSolverWithMesh
:
public
SolverWithMesh
<SpaceT, MeshT> {
31
ComplexFemMatrixAlgorithm
algorithm
=
ALGORITHM_GAUSS
;
32
33
ComplexFemSolverWithMesh
(
const
std::string& name =
""
) :
SolverWithMesh
<
SpaceT
,
MeshT
>(name) {}
34
35
bool
parseFemConfiguration
(
XMLReader
& reader,
Manager
& manager) {
36
// if (reader.getNodeName() == "matrix") {
37
// algorithm = reader.enumAttribute<ComplexFemMatrixAlgorithm>("algorithm")
38
// .value("gauss", ALGORITHM_GAUSS)
39
// .value("iterative", ALGORITHM_ITERATIVE)
40
// .get(algorithm);
41
// reader.requireTagEnd(); // </matrix>
42
// return true;
43
// }
44
return
false
;
45
}
46
47
inline
FemMatrix<dcomplex>
*
getMatrix
();
48
};
49
50
template
<
typename
SpaceT,
typename
MeshT>
inline
FemMatrix<dcomplex>
*
ComplexFemSolverWithMesh<SpaceT, MeshT>::getMatrix
() {
51
switch
(algorithm) {
52
case
ALGORITHM_GAUSS
:
return
new
ZgbMatrix
(
this
, this->mesh->size(),
this
->mesh->minorAxis()->size() + 1);
53
// case ALGORITHM_ITERATIVE: return new SparseBandMatrix(this, 2 * this->mesh->size(), 2 * this->mesh->minorAxis()->size());
54
}
55
return
nullptr
;
56
}
57
58
template
<>
inline
FemMatrix<dcomplex>
*
ComplexFemSolverWithMesh<Geometry3D, RectangularMesh<3>
>::getMatrix() {
59
size_t
band
= this->mesh->minorAxis()->size() * (this->mesh->mediumAxis()->size() + 1) + 1;
60
switch
(algorithm) {
61
case
ALGORITHM_GAUSS
:
return
new
ZgbMatrix
(
this
, this->mesh->size(),
band
);
62
// case ALGORITHM_ITERATIVE:
63
// return new SparseBandMatrix(this, 2 * this->mesh->size(), 2 * this->mesh->mediumAxis()->size() * this->mesh->minorAxis()->size(),
64
// 2 * this->mesh->minorAxis()->size());
65
}
66
return
nullptr
;
67
}
68
70
71
template
<
typename
SpaceT,
typename
MeshT>
struct
ComplexFemSolverWithMaskedMesh
:
public
ComplexFemSolverWithMesh
<SpaceT, MeshT> {
72
static_assert
(std::is_base_of<RectangularMesh<MeshT::DIM>,
MeshT
>::value,
73
"ComplexFemSolverWithMaskedMesh only works with RectangularMesh"
);
74
75
ComplexFemSolverWithMaskedMesh
(
const
std::string& name =
""
) :
ComplexFemSolverWithMesh
<
SpaceT
,
MeshT
>(name) {}
76
77
protected
:
78
plask::shared_ptr<RectangularMaskedMesh<MeshT::DIM>
>
maskedMesh
=
plask::make_shared<RectangularMaskedMesh<MeshT::DIM>
>();
79
EmptyElementsHandling
empty_elements
=
EMPTY_ELEMENTS_DEFAULT
;
80
81
public
:
83
EmptyElementsHandling
getEmptyElements
()
const
{
return
empty_elements
; }
85
void
setEmptyElements
(
EmptyElementsHandling
val) {
86
empty_elements
= val;
87
this->
invalidate
();
88
}
89
90
bool
parseFemConfiguration
(
XMLReader
& reader,
Manager
& manager) {
91
if
(reader.
getNodeName
() ==
"mesh"
) {
92
if
(reader.
hasAttribute
(
"include-empty"
)) {
93
this->
writelog
(
LOG_WARNING
, this->
getId
(),
"Attribute 'include-empty' is deprecated, use 'empty-elements' instead"
);
94
empty_elements = reader.
requireAttribute
<
bool
>(
"include-empty"
) ?
EMPTY_ELEMENTS_INCLUDED
:
EMPTY_ELEMENTS_EXCLUDED
;
95
}
96
empty_elements
= reader.
enumAttribute
<
EmptyElementsHandling
>(
"empty-elements"
)
97
.value(
"default"
,
EMPTY_ELEMENTS_DEFAULT
)
98
.value(
"exclude"
,
EMPTY_ELEMENTS_EXCLUDED
)
99
.value(
"include"
,
EMPTY_ELEMENTS_INCLUDED
)
100
.value(
"excluded"
,
EMPTY_ELEMENTS_EXCLUDED
)
101
.value(
"included"
,
EMPTY_ELEMENTS_INCLUDED
)
102
.get(
empty_elements
);
103
return
false
;
104
}
105
return
ComplexFemSolverWithMesh<SpaceT, MeshT>::parseFemConfiguration
(reader, manager);
106
}
107
108
void
setupMaskedMesh
() {
109
if
(
empty_elements
==
EMPTY_ELEMENTS_INCLUDED
||
110
(this->
algorithm
==
ALGORITHM_ITERATIVE
&& empty_elements ==
EMPTY_ELEMENTS_DEFAULT
)) {
111
maskedMesh
->selectAll(*this->
mesh
);
112
}
else
{
113
maskedMesh->reset(*this->
mesh
, *this->
geometry
, ~
plask::Material::EMPTY
);
114
}
115
}
116
117
void
onInitialize
() {
setupMaskedMesh
(); }
118
119
inline
FemMatrix<dcomplex>
*
getMatrix
();
120
};
121
122
template
<
typename
SpaceT,
typename
MeshT>
inline
FemMatrix<dcomplex>
*
ComplexFemSolverWithMaskedMesh<SpaceT, MeshT>::getMatrix
() {
123
size_t
band
;
124
if
(empty_elements ==
EMPTY_ELEMENTS_INCLUDED
|| this->algorithm ==
ALGORITHM_ITERATIVE
) {
125
band
= this->mesh->minorAxis()->
size
() + 1;
126
}
else
{
127
band
= 0;
128
for
(
auto
element : this->maskedMesh->elements()) {
129
size_t
span = element.getUpUpIndex() - element.getLoLoIndex();
130
if
(span >
band
)
band
= span;
131
}
132
}
133
switch
(this->algorithm) {
134
case
ALGORITHM_GAUSS
:
return
new
ZgbMatrix
(
this
, this->maskedMesh->size(),
band
);
135
// case ALGORITHM_ITERATIVE:
136
// if (empty_elements != EMPTY_ELEMENTS_EXCLUDED)
137
// return new SparseBandMatrix(this, this->maskedMesh->size(), this->mesh->minorAxis()->size());
138
// else
139
// return new SparseFreeMatrix(this, this->maskedMesh->size(), this->maskedMesh->elements().size() * 10);
140
}
141
return
nullptr
;
142
}
143
144
template
<>
inline
FemMatrix<dcomplex>
*
ComplexFemSolverWithMaskedMesh<Geometry3D, RectangularMesh<3>
>::getMatrix() {
145
size_t
band
;
146
if
(empty_elements || algorithm ==
ALGORITHM_ITERATIVE
) {
147
band
= this->mesh->minorAxis()->size() * (this->mesh->mediumAxis()->size() + 1) + 1;
148
}
else
{
149
band
= 0;
150
for
(
auto
element : this->maskedMesh->elements()) {
151
size_t
span = element.getUpUpUpIndex() - element.getLoLoLoIndex();
152
if
(span >
band
)
band
= span;
153
}
154
}
155
switch
(algorithm) {
156
case
ALGORITHM_GAUSS
:
return
new
ZgbMatrix
(
this
, this->maskedMesh->size(),
band
);
157
case
ALGORITHM_ITERATIVE
:
throw
NotImplemented
(this->getId(),
"Iterative solver for complex FEM is not implemented yet"
);
158
// case ALGORITHM_ITERATIVE:
159
// if (empty_elements != EMPTY_ELEMENTS_EXCLUDED)
160
// return new SparseBandMatrix(this, this->maskedMesh->size(), mesh->mediumAxis()->size() * mesh->minorAxis()->size(),
161
// mesh->minorAxis()->size());
162
// else
163
// return new SparseFreeMatrix(this, this->maskedMesh->size(), this->maskedMesh->elements().size() * 36);
164
}
165
return
nullptr
;
166
}
167
168
}}}
// namespace plask::electrical::capacitance
169
170
#endif
solvers
electrical
capacitance
complex_fem_solver.hpp
Generated by
1.9.8