PLaSK library
Loading...
Searching...
No Matches
material.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__MATERIAL_H
15#define PLASK__MATERIAL_H
16
21#include <string>
22#include <map>
23#include <vector>
24#include <functional>
25#include <tuple>
26#include <type_traits>
27
28#include "../math.hpp"
29#include "../memory.hpp"
30#include "../exceptions.hpp"
31#include "../phys/constants.hpp"
32#include "../phys/functions.hpp"
33#include "../vector/tensor2.hpp"
34#include "../vector/tensor3.hpp"
35#include "../parallel.hpp"
36#include "../optional.hpp"
37
38#define RETURN_MATERIAL_NAN(param) \
39 static bool warn = true; \
40 if (warn) { writelog(LOG_WARNING, "Material {}: non-applicable parameter " BOOST_PP_STRINGIZE(param) " returned as NAN", name()); warn = false; } \
41 return NAN;
42
43namespace plask {
44
47
53int elementGroup(const std::string& objectName);
54
55struct MaterialsDB;
56
61
63 enum Kind: unsigned {
64 GENERIC = (1<<0),
65 EMPTY = (1<<1),
66 SEMICONDUCTOR = (1<<2),
67 OXIDE = (1<<3),
68 DIELECTRIC = (1<<4),
69 METAL = (1<<5),
70 LIQUID_CRYSTAL = (1<<6),
71 MIXED = (1<<7)
72 };
73
82
86 typedef std::map<std::string, double> Composition;
87
88
89 private:
90
92 template <typename MaterialType>
93 struct is_with_composition {
94 static const bool value =
95 std::is_constructible<MaterialType, Composition>::value ||
96 std::is_constructible<MaterialType, Composition, double>::value;
97 };
98
100 template <typename MaterialType>
101 struct is_with_dopant {
102 static const bool value =
103 std::is_constructible<MaterialType, double>::value ||
104 std::is_constructible<MaterialType, Composition, double>::value;
105 };
106
107 friend struct MaterialsDB;
108
109 public:
110
116 static bool isNameWithDopant(const std::string& material_name) { return material_name.find(':') != std::string::npos; }
117
118
119
125 static bool isSimpleMaterialName(const std::string &material_name) {
126 auto brace = material_name.find('(');
127 return brace == std::string::npos || brace == 0;
128 }
129
139
141 std::string name;
142
144 std::string label;
145
148
150 std::string dopant;
151
153 double doping;
154
156 Parameters(): doping(0.) {}
157
165 explicit Parameters(const std::string& full_name, bool allow_dopant_without_amount = false)
166 { parse(full_name, allow_dopant_without_amount); }
167
168 bool operator==(const Parameters& other) const {
169 return name == other.name && label == other.label && composition == other.composition &&
170 dopant == other.dopant && doping == other.doping;
171 }
172
177 bool isAlloy() const { return !composition.empty(); }
178
183 bool hasDopantName() const { return !dopant.empty(); }
184
189 bool hasDoping() const { return !isnan(doping) && hasDopantName(); }
190
198 void parse(const std::string& full_material_str, bool allow_dopant_without_amount = false);
199
204 Composition completeComposition() const;
205
210 void setDoping(const std::string& dopant, double doping);
211
215 void clearDoping() {
216 setDoping("", 0.);
217 }
218
222 std::string str() const;
223 };
224
239
241 std::stringstream str;
242
247 operator std::string() const { return str.str(); }
248
254 StringBuilder& operator()(const std::string& objectName) { str << objectName; return *this; }
255
260 StringBuilder(const std::string& objectName) {
261 this->operator ()(objectName);
262 }
263
270 StringBuilder& operator()(const std::string& objectName, double ammount);
271
277 StringBuilder(const std::string& objectName, double ammount) {
278 this->operator ()(objectName, ammount);
279 }
280
287 std::string dopant(const std::string& dopant, double dopantConcentration);
288 };
289
297 static std::pair<std::string, double> firstCompositionObject(const char*& begin, const char* end, const char* fullname);
298
306 static Composition completeComposition(const Composition& composition);
307
315 static Composition minimalComposition(const Composition& composition);
316
325 static Composition parseComposition(const char* begin, const char* end, const char* fullname = nullptr);
326
335 static Composition parseComposition(const std::string& composition_str, const std::string& fullname = "");
336
346 static void parseDopant(const char* begin, const char* end, std::string& dopant_elem_name, double& doping, bool allow_dopant_without_amount, const char* fullname);
347
357 static void parseDopant(const std::string& dopant, std::string& dopant_elem_name, double& doping, bool allow_dopant_without_amount, const std::string& fullname);
358
365 static std::vector<std::string> parseObjectsNames(const char* begin, const char* end);
366
373 static std::vector<std::string> parseObjectsNames(const std::string& allNames);
374
378 virtual OmpLockGuard lock() const {
379 return OmpLockGuard();
380 }
381
383 virtual ~Material() {}
384
389 virtual std::string name() const = 0;
390
395 std::string dopant() const;
396
401 std::string nameWithoutDopant() const;
402
410 virtual std::string str() const;
411
416 bool isAlloy() const;
417
422 virtual Composition composition() const;
423
427 virtual double doping() const;
428
430 virtual Kind kind() const = 0;
431
438 virtual double lattC(double T, char x) const;
439
447 virtual double Eg(double T, double e=0., char point='*') const;
448
456 virtual double CB(double T, double e=0., char point='*') const;
457
466 virtual double VB(double T, double e=0., char point='*', char hole='H') const;
467
474 virtual double Dso(double T, double e=0.) const;
475
482 virtual double Mso(double T, double e=0.) const;
483
491 virtual Tensor2<double> Me(double T, double e=0., char point='*') const;
492
499 virtual Tensor2<double> Mhh(double T, double e=0.) const;
500
507 virtual Tensor2<double> Mlh(double T, double e=0.) const;
508
515 virtual Tensor2<double> Mh(double T, double e=0.) const;
516
521 virtual double y1() const;
522
527 virtual double y2() const;
528
533 virtual double y3() const;
534
540 virtual double ac(double T) const;
541
547 virtual double av(double T) const;
548
554 virtual double b(double T) const;
555
561 virtual double d(double T) const;
562
568 virtual double c11(double T) const;
569
575 virtual double c12(double T) const;
576
582 virtual double c44(double T) const;
583
589 virtual double eps(double T) const;
590
598 virtual Tensor3<dcomplex> Eps(double lam, double T, double n = 0) const;
599
607 virtual double chi(double T, double e=0., char point='*') const;
608
614 virtual double Ni(double T) const;
615
621 virtual double Nf(double T) const;
622
628 virtual double EactD(double T) const;
629
635 virtual double EactA(double T) const;
636
642 virtual Tensor2<double> mob(double T) const;
643
649 virtual Tensor2<double> cond(double T) const;
650
655 virtual ConductivityType condtype() const;
656
662 virtual double A(double T) const;
663
669 virtual double B(double T) const;
670
676 virtual double C(double T) const;
677
683 virtual double D(double T) const;
684
691 virtual Tensor2<double> thermk(double T, double h=INFINITY) const;
692
698 virtual double dens(double T) const;
699
705 virtual double cp(double T) const;
706
714 virtual double nr(double lam, double T, double n = 0) const;
715
723 virtual double absp(double lam, double T) const;
724
731 virtual dcomplex Nr(double lam, double T, double n = 0) const;
732
738 virtual Tensor2<double> mobe(double T) const;
739
745 virtual Tensor2<double> mobh(double T) const;
746
752 virtual double taue(double T) const;
753
759 virtual double tauh(double T) const;
760
766 virtual double Ce(double T) const;
767
773 virtual double Ch(double T) const;
774
780 virtual double e13(double T) const;
781
787 virtual double e15(double T) const;
788
794 virtual double e33(double T) const;
795
801 virtual double c13(double T) const;
802
808 virtual double c33(double T) const;
809
815 virtual double Psp(double T) const;
816
821 virtual double Na() const;
822
827 virtual double Nd() const;
828
829
830
836 bool operator==(const Material& other) const;
837
844 return other ? this->operator==(*other) : false;
845 }
846
852 bool operator!=(const Material& other) const { return !this->operator==(other); }
853
859 bool operator!=(shared_ptr<const Material> other) const { return !this->operator==(other); }
860
861protected:
862
872 virtual bool isEqual(const Material& other) const;
873
878 [[noreturn]] void throwNotImplemented(const std::string& method_name) const;
879};
880
881
886
887 protected:
888 std::string _name;
889
890 public:
891
892 DummyMaterial(const std::string name): _name(name) {}
893
894 std::string name() const override { return _name; }
895
896 Kind kind() const override { return GENERIC; }
897};
898
903 static constexpr const char* NAME = "semiconductor";
904 std::string name() const override;
905 Kind kind() const override;
906};
907
911struct PLASK_API Metal: public Material {
912 static constexpr const char* NAME = "metal";
913 std::string name() const override;
914 Kind kind() const override;
915 double eps(double T) const override;
916
917};
918
922struct PLASK_API Oxide: public Material {
923 static constexpr const char* NAME = "oxide";
924 std::string name() const override;
925 Kind kind() const override;
926};
927
932 static constexpr const char* NAME = "dielectric";
933 std::string name() const override;
934 Kind kind() const override;
935};
936
941 static constexpr const char* NAME = "liquid_crystal";
942 std::string name() const override;
943 Kind kind() const override;
944};
945
950 std::string name() const override { return ""; }
951 Material::Kind kind() const override { return Material::GENERIC; }
952 bool isEqual(const Material&) const override { return true; } // all generic materials are always equal
953};
954
965
967 plask::optional<double> lattC;
968 plask::optional<double> Eg;
969 plask::optional<double> CB;
970 plask::optional<double> VB;
971 plask::optional<double> Dso;
972 plask::optional<double> Mso;
977 plask::optional<double> ac;
978 plask::optional<double> av;
979 plask::optional<double> b;
980 plask::optional<double> d;
981 plask::optional<double> c11;
982 plask::optional<double> c12;
983 plask::optional<double> c44;
984 plask::optional<double> eps;
986 plask::optional<double> chi;
987 plask::optional<double> Na;
988 plask::optional<double> Nd;
989 plask::optional<double> Ni;
990 plask::optional<double> Nf;
991 plask::optional<double> EactD;
992 plask::optional<double> EactA;
995 plask::optional<double> A;
996 plask::optional<double> B;
997 plask::optional<double> C;
998 plask::optional<double> D;
1000 plask::optional<double> dens;
1001 plask::optional<double> cp;
1002 plask::optional<double> nr;
1003 plask::optional<double> absp;
1004 plask::optional<dcomplex> Nr;
1007 plask::optional<double> taue;
1008 plask::optional<double> tauh;
1009 plask::optional<double> Ce;
1010 plask::optional<double> Ch;
1011 plask::optional<double> e13;
1012 plask::optional<double> e15;
1013 plask::optional<double> e33;
1014 plask::optional<double> c13;
1015 plask::optional<double> c33;
1016 plask::optional<double> Psp;
1017 plask::optional<double> y1;
1018 plask::optional<double> y2;
1019 plask::optional<double> y3;
1020
1021 bool operator==(const MaterialCache& other) const {
1022 return
1023 lattC == other.lattC &&
1024 Eg == other.Eg &&
1025 CB == other.CB &&
1026 VB == other.VB &&
1027 Dso == other.Dso &&
1028 Mso == other.Mso &&
1029 Me == other.Me &&
1030 Mhh == other.Mhh &&
1031 Mlh == other.Mlh &&
1032 Mh == other.Mh &&
1033 ac == other.ac &&
1034 av == other.av &&
1035 b == other.b &&
1036 d == other.d &&
1037 c11 == other.c11 &&
1038 c12 == other.c12 &&
1039 c44 == other.c44 &&
1040 eps == other.eps &&
1041 chi == other.chi &&
1042 Na == other.Na &&
1043 Nd == other.Nd &&
1044 Ni == other.Ni &&
1045 Nf == other.Nf &&
1046 EactD == other.EactD &&
1047 EactA == other.EactA &&
1048 mob == other.mob &&
1049 cond == other.cond &&
1050 A == other.A &&
1051 B == other.B &&
1052 C == other.C &&
1053 D == other.D &&
1054 thermk == other.thermk &&
1055 dens == other.dens &&
1056 cp == other.cp &&
1057 nr == other.nr &&
1058 absp == other.absp &&
1059 Nr == other.Nr &&
1060 Eps == other.Eps &&
1061 mobe == other.mobe &&
1062 mobh == other.mobh &&
1063 taue == other.taue &&
1064 tauh == other.tauh &&
1065 Ce == other.Ce &&
1066 Ch == other.Ch &&
1067 e13 == other.e13 &&
1068 e15 == other.e15 &&
1069 e33 == other.e33 &&
1070 c13 == other.c13 &&
1071 c33 == other.c33 &&
1072 Psp == other.Psp &&
1073 y1 == other.y1 &&
1074 y2 == other.y2 &&
1075 y3 == other.y3;
1076 }
1077};
1078
1079} // namespace plask
1080
1081#endif //PLASK__MATERIAL_H