step one
This commit is contained in:
parent
7a8d5d13fa
commit
9e663db9dc
68 changed files with 5647 additions and 2958 deletions
94
internal/numerics/grid_test.go
Normal file
94
internal/numerics/grid_test.go
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package numerics
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAxisLocate(t *testing.T) {
|
||||
a := Axis{Left: -90, Step: 0.5, N: 361, Name: "lat"}
|
||||
|
||||
b, err := a.Locate(-90)
|
||||
if err != nil || b.Lo != 0 || b.Hi != 1 || b.Frac != 0 {
|
||||
t.Errorf("Locate(-90) = %+v, %v; want {0 1 0}, nil", b, err)
|
||||
}
|
||||
|
||||
b, err = a.Locate(0)
|
||||
if err != nil || b.Lo != 180 || b.Hi != 181 || b.Frac != 0 {
|
||||
t.Errorf("Locate(0) = %+v, %v; want {180 181 0}, nil", b, err)
|
||||
}
|
||||
|
||||
b, err = a.Locate(-89.75)
|
||||
if err != nil || b.Lo != 0 || b.Hi != 1 || math.Abs(b.Frac-0.5) > 1e-12 {
|
||||
t.Errorf("Locate(-89.75) = %+v, %v; want frac=0.5", b, err)
|
||||
}
|
||||
|
||||
// 90 is exactly on the upper boundary — there's no Hi above it
|
||||
if _, err := a.Locate(90); err == nil {
|
||||
t.Errorf("Locate(90) should error, got nil")
|
||||
}
|
||||
|
||||
if _, err := a.Locate(-91); err == nil {
|
||||
t.Errorf("Locate(-91) should error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAxisLocateWrap(t *testing.T) {
|
||||
a := Axis{Left: 0, Step: 0.5, N: 720, Wrap: true, Name: "lng"}
|
||||
|
||||
b, err := a.Locate(0)
|
||||
if err != nil || b.Lo != 0 || b.Hi != 1 || b.Frac != 0 {
|
||||
t.Errorf("Locate(0) = %+v, %v", b, err)
|
||||
}
|
||||
|
||||
// Right up against the wrap boundary
|
||||
b, err = a.Locate(359.75)
|
||||
if err != nil || b.Lo != 719 || b.Hi != 0 || math.Abs(b.Frac-0.5) > 1e-12 {
|
||||
t.Errorf("Locate(359.75) = %+v, %v; want {719 0 0.5}", b, err)
|
||||
}
|
||||
|
||||
// 360 is outside the half-open interval
|
||||
if _, err := a.Locate(360); err == nil {
|
||||
t.Errorf("Locate(360) should error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvalTrilinear(t *testing.T) {
|
||||
// Field f(i,j,k) = 100*i + 10*j + k.
|
||||
f := func(i, j, k int) float64 { return 100*float64(i) + 10*float64(j) + float64(k) }
|
||||
|
||||
// At all fractions = 0.5, expected value is the mean of the 8 corners.
|
||||
bs := [3]Bracket{{Lo: 0, Hi: 1, Frac: 0.5}, {Lo: 0, Hi: 1, Frac: 0.5}, {Lo: 0, Hi: 1, Frac: 0.5}}
|
||||
got := EvalTrilinear(bs, f)
|
||||
want := (0 + 1 + 10 + 11 + 100 + 101 + 110 + 111) / 8.0
|
||||
if math.Abs(got-want) > 1e-12 {
|
||||
t.Errorf("EvalTrilinear at center = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
// At all fractions = 0, expected value is f(lo, lo, lo) = 0.
|
||||
bs = [3]Bracket{{Lo: 0, Hi: 1, Frac: 0}, {Lo: 0, Hi: 1, Frac: 0}, {Lo: 0, Hi: 1, Frac: 0}}
|
||||
got = EvalTrilinear(bs, f)
|
||||
if got != 0 {
|
||||
t.Errorf("EvalTrilinear at (lo,lo,lo) = %v, want 0", got)
|
||||
}
|
||||
|
||||
// Asymmetric: linear field f(i,j,k) = i should give frac of axis 0 exactly.
|
||||
f2 := func(i, _, _ int) float64 { return float64(i) }
|
||||
bs = [3]Bracket{{Lo: 0, Hi: 1, Frac: 0.3}, {Lo: 0, Hi: 1, Frac: 0.7}, {Lo: 0, Hi: 1, Frac: 0.9}}
|
||||
got = EvalTrilinear(bs, f2)
|
||||
if math.Abs(got-0.3) > 1e-12 {
|
||||
t.Errorf("EvalTrilinear of i-field = %v, want 0.3", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLerp(t *testing.T) {
|
||||
if Lerp(10, 20, 0) != 10 {
|
||||
t.Errorf("Lerp(10, 20, 0) != 10")
|
||||
}
|
||||
if Lerp(10, 20, 1) != 20 {
|
||||
t.Errorf("Lerp(10, 20, 1) != 20")
|
||||
}
|
||||
if math.Abs(Lerp(10, 20, 0.25)-12.5) > 1e-12 {
|
||||
t.Errorf("Lerp(10, 20, 0.25) != 12.5")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue