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>
19
21
22namespace plask { namespace electrical { namespace capacitance {
23
29
30template <typename SpaceT, typename MeshT> struct ComplexFemSolverWithMesh : public SolverWithMesh<SpaceT, MeshT> {
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
48};
49
50template <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
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
71template <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:
80
81 public:
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 }
106 }
107
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
118
120};
121
122template <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
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