@neaps/tide-predictor 0.0.4
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.
- package/.eslintrc.js +22 -0
- package/.github/workflows/test.yml +15 -0
- package/.prettierrc +4 -0
- package/Gruntfile.js +87 -0
- package/LICENSE +21 -0
- package/README.md +199 -0
- package/babel.config.js +9 -0
- package/dist/tide-predictor.js +1013 -0
- package/examples/browser/index.html +51 -0
- package/jest.config.js +14 -0
- package/lib/astronomy/coefficients.js +31 -0
- package/lib/astronomy/constants.js +10 -0
- package/lib/astronomy/index.js +199 -0
- package/lib/constituents/compound-constituent.js +67 -0
- package/lib/constituents/constituent.js +74 -0
- package/lib/constituents/index.js +140 -0
- package/lib/harmonics/index.js +113 -0
- package/lib/harmonics/prediction.js +195 -0
- package/lib/index.es6.js +1005 -0
- package/lib/index.js +53 -0
- package/lib/node-corrections/index.js +147 -0
- package/package.json +45 -0
- package/rollup.config.js +21 -0
- package/src/__mocks__/constituents.js +335 -0
- package/src/__mocks__/secondary-station.js +11 -0
- package/src/__tests__/index.js +81 -0
- package/src/__tests__/noaa.js +92 -0
- package/src/astronomy/__tests__/coefficients.js +12 -0
- package/src/astronomy/__tests__/index.js +96 -0
- package/src/astronomy/coefficients.js +72 -0
- package/src/astronomy/constants.js +4 -0
- package/src/astronomy/index.js +201 -0
- package/src/constituents/__tests__/compound-constituent.js +44 -0
- package/src/constituents/__tests__/constituent.js +65 -0
- package/src/constituents/__tests__/index.js +34 -0
- package/src/constituents/compound-constituent.js +55 -0
- package/src/constituents/constituent.js +74 -0
- package/src/constituents/index.js +119 -0
- package/src/harmonics/__mocks__/water-levels.js +0 -0
- package/src/harmonics/__tests__/index.js +123 -0
- package/src/harmonics/__tests__/prediction.js +148 -0
- package/src/harmonics/index.js +87 -0
- package/src/harmonics/prediction.js +175 -0
- package/src/index.js +45 -0
- package/src/node-corrections/__tests__/index.js +114 -0
- package/src/node-corrections/index.js +208 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import nodeCorrections from '../index'
|
|
2
|
+
|
|
3
|
+
const testItems = {
|
|
4
|
+
i: {
|
|
5
|
+
value: 5
|
|
6
|
+
},
|
|
7
|
+
I: { value: 6 },
|
|
8
|
+
omega: { value: 3 },
|
|
9
|
+
nu: { value: 4 },
|
|
10
|
+
nup: { value: 4 },
|
|
11
|
+
nupp: { value: 2 },
|
|
12
|
+
P: { value: 14 },
|
|
13
|
+
xi: {
|
|
14
|
+
value: 4
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('Node corrections', () => {
|
|
19
|
+
test('have correct unity', () => {
|
|
20
|
+
expect(nodeCorrections.fUnity()).toBe(1)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('calculates Schureman equations 73, 65 (f_Mm)', () => {
|
|
24
|
+
expect(nodeCorrections.fMm(testItems)).toBeCloseTo(0.999051998091, 4)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('calculates Schureman equations 74, 66 (f_Mf)', () => {
|
|
28
|
+
expect(nodeCorrections.fMf(testItems)).toBeCloseTo(4.00426673883, 4)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('calculates Schureman equations 75, 67 (f_O1)', () => {
|
|
32
|
+
expect(nodeCorrections.fO1(testItems)).toBeCloseTo(2.00076050158, 4)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('calculates Schureman equations 76, 68 (f_J1)', () => {
|
|
36
|
+
expect(nodeCorrections.fJ1(testItems)).toBeCloseTo(2.0119685329, 4)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('calculates Schureman equations 77, 69 (f_OO1)', () => {
|
|
40
|
+
expect(nodeCorrections.fOO1(testItems)).toBeCloseTo(8.01402871709, 4)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('calculates Schureman equations 78, 70 (f_M2)', () => {
|
|
44
|
+
expect(nodeCorrections.fM2(testItems)).toBeCloseTo(0.999694287563, 4)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('calculates Schureman equations 227, 226, 68 (f_K1)', () => {
|
|
48
|
+
expect(nodeCorrections.fK1(testItems)).toBeCloseTo(1.23843964182, 4)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('calculates Schureman equations 215, 213, 204 (f_L2)', () => {
|
|
52
|
+
expect(nodeCorrections.fL2(testItems)).toBeCloseTo(0.98517860327, 4)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('calculates Schureman equations 235, 234, 71 (f_K2)', () => {
|
|
56
|
+
expect(nodeCorrections.fK2(testItems)).toBeCloseTo(1.09775430048, 4)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('calculates Schureman equations 206, 207, 195 (f_M1)', () => {
|
|
60
|
+
expect(nodeCorrections.fM1(testItems)).toBeCloseTo(3.90313810168, 4)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('calculates e.g. Schureman equation 149 (f_Modd)', () => {
|
|
64
|
+
expect(nodeCorrections.fModd(testItems, 3)).toBeCloseTo(0.999541466395, 4)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('has a zero for u_zero', () => {
|
|
68
|
+
expect(nodeCorrections.uZero()).toBe(0.0)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('calculates u_Mf', () => {
|
|
72
|
+
expect(nodeCorrections.uMf(testItems)).toBe(-8.0)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('calculates u_O1', () => {
|
|
76
|
+
expect(nodeCorrections.uO1(testItems)).toBe(4.0)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('calculates u_J1', () => {
|
|
80
|
+
expect(nodeCorrections.uJ1(testItems)).toBe(-4)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test('calculates u_OO1', () => {
|
|
84
|
+
expect(nodeCorrections.uOO1(testItems)).toBe(-12.0)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('calculates u_M2', () => {
|
|
88
|
+
expect(nodeCorrections.uM2(testItems)).toBe(0.0)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('calculates u_K1', () => {
|
|
92
|
+
expect(nodeCorrections.uK1(testItems)).toBe(-4)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('calculates u_L2', () => {
|
|
96
|
+
expect(nodeCorrections.uL2(testItems)).toBeCloseTo(-0.449812364499, 4)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('calculates u_K2', () => {
|
|
100
|
+
expect(nodeCorrections.uK2(testItems)).toBe(-4.0)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('calculates u_K2', () => {
|
|
104
|
+
expect(nodeCorrections.uK2(testItems)).toBe(-4.0)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('calculates u_M1', () => {
|
|
108
|
+
expect(nodeCorrections.uM1(testItems)).toBeCloseTo(7.09154172301, 4)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('calculates u_Modd', () => {
|
|
112
|
+
expect(nodeCorrections.uModd(testItems, 3)).toBe(0)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { d2r, r2d } from '../astronomy/constants'
|
|
2
|
+
|
|
3
|
+
const corrections = {
|
|
4
|
+
fUnity() {
|
|
5
|
+
return 1
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
// Schureman equations 73, 65
|
|
9
|
+
fMm(a) {
|
|
10
|
+
const omega = d2r * a.omega.value
|
|
11
|
+
const i = d2r * a.i.value
|
|
12
|
+
const I = d2r * a.I.value
|
|
13
|
+
const mean =
|
|
14
|
+
(2 / 3.0 - Math.pow(Math.sin(omega), 2)) *
|
|
15
|
+
(1 - (3 / 2.0) * Math.pow(Math.sin(i), 2))
|
|
16
|
+
return (2 / 3.0 - Math.pow(Math.sin(I), 2)) / mean
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
// Schureman equations 74, 66
|
|
20
|
+
fMf(a) {
|
|
21
|
+
const omega = d2r * a.omega.value
|
|
22
|
+
const i = d2r * a.i.value
|
|
23
|
+
const I = d2r * a.I.value
|
|
24
|
+
const mean = Math.pow(Math.sin(omega), 2) * Math.pow(Math.cos(0.5 * i), 4)
|
|
25
|
+
return Math.pow(Math.sin(I), 2) / mean
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
// Schureman equations 75, 67
|
|
29
|
+
fO1(a) {
|
|
30
|
+
const omega = d2r * a.omega.value
|
|
31
|
+
const i = d2r * a.i.value
|
|
32
|
+
const I = d2r * a.I.value
|
|
33
|
+
const mean =
|
|
34
|
+
Math.sin(omega) *
|
|
35
|
+
Math.pow(Math.cos(0.5 * omega), 2) *
|
|
36
|
+
Math.pow(Math.cos(0.5 * i), 4)
|
|
37
|
+
return (Math.sin(I) * Math.pow(Math.cos(0.5 * I), 2)) / mean
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// Schureman equations 76, 68
|
|
41
|
+
fJ1(a) {
|
|
42
|
+
const omega = d2r * a.omega.value
|
|
43
|
+
const i = d2r * a.i.value
|
|
44
|
+
const I = d2r * a.I.value
|
|
45
|
+
const mean =
|
|
46
|
+
Math.sin(2 * omega) * (1 - (3 / 2.0) * Math.pow(Math.sin(i), 2))
|
|
47
|
+
return Math.sin(2 * I) / mean
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Schureman equations 77, 69
|
|
51
|
+
fOO1(a) {
|
|
52
|
+
const omega = d2r * a.omega.value
|
|
53
|
+
const i = d2r * a.i.value
|
|
54
|
+
const I = d2r * a.I.value
|
|
55
|
+
const mean =
|
|
56
|
+
Math.sin(omega) *
|
|
57
|
+
Math.pow(Math.sin(0.5 * omega), 2) *
|
|
58
|
+
Math.pow(Math.cos(0.5 * i), 4)
|
|
59
|
+
return (Math.sin(I) * Math.pow(Math.sin(0.5 * I), 2)) / mean
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// Schureman equations 78, 70
|
|
63
|
+
fM2(a) {
|
|
64
|
+
const omega = d2r * a.omega.value
|
|
65
|
+
const i = d2r * a.i.value
|
|
66
|
+
const I = d2r * a.I.value
|
|
67
|
+
const mean =
|
|
68
|
+
Math.pow(Math.cos(0.5 * omega), 4) * Math.pow(Math.cos(0.5 * i), 4)
|
|
69
|
+
return Math.pow(Math.cos(0.5 * I), 4) / mean
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// Schureman equations 227, 226, 68
|
|
73
|
+
// Should probably eventually include the derivations of the magic numbers (0.5023 etc).
|
|
74
|
+
fK1(a) {
|
|
75
|
+
const omega = d2r * a.omega.value
|
|
76
|
+
const i = d2r * a.i.value
|
|
77
|
+
const I = d2r * a.I.value
|
|
78
|
+
const nu = d2r * a.nu.value
|
|
79
|
+
const sin2IcosnuMean =
|
|
80
|
+
Math.sin(2 * omega) * (1 - (3 / 2.0) * Math.pow(Math.sin(i), 2))
|
|
81
|
+
const mean = 0.5023 * sin2IcosnuMean + 0.1681
|
|
82
|
+
return (
|
|
83
|
+
Math.pow(
|
|
84
|
+
0.2523 * Math.pow(Math.sin(2 * I), 2) +
|
|
85
|
+
0.1689 * Math.sin(2 * I) * Math.cos(nu) +
|
|
86
|
+
0.0283,
|
|
87
|
+
0.5
|
|
88
|
+
) / mean
|
|
89
|
+
)
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// Schureman equations 215, 213, 204
|
|
93
|
+
// It can be (and has been) confirmed that the exponent for R_a reads 1/2 via Schureman Table 7
|
|
94
|
+
fL2(a) {
|
|
95
|
+
const P = d2r * a.P.value
|
|
96
|
+
const I = d2r * a.I.value
|
|
97
|
+
const rAInv = Math.pow(
|
|
98
|
+
1 -
|
|
99
|
+
12 * Math.pow(Math.tan(0.5 * I), 2) * Math.cos(2 * P) +
|
|
100
|
+
36 * Math.pow(Math.tan(0.5 * I), 4),
|
|
101
|
+
0.5
|
|
102
|
+
)
|
|
103
|
+
return corrections.fM2(a) * rAInv
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// Schureman equations 235, 234, 71
|
|
107
|
+
// Again, magic numbers
|
|
108
|
+
fK2(a) {
|
|
109
|
+
const omega = d2r * a.omega.value
|
|
110
|
+
const i = d2r * a.i.value
|
|
111
|
+
const I = d2r * a.I.value
|
|
112
|
+
const nu = d2r * a.nu.value
|
|
113
|
+
const sinsqIcos2nuMean =
|
|
114
|
+
Math.sin(omega) ** 2 * (1 - (3 / 2.0) * Math.sin(i) ** 2)
|
|
115
|
+
const mean = 0.5023 * sinsqIcos2nuMean + 0.0365
|
|
116
|
+
return (
|
|
117
|
+
Math.pow(
|
|
118
|
+
0.2523 * Math.pow(Math.sin(I), 4) +
|
|
119
|
+
0.0367 * Math.pow(Math.sin(I), 2) * Math.cos(2 * nu) +
|
|
120
|
+
0.0013,
|
|
121
|
+
0.5
|
|
122
|
+
) / mean
|
|
123
|
+
)
|
|
124
|
+
},
|
|
125
|
+
// Schureman equations 206, 207, 195
|
|
126
|
+
fM1(a) {
|
|
127
|
+
const P = d2r * a.P.value
|
|
128
|
+
const I = d2r * a.I.value
|
|
129
|
+
const qAInv = Math.pow(
|
|
130
|
+
0.25 +
|
|
131
|
+
1.5 *
|
|
132
|
+
Math.cos(I) *
|
|
133
|
+
Math.cos(2 * P) *
|
|
134
|
+
Math.pow(Math.cos(0.5 * I), -0.5) +
|
|
135
|
+
2.25 * Math.pow(Math.cos(I), 2) * Math.pow(Math.cos(0.5 * I), -4),
|
|
136
|
+
0.5
|
|
137
|
+
)
|
|
138
|
+
return corrections.fO1(a) * qAInv
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
// See e.g. Schureman equation 149
|
|
142
|
+
fModd(a, n) {
|
|
143
|
+
return Math.pow(corrections.fM2(a), n / 2.0)
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// Node factors u, see Table 2 of Schureman.
|
|
147
|
+
|
|
148
|
+
uZero(a) {
|
|
149
|
+
return 0.0
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
uMf(a) {
|
|
153
|
+
return -2.0 * a.xi.value
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
uO1(a) {
|
|
157
|
+
return 2.0 * a.xi.value - a.nu.value
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
uJ1(a) {
|
|
161
|
+
return -a.nu.value
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
uOO1(a) {
|
|
165
|
+
return -2.0 * a.xi.value - a.nu.value
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
uM2(a) {
|
|
169
|
+
return 2.0 * a.xi.value - 2.0 * a.nu.value
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
uK1(a) {
|
|
173
|
+
return -a.nup.value
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// Schureman 214
|
|
177
|
+
uL2(a) {
|
|
178
|
+
const I = d2r * a.I.value
|
|
179
|
+
const P = d2r * a.P.value
|
|
180
|
+
const R =
|
|
181
|
+
r2d *
|
|
182
|
+
Math.atan(
|
|
183
|
+
Math.sin(2 * P) /
|
|
184
|
+
((1 / 6.0) * Math.pow(Math.tan(0.5 * I), -2) - Math.cos(2 * P))
|
|
185
|
+
)
|
|
186
|
+
return 2.0 * a.xi.value - 2.0 * a.nu.value - R
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
uK2(a) {
|
|
190
|
+
return -2.0 * a.nupp.value
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
// Schureman 202
|
|
194
|
+
uM1(a) {
|
|
195
|
+
const I = d2r * a.I.value
|
|
196
|
+
const P = d2r * a.P.value
|
|
197
|
+
const Q =
|
|
198
|
+
r2d *
|
|
199
|
+
Math.atan(((5 * Math.cos(I) - 1) / (7 * Math.cos(I) + 1)) * Math.tan(P))
|
|
200
|
+
return a.xi.value - a.nu.value + Q
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
uModd(a, n) {
|
|
204
|
+
return (n / 2.0) * corrections.uM2(a)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export default corrections
|