maxwell.scm 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. ; -*- mode: scheme; coding: utf-8 -*-
  2. ; (c) Daniel Llorens - 2019
  3. ; This library is free software; you can redistribute it and/or modify it under
  4. ; the terms of the GNU General Public License as published by the Free
  5. ; Software Foundation; either version 3 of the License, or (at your option) any
  6. ; later version.
  7. ;;; Commentary:
  8. ;; 4-vector potential vacuum field equations
  9. ;; Version of 'Maxwell' from Chaitin 1986, Physics in APL2, p.20, to demo guile-newra.
  10. ;; FIXME Redo with lazy ops.
  11. ;;; Code:
  12. (import (newra) (srfi srfi-64) (ice-9 format)
  13. (only (srfi srfi-43) vector-swap!)
  14. (only (rnrs base) exact))
  15. ; transpose/untranspose isn't convenient here :-\
  16. (define (⌽ n k A)
  17. (let ((A (ra-copy A)))
  18. (vector-swap! (ra-dims A) 0 k)
  19. (ra-rotate! n A)
  20. (vector-swap! (ra-dims A) 0 k)
  21. A))
  22. (define ι (ra-iota)) ; index for the first dimension
  23. (define ⍉ ra-transpose)
  24. (define .. (dots))
  25. (define : (dots 1))
  26. (define (draw t F)
  27. (show t "Ey" (F t : 0 0 2 0))
  28. (show t "Bz" (F t : 0 0 2 1))
  29. (usleep #e1e4))
  30. (define (show t name F)
  31. (format #t "~a(0)=~12,10f t=~a:\n" name (F 0) t)
  32. (ra-for-each
  33. (lambda (F) (format #t "~a*\n" (make-string (exact (round (* 20 (+ 1 (max (min F +1) -1))))) #\space)))
  34. F))
  35. (define (maxwell)
  36. (let* ((δ 1)
  37. (o 20)
  38. (n 20)
  39. (m 2)
  40. (l 2)
  41. (A (make-ra 0 o n m l 4))
  42. (DA (make-ra 0 o n m l 4 4))
  43. (F (make-ra 0 o n m l 4 4))
  44. (divA (make-ra 0 o n m l))
  45. (X (make-ra 0 n m l 4))
  46. (Y (make-ra 0 n m l 4))
  47. (dn (* 2 (acos -1) (/ n))))
  48. (ra-map! (A 0 .. 2) (lambda (x) (* -1 (/ dn) (cos (* x dn)))) ι)
  49. (ra-map! (A 1 .. 2) (lambda (x) (* -1 (/ dn) (cos (* (- x δ) dn)))) ι)
  50. (do ((t 1 (+ t 1))) ((= o (+ t 1)))
  51. (ra-map! X + (⌽ +1 0 (A t)) (⌽ +1 1 (A t)) (⌽ +1 2 (A t)))
  52. (ra-map! Y + (⌽ -1 0 (A t)) (⌽ -1 1 (A t)) (⌽ -1 2 (A t)))
  53. (ra-map! (A (+ t 1)) (lambda (x y am1 a) (+ x y (- am1) (* -4 a))) X Y (A (- t 1)) (A t)))
  54. (ra-map! (DA .. 0) (lambda (a b) (/ (- a b) +2 δ)) (⌽ 1 0 A) (⌽ -1 0 A))
  55. (ra-map! (DA .. 1) (lambda (a b) (/ (- a b) -2 δ)) (⌽ 1 1 A) (⌽ -1 1 A))
  56. (ra-map! (DA .. 2) (lambda (a b) (/ (- a b) -2 δ)) (⌽ 1 2 A) (⌽ -1 2 A))
  57. (ra-map! (DA .. 3) (lambda (a b) (/ (- a b) -2 δ)) (⌽ 1 3 A) (⌽ -1 3 A))
  58. (format #t "'LORENTZ CONDITION: MAX|DIV| = 0? ~a'\n"
  59. (ra-fold (lambda (a b) (max a (magnitude b)))
  60. 0 (ra-map! divA + divA (⍉ DA 0 1 2 3 4 4))))
  61. (ra-map! F - (⍉ DA 0 1 2 3 5 4) DA)
  62. (do ((t 0 (+ t 1))) ((= o t))
  63. (draw t F))
  64. F))
  65. (test-begin "maxwell")
  66. (test-approximate 0.3039588939177449 (pk 'result ((maxwell) 19 0 0 0 2 1)) 1e-14)
  67. (define error-count (test-runner-fail-count (test-runner-current)))
  68. (test-end "maxwell")
  69. (exit error-count)