PLaSK library
Loading...
Searching...
No Matches
electr2d.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__MODULE_ELECTRICAL_ELECTR2D_H
15#define PLASK__MODULE_ELECTRICAL_ELECTR2D_H
16
17#include "common.hpp"
18
19namespace plask { namespace electrical { namespace shockley {
20
24template <typename Geometry2DType>
25struct PLASK_SOLVER_API ElectricalFem2DSolver : public FemSolverWithMaskedMesh<Geometry2DType, RectangularMesh<2>> {
26 protected:
27
29 struct Active {
30 struct Region {
31 size_t left, right, bottom, top;
32 size_t rowl, rowr;
33 bool warn;
35 : left(0),
36 right(0),
37 bottom(std::numeric_limits<size_t>::max()),
38 top(std::numeric_limits<size_t>::max()),
39 rowl(std::numeric_limits<size_t>::max()),
40 rowr(0),
41 warn(true) {}
42 };
43 size_t left, right, bottom, top;
44 ptrdiff_t offset;
45 double height;
46 Active() : left(0), right(0), bottom(0), top(0), offset(0), height(0.) {}
47 Active(size_t tot, size_t l, size_t r, size_t b, size_t t, double h)
48 : left(l), right(r), bottom(b), top(t), offset(tot - l), height(h) {}
49 };
50
51 double pcond;
52 double ncond;
53
54 int loopno;
55 double toterr;
58
61
66
67 std::vector<Active> active;
68
70 inline void setLocalMatrix(double& k44,
71 double& k33,
72 double& k22,
73 double& k11,
74 double& k43,
75 double& k21,
76 double& k42,
77 double& k31,
78 double& k32,
79 double& k41,
80 double ky,
81 double width,
82 const Vec<2, double>& midpoint);
83
90 virtual Tensor2<double> activeCond(size_t n, double U, double jy, double T) = 0;
91
95 LazyData<double> loadConductivities();
96
98 void saveConductivities();
99
101 void saveHeatDensities();
102
104 void onInitialize() override;
105
107 void onInvalidate() override;
108
110 void setupActiveRegions();
111
112 // void onMeshChange(const typename RectangularMesh<2>::Event& evt) override {
113 // SolverWithMesh<Geometry2DType, RectangularMesh<2>>::onMeshChange(evt);
114 // setupActiveRegions();
115 // }
116
117 // void onGeometryChange(const Geometry::Event& evt) override {
118 // SolverWithMesh<Geometry2DType, RectangularMesh<2>>::onGeometryChange(evt);
119 // setupActiveRegions();
120 // }
121
123 void setMatrix(FemMatrix& A,
126 const LazyData<double>& temperature);
127
132 size_t isActive(const Vec<2>& point) const {
133 size_t no(0);
134 auto roles = this->geometry->getRolesAt(point);
135 for (auto role : roles) {
136 size_t l = 0;
137 if (role.substr(0, 6) == "active")
138 l = 6;
139 else if (role.substr(0, 8) == "junction")
140 l = 8;
141 else
142 continue;
143 if (no != 0) throw BadInput(this->getId(), "multiple 'active'/'junction' roles specified");
144 if (role.size() == l)
145 no = 1;
146 else {
147 try {
148 no = boost::lexical_cast<size_t>(role.substr(l)) + 1;
149 } catch (boost::bad_lexical_cast&) {
150 throw BadInput(this->getId(), "bad junction number in role '{0}'", role);
151 }
152 }
153 }
154 return no;
155 }
156
158 size_t isActive(const RectangularMaskedMesh2D::Element& element) const { return isActive(element.getMidpoint()); }
159
160 public:
161 double maxerr;
162
165
167
169
171
173
175
177
183 double compute(unsigned loops = 1);
184
191 double integrateCurrent(size_t vindex, bool onlyactive = false);
192
198 double getTotalCurrent(size_t nact = 0);
199
205
210 double getCapacitance();
211
216 double getTotalHeat();
217
219 double getErr() const { return toterr; }
220
222 double getCondPcontact() const { return pcond; }
224 void setCondPcontact(double cond) {
225 pcond = cond;
226 this->invalidate();
227 }
228
230 double getCondNcontact() const { return ncond; }
232 void setCondNcontact(double cond) {
233 ncond = cond;
234 this->invalidate();
235 }
236
238 DataVector<const Tensor2<double>> getCondJunc() const { return junction_conductivity; }
240 void setCondJunc(double cond) {
241 junction_conductivity.reset(max(junction_conductivity.size(), size_t(1)), cond);
242 default_junction_conductivity = Tensor2<double>(0., cond);
243 }
246 junction_conductivity.reset(max(junction_conductivity.size(), size_t(1)), cond);
247 default_junction_conductivity = cond;
248 }
251 size_t condsize = 0;
252 condsize = max(condsize, size_t(1));
253 if (!this->mesh || cond.size() != condsize)
254 throw BadInput(this->getId(), "provided junction conductivity vector has wrong size");
255 junction_conductivity = cond.claim();
256 }
257
258 void loadConfiguration(XMLReader& source, Manager& manager) override;
259
260 void parseConfiguration(XMLReader& source, Manager& manager);
261
262 ElectricalFem2DSolver(const std::string& name = "");
263
265
266 protected:
267 const LazyData<double> getVoltage(shared_ptr<const MeshD<2>> dest_mesh, InterpolationMethod method) const;
268
269 const LazyData<double> getHeatDensities(shared_ptr<const MeshD<2>> dest_mesh, InterpolationMethod method);
270
271 const LazyData<Vec<2>> getCurrentDensities(shared_ptr<const MeshD<2>> dest_mesh, InterpolationMethod method);
272
273 const LazyData<Tensor2<double>> getConductivity(shared_ptr<const MeshD<2>> dest_mesh, InterpolationMethod method);
274};
275
276}}} // namespace plask::electrical::shockley
277
278#endif