This repository has been archived by the owner on Jan 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwavetools.go
140 lines (116 loc) · 4.62 KB
/
wavetools.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package surfnerd
import (
"math"
)
// Computes speed and heading given the u and vvector components
func ScalarFromUV(ucomponent, vcomponent float64) (speed, heading float64) {
heading = math.Mod((270.0 - (math.Atan2(vcomponent, ucomponent) * (180 / math.Pi))), 360)
speed = math.Sqrt(math.Pow(math.Abs(vcomponent), 2) + math.Pow(math.Abs(ucomponent), 2))
return
}
// Computes the wavelength for a wave with the given period
// and depth. Units are metric, gravity is 9.81.
func LDis(period, depth float64) float64 {
const gravity = 9.81
const eps = 0.000001
const maxIteration = 50
iteration := 0
err := float64(1.0)
var OMEGA float64 = 2 * math.Pi / period
var D float64 = math.Pow(OMEGA, 2) * depth / gravity
var Xo float64
var Xf float64
var F float64
var DF float64
// Make an initial guess for non dimentional solutions
if D >= 1 {
Xo = D
} else {
Xo = math.Sqrt(D)
}
// Solve using Newton Raphson Iteration
for (err > eps) && (iteration < maxIteration) {
F = Xo - (D / math.Tanh(Xo))
DF = 1 + (D / math.Pow(math.Sinh(Xo), 2))
Xf = Xo - (F / DF)
err = math.Abs((Xf - Xo) / Xo)
Xo = Xf
iteration += 1
}
// Check for convergence failure
if iteration >= maxIteration {
return -1.0
}
return 2 * math.Pi * depth / Xf
}
// Solves for the Breaking Wave Height and Breaking Water Depth given a swell and beach conditions.
// All units are metric and gravity is 9.81.
func SolveBreakingCharacteristics(period, incidentAngle, deepWaveHeight, beachSlope, waterDepth float64) (breakingWaveHeight, breakingWaterDepth float64) {
const gravity = 9.81
incidentAngleRad := incidentAngle * math.Pi / 180
// Find all of the wave characteristics
wavelength := LDis(period, waterDepth)
deepWavelength := (gravity * math.Pow(period, 2)) / (2 * math.Pi)
initialCelerity := (gravity * period) / (2 * math.Pi)
celerity := wavelength / period
theta := math.Asin(celerity * ((math.Sin(incidentAngleRad)) / initialCelerity))
refractionCoeff := math.Sqrt(math.Cos(incidentAngleRad) / math.Cos(theta))
a := 43.8 * (1 - math.Exp(-19*beachSlope))
b := 1.56 / (1 + math.Exp(-19.5*beachSlope))
deepRefractedWaveHeight := refractionCoeff * deepWaveHeight
w := 0.56 * math.Pow(deepRefractedWaveHeight/deepWavelength, -0.2)
// Find the breaking wave height!
breakingWaveHeight = w * deepRefractedWaveHeight
// Solve for the breaking depth
K := b - a*(breakingWaveHeight/(gravity*math.Pow(period, 2)))
breakingWaterDepth = breakingWaveHeight / K
return
}
// Calculate the refraction coefficient Kr with given
// inputs on a straight beach with parrellel bottom contours
func SolveRefractionCoefficient(wavelength, depth, incidentAngle float64) (refractionCoeff, shallowIncidentAngle float64) {
incidentAngleRad := incidentAngle * math.Pi / 180.0
wavenumber := (2.0 * math.Pi) / wavelength
shallowIncidentAngleRad := math.Asin(math.Sin(incidentAngleRad) * math.Tanh(wavenumber*depth))
refractionCoeff = math.Sqrt(math.Cos(incidentAngleRad) / math.Cos(shallowIncidentAngleRad))
shallowIncidentAngle = shallowIncidentAngleRad * 180 / math.Pi
return
}
// Calculate the shoaling coeffecient Ks. Units are metric, gravity is 9.81
func SolveShoalingCoefficient(wavelength, depth float64) (shoalingCoefficient float64) {
const gravity = 9.81
// Basic dispersion relationships
wavenumber := (2.0 * math.Pi) / wavelength
deepWavelength := wavelength / math.Tanh(wavenumber*depth)
w := math.Sqrt(wavenumber * gravity)
period := (2.0 * math.Pi) / w
// Celerity
initialCelerity := deepWavelength / period
celerity := initialCelerity * math.Tanh(wavenumber*depth)
groupVelocity := 0.5 * celerity * (1 + ((2 * wavenumber * depth) / (math.Sinh(2 * wavenumber * depth))))
shoalingCoefficient = math.Sqrt(initialCelerity / (2 * groupVelocity))
return
}
// Calculates the zero moment of a wave spectra point given energy and bandwidth
func SolveZeroSpectralMoment(energy, bandwidth float64) float64 {
return energy * bandwidth
}
// Calculates the second moment of a wave spectra point given enrgy, frequency and bandwith
func SolveSecondSpectralMoment(energy, bandwidth, frequency float64) float64 {
return energy * bandwidth * math.Pow(frequency, 2)
}
func SolveSteepnessCoeffWithMoments(zeroMoment, secondMoment float64) float64 {
return (8.0 * math.Pi * secondMoment) / (9.81 * math.Sqrt(zeroMoment))
}
func SolveSteepness(significantWaveWieght, dominantPeriod float64) string {
val := math.Exp(-3.3 * math.Log(dominantPeriod))
if significantWaveWieght > (val / 250.0) {
return "Very Steep"
} else if significantWaveWieght > (val / 500.0) {
return "Steep"
} else if significantWaveWieght > (val / 1000.0) {
return "Average"
} else {
return "Swell"
}
}