diff --git a/Project.toml b/Project.toml index 919b819..bf58126 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Geophysics" uuid = "74efdf00-b554-44e1-bd21-abb9281d951c" authors = ["Michael Reed"] -version = "0.3.1" +version = "0.3.2" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/docs/src/constants.md b/docs/src/constants.md new file mode 100644 index 0000000..e79d04a --- /dev/null +++ b/docs/src/constants.md @@ -0,0 +1,306 @@ +# Physics Constants + +```@contents +Pages = ["units.md","constants.md","convert.md"] +``` + +The following are fundamental constants of physics: + +```math +\alpha = \frac{\lambda e^2}{4\pi\varepsilon_0\hbar c} = +\frac{\lambda c\mu_0 (e\alpha_L)^2}{4\pi\hbar} = +\frac{e^2k_e}{\hbar c} = +\frac{\lambda e^2}{2\mu_0ch} = +\frac{\lambda c\mu_0\alpha_L^2}{2R_K} = +\frac{e^2Z_0}{2h} +``` + +There exists a deep relationship between the fundamental constants, which also makes them very suitable as a basis for `UnitSystem` dimensional analysis. All of the formulas on this page are part of the `Test` suite to guarantee their universal correctness. + +```math +\mu_{eu} = \frac{m_e}{m_u}, \qquad +\mu_{pu} = \frac{m_p}{m_u}, \qquad +\mu_{pe} = \frac{m_p}{m_e}, \qquad +\alpha_\text{inv} = \frac{1}{\alpha}, \qquad +\alpha_G = \left(\frac{m_e}{m_P}\right)^2 +``` + +```@docs +αinv +``` + +## Fundamental Constants + +```math +\Delta\nu_{\text{Cs}} = \Delta\tilde\nu_{\text{Cs}}c = \frac{\Delta\omega_{\text{Cs}}}{2\pi} = \frac{c}{\Delta\lambda_{\text{Cs}}} = \frac{\Delta E_{\text{Cs}}}{h} +``` + +```@docs +hyperfine +``` + +```math +c = \frac1{\alpha_L\sqrt{\mu_0\varepsilon_0}} = \frac{1}{\alpha}\sqrt{\frac{E_h}{m_e}} = \frac{\hbar\alpha}{m_e r_e} = \frac{e^2k_e}{\hbar\alpha} = \frac{m_e^2G}{\hbar\alpha_G} +``` +```@docs +lightspeed +``` + +```math +h = 2\pi\hbar = \frac{2e\alpha_L}{K_J} = \frac{8\alpha}{\lambda c\mu_0K_J^2} = \frac{4\alpha_L^2}{K_J^2R_K} +``` +```@docs +planck +``` + +```math +\hbar = \frac{h}{2\pi} = \frac{e\alpha_L}{\pi K_J} = \frac{4\alpha}{\pi\lambda c\mu_0K_J^2} = \frac{2\alpha_L}{\pi K_J^2R_K} +``` +```@docs +planckreduced +``` + +```math +m_P = \sqrt{\frac{\hbar c}{G}} = \frac{m_e}{\sqrt{\alpha_G}} = \frac{2R_\infty h}{c\alpha^2\sqrt{\alpha_G}} +``` +```@docs +planckmass +``` + +```math +G = \frac{\hbar c}{m_P^2} = \frac{\hbar c\alpha_G}{m_e^2} = \frac{c^3\alpha^4\alpha_G}{8\pi R_\infty^2 h} = \frac{\kappa c^4}{8\pi} +``` +```@docs +newton +``` + +```math +\kappa = \frac{8\pi G}{c^4} = \frac{8\pi\hbar}{c^3m_P^2} = \frac{8\pi\hbar\alpha_G}{c^3m_e^2} = \frac{\alpha^4\alpha_G}{R_\infty^2 h c} +``` +```@docs +einstein +``` + +## Atomic Constants + +```math +m_u = \frac{M_u}{N_A} = \frac{m_e}{\mu_{eu}} = \frac{m_p}{\mu_{pu}} = \frac{2R_\infty h}{\mu_{eu}c\alpha^2} = \frac{m_P}{\mu_{eu}}\sqrt{\alpha_G} +``` +```@docs +atomicmass +``` + +```math +m_p = \mu_{pu} m_u = \mu_{pu}\frac{M_u}{N_A} = \mu_{pe}m_e = \mu_{pe}\frac{2R_\infty h}{c\alpha^2} = m_P\mu_{pe}\sqrt{\alpha_G} +``` +```@docs +protonmass +``` + +```math +m_e = \mu_{eu}m_u = \mu_{eu}\frac{M_u}{N_A} = \frac{m_p}{\mu_{pe}} = \frac{2R_\infty h}{c\alpha^2} = m_P\sqrt{\alpha_G} +``` +```@docs +electronmass +``` + +```math +E_h = m_e(c\alpha)^2 = \frac{\hbar c\alpha}{a_0} = \frac{\hbar^2}{m_ea_0^2} = 2R_\infty hc = m_P\sqrt{\alpha_G}(c\alpha)^2 +``` +```@docs +hartree +``` + +```math +R_\infty = \frac{E_h}{2hc} = \frac{m_e c\alpha^2}{2h} = \frac{\alpha}{4\pi a_0} = \frac{m_e r_e c}{2ha_0} = \frac{\alpha^2m_ec}{4\pi\hbar} = \frac{m_Pc\alpha^2\sqrt{\alpha_G}}{2h} +``` +```@docs +rydberg +``` + +```math +a_0 = \frac{\hbar}{m_ec\alpha} = \frac{\hbar^2}{k_e m_ee^2} = \frac{\mu_{pe}a_0^*}{\mu_{pe}+1} = \frac{r_e}{\alpha^2} = \frac{\alpha}{4\pi R_\infty} +``` +```@docs +bohr +``` + +```math +a_0^* = \left(1+\frac{1}{\mu_{pe}}\right)a_0 +``` +```@docs +bohrreduced +``` + +```math +r_e = \frac{\hbar\alpha}{m_ec} = \alpha^2a_0 = \frac{e^2 k_e}{m_ec^2} = \frac{2hR_\infty a_0}{m_ec} = \frac{\alpha^3}{4\pi R_\infty} +``` +```@docs +electronradius +``` + +## Thermodynamic Constants + +```math +M_u = m_uN_A = N_A\frac{m_e}{\mu_{eu}} = N_A\frac{m_p}{\mu_{pu}} = N_A\frac{2R_\infty h}{\mu_{eu}c\alpha^2} +``` +```@docs +molarmass +``` + +```math +N_A = \frac{R_u}{k_B} = \frac{M_u}{m_u} = M_u\frac{\mu_{eu}}{m_e} = M_u\frac{\mu_{eu}c\alpha^2}{2R_\infty h} +``` +```@docs +avogadro +``` + +```math +k_B = \frac{R_u}{N_A} = m_u\frac{R_u}{M_u} = \frac{m_e R_u}{\mu_{eu}M_u} = \frac{2R_uR_\infty h}{M_u \mu_{eu}c\alpha^2} +``` +```@docs +boltzmann +``` + +```math +R_u = k_B N_A = k_B\frac{M_u}{m_u} = k_BM_u\frac{\mu_{eu}}{m_e} = k_BM_u\frac{\mu_{eu}c\alpha^2}{2hR_\infty} +``` +```@docs +universal +``` + +```math +\sigma = \frac{2\pi^5 k_B^4}{15h^3c^2} = \frac{\pi^2 k_B^4}{60\hbar^3c^2} = \frac{32\pi^5 h}{15c^6\alpha^8} \left(\frac{R_uR_\infty}{\mu_{eu}M_u}\right)^4 +``` +```@docs +stefan +``` + +```math +a = 4\frac{\sigma}{c} = \frac{8\pi^5 k_B^4}{15h^3c^3} = \frac{\pi^2 k_B^4}{15\hbar^3c^3} = \frac{2^7\pi^5 h}{15c^7\alpha^8} \left(\frac{R_uR_\infty}{\mu_{eu}M_u}\right)^4 +``` +```@docs +radiationdensity +``` + +```math +K_{\text{cd}} = \frac{I_v}{\int_0^\infty \bar{y}(\lambda)\cdot\frac{dI_e}{d\lambda}d\lambda}, \qquad +\bar{y}\left(\frac{c}{540\times 10^{12}}\right)\cdot I_e = 1 +``` +```@docs +luminousefficacy +``` + +## Electromagnetic Constants + +```math +\lambda = \frac{4\pi\alpha_B}{\mu_0\alpha_L} = 4\pi k_e\varepsilon_0 = Z_0\varepsilon_0c +``` +```@docs +rationalization +``` + +```math +\mu_0 = \frac{1}{\varepsilon_0 (c\alpha_L)^2} = \frac{4\pi k_e}{\lambda (c\alpha_L)^2} = \frac{2h\alpha}{\lambda c(e\alpha_L)^2} = \frac{2R_K\alpha}{\lambda c\alpha_L^2} +``` +```@docs +permeability +``` + +```math +\varepsilon_0 = \frac{1}{\mu_0(c\alpha_L)^2} = \frac{\lambda}{4\pi k_e} = \frac{\lambda e^2}{2\alpha hc} = \frac{\lambda}{2R_K\alpha c} +``` +```@docs +permittivity +``` + +```math +k_e = \frac{\lambda}{4\pi\varepsilon_0} = \frac{\mu_0\lambda (c\alpha_L)^2}{4\pi} = \frac{\alpha \hbar c}{e^2} = \frac{R_K\alpha c}{2\pi} = \frac{\alpha_B}{\alpha_L\mu_0\varepsilon_0} = k_mc^2 +``` +```@docs +coulomb +``` + +```math +k_m = \alpha_L\alpha_B = \mu_0\alpha_L^2\frac{\lambda}{4\pi} = \frac{k_e}{c^2} = \frac{\alpha \hbar}{ce^2} = \frac{R_K\alpha}{2\pi c} +``` +```@docs +ampere +``` + +```math +\alpha_L = \frac{1}{c\sqrt{\mu_0\varepsilon_0}} = \frac{\alpha_B}{\mu_0\varepsilon_0k_e} = \frac{4\pi \alpha_B}{\lambda\mu_0} = \frac{k_m}{\alpha_B} +``` +```@docs +lorentz +``` + +```math +\alpha_B = \mu_0\alpha_L\frac{\lambda}{4\pi} = \alpha_L\mu_0\varepsilon_0k_e = \frac{k_m}{\alpha_L} = \frac{k_e}{c}\sqrt{\mu_0\varepsilon_0} +``` +```@docs +biotsavart +``` + +```math +e = \sqrt{\frac{2h\alpha}{Z_0}} = \frac{2\alpha_L}{K_JR_K} = \sqrt{\frac{h}{R_K}} = \frac{hK_J}{2\alpha_L} = \frac{F}{N_A} +``` +```@docs +charge +``` + +```math +F = eN_A = N_A\sqrt{\frac{2h\alpha}{Z_0}} = \frac{2N_A\alpha_L}{K_JR_K} = N_A\sqrt{\frac{h}{R_K}} = \frac{hK_JN_A}{2\alpha_L} +``` +```@docs +faraday +``` + +```math +Z_0 = \mu_0\lambda c\alpha_L^2 = \frac{\lambda}{\varepsilon_0 c} = \lambda\alpha_L\sqrt{\frac{\mu_0}{\varepsilon_0}} = \frac{2h\alpha}{e^2} = 2R_K\alpha +``` +```@docs +impedance +``` + +```math +G_0 = \frac{2e^2}{h} = \frac{4\alpha}{Z_0} = \frac{2}{R_K} = \frac{hK_J^2}{2\alpha_L^2} = \frac{2F^2}{hN_A^2} +``` +```@docs +conductance +``` + +```math +R_K = \frac{h}{e^2} = \frac{Z_0}{2\alpha} = \frac{2}{G_0} = \frac{4\alpha_L^2}{hK_J^2} = h\frac{N_A^2}{F^2} +``` +```@docs +klitzing +``` + +```math +K_J = \frac{2e\alpha_L}{h} = \alpha_L\sqrt{\frac{8\alpha}{hZ_0}} = \alpha_L\sqrt{\frac{4}{hR_K}} = \frac{1}{\Phi_0} = \frac{2F\alpha_L}{hN_A} +``` +```@docs +josephson +``` + +```math +\Phi_0 = \frac{h}{2e\alpha_L} = \frac{1}{\alpha_L}\sqrt{\frac{hZ_0}{8\alpha}} = \frac{1}{\alpha_L}\sqrt{\frac{hR_K}{4}} = \frac{1}{K_J} = \frac{hN_A}{2F\alpha_L} +``` +```@docs +magneticflux +``` + +```math +\mu_B = \frac{e\hbar\alpha_L}{2m_e} = \frac{\hbar\alpha_L^2}{m_eK_JR_K} = \frac{h^2K_J}{8\pi m_e} = \frac{\alpha_L\hbar F}{2m_e N_A} = \frac{ec\alpha^2\alpha_L}{8\pi R_\infty} +``` +```@docs +magneton +``` + +## Constants Index + +```@index +Pages = ["constants.md","units.md"] +``` + diff --git a/docs/src/convert.md b/docs/src/convert.md new file mode 100644 index 0000000..ca777fb --- /dev/null +++ b/docs/src/convert.md @@ -0,0 +1,152 @@ +# Unit Conversions + +```@contents +Pages = ["units.md","constants.md","convert.md"] +``` + +Common conversion factors for physics units between `UnitSystem` specifications. + +## Kinematic Units + +```@docs +time +length +area +UnitSystems.volume(::UnitSystem,::UnitSystem) +wavenumber +fuelefficiency +frequency +frequencydrift +speed +acceleration +jerk +snap +volumeflow +``` + +## Mechanical Units + +```@docs +mass +massflow +lineardensity +areadensity +density +specificvolume +force +stiffness +pressure +compressibility +viscosity +diffusivity +rotationalinertia +momentum +angularmomentum +yank +energy +specificenergy +action +fluence +power +powerdensity +intensity +spectralflux +soundexposure +impedance(::UnitSystem,::UnitSystem) +specificimpedance +admittance +compliance +inertance +``` + +## Electromagnetic Units + +**Warning**: the following unit conversions have not yet been verified for CGS `UnitSystem` variants due to lack of [reference](https://www.qsl.net/g4cnn/units/units.htm) [information](https://phys.libretexts.org/Bookshelves/Electricity_and_Magnetism/Book%3A_Electricity_and_Magnetism_(Tatum)/17%3A_Magnetic_Dipole_Moment/17.05%3A_Possible_Alternative_Definitions_of_Magnetic_Moment): `rigidity`, `mobility`, `magneticmoment`. + +```@docs +charge(::UnitSystem,::UnitSystem) +chargedensity +linearchargedensity +exposure +mobility +current +currentdensity +resistance +conductance(::UnitSystem,::UnitSystem) +resistivity +conductivity +capacitance +inductance +reluctance +permeance +permittivity(::UnitSystem,::UnitSystem) +permeability(::UnitSystem,::UnitSystem) +susceptibility +specificsusceptibility +demagnetizingfactor +vectorpotential +electricpotential +magneticpotential +electricfield +magneticfield +electricflux +magneticflux(::UnitSystem,::UnitSystem) +electricfluxdensity +magneticfluxdensity +electricdipolemoment +magneticdipolemoment +electricpolarizability +magneticpolarizability +magneticmoment +magnetizability +magnetization +specificmagnetization +rigidity +polestrength +``` + +## Thermodynamic Units + +```@docs +temperature +entropy +specificentropy +volumeheatcapacity +thermalconductivity +thermalconductance +thermalresistance +thermalexpansion +lapserate +``` + +## Molar Units + +```@docs +molarmass(::UnitSystem,::UnitSystem) +molality +mole +molarity +molarvolume +molarentropy +molarenergy +molarconductivity +molarsusceptibility +catalysis +specificity +``` + +## Photometric Units + +```@docs +luminousflux +luminance +luminousenergy +luminousexposure +luminousefficacy(::UnitSystem,::UnitSystem) +``` + +## Conversion Index + +```@index +Pages = ["convert.md","units.md"] +``` diff --git a/src/Geophysics.jl b/src/Geophysics.jl index 66a6a6c..156c20f 100644 --- a/src/Geophysics.jl +++ b/src/Geophysics.jl @@ -31,7 +31,7 @@ include("chemistry.jl") FluidState{f} Thermodynamic state of fluid `f` at temperature `T` and pressure `P`. -Induces derived values `fluid`, `temperature`, `pressure`, `density`, `specificvolume`, `kinematic`, `heatcapacity`, `thermaldiffusivity`, `elasticity`, `impedance`, `intensity`, and values associated with `f::AbstractMole` derivations. +Induces derived values `fluid`, `temperature`, `pressure`, `density`, `specificvolume`, `kinematic`, `heatcapacity`, `thermaldiffusivity`, `elasticity`, `specificimpedance`, `intensity`, and values associated with `f::AbstractMole` derivations. """ struct FluidState{f,u} T::Float64 @@ -42,7 +42,8 @@ for Gas ∈ (:SutherlandGas,:Mixture,:AtomicGas,:DiatomicGas,:TriatomicGas) @eval (G::$Gas)(T=288.15,P=atm,U=Metric) = FluidState{G,U}(T,P) end -units(::FluidState{f,u}) where {f,u} = u +@pure units(::FluidState{f,u}) where {f,u} = u +(U::UnitSystem)(F::FluidState{G,S}) where {G,S} = FluidState{G,U}(temperature(F,U),pressure(F,U)) """ fluid(x) @@ -71,7 +72,7 @@ for op ∈ Properties @eval @pure $op(F::FluidState,U::US=units(F)) = $op(fluid(F),U) end for op ∈ Intrinsic - @eval @pure $op(F::FluidState,U::US=units(F)) = $op(temperature(F),fluid(F),U) + @eval @pure $op(F::FluidState,U::US=units(F)) = $op(temperature(F,U),fluid(F),U) end @doc """ @@ -177,11 +178,11 @@ Bulk modulus of elasticity `B` at a pressure and temperature (Pa or slug⋅ft⁻ @pure elasticity(F::FluidState,U::US=units(F)) = heatratio(F,U)*pressure(F,U) """ - impedance(F::FluidState) = density(F)*sonicspeed(F) + specificimpedance(F::FluidState) = density(F)*sonicspeed(F) Specific acoustic resistance at a pressure and temperature (kg⋅m⁻³⋅s⁻¹ or slug⋅ft⁻³⋅s⁻¹). """ -@pure impedance(F::FluidState,U::US=units(F)) = density(F,U)*sonicspeed(F,U) +@pure specificimpedance(F::FluidState,U::US=units(F)) = density(F,U)*sonicspeed(F,U) """ intensity(F::FluidState) = pressure(F)^2/impedance(F) @@ -207,6 +208,7 @@ end @pure units(::Atmosphere{n,U}) where {n,U} = U Atmosphere(a::Values{n},h::Values{n}) where n = Atmosphere{Metric}(a,h) Atmosphere{U}(a::Values{n},h::Values{n}) where {n,U} = Atmosphere{U}(a,h,zeros(Values{n})) +(U::UnitSystem)(A::Atmosphere{n,S}) where {n,S} = Atmosphere{U}(lapserate.(A.a,Ref(U),Ref(S)),length.(A.h,Ref(U),Ref(S))) function display(A::Atmosphere) println(typeof(A)) @@ -221,7 +223,7 @@ end Weather{r,g,f,n} Thermodynamic column state of fluid `f` at sea level radius `r` and gravitational acceleration `g` having `n` thermal `Atmosphere` layers. -Induces derived values `fluid`, `temperature`, `pressure`, `density`, `specificvolume`, `kinematic`, `heatcapacity`, `thermaldiffusivity`, `elasticity`, `impedance`, `intensity`, `specificweight`, `geopotential`, and inherited values associated with `f::AbstractMole` derivations. +Induces derived values `fluid`, `temperature`, `pressure`, `density`, `specificvolume`, `kinematic`, `heatcapacity`, `thermaldiffusivity`, `elasticity`, `specificimpedance`, `intensity`, `specificweight`, `geopotential`, and inherited values associated with `f::AbstractMole` derivations. """ struct Weather{r,g,f,n,U} # radius, acceleration A::Atmosphere{n,U} # altitude lapse rate @@ -254,6 +256,7 @@ function Weather{r,g}(A::Atmosphere{n,U},F::FluidState{f}) where {r,g,f,n,U} Weather{r,g,f}(A,Values(T),Values(p),Values(ρ)) end +(U::UnitSystem)(W::Weather{r,g,f,n,S}) where {r,g,f,n,S} = Weather{r,g,f}(U(W.A),temperature.(W.T,Ref(U),Ref(S)),pressure.(W.p,Ref(U),Ref(S)),density.(W.ρ,Ref(U),Ref(S))) (A::Atmosphere)(F::FluidState=Air(288.16,atm,US(A)),r=6.356766e6,g=g₀) = Weather{r,g}(A,F) (A::Atmosphere)(T,p=atm,r=6.356766e6,g=g₀) = Weather{r,g}(A,Air(T,p,units(A))) (W::Weather)(hG::Real=0) = W(hG,layer(hG,W)) @@ -272,11 +275,14 @@ function display(W::Weather) println(" ρ = ",W.ρ) end -@pure @inline Base.getindex(W::Weather,i::Int) = W.T[i],W.A.a[i],W.A.h[i],W.p[i],W.ρ[i] +@pure @inline function Base.getindex(W::Weather,i::Int,U::UnitSystem=units(W)) + T,a,h,p,ρ = W.T[i],W.A.a[i],W.A.h[i],W.p[i],W.ρ[i]; S = units(W) + temperature(T,U,S),lapserate(a,U,S),length(h,U,S),pressure(p,U,S),density(ρ,U,S) +end @pure @inline Base.getindex(W::Weather,::Val{i}) where i = getindex(W,i) -@pure @inline lapserate(h::Real,W::Weather=Standard) = W[layer(h,W)] -@pure @inline layer(h::Real,W::Weather,U::US) = layer(length(h,U,units(W)),W) -@pure layer(h::Real,W::Weather=Standard) = h≤W.A.h[1] ? 1 : (i=findfirst(x->x≥h,W.A.h); isnothing(i) ? length(W.A.h) : i-1) +@pure @inline lapserate(h::Real,W::Weather=Standard) = W.A.a[layer(h,W)] +@pure @inline layer(h::Real,W::Weather=Standard) = h≤W.A.h[1] ? 1 : (i=findfirst(x->x≥h,W.A.h); isnothing(i) ? length(W.A.h) : i-1) +@pure @inline layer(h::Real,W::Weather,U::US) = layer(length(h,units(W),U),W) @pure units(::Weather{r,g,f,n,U}) where {r,g,f,n,U} = U @pure fluid(::Weather{r,g,f}=Standard) where {r,g,f} = f @@ -286,18 +292,17 @@ end Sea level radius `r` to planet's center of gravity at `Weather` column location (m or ft). """ -@pure radius(::Weather{r}=Standard) where r = r +@pure radius(W::Weather{r}=Standard,U::US=units(W)) where r = length(r,U,units(W)) """ gravity(::Weather) Sea level gravitational acceleration `g` at `Weather` column location (m⋅s⁻² or ft⋅s⁻²). """ -@pure gravity(::Weather{r,g}=Standard) where {r,g} = g +@pure gravity(W::Weather{r,g}=Standard,U::US=units(W)) where {r,g} = acceleration(g,U,units(W)) -for op ∈ Properties - @eval @pure $op(W::Weather=Standard) = $op(fluid(W)) -end +@pure molecularmass(W::Weather=Standard,U::US=units(W)) = molecularmass(fluid(W),U) +@pure gasconstant(W::Weather=Standard,U::US=units(W)) = gasconstant(fluid(W),U) # hG = geopotential altitude, h = geometric altitude @@ -306,44 +311,49 @@ end Absolute altitude from planet's center of gravity (m or ft). """ -@pure @inline altabs(h::Real=0,W::Weather=Standard) = radius(W)+h +@pure @inline altabs(h::Real=0,W::Weather=Standard,U::US=units(W)) = radius(W,U)+h +@pure @inline altabs(h::Real,W::Weather,U::US,S::US) = altabs(length(h,U,S),W,U) """ altgeopotent(h::Real,W::Weather=Standard) = h*radius(W)/altabs(h,W) Geopotential altitude `hG` conversion from geometric altitude (m or ft). """ -@pure altgeopotent(h::Real,W::Weather=Standard) = (h/altabs(h,W))radius(W) +@pure altgeopotent(h::Real,W::Weather=Standard,U::US=US(W)) = (h/altabs(h,W,U))radius(W,U) +@pure altgeopotent(h::Real,W::Weather,U::US,S::US) = altgeopotent(length(h,U,S),W,U) """ altgeometric(hG::Real,W::Weather=Standard) = radius(W)/(radius(W)/hG-1) Geometric altitude `h` conversion from geopotential altitude (m or ft). """ -@pure altgeometric(hG::Real,W::Weather=Standard) = (r=radius(W); r/(r/hG-1)) +@pure altgeometric(hG::Real,W::Weather=Standard,U::US=US(W)) = (r=radius(W,U); r/(r/hG-1)) +@pure altgeometric(hG::Real,W::Weather,U::US,S::US) = altgeometric(length(hG,U,S),W,U) """ gravity(h::Real=0,W::Weather=Standard) = gravity(W)*radius(W)^2/altabs(h,W)^2 Gravitational acceleration `g` at altitude `h` of `Weather` column (m⋅s⁻² or ft⋅s⁻²). """ -@pure gravity(h::Real,W::Weather=Standard) = (gravity(W)*radius(W)^2)/altabs(h,W)^2 +@pure gravity(h::Real,W::Weather=Standard,U::US=US(W)) = (gravity(W,U)*radius(W,U)^2)/altabs(h,W,U)^2 +@pure gravity(h::Real,W::Weather,U::US,S::US) = gravity(length(h,U,S),W,U) """ temperature(h::Real=0,::Weather=Standard) Absolute temperature `T` at geometric altitude `h` of `Weather` location (K or °R). """ -@pure temperature(h::Real,i,W::Weather=Standard) = _temperature(altgeopotent(h,W),i,W) -@pure function _temperature(hG::Real,i,W::Weather=Standard) - T0,a0,h0 = W[i] +@pure temperature(h::Real,i,W::Weather=Standard,U::US=US(W)) = _temperature(altgeopotent(h,W,U),i,W,U) +@pure function _temperature(hG::Real,i,W::Weather=Standard,U::US=units(W)) + T0,a0,h0 = W[i,U] return T0+a0*(hG-h0) end # k, μ, cᵥ, cₚ, γ, Pr, a, e, h for op ∈ Intrinsic - @eval @pure $op(h::Real,i,W::Weather=Standard) = $op(temperature(h,i,W),fluid(W),US(W)) + @eval @pure $op(h::Real,i,W::Weather=Standard,U::US=US(W)) = $op(temperature(h,i,W,U),fluid(W),U) + @eval @pure $op(h::Real,i,W::Weather,U::US,S::US) = $op(length(h,U,S),i,W,U) end @doc """ @@ -411,13 +421,13 @@ Speed of sound wave disturbance at altitude `h` of `Weather` location (m⋅s⁻ Absolute force per unit area `P` at altitude `h` of `Weather` column (Pa or slug⋅ft⁻¹⋅s⁻²). """ -@pure function pressure(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - pressure(h,_temperature(hG,i,W),i,W) +@pure function pressure(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + pressure(h,_temperature(hG,i,W,U),i,W,U) end -@pure function pressure(hG::Real,T,i,W::Weather=Standard) - g,R = gravity(W),gasconstant(W) - T0,a,h0,p = W[i] +@pure function pressure(hG::Real,T,i,W::Weather=Standard,U::US=units(W)) + g,R = gravity(W,U),gasconstant(W,U) + T0,a,h0,p = W[i,U] p*(if iszero(a) exp((-g/R)*(hG-h0)/T) else @@ -430,13 +440,14 @@ end Inertial mass per volume `ρ` at altitude `h` of `Weather` location (kg⋅m⁻³ or slugs⋅ft⁻³). """ -@pure function density(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - density(h,_temperature(hG,i,W),i,W) +@pure function density(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + density(h,_temperature(hG,i,W,U),i,W,U) end -@pure function density(hG::Real,T,i,W::Weather=Standard) - g,R = gravity(W),gasconstant(W) - T0,a,h0,_,ρ = W[i] +@pure density(hG::Real,T,i,W::Weather,U::US,S::US) = density(length(h,U,S),temperature(T,U,S),i,W,U) +@pure function density(hG::Real,T,i,W::Weather=Standard,U::US=units(W)) + g,R = gravity(W,U),gasconstant(W,U) + T0,a,h0,_,ρ = W[i,U] ρ*(if iszero(a) exp((-g/R)*(hG-h0)/T) else @@ -449,21 +460,22 @@ end Kinematic viscosity ratio `ν` at altitude `h` of `Weather` location (m²⋅s⁻¹ or ft²⋅s⁻¹). """ -@pure function kinematic(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - kinematic(h,_temperature(hG,i,W),i,W) +@pure function kinematic(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + kinematic(h,_temperature(hG,i,W,U),i,W,U) end -@pure kinematic(hG::Real,T,i,W::Weather=Standard) = viscosity(T,fluid(W),units(W))/density(hG,T,i,W) +@pure kinematic(hG::Real,T,i,W::Weather,U::US,S::US) = kinematic(length(h,U,S),temperature(T,U,S),i,W,U) +@pure kinematic(hG::Real,T,i,W::Weather=Standard,U::US=units(W)) = viscosity(T,fluid(W),U)/density(hG,T,i,W,U) """ heatcapacity(h::Real=0,W::Weather=Standard) = heatcapacity(W(h)) Specific heat per mass at altitude `h` of `Weather` location (J⋅m⁻³⋅K⁻¹ or lb⋅ft⁻²⋅°R⁻¹). """ -@pure function heatcapacity(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - T = _temperature(hG,i,W) - heatpressure(T,fluid(W),units(W))*density(hG,T,i,W) +@pure function heatcapacity(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + heatpressure(T,fluid(W),U)*density(hG,T,i,W,U) end """ @@ -471,11 +483,10 @@ end Thermal diffusivity `α` at altitude `h` of `Weather` location (m²⋅s⁻¹ or ft²⋅s⁻¹). """ -@pure function thermaldiffusivity(h::Real,i,W::Weather=Standard) - F,U = fluid(W),units(W) - hG = altgeopotent(h,W) - T = _temperature(h,i,W) - thermalconductivity(T,F,U)/heatpressure(T,F,U)/density(hG,T,i,W) +@pure function thermaldiffusivity(h::Real,i,W::Weather=Standard,U::US=units(W)) + F,hG = fluid(W),altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + thermalconductivity(T,F,U)/heatpressure(T,F,U)/density(hG,T,i,W,U) end """ @@ -483,21 +494,21 @@ end Bulk modulus of elasticity `B` at altitude `h` of `Weather` location (Pa or slug⋅ft⁻¹⋅s⁻²). """ -@pure function elasticity(h,i,W::Weather=Standard) - hG = altgeopotent(h,W) - T = _temperature(hG,i,W) - heatratio(T,fluid(W),units(W))*pressure(hG,T,i,W) +@pure function elasticity(h,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + heatratio(T,fluid(W),U)*pressure(hG,T,i,W,U) end """ - impedance(h::Real=0,W::Weather=Standard) = impedance(W(h)) + specificimpedance(h::Real=0,W::Weather=Standard) = impedance(W(h)) Specific acoustic resistance at altitude `h` of `Weather` (kg⋅m⁻³⋅s⁻¹ or slug⋅ft⁻³⋅s⁻¹). """ -@pure function impedance(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - T = _temperature(hG,i,W) - density(hG,T,i,W)*sonicspeed(T,fluid(W),units(W)) +@pure function specificimpedance(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + density(hG,T,i,W,U)*sonicspeed(T,fluid(W),U) end """ @@ -505,25 +516,25 @@ end Instantaneous intensity `I` at altitude `h` of `Weather` at location (W⋅m⁻² or slug⋅s⁻³). """ -@pure function intensity(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - T = _temperature(hG,i,W) - g,R = gravity(W),gasconstant(W) - T0,a,h0,p,ρ = W[i] +@pure function intensity(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + g,R = gravity(W,U),gasconstant(W,U) + T0,a,h0,p,ρ = W[i,U] (p^2/ρ)*(if iszero(a) exp((-g/R)*(hG-h0)/T) else t,gRa = T/T0,(-g/R)/a t^2gRa/t^(gRa-1) - end)/sonicspeed(T,fluid(W),units(W)) + end)/sonicspeed(T,fluid(W),U) end # Grashof number -@pure function grashof(h::Real,i,W::Weather=Standard) - hG = altgeopotent(h,W) - T = _temperature(hG,i,W) - gravity(h,W)*(temperature(W)-T)*(h^3)/(T*kinematic(hG,T,i,W)^2) +@pure function grashof(h::Real,i,W::Weather=Standard,U::US=units(W)) + hG = altgeopotent(h,W,U) + T = _temperature(hG,i,W,U) + gravity(h,W,U)*(temperature(W,U)-T)*(h^3)/(T*kinematic(hG,T,i,W,U)^2) end """ @@ -531,35 +542,39 @@ end Specific weight at altitude `h` of `Weather` location (kg⋅m⁻²⋅s⁻² or slugs⋅ft⁻²⋅s⁻²). """ -@pure specificweight(h::Real,i,W::Weather=Standard) = density(h,i,W)*gravity(h,W) +@pure specificweight(h::Real,i,W::Weather=Standard,U::US=US(W)) = density(h,i,W,U)*gravity(h,W,U) """ specificvolume(h::Real=0,W::Weather=Standard) = specificvolume(W(h)) Specific volume per mass `v` at altitude `h` of `Weather` location (m³⋅kg⁻¹, ft³⋅slug⁻¹). """ -@pure specificvolume(h::Real,i,W::Weather=Standard) = inv(density(h,i,W)) +@pure specificvolume(h::Real,i,W::Weather=Standard,U::US=US(W)) = inv(density(h,i,W,U)) """ geopotential(h::Real=0,W::Weather=Standard) = gravity(h,W)*h Specifc gravitational potential energy `g` at altitude `h` of `Weather` (m²⋅s⁻², ft²⋅s⁻²). """ -@pure geopotential(h::Real,i,W::Weather=Standard) = gravity(h,W)*h +@pure geopotential(h::Real,i,W::Weather=Standard,U::US=US(W)) = gravity(h,W,U)*h # common interface -for op ∈ (:temperature,:pressure,:density,:weight,:specificvolume,:geopotential,:impedance,:grashof,:thermaldiffusivity,:intensity,:heatcapacity,:kinematic,:elasticity,Intrinsic...) +for op ∈ (:temperature,:pressure,:density,:specificweight,:specificvolume,:geopotential,:specificimpedance,:grashof,:thermaldiffusivity,:intensity,:heatcapacity,:kinematic,:elasticity,Intrinsic...) opratio = Symbol(op,:ratio) @eval begin export $op - @pure $op(W::Weather=Standard) = $op(0,W) - @pure $op(h::Real,W::Weather=Standard) = $op(h,layer(h,W),W) + @pure $op(W::Weather=Standard,U::US=Metric) = $op(0,W,U) + @pure $op(h::Real,W::Weather=Standard,U::US=US(W)) = $op(h,layer(h,W,U),W,U) + @pure $op(h::Real,W::Weather,U::US,S::US) = $op(length(h,U,S),W,U) + @pure $op(h,i,W::Weather,U::US,S::US) = $op(length(h,U,S),i,W,U) end op ∉ (:heatcapacity,:grashof,:geopotential) && @eval begin export $opratio - @pure $opratio(h::Real,W::Weather=Standard) = $opratio(h,layer(h,W),W) - @pure $opratio(h::Real,i,W::Weather=Standard) = $op(h,i,W)/$op(W) + @pure $opratio(h::Real,W::Weather=Standard,U::US=US(W)) = $opratio(h,layer(h,W,U),W,U) + @pure $opratio(h::Real,i,W::Weather=Standard,U::US=US(W)) = $op(h,i,W,U)/$op(W,U) + @pure $opratio(h::Real,W::Weather,U::US,S::US) = $opratio(length(h,U,S),W,U) + @pure $opratio(h::Real,i,W::Weather,U::US,S::US) = $opratio(length(h,U,S),i,W,U) end end diff --git a/src/chemistry.jl b/src/chemistry.jl index 4b44fff..b084574 100644 --- a/src/chemistry.jl +++ b/src/chemistry.jl @@ -97,6 +97,13 @@ end k = k0*sqrt(Tk)*(T0+Tk)/T return μ,k end +#=@pure function viscond(G,T=518.69) + μ = viscosity(T/kelvin,G)*0.020886 + Tμ = sutherlandviscosity(G)/rankine + k = thermalconductivity(T/kelvin,G)*0.5778*778/3600 + Tk = sutherlandconductivity(G)/rankine + return μ,Tμ,k,Tk +end=# for heat ∈ (:heatratio,:heatvolume,:heatpressure) @eval @pure $heat(M::AbstractMole,U::US=Metric) = $heat(temperature(288.16,U,Metric),M,U) diff --git a/test/runtests.jl b/test/runtests.jl index 102a4e2..ef9a770 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,4 +15,4 @@ st = Standard(0) @test thermaldiffusivity() ≈ thermaldiffusivity(st) @test prandtl() ≈ prandtl(st) @test sonicspeed() == sonicspeed(st) -@test impedance() ≈ impedance(st) +@test specificimpedance() ≈ specificimpedance(st)