Skip to content

Commit fc2125f

Browse files
committed
modified: Project.toml 0.2.3
modified: README.md Update modified: src/MechGlueDiffEqBase.jl similar, zero, precompile modified: test/test_4.jl Test zero and similar inferrable
1 parent b26f560 commit fc2125f

File tree

4 files changed

+119
-14
lines changed

4 files changed

+119
-14
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MechGlueDiffEqBase"
22
uuid = "2532746b-52b5-4539-9431-8bb183ab067f"
33
authors = ["hustf <[email protected]> and contributors"]
4-
version = "0.2.2"
4+
version = "0.2.3"
55

66
[deps]
77
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
# MechGlueDiffEqBase
22
Glue code for making [DiffEqBase](https://github.com/SciML/DiffEqBase.jl) work with units.
33

4-
This defines how to calculate the vector norm when the vector is given in units compatible with [Unitfu.jl](https://github.com/hustf/Unitfu.jl), from registy [M8](https://github.com/hustf/M8). The differential equation algorithms expects the norm to be unitless, as can be seen in e.g. step size estimators:
4+
This defines
55

6-
It also used to include glue code for [RecursiveArrayTools](https://github.com/SciML/RecursiveArrayTools.jl), which enables type-stable solution of equations with mixed units. This may not be needed after a change to Unitfu.jl v1.7.7, but the depencency is kept until further upstream testing.
6+
* how to calculate the vector norm 'ODE_DEFAULT_NORM' when the vector is given in units compatible with [Unitfu.jl](https://github.com/hustf/Unitfu.jl), from registy [M8](https://github.com/hustf/M8). The differential equation algorithms expects the norm to be unitless, as can be seen in e.g. step size estimators.
7+
8+
* type-stable and inferrable 'zero', 'value', 'UNITLESS_ABS2', 'similar'
9+
10+
These functions preserve types for mixed-unit vectors. E.g. [1.0kg, 2.0N, 3.0m/s, 4.0m/s].
11+
12+
This package also uses and reexports 'ArrayPartition' from [RecursiveArrayTools](https://github.com/SciML/RecursiveArrayTools.jl), which enables type-stable solution of equations with mixed units. It pre-compiles it with use of mixed unit vectors.
13+
14+
15+
Note: The way error tolerances are defined is initially confusing, but good to know:
716

817
err_scaled = **error** / (**abstol** + norm(u) * **reltol**)
918

1019
where **bold** indicates unitful objects.
1120

12-
The functions are adaptions of corresponding code from [DiffEqBase](https://github.com/SciML/DiffEqBase.jl/blob/6bb8830711e729ef513f2b1beb95853e4a691375/src/init.jl).
21+
Some functions are adaptions of corresponding code from [DiffEqBase](https://github.com/SciML/DiffEqBase.jl/blob/6bb8830711e729ef513f2b1beb95853e4a691375/src/init.jl).

src/MechGlueDiffEqBase.jl

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
module MechGlueDiffEqBase
2-
import Unitfu: AbstractQuantity, Quantity, ustrip, norm, unit
3-
import DiffEqBase: value, ODE_DEFAULT_NORM, UNITLESS_ABS2, zero
2+
import Base: similar
3+
import Unitfu: AbstractQuantity, Quantity, ustrip, norm, unit, zero
4+
import Unitfu: Dimensions, FreeUnits
5+
import DiffEqBase: value, ODE_DEFAULT_NORM, UNITLESS_ABS2
46
import DiffEqBase: calculate_residuals, @muladd
57
using RecursiveArrayTools
68
export value, ODE_DEFAULT_NORM, UNITLESS_ABS2, Unitfu, AbstractQuantity, Quantity
7-
export norm , ArrayPartition # Probably no longer necessary with changes in Unitfu 1.7.7. We could perhaps drop this depencency.
9+
export norm , ArrayPartition, similar, zero
810

911
# This is identical to what DiffEqBase defines for Unitful
1012
function value(x::Type{AbstractQuantity{T,D,U}}) where {T,D,U}
@@ -45,4 +47,79 @@ end
4547
abs2(xul)::T
4648
end
4749

50+
# Vectors with compatible units, treat as normal
51+
zero(x::Vector{Quantity{T, D, U}}) where {T,D,U} = fill!(similar(x), zero(Quantity{T, D, U}))
52+
# Vectors with incompatible units, special inferreable treatment
53+
function zero(x::Vector{Q}) where {Q<:AbstractQuantity{T, D, U} where {D,U}} where T
54+
x0 = copy(x)
55+
for i in eachindex(x0)
56+
x = x0[i]
57+
x0[i] = 0 * x * sign(x)
58+
end
59+
x0
60+
end
61+
62+
# Vectors with compatible units, treat as normal
63+
similar(x::Vector{Quantity{T, D, U}}) where {T,D,U} = Vector{Quantity{T, D, U}}(undef, size(x,1))
64+
#similar(a::Array{T,1}) where {T} = Vector{T}(undef, size(a,1))
65+
# Vectors with incompatible units, special inferreable treatment
66+
# VERY similar is still similar and (very slightly) different
67+
similar(x::Vector{Q}) where {Q<:AbstractQuantity{T, D, U} where {D,U}} where T = copy(x)
68+
69+
70+
71+
72+
# KISS pre-compillation to reduce loading times
73+
# This is simply a boiled-down obfuscated test_4.jl
74+
import Unitfu: m, s, kg, N,
75+
let
76+
r0ul = [1131.340, -2282.343, 6672.423]
77+
r0ul = [1131.340, -2282.343, 6672.423]
78+
v0ul = [-5.64305, 4.30333, 2.42879]
79+
rv0ul = ArrayPartition(r0ul,v0ul)
80+
ODE_DEFAULT_NORM(rv0ul, 0.0)
81+
r0 = [1131.340, -2282.343, 6672.423]kg
82+
v0 = [-5.64305, 4.30333, 2.42879]kg/s
83+
rv0 = ArrayPartition(r0, v0)
84+
ODE_DEFAULT_NORM(rv0, 0.0s)
85+
r0 = [1.0kg, 2.0N, 3.0m/s, 4.0m/s]
86+
v0 = [1.0kg/s, 2.0N/s, 3.0m/s^2, 4m/s^2]
87+
rv0 = ArrayPartition(r0, v0)
88+
r0ul = [1131.340, -2282.343, 6672.423]
89+
v0ul = [-5.64305, 4.30333, 2.42879]
90+
rv0ul = ArrayPartition(r0ul, v0ul)
91+
r0 = [1131.340, -2282.343, 6672.423]kg
92+
r1 = [1kg, 2.0m]
93+
zero(r0)
94+
zero(r1)
95+
rv0 = ArrayPartition(r0)
96+
zero(rv0)
97+
rv1 = ArrayPartition(r1)
98+
zero(rv1)
99+
r0 = [1.0kg, -2kg, 3m/s, 4m/s]
100+
zero(r0)
101+
rv0 = ArrayPartition(r0)
102+
zer = zero(rv0)
103+
zer == [0.0kg, 0.0kg, 0.0m/s, 0.0m/s]
104+
r0 = [1131.340, -2282.343, 6672.423]kg
105+
simi = similar(r0)
106+
rv0 = ArrayPartition(r0)
107+
sima = similar(rv0)
108+
r0 = [1.0kg, -2kg, 3m/s, 4m/s]
109+
similar(r0)
110+
rv0 = ArrayPartition(r0)
111+
sima = similar(rv0)
112+
r0ul = [1131.340, -2282.343, 6672.423]
113+
v0ul = [-5.64305, 4.30333, 2.42879]
114+
rv0ul = ArrayPartition(r0ul,v0ul)
115+
UNITLESS_ABS2(rv0ul)
116+
r0 = [1.0kg, 2.0N, 3.0m/s, 4.0m/s]
117+
v0 = [1.0kg/s, 2.0N/s, 3.0m/s^2, 4m/s^2]
118+
rv0 = ArrayPartition(r0, v0)
119+
UNITLESS_ABS2(1.0kg)
120+
UNITLESS_ABS2(r0)
121+
UNITLESS_ABS2(rv0)
122+
nothing
123+
end
124+
48125
end

test/test_4.jl

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Check type stability of ODE_DEFAULT_NORM with mixed units and with ArrayPartition
22
using Test
33
using MechGlueDiffEqBase
4-
import MechGlueDiffEqBase: zero_collection
54
using MechanicalUnits: @import_expand, dimension, NoDims,
65
import MechanicalUnits: g, g⁻¹
76
@import_expand(km, N, s, m, km, kg, °, inch)
@@ -46,18 +45,38 @@ end
4645
@test @inferred(zero(rv1)) == [0.0, 0.0]km
4746
@test typeof(zero(rv0)) == typeof(rv0)
4847
end
49-
@testset "(Inferrable) zero ArrayPartition mixed units" begin
50-
r0 = [1.0km, 2km, 3m/s, 4m/s]
51-
v0 = [1.0km/s, 2.0km/s, 3.0m/s², 4m/s²]
52-
# Not inferrable, but inferred return type is now AbstractVector{var"#s831"} where var"#s831", not Any
53-
@test zero(r0) == [0.0km, 0.0km, 0.0m/s, 0.0m/s]
54-
# ArrayPartition fixes that
48+
@testset "Inferrable zero vector and ArrayPartition mixed units" begin
49+
r0 = [1.0km, -2km, 3m/s, 4m/s]
50+
@test @inferred(zero(r0)) == [0.0km, 0.0km, 0.0m/s, 0.0m/s]
5551
rv0 = @inferred ArrayPartition(r0)
5652
zer = @inferred zero(rv0)
5753
@test zer == [0.0km, 0.0km, 0.0m/s, 0.0m/s]
5854
@test typeof(zer) === typeof(rv0)
5955
end
6056

57+
@testset "Inferrable similar vector and ArrayPartition compatible units" begin
58+
r0 = [1131.340, -2282.343, 6672.423]km
59+
simi = @inferred(similar(r0))
60+
@test all(typeof.(r0) == typeof.(simi))
61+
@test simi !== r0
62+
rv0 = @inferred ArrayPartition(r0)
63+
sima = @inferred similar(rv0)
64+
@test all(typeof.(rv0) == typeof.(sima))
65+
@test sima !== rv0
66+
end
67+
68+
69+
@testset "Inferrable similar vector and ArrayPartition mixed units" begin
70+
r0 = [1.0km, -2km, 3m/s, 4m/s]
71+
simi = @inferred(similar(r0))
72+
@test all(typeof.(r0) == typeof.(simi))
73+
@test simi !== r0
74+
rv0 = @inferred ArrayPartition(r0)
75+
sima = @inferred similar(rv0)
76+
@test all(typeof.(rv0) == typeof.(sima))
77+
@test sima !== rv0
78+
end
79+
6180
@testset "Inferrable UNITLESS_ABS2 Unitless ArrayPartition" begin
6281
r0ul = [1131.340, -2282.343, 6672.423]
6382
v0ul = [-5.64305, 4.30333, 2.42879]

0 commit comments

Comments
 (0)