Skip to content

Commit 5f3a5cb

Browse files
authored
Refactor boule impurity densities (#477)
* refactor boule impurity densities * default impurity param vals
1 parent 3f6dc70 commit 5f3a5cb

File tree

9 files changed

+190
-15
lines changed

9 files changed

+190
-15
lines changed

src/ConstructiveSolidGeometry/Units.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ to_internal_units(x::AngleQuantity) = ustrip(internal_angle_unit, x)
1111
to_internal_units(x::Quantity{<:Real, Unitful.𝐋^(-1)}) = ustrip(internal_length_unit^(-1), x) # charge trapping
1212
to_internal_units(x::Quantity{<:Real, Unitful.𝐋^(-3)}) = ustrip(internal_length_unit^(-3), x) # densities
1313
to_internal_units(x::Quantity{<:Real, Unitful.𝐋^(-4)}) = ustrip(internal_length_unit^(-4), x) # density gradients
14+
to_internal_units(x::Quantity{<:Real, Unitful.𝐋^(-5)}) = ustrip(internal_length_unit^(-5), x) # density quadratic components
1415
to_internal_units(x::AbstractArray) = to_internal_units.(x)
1516

1617
from_internal_units(x::Real, unit::Unitful.Units{<:Any, Unitful.𝐋}) = uconvert(unit, x * internal_length_unit)
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
include("ParBouleImpurityDensity.jl")
12
include("LinBouleImpurityDensity.jl")
2-
include("LinExpBouleImpurityDensity.jl")
3+
include("LinExpBouleImpurityDensity.jl")
4+
include("ParExpBouleImpurityDensity.jl")

src/ImpurityDensities/BouleImpurityDensities/LinBouleImpurityDensity.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ struct LinBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
1616
det_z0::T
1717
end
1818

19+
function ImpurityDensity(T::DataType, t::Val{:linear_boule}, dict::AbstractDict, input_units::NamedTuple)
20+
a::T = haskey(dict, "a") ? _parse_value(T, dict["a"], input_units.length^(-3)) : T(0)
21+
b::T = haskey(dict, "b") ? _parse_value(T, dict["b"], input_units.length^(-4)) : T(0)
22+
det_z0::T = haskey(dict, "det_z0") ? _parse_value(T, dict["det_z0"], input_units.length) : T(0)
23+
LinBouleImpurityDensity{T}(a, b, det_z0)
24+
end
25+
1926
function get_impurity_density(idm::LinBouleImpurityDensity, pt::AbstractCoordinatePoint{T})::T where {T}
2027
cpt = CartesianPoint(pt)
2128
z = cpt[3]
Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,39 @@
11
"""
22
struct LinExpBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
33
4-
a + b*z + c*exp((z-L)/tau)
4+
a + b*z + n*exp((z-l)/m)
55
Impurity density model which assumes a linear + exponential component in impurity density in z.
66
77
## Fields
88
* `a:T`: impurity density values at the boule origin.
99
* `b::T`: linear slope in `z` direction.
10-
* `c::T`: exponential coefficient.
11-
* `L::T`: exponential offset.
12-
* `tau::T`: exponential scale factor.
10+
* `n::T`: exponential coefficient.
11+
* `l::T`: exponential offset.
12+
* `m::T`: exponential scale factor.
1313
* `det_z0::T`: z coordinate of the detector origin in boule coordinates. The z-direction of the detector is opposite to the z-direction of the boule coordinates.
1414
"""
1515

1616
struct LinExpBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
1717
a::T
1818
b::T
19-
c::T
20-
L::T
21-
tau::T
19+
n::T
20+
l::T
21+
m::T
2222
det_z0::T
2323
end
2424

25+
function ImpurityDensity(T::DataType, t::Val{:linear_exponential_boule}, dict::AbstractDict, input_units::NamedTuple)
26+
a::T = haskey(dict, "a") ? _parse_value(T, dict["a"], input_units.length^(-3)) : T(0)
27+
b::T = haskey(dict, "b") ? _parse_value(T, dict["b"], input_units.length^(-4)) : T(0)
28+
n::T = haskey(dict, "n") ? _parse_value(T, dict["n"], input_units.length^(-3)) : T(0)
29+
l::T = haskey(dict, "l") ? _parse_value(T, dict["l"], input_units.length) : T(0)
30+
m::T = haskey(dict, "m") ? _parse_value(T, dict["m"], input_units.length) : T(1)
31+
det_z0::T = haskey(dict, "det_z0") ? _parse_value(T, dict["det_z0"], input_units.length) : T(0)
32+
LinExpBouleImpurityDensity{T}(a, b, n, l, m, det_z0)
33+
end
34+
2535
function get_impurity_density(idm::LinExpBouleImpurityDensity, pt::AbstractCoordinatePoint{T})::T where {T}
2636
cpt = CartesianPoint(pt)
2737
z = cpt[3]
28-
idm.a + idm.b * (idm.det_z0 - z) + idm.c * exp((idm.det_z0 - z - idm.L)/idm.tau)
38+
idm.a + idm.b * (idm.det_z0 - z) + idm.n * exp((idm.det_z0 - z - idm.l)/idm.m)
2939
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
struct ParBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
3+
4+
a + b*z + c*z^2
5+
Impurity density model which assumes a linear + exponential component in impurity density in z.
6+
7+
## Fields
8+
* `a:T`: impurity density values at the boule origin.
9+
* `b::T`: linear slope in `z` direction.
10+
* `c::T`: quadratic coefficient.
11+
* `det_z0::T`: z coordinate of the detector origin in boule coordinates. The z-direction of the detector is opposite to the z-direction of the boule coordinates.
12+
"""
13+
14+
struct ParBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
15+
a::T
16+
b::T
17+
c::T
18+
det_z0::T
19+
end
20+
21+
function ImpurityDensity(T::DataType, t::Val{:parabolic_boule}, dict::AbstractDict, input_units::NamedTuple)
22+
a::T = haskey(dict, "a") ? _parse_value(T, dict["a"], input_units.length^(-3)) : T(0)
23+
b::T = haskey(dict, "b") ? _parse_value(T, dict["b"], input_units.length^(-4)) : T(0)
24+
c::T = haskey(dict, "c") ? _parse_value(T, dict["c"], input_units.length^(-5)) : T(0)
25+
det_z0::T = haskey(dict, "det_z0") ? _parse_value(T, dict["det_z0"], input_units.length) : T(0)
26+
ParExpBouleImpurityDensity{T}(a, b, c, det_z0)
27+
end
28+
29+
function get_impurity_density(idm::ParBouleImpurityDensity, pt::AbstractCoordinatePoint{T})::T where {T}
30+
cpt = CartesianPoint(pt)
31+
z = cpt[3]
32+
idm.a + idm.b * (idm.det_z0 - z) + idm.c * (idm.det_z0 - z)^2
33+
end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
struct ParExpBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
3+
4+
a + b*z + c*z^2 + n*exp((z-l)/m)
5+
Impurity density model which assumes a linear + exponential component in impurity density in z.
6+
7+
## Fields
8+
* `a:T`: impurity density values at the boule origin.
9+
* `b::T`: linear slope in `z` direction.
10+
* `c::T`: quadratic coefficient.
11+
* `n::T`: exponential coefficient.
12+
* `l::T`: exponential offset.
13+
* `m::T`: exponential scale factor.
14+
* `det_z0::T`: z coordinate of the detector origin in boule coordinates. The z-direction of the detector is opposite to the z-direction of the boule coordinates.
15+
"""
16+
17+
struct ParExpBouleImpurityDensity{T <: SSDFloat} <: AbstractImpurityDensity{T}
18+
a::T
19+
b::T
20+
c::T
21+
n::T
22+
l::T
23+
m::T
24+
det_z0::T
25+
end
26+
27+
function ImpurityDensity(T::DataType, t::Val{:parabolic_exponential_boule}, dict::AbstractDict, input_units::NamedTuple)
28+
a::T = haskey(dict, "a") ? _parse_value(T, dict["a"], input_units.length^(-3)) : T(0)
29+
b::T = haskey(dict, "b") ? _parse_value(T, dict["b"], input_units.length^(-4)) : T(0)
30+
c::T = haskey(dict, "c") ? _parse_value(T, dict["c"], input_units.length^(-5)) : T(0)
31+
n::T = haskey(dict, "n") ? _parse_value(T, dict["n"], input_units.length^(-3)) : T(0)
32+
l::T = haskey(dict, "l") ? _parse_value(T, dict["l"], input_units.length) : T(0)
33+
m::T = haskey(dict, "m") ? _parse_value(T, dict["m"], input_units.length) : T(1)
34+
det_z0::T = haskey(dict, "det_z0") ? _parse_value(T, dict["det_z0"], input_units.length) : T(0)
35+
ParExpBouleImpurityDensity{T}(a, b, c, n, l, m, det_z0)
36+
end
37+
38+
function get_impurity_density(idm::ParExpBouleImpurityDensity, pt::AbstractCoordinatePoint{T})::T where {T}
39+
cpt = CartesianPoint(pt)
40+
z = cpt[3]
41+
idm.a + idm.b * (idm.det_z0 - z) + idm.c * (idm.det_z0 - z)^2 + idm.n * exp((idm.det_z0 - z - idm.l)/idm.m)
42+
end

src/SolidStateDetectors.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export Simulation, simulate!
7878
export Event, drift_charges!
7979
export add_baseline_and_extend_tail
8080
export NBodyChargeCloud
81-
export LinearImpurityDensity, LinBouleImpurityDensity, LinExpBouleImpurityDensity
81+
export LinBouleImpurityDensity, ParBouleImpurityDensity, LinExpBouleImpurityDensity, ParExpBouleImpurityDensity
8282

8383
using Unitful: RealOrRealQuantity as RealQuantity
8484
const SSDFloat = Union{Float16, Float32, Float64}

test/BEGe_02.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Point-contact detector
2+
units:
3+
length: mm
4+
angle: deg
5+
potential: V
6+
temperature: K
7+
grid:
8+
coordinates: cylindrical
9+
axes:
10+
r:
11+
to: 60
12+
boundaries: inf
13+
phi:
14+
from: 0
15+
to: 0
16+
boundaries:
17+
left: periodic
18+
right: periodic
19+
z:
20+
from: -20
21+
to: 60
22+
boundaries:
23+
left: inf
24+
right: inf
25+
medium: vacuum
26+
27+
detectors:
28+
- semiconductor:
29+
material: HPGe
30+
impurity_density:
31+
name: linear_boule
32+
a: -1e7
33+
b: -1e5
34+
det_z0: 120
35+
geometry:
36+
translate:
37+
tube:
38+
r: 40
39+
h: 40
40+
z: 20
41+
contacts:
42+
- name: Core
43+
material: HPGe
44+
id: 1
45+
potential: -3000
46+
geometry:
47+
tube:
48+
r: 3
49+
h: 0.3
50+
origin:
51+
z: 39.85
52+
- name: Mantle
53+
material: HPGe
54+
id: 2
55+
potential: 0
56+
geometry:
57+
union:
58+
- tube:
59+
r:
60+
from: 0
61+
to: 40
62+
h: 0
63+
- tube:
64+
r:
65+
from: 40
66+
to: 40
67+
h: 40
68+
origin:
69+
z: 20
70+
- tube:
71+
r:
72+
from: 10
73+
to: 40
74+
h: 0
75+
origin:
76+
z: 40

test/test_boule_impurity_densities.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ T = Float32
1515

1616
@test det_ρ0 == boule_ρ0 + boule_gradient * det_z0
1717

18-
boule_c = T(-2e15)
19-
boule_L = T(0.05)
20-
boule_tau = T(0.03)
21-
idm = LinExpBouleImpurityDensity{T}(boule_ρ0, boule_gradient, boule_c, boule_L, boule_tau, det_z0)
18+
sim2 = Simulation{T}("BEGe_02.yaml")
19+
20+
@test sim.detector.semiconductor.impurity_density_model == sim2.detector.semiconductor.impurity_density_model
21+
22+
boule_n = T(-2e15)
23+
boule_l = T(0.05)
24+
boule_m = T(0.03)
25+
idm = LinExpBouleImpurityDensity{T}(boule_ρ0, boule_gradient, boule_n, boule_l, boule_m, det_z0)
2226
sim.detector = SolidStateDetector(sim.detector, idm)
2327

2428
det_ρ0 = SolidStateDetectors.get_impurity_density(sim.detector.semiconductor.impurity_density_model, CylindricalPoint{T}(0,0,0))
2529

26-
@test det_ρ0 == boule_ρ0 + boule_gradient * det_z0 + boule_c * exp((det_z0 - boule_L)/boule_tau)
30+
@test det_ρ0 == boule_ρ0 + boule_gradient * det_z0 + boule_n * exp((det_z0 - boule_l)/boule_m)
2731
end

0 commit comments

Comments
 (0)