| Line | Exclusive | Inclusive | Code |
|---|---|---|---|
| 1 | module AtmosphericModels | ||
| 2 | |||
| 3 | using KiteUtils | ||
| 4 | using HypergeometricFunctions:_âFâ | ||
| 5 | |||
| 6 | export AtmosphericModel, ProfileLaw, EXP, LOG, EXPLOG, FAST_EXP, FAST_LOG, FAST_EXPLOG | ||
| 7 | export clear, calc_rho, calc_wind_factor | ||
| 8 | |||
| 9 | const ABS_ZERO = -273.15 | ||
| 10 | """ | ||
| 11 | mutable struct AtmosphericModel | ||
| 12 | |||
| 13 | Stuct that is storing the settings and the state of the atmosphere. | ||
| 14 | """ | ||
| 15 | Base.@kwdef mutable struct AtmosphericModel | ||
| 16 | set::Settings = se() | ||
| 17 | turbulence::Float64 = 0.0 | ||
| 18 | rho_zero_temp::Float64 = (15.0 - ABS_ZERO) / (se().temp_ref - ABS_ZERO) * se().rho_0 | ||
| 19 | end | ||
| 20 | |||
| 21 | const AM = AtmosphericModel | ||
| 22 | |||
| 23 | function clear(s::AM) | ||
| 24 | s.rho_zero_temp = (15.0 - ABS_ZERO) / (s.set.temp_ref - ABS_ZERO) * s.set.rho_0 | ||
| 25 | end | ||
| 26 | |||
| 27 | @inline function fastexp(x) | ||
| 28 | y = 1 + x / 1024 | ||
| 29 | y *= y; y *= y; y *= y; y *= y; y *= y | ||
| 30 | y *= y; y *= y; y *= y; y *= y; y *= y | ||
| 31 | y | ||
| 32 | end | ||
| 33 | |||
| 34 | # Calculate the air densisity as function of height | ||
| 35 | calc_rho(s::AM, height) = s.rho_zero_temp * fastexp(-(height+s.set.height_gnd) / 8550.0) | ||
| 36 | |||
| 37 | """ | ||
| 38 | @enum ProfileLaw EXP=1 LOG=2 EXPLOG=3 | ||
| 39 | |||
| 40 | Enumeration to describe the wind profile low that is used. | ||
| 41 | """ | ||
| 42 | @enum ProfileLaw EXP=1 LOG=2 EXPLOG=3 FAST_EXP=4 FAST_LOG=5 FAST_EXPLOG=6 | ||
| 43 | |||
| 44 | # Calculate the wind speed at a given height and reference height. | ||
| 45 | @inline function calc_wind_factor1(s::AM, height); exp(s.set.alpha * log(height/s.set.h_ref)); end | ||
| 46 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{1}}) | ||
| 47 | calc_wind_factor1(s, height) | ||
| 48 | end | ||
| 49 | |||
| 50 | @inline function calc_wind_factor2(s::AM, height); log(height / s.set.z0) / log(s.set.h_ref / s.set.z0); end | ||
| 51 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{2}}) | ||
| 52 | calc_wind_factor2(s, height) | ||
| 53 | end | ||
| 54 | |||
| 55 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{3}}); calc_wind_factor3(s, height); end | ||
| 56 | @inline function calc_wind_factor3(s::AM, height) | ||
| 57 | K = 1.0 | ||
| 58 | log1 = log(height / s.set.z0) / log(s.set.h_ref / s.set.z0) | ||
| 59 | 2 (3 %) |
2 (3 %)
samples spent in calc_wind_factor3
2 (100 %) (incl.) when called from calc_wind_factor line 90
2 (100 %)
samples spent calling
exp
exp1 = exp(s.set.alpha * log(height/s.set.h_ref))
|
|
| 60 | log1 + K * (log1 - exp1) | ||
| 61 | end | ||
| 62 | |||
| 63 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{4}}); calc_wind_factor4(s, height); end | ||
| 64 | @inline function calc_wind_factor4(s::AM, height) | ||
| 65 | if height < 6.0 return 1.0 end | ||
| 66 | evalpoly(1/height, (1.8427619589823305, 3617.0786194064476, 590119.886685333, -2.53435240735932e6, 5.4120682033388115e7, -9.636216067310344e8, 1.2056636533430845e10, -9.962127083327875e10, 5.1324465874649536e11, -1.4865348277628154e12, 1.8431054022301477e12))/ | ||
| 67 | evalpoly(1/height, (1.0, 2487.0429567107535, 495940.74312868936)) | ||
| 68 | end | ||
| 69 | |||
| 70 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{5}}); calc_wind_factor5(s, height); end | ||
| 71 | @inline function calc_wind_factor5(s::AM, height) | ||
| 72 | if height < 6.0 return 1.0 end | ||
| 73 | evalpoly(1/height, (1.7254692847178346, 3180.6368701426595, 489764.5131517146, -2.1080713892318057e6, 4.227143439940046e7, -7.322154139158928e8, 9.013764300164715e9, -7.36716754548423e10, 3.7658022380555835e11, -1.0842283673197954e12, 1.338030926540245e12))/ | ||
| 74 | evalpoly(1/height, (1.0, 2200.4764287411545, 404389.8285052791)) | ||
| 75 | end | ||
| 76 | |||
| 77 | @inline function calc_wind_factor(s::AM, height, ::Type{Val{6}}); calc_wind_factor6(s, height); end | ||
| 78 | function calc_wind_factor6(s::AM, height) | ||
| 79 | if height < 6.0 return 1.0 end | ||
| 80 | evalpoly(1/height, (1.6133163094857612, 2488.963179734051, 343230.7633444393, -1.450703528831999e6, 2.6919154959563803e7, -4.4848947369166476e8, 5.387689053876384e9, -4.329358467994954e10, 2.1854676308520227e11, -6.232058566966395e11, 7.632537480818357e11))/ | ||
| 81 | evalpoly(1/height, (1.0, 1735.2333827029918, 279373.0012683715)) | ||
| 82 | end | ||
| 83 | |||
| 84 | @inline function calc_wind_factor(am::AM, height, profile_law::Int64=am.set.profile_law) | ||
| 85 | 2 (3 %) |
2 (100 %)
samples spent calling
calc_wind_factor
if profile_law == 1
|
|
| 86 | calc_wind_factor1(am, height) | ||
| 87 | elseif profile_law == 2 | ||
| 88 | calc_wind_factor2(am, height) | ||
| 89 | elseif profile_law == 3 | ||
| 90 | 2 (3 %) |
2 (3 %)
samples spent in calc_wind_factor
2 (100 %) (incl.) when called from calc_wind_factor line 85
2 (100 %)
samples spent calling
calc_wind_factor3
calc_wind_factor3(am, height)
|
|
| 91 | elseif profile_law == 4 | ||
| 92 | calc_wind_factor4(am, height) | ||
| 93 | elseif profile_law == 5 | ||
| 94 | calc_wind_factor5(am, height) | ||
| 95 | elseif profile_law == 6 | ||
| 96 | calc_wind_factor6(am, height) | ||
| 97 | else | ||
| 98 | throw(DomainError(profile_law, "invalid profile_law")) | ||
| 99 | end | ||
| 100 | end | ||
| 101 | |||
| 102 | include("windfield.jl") | ||
| 103 | |||
| 104 | end |