Skip to content

Commit 5a0345b

Browse files
authored
Add effective DOS and energy band gap model
Add effective DOS and energy band gap model
2 parents ddaaccb + d7f7a06 commit 5a0345b

File tree

8 files changed

+271
-9
lines changed

8 files changed

+271
-9
lines changed

tests/test_components/test_heat_charge.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from tidy3d.components.tcad.types import (
1212
AugerRecombination,
1313
CaugheyThomasMobility,
14+
ConstantEffectiveDOS,
15+
ConstantEnergyBandGap,
1416
SlotboomBandGapNarrowing,
1517
)
1618
from tidy3d.exceptions import DataError
@@ -39,9 +41,9 @@ class CHARGE_SIMULATION:
3941
permittivity=11.7,
4042
N_d=0,
4143
N_a=0,
42-
N_c=2.86e19,
43-
N_v=3.1e19,
44-
E_g=1.11,
44+
N_c=ConstantEffectiveDOS(N=2.86e19),
45+
N_v=ConstantEffectiveDOS(N=3.1e19),
46+
E_g=ConstantEnergyBandGap(eg=1.11),
4547
mobility_n=CaugheyThomasMobility(
4648
mu_min=52.2,
4749
mu=1471.0,

tidy3d/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,24 @@
6767
from tidy3d.components.tcad.types import (
6868
AugerRecombination,
6969
CaugheyThomasMobility,
70+
ConstantEffectiveDOS,
71+
ConstantEnergyBandGap,
7072
ConstantMobilityModel,
7173
ConvectionBC,
7274
CurrentBC,
75+
DualValleyEffectiveDOS,
7376
HeatFluxBC,
7477
HeatFromElectricSource,
7578
HeatSource,
7679
InsulatingBC,
80+
IsotropicEffectiveDOS,
81+
MultiValleyEffectiveDOS,
7782
RadiativeRecombination,
7883
ShockleyReedHallRecombination,
7984
SlotboomBandGapNarrowing,
8085
TemperatureBC,
8186
UniformHeatSource,
87+
VarshniEnergyBandGap,
8288
VoltageBC,
8389
)
8490

@@ -450,6 +456,8 @@ def set_logging_level(level: str) -> None:
450456
"ClipOperation",
451457
"CoaxialLumpedResistor",
452458
"ConstantDoping",
459+
"ConstantEffectiveDOS",
460+
"ConstantEnergyBandGap",
453461
"ConstantMobilityModel",
454462
"ContinuousWave",
455463
"ContinuousWaveTimeModulation",
@@ -488,6 +496,7 @@ def set_logging_level(level: str) -> None:
488496
"DirectivityMonitor",
489497
"DistanceUnstructuredGrid",
490498
"Drude",
499+
"DualValleyEffectiveDOS",
491500
"EMECoefficientData",
492501
"EMECoefficientDataArray",
493502
"EMECoefficientDataset",
@@ -579,6 +588,7 @@ def set_logging_level(level: str) -> None:
579588
"IndexedVoltageDataArray",
580589
"InsulatingBC",
581590
"IsothermalSteadyChargeDCAnalysis",
591+
"IsotropicEffectiveDOS",
582592
"KerrNonlinearity",
583593
"LayerRefinementSpec",
584594
"LinearChargePerturbation",
@@ -606,6 +616,7 @@ def set_logging_level(level: str) -> None:
606616
"ModulationSpec",
607617
"Monitor",
608618
"MultiPhysicsMedium",
619+
"MultiValleyEffectiveDOS",
609620
"NedeljkovicSorefMashanovich",
610621
"NonlinearModel",
611622
"NonlinearSpec",
@@ -696,6 +707,7 @@ def set_logging_level(level: str) -> None:
696707
"UnsteadyHeatAnalysis",
697708
"UnsteadySpec",
698709
"Updater",
710+
"VarshniEnergyBandGap",
699711
"VisualizationSpec",
700712
"VoltageBC",
701713
"VoltageSourceType",

tidy3d/components/material/tcad/charge.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from tidy3d.components.tcad.doping import DopingBoxType
1010
from tidy3d.components.tcad.types import (
1111
BandGapNarrowingModelType,
12+
EffectiveDOSModelType,
13+
EnergyBandGapModelType,
1214
MobilityModelType,
1315
RecombinationModelType,
1416
)
@@ -254,21 +256,21 @@ class SemiconductorMedium(AbstractChargeMedium):
254256
255257
"""
256258

257-
N_c: pd.PositiveFloat = pd.Field(
259+
N_c: EffectiveDOSModelType = pd.Field(
258260
...,
259261
title="Effective density of electron states",
260262
description=r"$N_c$ Effective density of states in the conduction band.",
261263
units="cm^(-3)",
262264
)
263265

264-
N_v: pd.PositiveFloat = pd.Field(
266+
N_v: EffectiveDOSModelType = pd.Field(
265267
...,
266268
title="Effective density of hole states",
267269
description=r"$N_v$ Effective density of states in the valence band.",
268270
units="cm^(-3)",
269271
)
270272

271-
E_g: pd.PositiveFloat = pd.Field(
273+
E_g: EnergyBandGapModelType = pd.Field(
272274
...,
273275
title="Band-gap energy",
274276
description="Band-gap energy",
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from __future__ import annotations
2+
3+
import pydantic.v1 as pd
4+
5+
from tidy3d.components.base import Tidy3dBaseModel
6+
from tidy3d.constants import ELECTRON_VOLT
7+
8+
9+
class ConstantEnergyBandGap(Tidy3dBaseModel):
10+
"""Constant Energy band gap"""
11+
12+
eg: pd.PositiveFloat = pd.Field(
13+
title="Band Gap",
14+
description="Energy band gap",
15+
units=ELECTRON_VOLT,
16+
)
17+
18+
19+
class VarshniEnergyBandGap(Tidy3dBaseModel):
20+
"""
21+
Models the temperature dependence of the energy band gap (Eg)
22+
using the Varshni formula.
23+
24+
Notes
25+
-----
26+
The model implements the following formula:
27+
28+
.. math::
29+
30+
E_g(T) = E_g(0) - \\frac{\\alpha T^2}{T + \\beta}$
31+
32+
Example
33+
-------
34+
>>> # Parameters for Silicon (Si)
35+
>>> si_model = VarshniEnergyBandGap(
36+
... eg_0=1.17,
37+
... alpha=4.73e-4,
38+
... beta=636.0,
39+
... )
40+
41+
References
42+
-------
43+
44+
Varshni, Y. P. (1967). Temperature dependence of the energy gap in semiconductors. Physica, 34(1), 149-154.
45+
46+
"""
47+
48+
eg_0: pd.PositiveFloat = pd.Field(
49+
...,
50+
title="Band Gap at 0 K",
51+
description="Energy band gap at absolute zero (0 Kelvin).",
52+
units=ELECTRON_VOLT,
53+
)
54+
55+
alpha: pd.PositiveFloat = pd.Field(
56+
...,
57+
title="Varshni Alpha Coefficient",
58+
description="Empirical Varshni coefficient (α).",
59+
units="eV/K",
60+
)
61+
62+
beta: pd.PositiveFloat = pd.Field(
63+
...,
64+
title="Varshni Beta Coefficient",
65+
description="Empirical Varshni coefficient (β), related to the Debye temperature.",
66+
units="K",
67+
)
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from __future__ import annotations
2+
3+
from abc import ABC, abstractmethod
4+
5+
import numpy as np
6+
import pydantic.v1 as pd
7+
8+
from tidy3d.components.base import Tidy3dBaseModel
9+
from tidy3d.constants import HBAR, K_B, M_E_EV
10+
from tidy3d.exceptions import DataError
11+
12+
um_3_to_cm_3 = 1e12 # conversion factor from micron^(-3) to cm^(-3)
13+
DOS_aux_const = 2.0 * np.power((M_E_EV * K_B) / (2 * np.pi * HBAR * HBAR), 1.5) * um_3_to_cm_3
14+
15+
16+
class EffectiveDOS(Tidy3dBaseModel, ABC):
17+
"""Abstract class for the effective density of states"""
18+
19+
@abstractmethod
20+
def calc_eff_dos(self, T: float):
21+
"""Abstract method to calculate the effective density of states."""
22+
23+
@abstractmethod
24+
def calc_eff_dos_derivative(self, T: float):
25+
"""Abstract method to calculate the temperature derivative of the effective density of states."""
26+
27+
def get_effective_DOS(self, T: float):
28+
if T <= 0:
29+
raise DataError(
30+
f"Incorrect temperature value ({T}) for the effective density of states calculation."
31+
)
32+
33+
return self.calc_eff_dos(T)
34+
35+
def get_effective_DOS_derivative(self, T: float):
36+
if T <= 0:
37+
raise DataError(
38+
f"Incorrect temperature value ({T}) for the effectve density of states calculation."
39+
)
40+
41+
return self.calc_eff_dos_derivative(T)
42+
43+
44+
class ConstantEffectiveDOS(EffectiveDOS):
45+
"""Constant effective density of states model."""
46+
47+
N: pd.PositiveFloat = pd.Field(
48+
..., title="Effective DOS", description="Effective density of states", units="cm^(-3)"
49+
)
50+
51+
def calc_eff_dos(self, T: float):
52+
return self.N
53+
54+
def calc_eff_dos_derivative(self, T: float):
55+
return 0.0
56+
57+
58+
class IsotropicEffectiveDOS(EffectiveDOS):
59+
"""Effective density of states model that assumes single valley and isotropic effective mass.
60+
The model assumes the standard equation for the 3D semiconductor with parabolic energy dispersion:
61+
62+
.. math::
63+
64+
\\begin{equation}
65+
\\mathbf{N_eff} = 2 * (\\frac{m_eff * m_e * k_B T}{2 \\pi \\hbar^2})^(3/2)
66+
\\end{equation}
67+
"""
68+
69+
m_eff: pd.PositiveFloat = pd.Field(
70+
...,
71+
title="Effective mass",
72+
description="Effective mass of the carriers",
73+
units="Electron mass",
74+
)
75+
76+
def calc_eff_dos(self, T: float):
77+
return np.power(self.m_eff * T, 1.5) * DOS_aux_const
78+
79+
def calc_eff_dos_derivative(self, T: float):
80+
return self.calc_eff_dos(T) * 1.5 / T
81+
82+
83+
class MultiValleyEffectiveDOS(EffectiveDOS):
84+
"""Effective density of states model that assumes multiple equivalent valleys and anisotropic effective mass.
85+
The model assumes the standard equation for the 3D semiconductor with parabolic energy dispersion:
86+
87+
.. math::
88+
89+
\\begin{equation}
90+
\\mathbf{N_eff} = 2 * N_valley * (m_{eff_long} * m_{eff_trans} * m_{eff_trans})^(1/2) *(\\frac{m_e * k_B * T}{2 \\pi * \\hbar^2})^(3/2)
91+
\\end{equation}
92+
"""
93+
94+
m_eff_long: pd.PositiveFloat = pd.Field(
95+
...,
96+
title="Longitudinal effective mass",
97+
description="Effective mass of the carriers in the longitudinal direction",
98+
units="Electron mass",
99+
)
100+
101+
m_eff_trans: pd.PositiveFloat = pd.Field(
102+
...,
103+
title="Longitudinal effective mass",
104+
description="Effective mass of the carriers in the transverse direction",
105+
units="Electron mass",
106+
)
107+
108+
N_valley: pd.PositiveFloat = pd.Field(
109+
..., title="Number of valleys", description="Number of effective valleys"
110+
)
111+
112+
def calc_eff_dos(self, T: float):
113+
return (
114+
self.N_valley
115+
* np.power(self.m_eff_long * self.m_eff_trans * self.m_eff_trans, 0.5)
116+
* np.power(T, 1.5)
117+
* DOS_aux_const
118+
)
119+
120+
def calc_eff_dos_derivative(self, T: float):
121+
return self.calc_eff_dos(T) * 1.5 / T
122+
123+
124+
class DualValleyEffectiveDOS(EffectiveDOS):
125+
"""Effective density of states model that assumes combination of light holes and heavy holes with isotropic effective masses.
126+
The model assumes the standard equation for the 3D semiconductor with parabolic energy dispersion:
127+
128+
.. math::
129+
130+
\\begin{equation}
131+
\\mathbf{N_eff} = 2 * ( {\\frac{m_{eff_lh} * m_e * k_B * T}{2 \\pi \\hbar^2})^(3/2) + (\\frac{m_{eff_hh} * m_e * k_B * T}{2 \\pi \\hbar^2})^(3/2) )
132+
\\end{equation}
133+
"""
134+
135+
m_eff_lh: pd.PositiveFloat = pd.Field(
136+
...,
137+
title="Light hole effective mass",
138+
description="Effective mass of the light holes",
139+
units="Electron mass",
140+
)
141+
142+
m_eff_hh: pd.PositiveFloat = pd.Field(
143+
...,
144+
title="Heavy hole effective mass",
145+
description="Effective mass of the heavy holes",
146+
units="Electron mass",
147+
)
148+
149+
def calc_eff_dos(self, T: float):
150+
return (np.power(self.m_eff_lh * T, 1.5) + np.power(self.m_eff_hh * T, 1.5)) * DOS_aux_const
151+
152+
def calc_eff_dos_derivative(self, T: float):
153+
return self.calc_eff_dos(T) * 1.5 / T

tidy3d/components/tcad/types.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,18 @@
33
from __future__ import annotations
44

55
from tidy3d.components.tcad.bandgap import SlotboomBandGapNarrowing
6+
from tidy3d.components.tcad.bandgap_energy import (
7+
ConstantEnergyBandGap,
8+
VarshniEnergyBandGap,
9+
)
610
from tidy3d.components.tcad.boundary.charge import CurrentBC, InsulatingBC, VoltageBC
711
from tidy3d.components.tcad.boundary.heat import ConvectionBC, HeatFluxBC, TemperatureBC
12+
from tidy3d.components.tcad.effective_DOS import (
13+
ConstantEffectiveDOS,
14+
DualValleyEffectiveDOS,
15+
IsotropicEffectiveDOS,
16+
MultiValleyEffectiveDOS,
17+
)
818
from tidy3d.components.tcad.generation_recombination import (
919
AugerRecombination,
1020
RadiativeRecombination,
@@ -23,6 +33,10 @@
2333
from tidy3d.components.tcad.source.heat import HeatSource, UniformHeatSource
2434
from tidy3d.components.types import Union
2535

36+
EffectiveDOSModelType = Union[
37+
ConstantEffectiveDOS, IsotropicEffectiveDOS, MultiValleyEffectiveDOS, DualValleyEffectiveDOS
38+
]
39+
EnergyBandGapModelType = Union[ConstantEnergyBandGap, VarshniEnergyBandGap]
2640
MobilityModelType = Union[CaugheyThomasMobility, ConstantMobilityModel]
2741
RecombinationModelType = Union[
2842
AugerRecombination, RadiativeRecombination, ShockleyReedHallRecombination

tidy3d/constants.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@
5353
Boltzmann constant [eV/K]
5454
"""
5555

56+
M_E_C_SQUARE = 0.51099895069e6
57+
"""
58+
Electron rest mass energy (m_e * c^2) [eV]
59+
"""
60+
61+
M_E_EV = M_E_C_SQUARE / C_0**2
62+
"""
63+
Electron mass [eV*s^2/um^2]
64+
"""
65+
5666
# floating point precisions
5767
dp_eps = np.finfo(np.float64).eps
5868
"""

0 commit comments

Comments
 (0)