Make Unitful simplify expressions like 1μm/1m to a unitless value by default

For this purpose, I’m using a small piece of code listed below. It allows me to use for example // as a unit stripping operator.

After including the code below, I can just define the unit stripping operator and use it in a pretty readable way - this way I keep variables tagged with units as long as possible and strip the units just before printing or plotting, so I know exactly if I’m plotting in ns, microseconds or seconds

julia> @stripunits_operator //
julia> u = 15u"V"; d = 5u"mm"; E = u/d
julia> println("The field intensity is \$(E // u"V/m") [V/m] in a gap of \$(d // u"m") [m]")
The field intensity is 3000.0 [V/m] in a gap of 0.005 [m]

julia> typeof(E // u"V/m")
Float64

The code to include:

function stripunits(a::Unitful.Quantity, u::Unitful.Units)
    try
        return _stripunits(a,u)
    catch
       throw(ArgumentError("Cannot convert $a / $u to a Float64"))
    end
end

function _stripunits(a::Unitful.Quantity{T,D,UA}, u::Unitful.Units{UU,D}) where {T, D, UA,  UU}
    return a.val * Float64(Unitful.convfact(u, UA()))
end

macro stripunits_operator(op)
    blk = quote
        import Base.$op
        function Base.$op(a::Unitful.Quantity{T,D,UA}, u::Unitful.Units{UU,D}) where {T, D, UA,  UU}
            _stripunits(a, u)
        end
    end
    push!(blk.args, :nothing)
    blk.head = :toplevel
    return blk
end
1 Like