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
960
961 MaterialWithBase() = default;
962 MaterialWithBase(const shared_ptr<Material>& base): base(base) {}
963 MaterialWithBase(Material* base): base(base) {}
964
965 Kind kind() const override;
966
967 double lattC(double T, char x) const override;
968 double Eg(double T, double e, char point) const override;
969 double CB(double T, double e, char point) const override;
970 double VB(double T, double e, char point, char hole) const override ;
971 double Dso(double T, double e) const override;
972 double Mso(double T, double e) const override;
973 Tensor2<double> Me(double T, double e, char point) const override;
974 Tensor2<double> Mhh(double T, double e) const override;
975 Tensor2<double> Mlh(double T, double e) const override;
976 Tensor2<double> Mh(double T, double e) const override;
977 double ac(double T) const override;
978 double av(double T) const override;
979 double b(double T) const override;
980 double d(double T) const override;
981 double c11(double T) const override;
982 double c12(double T) const override;
983 double c44(double T) const override;
984 double eps(double T) const override;
985 double chi(double T, double e, char point) const override;
986 double Na() const override;
987 double Nd() const override;
988 double Ni(double T) const override;
989 double Nf(double T) const override;
990 double EactD(double T) const override;
991 double EactA(double T) const override;
992 Tensor2<double> mob(double T) const override;
993 Tensor2<double> cond(double T) const override;
994 double A(double T) const override;
995 double B(double T) const override;
996 double C(double T) const override;
997 double D(double T) const override;
998 Tensor2<double> thermk(double T, double t) const override;
999 double dens(double T) const override;
1000 double cp(double T) const override;
1001 double nr(double lam, double T, double n) const override;
1002 double absp(double lam, double T) const override;
1003 dcomplex Nr(double lam, double T, double n) const override;
1004 Tensor3<dcomplex> Eps(double lam, double T, double n) const override;
1005 Tensor2<double> mobe(double T) const override;
1006 Tensor2<double> mobh(double T) const override;
1007 double taue(double T) const override;
1008 double tauh(double T) const override;
1009 double Ce(double T) const override;
1010 double Ch(double T) const override;
1011 double e13(double T) const override;
1012 double e15(double T) const override;
1013 double e33(double T) const override;
1014 double c13(double T) const override;
1015 double c33(double T) const override;
1016 double Psp(double T) const override;
1017 double y1() const override;
1018 double y2() const override;
1019 double y3() const override;
1020};
1021
1023 plask::optional<double> lattC;
1024 plask::optional<double> Eg;
1025 plask::optional<double> CB;
1026 plask::optional<double> VB;
1027 plask::optional<double> Dso;
1028 plask::optional<double> Mso;
1033 plask::optional<double> ac;
1034 plask::optional<double> av;
1035 plask::optional<double> b;
1036 plask::optional<double> d;
1037 plask::optional<double> c11;
1038 plask::optional<double> c12;
1039 plask::optional<double> c44;
1040 plask::optional<double> eps;
1042 plask::optional<double> chi;
1043 plask::optional<double> Na;
1044 plask::optional<double> Nd;
1045 plask::optional<double> Ni;
1046 plask::optional<double> Nf;
1047 plask::optional<double> EactD;
1048 plask::optional<double> EactA;
1051 plask::optional<double> A;
1052 plask::optional<double> B;
1053 plask::optional<double> C;
1054 plask::optional<double> D;
1056 plask::optional<double> dens;
1057 plask::optional<double> cp;
1058 plask::optional<double> nr;
1059 plask::optional<double> absp;
1060 plask::optional<dcomplex> Nr;
1063 plask::optional<double> taue;
1064 plask::optional<double> tauh;
1065 plask::optional<double> Ce;
1066 plask::optional<double> Ch;
1067 plask::optional<double> e13;
1068 plask::optional<double> e15;
1069 plask::optional<double> e33;
1070 plask::optional<double> c13;
1071 plask::optional<double> c33;
1072 plask::optional<double> Psp;
1073 plask::optional<double> y1;
1074 plask::optional<double> y2;
1075 plask::optional<double> y3;
1076
1077 bool operator==(const MaterialCache& other) const {
1078 return
1079 lattC == other.lattC &&
1080 Eg == other.Eg &&
1081 CB == other.CB &&
1082 VB == other.VB &&
1083 Dso == other.Dso &&
1084 Mso == other.Mso &&
1085 Me == other.Me &&
1086 Mhh == other.Mhh &&
1087 Mlh == other.Mlh &&
1088 Mh == other.Mh &&
1089 ac == other.ac &&
1090 av == other.av &&
1091 b == other.b &&
1092 d == other.d &&
1093 c11 == other.c11 &&
1094 c12 == other.c12 &&
1095 c44 == other.c44 &&
1096 eps == other.eps &&
1097 chi == other.chi &&
1098 Na == other.Na &&
1099 Nd == other.Nd &&
1100 Ni == other.Ni &&
1101 Nf == other.Nf &&
1102 EactD == other.EactD &&
1103 EactA == other.EactA &&
1104 mob == other.mob &&
1105 cond == other.cond &&
1106 A == other.A &&
1107 B == other.B &&
1108 C == other.C &&
1109 D == other.D &&
1110 thermk == other.thermk &&
1111 dens == other.dens &&
1112 cp == other.cp &&
1113 nr == other.nr &&
1114 absp == other.absp &&
1115 Nr == other.Nr &&
1116 Eps == other.Eps &&
1117 mobe == other.mobe &&
1118 mobh == other.mobh &&
1119 taue == other.taue &&
1120 tauh == other.tauh &&
1121 Ce == other.Ce &&
1122 Ch == other.Ch &&
1123 e13 == other.e13 &&
1124 e15 == other.e15 &&
1125 e33 == other.e33 &&
1126 c13 == other.c13 &&
1127 c33 == other.c33 &&
1128 Psp == other.Psp &&
1129 y1 == other.y1 &&
1130 y2 == other.y2 &&
1131 y3 == other.y3;
1132 }
1133};
1134
1135
1136
1137} // namespace plask
1138
1139#endif //PLASK__MATERIAL_H