solar 0.0.2 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +30 -5
- data/README.rdoc +2 -2
- data/VERSION +1 -1
- data/lib/solar.rb +7 -462
- data/lib/solar/day_night.rb +65 -0
- data/lib/solar/lambert.rb +68 -0
- data/lib/solar/passages.rb +174 -0
- data/lib/solar/position.rb +51 -0
- data/lib/solar/radiation.rb +258 -0
- data/lib/solar/support.rb +228 -0
- data/solar.gemspec +15 -8
- data/test/test_solar.rb +11 -0
- metadata +29 -38
@@ -0,0 +1,228 @@
|
|
1
|
+
module Solar
|
2
|
+
|
3
|
+
ALTITUDES = {
|
4
|
+
official: -50/60.0,
|
5
|
+
civil: -6.0,
|
6
|
+
nautical: -12.0,
|
7
|
+
astronomical: -18.0
|
8
|
+
}
|
9
|
+
|
10
|
+
class <<self
|
11
|
+
private
|
12
|
+
|
13
|
+
# Julian Day as Rational
|
14
|
+
def jd_r(t)
|
15
|
+
if false
|
16
|
+
# This computes JD with precision of seconds and yields smaller denominators
|
17
|
+
t = t.utc
|
18
|
+
t.to_date.ajd + Rational(t.hour,24) + Rational(t.min,1440) + Rational(t.sec,86_400)
|
19
|
+
else
|
20
|
+
# This preserves the internal precision of t (which we probably don't need)
|
21
|
+
# and produces larger denominators in general
|
22
|
+
t.to_datetime.utc.ajd
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Julian Day as Float
|
27
|
+
def jd_f(t)
|
28
|
+
# t.to_date.ajd.to_f + t.hour/24.0 + t.min/1440.0 + t.sec/86400.0
|
29
|
+
t.to_datetime.utc.ajd.to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_rad(deg)
|
33
|
+
deg*Math::PI/180.0
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_deg(rad)
|
37
|
+
rad*180.0/Math::PI
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_h(deg)
|
41
|
+
deg/15.0
|
42
|
+
end
|
43
|
+
|
44
|
+
# Julian day to Julian Centuries since J2000.0
|
45
|
+
def to_jc(jd)
|
46
|
+
(jd - 2_451_545)/36_525
|
47
|
+
end
|
48
|
+
|
49
|
+
def polynomial(coefficients, x)
|
50
|
+
coefficients.inject(0.0) { |p, a| p*x + a }
|
51
|
+
end
|
52
|
+
|
53
|
+
# Conversion of Float to Rational preserving the exact value of the number
|
54
|
+
def to_r(x)
|
55
|
+
x = x.to_f
|
56
|
+
return Rational(x.to_i,1) if x.modulo(1) == 0
|
57
|
+
if !x.finite?
|
58
|
+
return Rational(0,0) if x.nan?
|
59
|
+
return x < 0 ? Rational(-1,0) : Rational(1,0)
|
60
|
+
end
|
61
|
+
|
62
|
+
f,e = Math.frexp(x)
|
63
|
+
|
64
|
+
if e < Float::MIN_EXP
|
65
|
+
bits = e + Float::MANT_DIG - Float::MIN_EXP
|
66
|
+
else
|
67
|
+
bits = [Float::MANT_DIG, e].max
|
68
|
+
# return Rational(x.to_i, 1) if bits < e
|
69
|
+
end
|
70
|
+
p = Math.ldexp(f,bits)
|
71
|
+
e = bits - e
|
72
|
+
if e<Float::MAX_EXP
|
73
|
+
q = Math.ldexp(1, e)
|
74
|
+
else
|
75
|
+
q = Float::RADIX**e
|
76
|
+
end
|
77
|
+
Rational(p.to_i, q.to_i)
|
78
|
+
end
|
79
|
+
|
80
|
+
# time to dynamical time
|
81
|
+
def to_td(t)
|
82
|
+
t = t.utc
|
83
|
+
t + to_r(delta_t(t))/86_400
|
84
|
+
end
|
85
|
+
|
86
|
+
# dynamical_time to utc
|
87
|
+
def to_utc(td)
|
88
|
+
raise 'Invalid dynamical time (should be utc)' unless td.utc?
|
89
|
+
td - to_r(delta_t(td))/86_400
|
90
|
+
end
|
91
|
+
|
92
|
+
# Compute difference between dynamical time and UTC in seconds.
|
93
|
+
#
|
94
|
+
# See http://sunearth.gsfc.nasa.gov/eclipse/SEcat5/deltatpoly.html.
|
95
|
+
#
|
96
|
+
# Good from -1999 to +3000.
|
97
|
+
#
|
98
|
+
def delta_t(date)
|
99
|
+
year = date.year.to_f
|
100
|
+
y = year + (date.month.to_f - 0.5) / 12.0
|
101
|
+
|
102
|
+
case
|
103
|
+
when year < -500.0
|
104
|
+
u = (year - 1820.0) / 100.0
|
105
|
+
-20.0 + 32.0*u*u
|
106
|
+
when year < 500.0
|
107
|
+
u = y / 100.0
|
108
|
+
polynomial [0.0090316521, 0.022174192, -0.1798452, -5.952053, 33.78311, -1014.41, 10583.6], u
|
109
|
+
when year < 1600.0
|
110
|
+
u = (y - 1000.0) / 100.0
|
111
|
+
polynomial [0.0083572073, -0.005050998, -0.8503463, 0.319781, 71.23472, -556.01, 1574.2], u
|
112
|
+
when year < 1700.0
|
113
|
+
t = y - 1600.0
|
114
|
+
polynomial [1.0/7129.0, -0.01532, -0.9808, 120.0], t
|
115
|
+
when year < 1800.0
|
116
|
+
t = y - 1700.0
|
117
|
+
polynomial [-1.0/1174000.0, 0.00013336, -0.0059285, 0.1603, 8.83], t
|
118
|
+
when year < 1860.0
|
119
|
+
t = y - 1800.0
|
120
|
+
polynomial [0.000000000875, -0.0000001699, 0.0000121272, -0.00037436, 0.0041116, 0.0068612, -0.332447, 13.72], t
|
121
|
+
when year < 1900.0
|
122
|
+
t = y - 1860.0
|
123
|
+
polynomial [1.0/233174.0, -0.0004473624, 0.01680668, -0.251754, 0.5737, 7.62], t
|
124
|
+
when year < 1920.0
|
125
|
+
t = y - 1900.0
|
126
|
+
polynomial [-0.000197, 0.0061966, -0.0598939, 1.494119, -2.79], t
|
127
|
+
when year < 1941.0
|
128
|
+
t = y - 1920.0
|
129
|
+
polynomial [0.0020936, -0.076100, 0.84493, 21.20], t
|
130
|
+
when year < 1961.0
|
131
|
+
t = y - 1950.0
|
132
|
+
polynomial [1.0/2547.0, -1.0/233.0, 0.407, 29.07], t
|
133
|
+
when year < 1986.0
|
134
|
+
t = y - 1975.0
|
135
|
+
polynomial [-1.0/718.0, -1.0/260.0, 1.067, 45.45], t
|
136
|
+
when year < 2005.0
|
137
|
+
t = y - 2000.0
|
138
|
+
polynomial [0.00002373599, 0.000651814, 0.0017275, -0.060374, 0.3345, 63.86], t
|
139
|
+
when year < 2050.0
|
140
|
+
t = y - 2000.0
|
141
|
+
polynomial [0.005589, 0.32217, 62.92], t
|
142
|
+
when year < 2150.0
|
143
|
+
-20.0 + 32.0*((y - 1820.0)/100.0)**2 - 0.5628*(2150.0 - y)
|
144
|
+
else
|
145
|
+
u = (year - 1820.0) / 100.0
|
146
|
+
-20.0 + 32*u*u
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Solar equatorial coordinates / Low accuracy : Meeus pg 151
|
151
|
+
# returns [declination in radians, right ascension in radians]
|
152
|
+
def equatorial_position_rad(t)
|
153
|
+
# t as Julian centuries of 36525 ephemeris days form the epoch J2000.0
|
154
|
+
if false
|
155
|
+
# Float
|
156
|
+
jd = jd_f(to_td(t))
|
157
|
+
else
|
158
|
+
# Rational
|
159
|
+
jd = jd_r(to_td(t))
|
160
|
+
end
|
161
|
+
t = to_jc(jd)
|
162
|
+
|
163
|
+
# Geometric mean longitude of the Sun, referred to the mean equinox of the date
|
164
|
+
l = 280.46645 + (36_000.76983 + 0.0003032*t)*t
|
165
|
+
|
166
|
+
# Mean anomaly of the Sun
|
167
|
+
m_deg = 357.52910 + (35_999.05030 - (0.0001559 + 0.00000048*t)*t)*t
|
168
|
+
m_rad = to_rad(m_deg)
|
169
|
+
|
170
|
+
# Eccentricity of the Earth's orbit
|
171
|
+
e = 0.016708617 - (0.000042037 + 0.0000001236*t)*t
|
172
|
+
|
173
|
+
# Sun's Equation of the center
|
174
|
+
c = (1.914600 - (0.004817 + 0.000014*t)*t)*Math.sin(m_rad) +
|
175
|
+
(0.019993 - 0.000101*t)*Math.sin(2*m_rad) +
|
176
|
+
0.000290*Math.sin(3*m_rad)
|
177
|
+
|
178
|
+
# Sun's true longitude
|
179
|
+
o = l + c
|
180
|
+
|
181
|
+
# Reduce magnitude to minimize errors
|
182
|
+
o %= 360
|
183
|
+
|
184
|
+
# Sun's apparent Longitude
|
185
|
+
omega_deg = 125.04 - 1934.136*t
|
186
|
+
omega_rad = to_rad(omega_deg)
|
187
|
+
lambda_deg = o - 0.00569 - 0.00478 * Math.sin(omega_rad)
|
188
|
+
|
189
|
+
# Reduce magnitude to minimize errors
|
190
|
+
lambda_deg %= 360
|
191
|
+
|
192
|
+
lambda_rad = to_rad(lambda_deg)
|
193
|
+
|
194
|
+
# Obliquity of the ecliptic
|
195
|
+
epsilon_deg = 23.4392966666667 -
|
196
|
+
(0.012777777777777778 + (0.00059/60 - 0.00059/60*t)*t)*t +
|
197
|
+
0.00256*Math.cos(omega_rad)
|
198
|
+
epsilon_rad = to_rad(epsilon_deg)
|
199
|
+
|
200
|
+
# Sun's declination
|
201
|
+
delta_rad = Math.asin(Math.sin(epsilon_rad)*Math.sin(lambda_rad))
|
202
|
+
|
203
|
+
# Sun's right ascension
|
204
|
+
alpha_rad = Math.atan2(
|
205
|
+
Math.cos(epsilon_rad) * Math.sin(lambda_rad),
|
206
|
+
Math.cos(lambda_rad)
|
207
|
+
)
|
208
|
+
|
209
|
+
[delta_rad, alpha_rad]
|
210
|
+
end
|
211
|
+
|
212
|
+
def altitude_from_options(options)
|
213
|
+
if options.has_key?(:zenith)
|
214
|
+
zenith = options[:zenith]
|
215
|
+
if Symbol===zenith
|
216
|
+
altitude = ALTITUDES[zenith]
|
217
|
+
else
|
218
|
+
altitude = 90.0 - zenith
|
219
|
+
end
|
220
|
+
else
|
221
|
+
altitude = options[:altitude] || :official
|
222
|
+
altitude = ALTITUDES[altitude] if Symbol===altitude
|
223
|
+
end
|
224
|
+
altitude
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
data/solar.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: solar 0.1.1 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "solar"
|
8
|
-
s.version = "0.
|
9
|
+
s.version = "0.1.1"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Javier Goizueta"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2015-07-23"
|
13
15
|
s.description = "# Calculation of solar position, rise & set times for a given position & time."
|
14
16
|
s.email = "jgoizueta@gmail.com"
|
15
17
|
s.extra_rdoc_files = [
|
@@ -25,38 +27,43 @@ Gem::Specification.new do |s|
|
|
25
27
|
"Rakefile",
|
26
28
|
"VERSION",
|
27
29
|
"lib/solar.rb",
|
30
|
+
"lib/solar/day_night.rb",
|
31
|
+
"lib/solar/lambert.rb",
|
32
|
+
"lib/solar/passages.rb",
|
33
|
+
"lib/solar/position.rb",
|
34
|
+
"lib/solar/radiation.rb",
|
35
|
+
"lib/solar/support.rb",
|
28
36
|
"solar.gemspec",
|
29
37
|
"test/helper.rb",
|
30
38
|
"test/test_solar.rb"
|
31
39
|
]
|
32
40
|
s.homepage = "http://github.com/jgoizueta/solar"
|
33
41
|
s.licenses = ["MIT"]
|
34
|
-
s.
|
35
|
-
s.rubygems_version = "1.8.23"
|
42
|
+
s.rubygems_version = "2.2.2"
|
36
43
|
s.summary = "# Calculation of solar position, rise & set times"
|
37
44
|
|
38
45
|
if s.respond_to? :specification_version then
|
39
|
-
s.specification_version =
|
46
|
+
s.specification_version = 4
|
40
47
|
|
41
48
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
42
49
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
43
50
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
44
51
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
45
52
|
s.add_development_dependency(%q<bundler>, ["~> 1"])
|
46
|
-
s.add_development_dependency(%q<jeweler>, ["~>
|
53
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
|
47
54
|
else
|
48
55
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
49
56
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
50
57
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
51
58
|
s.add_dependency(%q<bundler>, ["~> 1"])
|
52
|
-
s.add_dependency(%q<jeweler>, ["~>
|
59
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
53
60
|
end
|
54
61
|
else
|
55
62
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
56
63
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
57
64
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
58
65
|
s.add_dependency(%q<bundler>, ["~> 1"])
|
59
|
-
s.add_dependency(%q<jeweler>, ["~>
|
66
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
data/test/test_solar.rb
CHANGED
@@ -26,4 +26,15 @@ class TestSolar < Test::Unit::TestCase
|
|
26
26
|
assert_equal :day, Solar.day_or_night(Time.utc(2012,10,7,9,0,0), 0, -89)
|
27
27
|
end
|
28
28
|
|
29
|
+
should "compute radiation accurately" do
|
30
|
+
# from [Duffie-1991] Example 1.10.1
|
31
|
+
dt = 600.0 # integrate in 10-minute steps
|
32
|
+
r = 0.0
|
33
|
+
(0...24*3600.0).step(dt) do |h|
|
34
|
+
t = Date.new(1991, 4, 15).to_time + h
|
35
|
+
r += dt*Solar.radiation(t, 0.0, 43.0, clearness_index: 1.0)*1E-6
|
36
|
+
end
|
37
|
+
assert_in_delta 33.8, r, 33.8*1E-3
|
38
|
+
end
|
39
|
+
|
29
40
|
end
|
metadata
CHANGED
@@ -1,98 +1,87 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Javier Goizueta
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-07-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activesupport
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: shoulda
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rdoc
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '3.12'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '3.12'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- - ~>
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '1'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '1'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: jeweler
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- - ~>
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
75
|
+
version: 2.0.1
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- - ~>
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
94
|
-
description:
|
95
|
-
& time.
|
82
|
+
version: 2.0.1
|
83
|
+
description: "# Calculation of solar position, rise & set times for a given position
|
84
|
+
& time."
|
96
85
|
email: jgoizueta@gmail.com
|
97
86
|
executables: []
|
98
87
|
extensions: []
|
@@ -100,7 +89,7 @@ extra_rdoc_files:
|
|
100
89
|
- LICENSE.txt
|
101
90
|
- README.rdoc
|
102
91
|
files:
|
103
|
-
- .document
|
92
|
+
- ".document"
|
104
93
|
- Gemfile
|
105
94
|
- Gemfile.lock
|
106
95
|
- LICENSE.txt
|
@@ -108,35 +97,37 @@ files:
|
|
108
97
|
- Rakefile
|
109
98
|
- VERSION
|
110
99
|
- lib/solar.rb
|
100
|
+
- lib/solar/day_night.rb
|
101
|
+
- lib/solar/lambert.rb
|
102
|
+
- lib/solar/passages.rb
|
103
|
+
- lib/solar/position.rb
|
104
|
+
- lib/solar/radiation.rb
|
105
|
+
- lib/solar/support.rb
|
111
106
|
- solar.gemspec
|
112
107
|
- test/helper.rb
|
113
108
|
- test/test_solar.rb
|
114
109
|
homepage: http://github.com/jgoizueta/solar
|
115
110
|
licenses:
|
116
111
|
- MIT
|
112
|
+
metadata: {}
|
117
113
|
post_install_message:
|
118
114
|
rdoc_options: []
|
119
115
|
require_paths:
|
120
116
|
- lib
|
121
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
118
|
requirements:
|
124
|
-
- -
|
119
|
+
- - ">="
|
125
120
|
- !ruby/object:Gem::Version
|
126
121
|
version: '0'
|
127
|
-
segments:
|
128
|
-
- 0
|
129
|
-
hash: -3223580498560321012
|
130
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
-
none: false
|
132
123
|
requirements:
|
133
|
-
- -
|
124
|
+
- - ">="
|
134
125
|
- !ruby/object:Gem::Version
|
135
126
|
version: '0'
|
136
127
|
requirements: []
|
137
128
|
rubyforge_project:
|
138
|
-
rubygems_version:
|
129
|
+
rubygems_version: 2.2.2
|
139
130
|
signing_key:
|
140
|
-
specification_version:
|
141
|
-
summary:
|
131
|
+
specification_version: 4
|
132
|
+
summary: "# Calculation of solar position, rise & set times"
|
142
133
|
test_files: []
|