Skip to content

Commit 51684ab

Browse files
authored
Introduce convert_unit (#255)
* introduce `convert_unit` * add tests for utility functions * fix value of physical constants
1 parent 48f8c41 commit 51684ab

File tree

4 files changed

+92
-1
lines changed

4 files changed

+92
-1
lines changed

docs/src/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ QuantumToolbox.versioninfo
239239
QuantumToolbox.about
240240
gaussian
241241
n_thermal
242+
convert_unit
242243
row_major_reshape
243244
meshgrid
244245
_calculate_expectation!

src/utilities.jl

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Utilities:
33
internal (or external) functions which will be used throughout the entire package
44
=#
55

6-
export gaussian, n_thermal
6+
export gaussian, n_thermal, convert_unit
77
export row_major_reshape, meshgrid
88

99
@doc raw"""
@@ -48,6 +48,50 @@ function n_thermal(ω::T1, ω_th::T2) where {T1<:Real,T2<:Real}
4848
return _FType(promote_type(T1, T2))(n)
4949
end
5050

51+
# some fundamental physical constants and common energy units
52+
const _e = 1.602176565e-19 # elementary charge (C)
53+
const _kB = 1.3806488e-23 # Boltzmann constant (J/K)
54+
const _h = 6.62607015e-34 # Planck constant (J⋅s)
55+
const _energy_units::Dict{Symbol,Float64} = Dict(
56+
# the values below are all in the unit of Joule
57+
:J => 1.0,
58+
:eV => _e,
59+
:meV => 1e-3 * _e,
60+
:GHz => 1e9 * _h,
61+
:mK => 1e-3 * _kB,
62+
)
63+
64+
@doc raw"""
65+
convert_unit(value::Real, unit1::Symbol, unit2::Symbol)
66+
67+
Convert the energy `value` from `unit1` to `unit2`.
68+
69+
Note that `unit1` and `unit2` can be either the following `Symbol`:
70+
- `:J`: Joule
71+
- `:eV`: electron volt.
72+
- `:meV`: milli-electron volt.
73+
- `:GHz`: Giga-Hertz multiplied by Planck constant ``h``.
74+
- `:mK`: milli-Kelvin multiplied by Boltzmann constant ``k_{\textrm{B}}``.
75+
76+
# Examples
77+
78+
```
79+
julia> convert_unit(1, :eV, :J)
80+
1.602176565e-19
81+
82+
julia> convert_unit(1, :GHz, :J)
83+
6.62607015e-25
84+
85+
julia> convert_unit(1, :meV, :mK)
86+
11604.51930280894
87+
```
88+
"""
89+
function convert_unit(value::T, unit1::Symbol, unit2::Symbol) where {T<:Real}
90+
!haskey(_energy_units, unit1) && throw(ArgumentError("Invalid unit :$(unit1)"))
91+
!haskey(_energy_units, unit2) && throw(ArgumentError("Invalid unit :$(unit2)"))
92+
return _FType(T)(value * (_energy_units[unit1] / _energy_units[unit2]))
93+
end
94+
5195
_get_dense_similar(A::AbstractArray, args...) = similar(A, args...)
5296
_get_dense_similar(A::AbstractSparseMatrix, args...) = similar(nonzeros(A), args...)
5397

test/core-test/utilities.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@testset "Utilities" verbose = true begin
2+
@testset "n_thermal" begin
3+
ω1 = rand(Float64)
4+
ω2 = rand(Float64)
5+
@test n_thermal(0, ω2) == 0.0
6+
@test n_thermal(ω1, 0) == 0.0
7+
@test n_thermal(ω1, -ω2) == 0.0
8+
@test n_thermal(ω1, ω2) == 1 / (exp(ω1 / ω2) - 1)
9+
@test typeof(n_thermal(Int32(2), Int32(3))) == Float32
10+
@test typeof(n_thermal(Float32(2), Float32(3))) == Float32
11+
@test typeof(n_thermal(Int64(2), Int32(3))) == Float64
12+
@test typeof(n_thermal(Int32(2), Int64(3))) == Float64
13+
@test typeof(n_thermal(Float64(2), Float32(3))) == Float64
14+
@test typeof(n_thermal(Float32(2), Float64(3))) == Float64
15+
end
16+
17+
@testset "convert unit" begin
18+
V = 100 * rand(Float64)
19+
_unit_list = [:J, :eV, :meV, :GHz, :mK]
20+
for origin in _unit_list
21+
for middle in _unit_list
22+
for target in _unit_list
23+
V_middle = convert_unit(V, origin, middle)
24+
V_target = convert_unit(V_middle, middle, target)
25+
V_origin = convert_unit(V_target, target, origin)
26+
@test V V_origin
27+
end
28+
end
29+
end
30+
@test_throws ArgumentError convert_unit(V, :bad_unit, :J)
31+
@test_throws ArgumentError convert_unit(V, :J, :bad_unit)
32+
end
33+
34+
@testset "Type Inference" begin
35+
v1 = rand(Float64)
36+
@inferred n_thermal(v1, Int32(123))
37+
38+
_unit_list = [:J, :eV, :meV, :GHz, :mK]
39+
for u1 in _unit_list
40+
for u2 in _unit_list
41+
@inferred convert_unit(v1, u1, u2)
42+
end
43+
end
44+
end
45+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ core_tests = [
2323
"states_and_operators.jl",
2424
"steady_state.jl",
2525
"time_evolution.jl",
26+
"utilities.jl",
2627
"wigner.jl",
2728
]
2829

0 commit comments

Comments
 (0)