109 void onInitialize()
override;
112 void onInvalidate()
override;
115 size_t getActiveRegionMeshIndex(
size_t actnum)
const;
136 auto roles = this->geometry->getRolesAt(point);
137 for (
auto role : roles) {
139 if (role.substr(0, 6) ==
"active")
141 else if (role.substr(0, 8) ==
"junction")
145 if (no != 0)
throw BadInput(this->getId(),
"multiple 'active'/'junction' roles specified");
146 if (role.size() == l)
150 no = boost::lexical_cast<size_t>(role.substr(l)) + 1;
151 }
catch (boost::bad_lexical_cast&) {
152 throw BadInput(this->getId(),
"bad junction number in role '{0}'", role);
167 double findPsiI(
double iEc0,
178 std::size_t& loop)
const;
189 double calcN(
double iNc,
double iFnEta,
double iPsi,
double iEc0,
double iT)
const {
194 return (iNc * pow(iFnEta, 1. / iT) * exp((iPsi - iEc0) / iT));
212 double calcP(
double iNv,
double iFpKsi,
double iPsi,
double iEv0,
double iT)
const {
215 case STAT_MB:
return (iNv * pow(iFpKsi, 1. / iT) * exp((iEv0 - iPsi) / iT));
217 case STAT_FD:
return (iNv * fermiDiracHalf((log(iFpKsi) - iPsi + iEv0) / iT));
222 void divideByElements(DataVector<double>& values) {
223 size_t majs = this->mesh->majorAxis()->size(), mins = this->mesh->minorAxis()->size();
224 if (mins == 0 || majs == 0)
return;
225 for (
size_t j = 1, jend = mins - 1; j < jend; ++j) values[j] *= 0.5;
226 for (
size_t i = 1, iend = majs - 1;
i < iend; ++
i) {
227 values[mins *
i] *= 0.5;
228 for (
size_t j = 1, jend = mins - 1; j < jend; ++j) values[mins * i + j] *= 0.25;
229 values[mins * (
i + 1) - 1] *= 0.5;
231 for (
size_t j = mins * (majs - 1) + 1, jend = this->mesh->size() - 1; j < jend; ++j) values[j] *= 0.5;
242 template <CalcType calctype>
243 double addCorr(DataVector<double>& corr,
const BoundaryConditionsWithMesh<RectangularMesh<2>::Boundary,
double>& vconst);
246 void saveHeatDensities();
249 inline void addCurvature(
double& k44,
261 const Vec<2, double>& midpoint);
264 template <CalcType calctype>
265 void setMatrix(FemMatrix& A,
266 DataVector<double>& B,
267 const BoundaryConditionsWithMesh<RectangularMesh<2>::Boundary,
double>& bvoltage);
271 struct ActiveRegionInfo {
272 shared_ptr<StackContainer<2>>
layers;
275 ActiveRegionInfo(Vec<2> origin) :
layers(
plask::make_shared<StackContainer<2>>()), origin(origin) {}
278 size_t size()
const {
return layers->getChildrenCount(); }
281 shared_ptr<Material> getLayerMaterial(
size_t n)
const {
282 auto block =
static_cast<Block<2>*
>(
static_cast<Translation<2>*
>(
layers->getChildNo(
n).get())->getChild().get());
283 if (
auto m = block->singleMaterial())
return m;
288 Box2D getLayerBox(
size_t n)
const {
289 return static_cast<GeometryObjectD<2>*
>(
layers->getChildNo(
n).get())->getBoundingBox() + origin;
293 bool isQW(
size_t n)
const {
return static_cast<Translation<2>*
>(
layers->getChildNo(
n).get())->getChild()->hasRole(
"QW"); }
296 Box2D getBoundingBox()
const {
return layers->getBoundingBox() + origin; }
299 bool contains(
const Vec<2>& point)
const {
return getBoundingBox().contains(point); }
302 bool inQW(
const Vec<2>& point)
const {
303 if (!contains(point))
return false;
304 assert(
layers->getChildForHeight(point.c1 - origin.c1));
305 return layers->getChildForHeight(point.c1 - origin.c1)->getChild()->hasRole(
"QW");
308 double averageNr(
double lam,
double T,
double conc = 0.)
const {
310 for (
size_t i = 0;
i != materials.size(); ++
i)
311 if (isQW(i))
nr += thicknesses[
i] * materials[
i]->Nr(lam, T, conc).real();
315 std::vector<shared_ptr<Material>> materials;
316 std::vector<double> thicknesses;
317 std::vector<size_t> wells;
324 enum ConsideredHoles :
unsigned {
335 void summarize(
const DriftDiffusionModel2DSolver<Geometry2DType>* solver);
339 shared_ptr<Material> substrateMaterial;
342 std::vector<ActiveRegionInfo> regions;
345 void detectActiveRegions();
348 shared_ptr<RectangularMesh<2>> meshAct;
351 shared_ptr<RectangularMesh<2>> meshActMid;
355 std::vector<double> z;
362 std::vector<double> CBelLev;
364 std::vector<double> lev_el;
366 double CBelMin, CBelMax;
423 double compute(
unsigned loops = 1);
429 double findEnergyLevels();
435 bool checkWell(std::string _carrier);
450 double getTotalCurrent(
size_t nact = 0);
473 void loadConfiguration(
XMLReader& source,
486 shared_ptr<
const MeshD<2>> dest_mesh,
498 shared_ptr<
const MeshD<2>> dest_mesh,