Skip to content

Commit ea4c8e1

Browse files
authored
Merge pull request #31 from asinghvi17/as/dyad
Add Dyad component and refactor MTK extension
2 parents 0b03b8c + 8580fef commit ea4c8e1

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Aqua = "0.8"
2929
Dates = "1"
3030
DocStringExtensions = "0.8, 0.9"
3131
Makie = "0.24"
32-
ModelingToolkit = "10.3.0 - 10.26.1"
32+
ModelingToolkit = "10.3.0"
3333
OhMyThreads = "0.8"
3434
StructArrays = "0.7"
3535
Symbolics = "6,7"

dyad/solarpositionblock.dyad

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
type Observer = Native
2+
type SolarAlgorithm = Native
3+
type RefractionAlgorithm = Native
4+
5+
"""
6+
Predict the Sun's position at a given `observer` location at the current time (in seconds)
7+
and output the `azimuth`, `elevation`, and `zenith` angles.
8+
9+
### Time Convention
10+
11+
The simulation time is assumed to be in **seconds** from the reference time `t0`. For example:
12+
- `t = 0` corresponds to `t0`
13+
- `t = 3600` corresponds to `t0 + 1 hour`
14+
- `t = 86400` corresponds to `t0 + 24 hours`
15+
"""
16+
external component SolarPositionBlock
17+
"Solar azimuth angle in degrees (0° = North, 90° = East, 180° = South, 270° = West)"
18+
azimuth = RealOutput()
19+
"Solar elevation angle in degrees (angle above horizon, positive when sun is visible)"
20+
elevation = RealOutput()
21+
"Solar zenith angle in degrees (angle from vertical, complementary to elevation: `zenith = 90° - elevation`)"
22+
zenith = RealOutput()
23+
24+
parameter t0::Real
25+
"location (latitude, longitude, altitude). Construct via the `SolarPosition.Observer(lat, long, alt)` constructor."
26+
parameter observer::Observer
27+
"Solar positioning algorithm. Must be a subtype of `SolarPosition.SolarAlgorithm`."
28+
parameter algorithm::SolarAlgorithm = PSA()
29+
"Atmospheric refraction correction. Must be a subtype of `SolarPosition.RefractionAlgorithm`."
30+
parameter refraction::RefractionAlgorithm = NoRefraction()
31+
end

ext/SolarPositionModelingToolkitExt.jl

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using SolarPosition: Observer, SolarAlgorithm, RefractionAlgorithm, PSA, NoRefra
44
using SolarPosition: SolPos, ApparentSolPos, SPASolPos, AbstractApparentSolPos
55
using ModelingToolkit: @parameters, @variables, System
66
using ModelingToolkit: t_nounits as t
7-
using Dates: DateTime, Millisecond
7+
using Dates: Dates, DateTime, Millisecond
88
import Symbolics
99

1010
import SolarPosition: SolarPositionBlock, solar_position
@@ -23,28 +23,39 @@ get_zenith(pos::SolPos) = pos.zenith
2323
get_elevation(pos::AbstractApparentSolPos) = pos.apparent_elevation
2424
get_zenith(pos::AbstractApparentSolPos) = pos.apparent_zenith
2525

26-
Symbolics.@register_symbolic seconds_to_datetime(t_sec, t0::DateTime)
26+
Symbolics.@register_symbolic seconds_to_datetime(t_sec, t0::DateTime)::DateTime
2727
Symbolics.@register_symbolic solar_position(
2828
observer::Observer,
2929
time::DateTime,
3030
algorithm::SolarAlgorithm,
3131
refraction::RefractionAlgorithm,
3232
)
3333

34-
Symbolics.@register_symbolic get_azimuth(pos)
35-
Symbolics.@register_symbolic get_elevation(pos)
36-
Symbolics.@register_symbolic get_zenith(pos)
34+
Symbolics.@register_symbolic get_azimuth(pos)::Real
35+
Symbolics.@register_symbolic get_elevation(pos)::Real
36+
Symbolics.@register_symbolic get_zenith(pos)::Real
3737

38-
function SolarPositionBlock(; name)
39-
@parameters t0::DateTime [tunable = false] observer::Observer [tunable = false]
40-
@parameters algorithm::SolarAlgorithm = PSA() [tunable = false]
41-
@parameters refraction::RefractionAlgorithm = NoRefraction() [tunable = false]
38+
function SolarPositionBlock(;
39+
name,
40+
t0 = Dates.now(),
41+
observer = Observer(0.0, 0.0, 0.0),
42+
algorithm = PSA(),
43+
refraction = NoRefraction(),
44+
)
45+
@parameters t0::DateTime = t0 [tunable = false]
46+
@parameters observer::Observer = observer [tunable = false]
47+
@parameters algorithm::SolarAlgorithm = algorithm [tunable = false]
48+
@parameters refraction::RefractionAlgorithm = refraction [tunable = false]
4249

4350
@variables azimuth(t) [output = true]
4451
@variables elevation(t) [output = true]
4552
@variables zenith(t) [output = true]
4653

47-
time_expr = Symbolics.term(seconds_to_datetime, t, t0; type = DateTime)
54+
# Ideally this should be expressed by a symbolic equation
55+
# but because it would involve some amount of type manipulation,
56+
# we can keep it this way for now.
57+
# But this might cause the position to be recalculated thrice (I think)
58+
time_expr = seconds_to_datetime(t, t0)
4859
pos = solar_position(observer, time_expr, algorithm, refraction)
4960

5061
eqs = [
@@ -53,7 +64,13 @@ function SolarPositionBlock(; name)
5364
zenith ~ get_zenith(pos),
5465
]
5566

56-
return System(eqs, t; name = name)
67+
return System(
68+
eqs,
69+
t,
70+
#=vars=#[azimuth, elevation, zenith],
71+
#=params=#[t0, observer, algorithm, refraction];
72+
name = name,
73+
)
5774
end
5875

5976
end # module SolarPositionModelingToolkitExt

0 commit comments

Comments
 (0)