Liam,
here is an example of use of gsll. I use the lu matrix solvers to calculate the radiative heat flux between three infinite parallel plates. This function takes advantage of letm to return a *closure* that contains several solutions to the problem.
To access the results of the calculation do the following
(funcall *closure* args) where args is one of :mat, :per, :rhs, :q1, :fluxes
There are probably other ways of accomplishing similar things (like values) but I like closure because it provides permanence to the calculation until I decide to discard it.
The code is not super-clean. I wrote it a month or two back, and there is some bit-rot in it.
You can see that I had to use the data statement to revive the data. Otherwise, the closure was not able to access them. It is for this reason that I asked if we could have letm not destroying by default all of its contents, but saving some for closure use. One could label such variables with a special symbol (like !S like foo!S, which the macro would detect and then decide whether to save or not).
Mirko
(defun 3parallel-plate-equilibrium-flux (eps0 T0 eps1-0 eps1-2 T1 eps2 T2) "Solve flux to middle of three parallel plates with diffuse emission Parameters: eps0, T0: emissivity and temperature of plate 0 eps1-0, eps1-2, T1: surface emissivities of plate 1 facing plate 1 and 2 and temperature eps2, T2: emissivity and temperature of plate 2
Get results as follows: q1: (send *prob* :q1): desired flux fluxes: (send *prob* :fluxes): all fluxes
Need macro send from my-utils. Otherwise use (funcall closer args)" (letm ((dim 5) (mat (make-array (list dim dim) :element-type 'double-float :initial-contents (list (list 1d0 (1- eps0) 0d0 0d0 0d0) (list (1- eps1-0) 1d0 0d0 0d0 (0- eps1-0)) (list 0d0 0d0 1d0 (1- eps1-2) (0- eps1-2)) (list 0d0 0d0 (1- eps2) 1d0 0d0) (list eps1-0 0d0 0d0 eps1-2 1d0)))) (mmat (matrix-double-float mat)) (mmat0 mmat) (rhs (make-array dim :element-type 'double-float :initial-contents (list (st4 T0 eps0) 0d0 0d0 (st4 T2 eps2) (st4 T1 (+ eps1-0 eps1-2))))) (mrhs (vector-double-float rhs)) (per (permutation dim)) (0-vec (vector-double-float (make-array dim :initial-element 0d0))) (x (vector-double-float dim))) (lu-decomp mmat per) (lu-solve mmat per mrhs x) (data x) (data mmat) (data per) (data mrhs) (data mmat0) (data 0-vec) (lambda (command) (case command ;; (:solve (lu-solve mmat per mrhs x)) ;; (:check (gemv :notrans 1d0 mmat0 x 0d0 0-vec)) (:mat mat) (:per (data per)) (:rhs (data mrhs)) (:q1 (aref (data x) 4)) (:fluxes (data x))))))
Thanks Mirko, this is interesting. I am thinking about how to do similar things in the next version of GSLL.
Liam