Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for luminous flux and illuminace #40

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion 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 @@ -78,7 +94,7 @@ Analogously, spatial period and frequency are [related by](https://en.wikipedia.
between wavelength `λ` (`𝐋`, `m`), wavenumber `ν` (`1/𝐋`, `1/m`), and angular wavenumber `k` (`𝐀/𝐋`, `rad/m`).
Additionally an angular period and angular wavelength can be defined analogously as the reciprocal of angular frequency and angular wavenumber.

![Diagram showing graphically the relationships between the various properties of harmonic waves: frequency, period, wavelength, angular frequency, and wavenumber.](../assets/Commutative_diagram_of_harmonic_wave_properties.svg
![Diagram showing graphically the relationships between the various properties of harmonic waves: frequency, period, wavelength, angular frequency, and wavenumber.](../assets/Commutative_diagram_of_harmonic_wave_properties.svg)\
*image-source: Waldir, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons*

*DimensionfulAngles.jl* provides [`Periodic`](@ref) a [UnitfulEquivalences.jl](https://sostock.github.io/UnitfulEquivalences.jl/stable/) `Equivalence` to convert between temporal or spatial period, frequency, angular frequency, and angular period of a periodic response.
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)
```
33 changes: 25 additions & 8 deletions docs/src/proposed.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,43 @@ different, but most (i) include angle as a base dimension, (ii) use a "fundament
constant, typically equal to one radian, to modify the equations of physics, and (iii)
define solid angle as a derived dimension equal to angle squared.
The different proposals, however, take different approaches to which equations or
quantity units to modify.
quantity units to modify.
One exception not considered here is a class of proposals that define a new dimension for *radius length* rather than for *angle*.

Some examples of how common equations would be modified in such systems, using ``θ₀=1rad``:

- Trigonometric functions:
- Trigonometric & exponential functions:

+ ``cos(θ) → cos(θ/θ₀)``
+ ``cos(ωt+φ) → cos([ωt+φ]/θ₀)``
+ ``Aℯⁱᶿ → Aℯ^[iθ/θ₀]``

- Angular frequency and frequency:
- Angular frequency and angular wave number:

+ ``ω=2πf → ω=2πfθ₀``
- Arc length ``s`` and other kinematic equations:
+ ``k=2π/λ → k=2πθ₀/λ``

- Arc length and sector area:

+ ``s=rθ → s=rθ/θ₀``
- For dynamic equations there's more variability between the different proposals.
As an example, [Quincey_2021](@cite) would modify torque (and its unit) while leaving the units of work intact, as
+ ``A=½r²θ → A=½r²θ/θ₀``

- Solid angles
+ ``Ω=A/r² → Ω=Aθ₀²/r²``

- kinematic equations:

+ ``v=rω → v=rω/θ₀``
+ ``a=rω² → a=rω²/θ₀²``

- For dynamic equations, there's more variability between the different proposals.
As an example, [Quincey_2021](@cite) would modify the units of torque and moment of inertia while leaving the units of work and energy intact.

+ ``T=(𝐫×𝐅) → T=(𝐫×𝐅)/θ₀``
+ ``W=Tθ``
+ ``T=(𝐫×𝐅) → T=(𝐫×𝐅)/θ₀`` (torque, new units: ``J/s``)
+ ``I=Σ(mᵢ⋅rᵢ)/θ₀²`` (moment of inertia, new units: ``kg⋅m²/rad²``)
+ ``L=Iω=(𝐫x𝐩)/θ₀`` (angular momentum, new units: ``J/(rad/s)``)
+ ``W=Tθ`` (work)
+ ``E=½Iω²`` (kinetic energy)

## *DimensionfulAngles.jl*'s relation to these proposals

Expand Down
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