Skip to content

Commit

Permalink
Merge pull request #369 from fhagemann/ADLChargeDriftModel
Browse files Browse the repository at this point in the history
Add constructor for `ADLChargeDriftModel`
  • Loading branch information
fhagemann authored Feb 5, 2024
2 parents 3beacd0 + b0039fe commit 1677a03
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 79 deletions.
22 changes: 11 additions & 11 deletions docs/src/man/charge_drift.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,30 @@ The parameters $\mu_{0}$, $E_{0}$ and $\beta$ differ for electrons and holes, an

```yaml
model: ADLChargeDriftModel
phi110: -0.785398
phi110: -45°
material: HPGe
drift:
velocity:
model: Bruyneel2006
parameters:
e100:
mu0: 3.8609
mu0: 38609cm^2/(V*s)
beta: 0.805
E0: 51100
mun: -0.0171
E0: 511V/cm
mun: -171cm^2/(V*s)
e111:
mu0: 3.8536
mu0: 38536cm^2/(V*s)
beta: 0.641
E0: 53800
mun: 0.051
E0: 538V/cm
mun: 510cm^2/(V*s)
h100:
mu0: 6.1824
mu0: 61824cm^2/(V*s)
beta: 0.942
E0: 18500
E0: 185V/cm
h111:
mu0: 6.1215
mu0: 61215cm^2/(V*s)
beta: 0.662
E0: 18200
E0: 182V/cm
```
where the parameters are stored under the keys `e100`, `e111`, `h100` and `h111`, in which `e` and `h` stand for electrons and holes, respectively, and `100` and `111`, for the principal axes $\langle$100$\rangle$ and $\langle$111$\rangle$.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
model: ADLChargeDriftModel
phi110: -0.785398
material: HPGe
drift:
velocity:
model: Bruyneel2006
parameters:
e100:
mu0: 3.8609
beta: 0.805
E0: 51100
mun: -0.0171
e111:
mu0: 3.8536
beta: 0.641
E0: 53800
mun: 0.051
h100:
mu0: 6.1824
beta: 0.942
E0: 18500
h111:
mu0: 6.1215
beta: 0.662
E0: 18200
model: ADLChargeDriftModel
phi110: -45°
material: HPGe
drift:
velocity:
model: Bruyneel2006
parameters:
e100:
mu0: 38609cm^2/(V*s)
beta: 0.805
E0: 511V/cm
mun: -171cm^2/(V*s)
e111:
mu0: 38536cm^2/(V*s)
beta: 0.641
E0: 538V/cm
mun: 510cm^2/(V*s)
h100:
mu0: 61824cm^2/(V*s)
beta: 0.942
E0: 185V/cm
h111:
mu0: 61215cm^2/(V*s)
beta: 0.662
E0: 182V/cm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
model: ADLChargeDriftModel
phi110: -0.785398
material: HPGe
drift:
velocity:
model: Bruyneel2006
parameters:
e100:
mu0: 3.8609
beta: 0.805
E0: 51100
mun: -0.0171
e111:
mu0: 3.8536
beta: 0.641
E0: 53800
mun: 0.051
h100:
mu0: 6.1824
beta: 0.942
E0: 18500
h111:
mu0: 6.1215
beta: 0.662
E0: 18200
121 changes: 86 additions & 35 deletions src/ChargeDriftModels/ADLChargeDriftModel/ADLChargeDriftModel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,39 +159,88 @@ function ADLChargeDriftModel{T,M,N,TM}(chargedriftmodel::ADLChargeDriftModel{<:A
end


ADLChargeDriftModel{T}(args...; kwargs...) where {T <: SSDFloat} = ADLChargeDriftModel(args..., T=T, kwargs...)
function ADLChargeDriftModel(configfilename::Union{Missing, AbstractString} = missing; T::Type=Float32, material::Type{<:AbstractDriftMaterial} = HPGe,
temperature::Union{Missing, Real}= missing, phi110::Union{Missing, Real} = missing)::ADLChargeDriftModel{T}

if ismissing(configfilename) configfilename = joinpath(get_path_to_example_config_files(), "ADLChargeDriftModel/drift_velocity_config.yaml") end
if !ismissing(temperature) temperature = T(temperature) end #if you give the temperature it will be used, otherwise read from config file

config = parse_config_file(configfilename)

#mu0 in m^2 / ( V * s )
#beta dimensionless
#E0 in V / m
#mun in m^2 / ( V * s )

e100mu0::T = config["drift"]["velocity"]["parameters"]["e100"]["mu0"]
e100beta::T = config["drift"]["velocity"]["parameters"]["e100"]["beta"]
e100E0::T = config["drift"]["velocity"]["parameters"]["e100"]["E0"]
e100mun::T = config["drift"]["velocity"]["parameters"]["e100"]["mun"]
e111mu0::T = config["drift"]["velocity"]["parameters"]["e111"]["mu0"]
e111beta::T = config["drift"]["velocity"]["parameters"]["e111"]["beta"]
e111E0::T = config["drift"]["velocity"]["parameters"]["e111"]["E0"]
e111mun::T = config["drift"]["velocity"]["parameters"]["e111"]["mun"]
h100mu0::T = config["drift"]["velocity"]["parameters"]["h100"]["mu0"]
h100beta::T = config["drift"]["velocity"]["parameters"]["h100"]["beta"]
h100E0::T = config["drift"]["velocity"]["parameters"]["h100"]["E0"]
h111mu0::T = config["drift"]["velocity"]["parameters"]["h111"]["mu0"]
h111beta::T = config["drift"]["velocity"]["parameters"]["h111"]["beta"]
h111E0::T = config["drift"]["velocity"]["parameters"]["h111"]["E0"]

e100 = VelocityParameters{T}(e100mu0, e100beta, e100E0, e100mun)
e111 = VelocityParameters{T}(e111mu0, e111beta, e111E0, e111mun)
h100 = VelocityParameters{T}(h100mu0, h100beta, h100E0, 0)
h111 = VelocityParameters{T}(h111mu0, h111beta, h111E0, 0)

ADLChargeDriftModel{T}(args...; kwargs...) where {T <: SSDFloat} = ADLChargeDriftModel(args...; T=T, kwargs...)

const default_ADL_config_file = joinpath(get_path_to_example_config_files(), "ADLChargeDriftModel/drift_velocity_config.yaml")
function ADLChargeDriftModel(config_filename::AbstractString = default_ADL_config_file; kwargs...)
ADLChargeDriftModel(parse_config_file(config_filename); kwargs...)
end

# Check the syntax of the ADLChargeDriftModel config file before parsing
function ADLChargeDriftModel(config::AbstractDict; kwargs...)
if !haskey(config, "drift")
throw(ConfigFileError("ADLChargeDriftModel config file needs entry 'drift'."))
elseif !haskey(config["drift"], "velocity")
throw(ConfigFileError("ADLChargeDriftModel config file needs entry 'drift/velocity'."))
elseif !haskey(config["drift"]["velocity"], "parameters")
throw(ConfigFileError("ADLChargeDriftModel config file needs entry 'drift/velocity/parameters'."))
end

for axis in ("e100", "e111", "h100", "h111")
if !haskey(config["drift"]["velocity"]["parameters"], axis)
throw(ConfigFileError("ADLChargeDriftModel config file needs entry 'drift/velocity/parameters/$(axis)'."))
end
for param in ("mu0", "beta", "E0", "mun")
if !haskey(config["drift"]["velocity"]["parameters"][axis], param) && !(axis[1] == 'h' && param == "mun") # holes have no μn
throw(ConfigFileError("ADLChargeDriftModel config file needs entry 'drift/velocity/parameters/$(axis)/$(param)'."))
end
end
end
_ADLChargeDriftModel(config; kwargs...)
end


function _ADLChargeDriftModel(
config::AbstractDict;
T::Type=Float32,
e100μ0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e100"]["mu0"],
e100β::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e100"]["beta"],
e100E0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e100"]["E0"],
e100μn::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e100"]["mun"],
e111μ0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e111"]["mu0"],
e111β::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e111"]["beta"],
e111E0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e111"]["E0"],
e111μn::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["e111"]["mun"],
h100μ0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h100"]["mu0"],
h100β::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h100"]["beta"],
h100E0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h100"]["E0"],
h111μ0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h111"]["mu0"],
h111β::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h111"]["beta"],
h111E0::Union{RealQuantity,String} = config["drift"]["velocity"]["parameters"]["h111"]["E0"],
material::Type{<:AbstractDriftMaterial} = HPGe,
temperature::Union{Missing, Real}= missing,
phi110::Union{Missing, Real, AngleQuantity} = missing
)::ADLChargeDriftModel{T}

e100 = VelocityParameters{T}(
_parse_value(T, e100μ0, internal_mobility_unit),
_parse_value(T, e100β, NoUnits),
_parse_value(T, e100E0, internal_efield_unit),
_parse_value(T, e100μn, internal_mobility_unit)
)

e111 = VelocityParameters{T}(
_parse_value(T, e111μ0, internal_mobility_unit),
_parse_value(T, e111β, NoUnits),
_parse_value(T, e111E0, internal_efield_unit),
_parse_value(T, e111μn, internal_mobility_unit)
)

h100 = VelocityParameters{T}(
_parse_value(T, h100μ0, internal_mobility_unit),
_parse_value(T, h100β, NoUnits),
_parse_value(T, h100E0, internal_efield_unit),
0
)

h111 = VelocityParameters{T}(
_parse_value(T, h111μ0, internal_mobility_unit),
_parse_value(T, h111β, NoUnits),
_parse_value(T, h111E0, internal_efield_unit),
0
)

electrons = CarrierParameters{T}(e100, e111)
holes = CarrierParameters{T}(h100, h111)

Expand Down Expand Up @@ -219,16 +268,18 @@ function ADLChargeDriftModel(configfilename::Union{Missing, AbstractString} = mi

crystal_orientation::SMatrix{3,3,T,9} = if ismissing(phi110)
if "phi110" in keys(config)
RotZ{T}(- π/4 - config["phi110"] )
RotZ{T}(- π/4 - _parse_value(T, config["phi110"], u"rad"))
else
transpose(parse_rotation_matrix(T, config, u"rad")) # replace u"rad" with the units in the config file
end
else
RotZ{T}(- π/4 - phi110)
RotZ{T}(- π/4 - _parse_value(T, phi110, u"rad"))
end

γ = setup_γj(crystal_orientation, parameters, material)

if !ismissing(temperature) temperature = T(temperature) end #if you give the temperature it will be used, otherwise read from config file

if "temperature_dependence" in keys(config)
if "model" in keys(config["temperature_dependence"])
model::String = config["temperature_dependence"]["model"]
Expand Down
7 changes: 5 additions & 2 deletions src/ConstructiveSolidGeometry/IO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,11 @@ end

# parses dictionary entries of type Real or String to their value in internal units
@inline _parse_value(::Type{T}, x::Real, unit::Unitful.Units) where {T} = T(to_internal_units(float(x) * unit))
@inline _parse_value(::Type{T}, x::Quantity, unit::Unitful.Units) where {T} = T(ustrip(unit, x))
@inline _parse_value(::Type{T}, s::String, ::Unitful.Units) where {T} = T(to_internal_units(uparse(s)))
@inline _parse_value(::Type{T}, x::Quantity, unit::Unitful.Units) where {T} = begin
if dimension(x) != dimension(unit) throw(ConfigFileError("The quantity '$(x)' cannot be converted to unit '$(unit)'")) end
T(to_internal_units(float(x)))
end
@inline _parse_value(::Type{T}, s::String, unit::Unitful.Units) where {T} = _parse_value(T, uparse(s), unit)
@inline _parse_value(::Type{T}, a::AbstractVector, unit::Unitful.Units) where {T} = _parse_value.(T, a, unit)

# parses dictionary entries of type {"from": ..., "to": ... } to a Tuple of the interval boundaries
Expand Down
3 changes: 1 addition & 2 deletions src/SolidStateDetectors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export NBodyChargeCloud

const SSDFloat = Union{Float16, Float32, Float64}

include("examples.jl")

include("Units.jl")
include("Axes/DiscreteAxis.jl")
Expand Down Expand Up @@ -108,8 +109,6 @@ include("MCEventsProcessing/MCEventsProcessing.jl")

include("IO/IO.jl")

include("examples.jl")

include("PlotRecipes/PlotRecipes.jl")
export @P_str # protected strings to overwrite plot labels with units

Expand Down
3 changes: 3 additions & 0 deletions src/Units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const internal_voltage_unit = u"V"
const internal_energy_unit = u"eV"
const internal_efield_unit = internal_voltage_unit / internal_length_unit
const internal_charge_unit = u"C"
const internal_mobility_unit = u"m^2/(V*s)"
const internal_diffusion_unit = internal_length_unit ^ 2 / internal_time_unit
const internal_charge_density_unit = internal_charge_unit / internal_length_unit ^ 3

Expand All @@ -23,6 +24,7 @@ to_internal_units(x::Quantity{<:Real, dimension(internal_voltage_unit)}) = ustri
to_internal_units(x::Quantity{<:Real, dimension(internal_efield_unit)}) = ustrip(internal_efield_unit, x)
to_internal_units(x::Quantity{<:Real, dimension(internal_energy_unit)}) = ustrip(internal_energy_unit, x)
to_internal_units(x::Quantity{<:Real, dimension(internal_charge_unit)}) = ustrip(internal_charge_unit, x)
to_internal_units(x::Quantity{<:Real, dimension(internal_mobility_unit)}) = ustrip(internal_mobility_unit, x)
to_internal_units(x::Quantity{<:Real, dimension(internal_diffusion_unit)}) = ustrip(internal_diffusion_unit, x)
to_internal_units(x::Quantity{<:Real, dimension(internal_charge_density_unit)}) = ustrip(internal_charge_density_unit, x)

Expand All @@ -31,6 +33,7 @@ from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_volta
from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_efield_unit)}) = uconvert(unit, x * internal_efield_unit)
from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_energy_unit)}) = uconvert(unit, x * internal_energy_unit)
from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_charge_unit)}) = uconvert(unit, x * internal_charge_unit)
from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_mobility_unit)}) = uconvert(unit, x * internal_mobility_unit)
from_internal_units(x::Real, unit::Unitful.Units{<:Any, dimension(internal_diffusion_unit)}) = uconvert(unit, x * internal_diffusion_unit)

# Internal function for now: We should also fano noise here (optionally)
Expand Down
2 changes: 1 addition & 1 deletion src/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Returns the path to the example detector configuration files provided by the pac
See also [`SSD_examples`](@ref).
"""
function get_path_to_example_config_files()::String
return joinpath(@__DIR__, "../examples/example_config_files")
return joinpath(dirname(@__DIR__), "examples", "example_config_files")
end

"""
Expand Down
Loading

0 comments on commit 1677a03

Please sign in to comment.