Skip to content

Commit

Permalink
Add support for luminous flux and illuminace (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmichelenstrofer authored Dec 4, 2023
1 parent 8b41b2f commit f40d25f
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 14 deletions.
30 changes: 30 additions & 0 deletions docs/src/guide/derived.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
These are:

- [`DimensionfulAngles.SolidAngle`](@ref)
- [`DimensionfulAngles.LuminousFlux`](@ref)
- [`DimensionfulAngles.Illuminance`](@ref)
- [`DimensionfulAngles.AngularVelocity`](@ref)
- [`DimensionfulAngles.AngularAcceleration`](@ref)
- [`DimensionfulAngles.AngularWavelength`](@ref)
Expand Down Expand Up @@ -31,6 +33,20 @@ DimensionfulAngles.SolidAngle
DimensionfulAngles.srᵃ
```

## Luminous flux and illuminance
Luminous flux is a measure of perceived power of light and has dimensions of ``𝐉*𝐀²``.
The SI unit lumen (lm) = candela x steradian is provided as [`DimensionfulAngles.lmᵃ`](@ref).

Illuminance is luminous flux per unit surface area and has dimensions of ``𝐉*𝐀²*𝐋⁻²``.
The SI unit lux (lx) = lumen / meter^2 is provided as [`DimensionfulAngles.lxᵃ`](@ref).

```@docs
DimensionfulAngles.LuminousFlux
DimensionfulAngles.Illuminance
DimensionfulAngles.lmᵃ
DimensionfulAngles.lxᵃ
```

## Angular velocity and acceleration
[Angular velocity](https://en.wikipedia.org/wiki/Angular_frequency) has dimensions of angle over time `𝐀/𝐓` and can be used to measure different quantities such as rotational velocity, rotational speed, and angular frequency of a phase angle.
Two units of angular velocity are defined: the revolutions per second (RPS) and the revolutions per minute (RPM), provided as [`DimensionfulAngles.rpsᵃ`](@ref) and [`DimensionfulAngles.rpmᵃ`](@ref) respectively.
Expand Down Expand Up @@ -111,6 +127,10 @@ DimensionfulAngles.AngularPeriodUnits
DimensionfulAngles.AngularPeriodFreeUnits
DimensionfulAngles.AngularWavelengthUnits
DimensionfulAngles.AngularWavelengthFreeUnits
DimensionfulAngles.LuminousFluxUnits
DimensionfulAngles.LuminousFluxFreeUnits
DimensionfulAngles.IlluminanceUnits
DimensionfulAngles.IlluminanceFreeUnits
```

### [Prefixed Units](@id derived_prefixed)
Expand All @@ -119,3 +139,13 @@ DimensionfulAngles.AngularWavelengthFreeUnits
Modules = [DimensionfulAngles]
Filter = x->_filter_prefixed("sr", x)
```

```@autodocs
Modules = [DimensionfulAngles]
Filter = x->_filter_prefixed("lm", x)
```

```@autodocs
Modules = [DimensionfulAngles]
Filter = x->_filter_prefixed("lx", x)
```
4 changes: 2 additions & 2 deletions src/DimensionfulAngles.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ module DimensionfulAngles

# using Base: Base # extend: see `base.jl` for full list of functions extended
using Unitful: Unitful # extend: has_unit_spacing, uconvert
using Unitful: minute, promotion, rad, rpm, rps, s, sr, 𝐓, 𝐋, °
using Unitful: cd as cdᵤ, lm, lx, m, minute, promotion, rad, rpm, rps, s, sr, 𝐉, 𝐋, 𝐓, °
using Unitful: ContextUnits, Dimension, Dimensions, DimensionlessQuantity, FixedUnits
using Unitful: FreeUnits, Frequency, FrequencyFreeUnits, Length, MixedUnits, NoDims
using Unitful: FreeUnits, Frequency, FrequencyFreeUnits, Length, MixedUnits, NoDims
using Unitful: NoUnits, Number, Quantity, Time, Unitlike, Unit, Units, Wavenumber
using Unitful: @dimension, @refunit, @derived_dimension, @unit
using Unitful: dimension, register, uconvert, unit, ustrip
Expand Down
4 changes: 4 additions & 0 deletions src/convert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ function Unitful.uconvert(s::Val{:Unitful}, x::Quantity)
x = _convert_units(x, srᵃ, 𝐀^2, sr, NoDims)
x = _convert_units(x, rpsᵃ, 𝐀*𝐓^-1, rps, 𝐓^-1)
x = _convert_units(x, rpmᵃ, 𝐀*𝐓^-1, rpm, 𝐓^-1)
x = _convert_units(x, lmᵃ, 𝐀^2*𝐉, lm, 𝐉)
x = _convert_units(x, lxᵃ, 𝐀^2*𝐉*𝐋^-2, lx, 𝐉*𝐋^-2)
return x
end

Expand All @@ -61,6 +63,8 @@ function Unitful.uconvert(s::Val{:DimensionfulAngles}, x::Quantity)
x = _convert_units(x, sr, NoDims, srᵃ, 𝐀^2)
x = _convert_units(x, rps, 𝐓^-1, rpsᵃ, 𝐀*𝐓^-1)
x = _convert_units(x, rpm, 𝐓^-1, rpmᵃ, 𝐀*𝐓^-1)
x = _convert_units(x, lm, 𝐉, lmᵃ, 𝐀^2*𝐉)
x = _convert_units(x, lx, 𝐉*𝐋^-2, lxᵃ, 𝐀^2*𝐉*𝐋^-2)
return x
end

Expand Down
30 changes: 21 additions & 9 deletions src/defaults.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ will bring the following into the calling namespace:
- Base and derived SI units, with SI prefixes
- Candela conflicts with `Base.cd` so it is not brought in (Unitful.jl issue #102)
- Candela conflicts with `Base.cd` so it is brought in as `cdᵤ`.
- Degrees: °
All angles imported removing the ᵃ superscript.
All angles and derived units imported removing the ᵃ superscript.
!!! note "Potential conflict with other packages"
Expand All @@ -40,7 +40,7 @@ baremodule DefaultSymbols
import DimensionfulAngles
using Base: filter, , !

__angle_units = (:rad,:sr)
__angle_units = (:rad, :sr, :lm, :lx)
__non_angle_units = filter(u -> !(u __angle_units), Unitful.si_no_prefix)

# Unitful Dimensions
Expand All @@ -49,10 +49,11 @@ baremodule DefaultSymbols
Core.eval(DefaultSymbols, Expr(:export, u))
end

# DimensionfulAngles Dimension
# DimensionfulAngles Dimensions
Core.eval(DefaultSymbols, Expr(:import, Expr(:(.), :DimensionfulAngles, :𝐀)))
Core.eval(DefaultSymbols, Expr(:export, :𝐀))

# units
for p in Unitful.si_prefixes
# Unitful units
for u in __non_angle_units
Expand All @@ -61,18 +62,29 @@ baremodule DefaultSymbols
end
# DimensionfulAngles units
for u in __angle_units
DAname = Symbol(p,u,:ᵃ)
name = Symbol(p,u)
Core.eval(DefaultSymbols, Expr(:import, Expr(:(.), :DimensionfulAngles, DAname)))
Core.eval(DefaultSymbols, Expr(:(=), name, DAname))
Core.eval(DefaultSymbols, Expr(:export, name))
Core.eval(
DefaultSymbols,
Expr(:import, Expr(:(.), :DimensionfulAngles, Symbol(p,u,:ᵃ)))
)
Core.eval(DefaultSymbols, Expr(:(=), Symbol(p,u), Symbol(p,u,:ᵃ)))
Core.eval(DefaultSymbols, Expr(:export, Symbol(p,u)))
end
end

# degrees Celsius
Core.eval(DefaultSymbols, Expr(:import, Expr(:(.), :Unitful, :°C)))
Core.eval(DefaultSymbols, Expr(:export, :°C))

# DimensionfulAngles degree
Core.eval(DefaultSymbols, Expr(:import, Expr(:(.), :DimensionfulAngles, :°ᵃ)))
Core.eval(DefaultSymbols, Expr(:(=), , :°ᵃ))
Core.eval(DefaultSymbols, Expr(:export, ))

# candela
u = :cd
for p in Unitful.si_prefixes
Core.eval(DefaultSymbols, Expr(:import, Expr(:(.), :Unitful, Symbol(p,u))))
Core.eval(DefaultSymbols, Expr(:(=), Symbol(p,u,:ᵤ), Symbol(p,u)))
Core.eval(DefaultSymbols, Expr(:export, Symbol(p,u,:ᵤ)))
end
end
26 changes: 26 additions & 0 deletions src/derived.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ Dimension: `𝐀²`."
"""
@unit srᵃ "sr" Steradianᵃ (1radᵃ*radᵃ) true true

# Luminous flux and illuminance
@derived_dimension LuminousFlux (𝐉*𝐀^2) true
@derived_dimension Illuminance (𝐉*𝐀^2*𝐋^-2) true

"""
lmᵃ
The lumen, an SI unit of luminous flux.
Defined as 1 cd × sr. Accepts SI prefixes.
Dimension: `𝐉𝐀²`."
"""
@unit lmᵃ "lm" Lumenᵃ 1cdᵤ*srᵃ true true

"""
lxᵃ
The lux, an SI unit of illuminance.
Defined as 1 lm / m^2. Accepts SI prefixes.
Dimension: `𝐉𝐀²𝐋⁻²`."
"""
@unit lxᵃ "lx" Luxᵃ 1lmᵃ/m^2 true true

# Angular velocity, angular acceleration, and angular frequency.
@derived_dimension AngularVelocity (𝐀*𝐓^-1) true
@derived_dimension AngularAcceleration (𝐀*𝐓^-2) true
Expand Down
14 changes: 11 additions & 3 deletions test/test_core_package.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Test, DimensionfulAngles, Unitful, UnitfulAngles
using Unitful: 𝐓, 𝐋, ContextUnits, FixedUnits, FreeUnits, Units
using Unitful: 𝐉, 𝐓, 𝐋, ContextUnits, FixedUnits, FreeUnits, Units
using DimensionfulAngles: 𝐀

function test_uamacro(unit::Symbol)
Expand Down Expand Up @@ -245,10 +245,18 @@ end
(1//60)^2 * (1//3600)^-1
)
end
# derived units
let x = 1.98u"rpm*rps^2*lm^-1*lx*msr^2"
@test unit(uconvert(:DimensionfulAngles, x)) == ua"rpm*rps^2*lm^-1*lx*msr^2"
@test (uconvert(:DimensionfulAngles, x)).val 1.98
end
end

@testset "DefaultSymbols" begin
@test typeof(DimensionfulAngles.DefaultSymbols) == Module
@test dimension(DimensionfulAngles.DefaultSymbols.rad) == DimensionfulAngles.𝐀
@test dimension(DimensionfulAngles.DefaultSymbols.°) == DimensionfulAngles.𝐀
@test dimension(DimensionfulAngles.DefaultSymbols.rad) == 𝐀
@test dimension(DimensionfulAngles.DefaultSymbols.°) == 𝐀
@test dimension(DimensionfulAngles.DefaultSymbols.lm) == 𝐉*𝐀^2
@test dimension(DimensionfulAngles.DefaultSymbols.lx) == 𝐉*𝐀^2*𝐋^-2
@test DimensionfulAngles.DefaultSymbols.cdᵤ === Unitful.cd
end

0 comments on commit f40d25f

Please sign in to comment.