(module bh-tree-test mzscheme
(require "bh-tree.scm"
(lib "math.ss")
(planet "test.ss" ("schematics" "schemeunit.plt"))
(planet "nbody-ics.scm" ("wmfarr" "nbody-ics.plt"))
(lib "42.ss" "srfi"))
(provide bh-tree-test-suite)
(define ((close? eps) a b)
(< (abs (- a b)) (abs eps)))
(define-simple-check (check-close? eps a b)
((close? eps) a b))
(define (distance-squared v w)
(sum-ec (:parallel (:vector vx v)
(:vector wx w))
(sqr (- vx wx))))
(define (distance v w) (sqrt (distance-squared v w)))
(define (body-tree-energy b t)
(let ((mb (body-m b))
(qb (body-q b))
(mt (tree-m t))
(qt (tree-q t)))
(cond
((= mt 0.0) 0.0)
((equal? qt qb) 0.0) (else (let ((r (distance qt qb)))
(- (/ (* mt mb) r)))))))
(define (tree-potential-energy bs beta2)
(let ((t (bodies->tree bs)))
(/ (sum-ec (:vector b bs)
(let ((qb (body-q b)))
(let ((cut? (lambda (t)
(let ((d2 (distance-squared (tree-q t) qb))
(s2 (tree-size-squared t)))
(< (/ s2 d2) beta2)))))
(tree-fold/sc cut?
(lambda (t E)
(let ((Ebt (body-tree-energy b t)))
(+ E Ebt)))
0
t))))
2)))
(define bh-tree-test-suite
(test-suite
"bh-tree.scm test suite"
(test-case
"Total mass and com correct for large tree."
(let ((t (bodies->tree (make-cold-spherical 1000))))
(check-close? 1e-6 1.0 (tree-m t))
(check-close? 1e-6 0.0 (vector-ref (tree-q t) 0))
(check-close? 1e-6 0.0 (vector-ref (tree-q t) 1))
(check-close? 1e-6 0.0 (vector-ref (tree-q t) 2))))
(test-case
"Number of bodies (computed from tree-fold ...) is OK."
(let ((n 1000))
(let ((t (bodies->tree (make-cold-spherical n))))
(let ((n-fold (tree-fold (lambda (b n) (+ n 1)) 0 t)))
(check-equal? n n-fold)))))
(test-case
"Compute potential energy of system"
(let ((bs (make-cold-spherical 250)))
(check-close? 0.1 -0.25 (tree-potential-energy bs (sqr 0.5))))))))