3 (defpackage odepack-system
6 (in-package #:odepack-system)
8 (defclass odepack-fortran-file (cl-source-file)
10 (:default-initargs :type "f"))
12 (defun fortran-compile (op c &key (array-slicing t) (array-type :array) (package "ODEPACK")
13 declare-common (common-as-array t))
14 (let ((file (component-pathname c)))
15 (f2cl:f2cl-compile file
16 :output-file (first (output-files op c))
17 :array-slicing array-slicing
18 :array-type array-type
20 :declare-common declare-common
21 :common-as-array common-as-array
24 (defmethod perform ((op compile-op) (c odepack-fortran-file))
25 (fortran-compile op c :package "ODEPACK"))
27 (defmethod perform ((op load-op) (c odepack-fortran-file))
28 (load (first (input-files op c))))
31 ;; Create a logical pathname for our files.
32 (let ((base (make-pathname :directory (pathname-directory *load-pathname*))))
33 (setf (logical-pathname-translations "odepack")
34 (list (list "**;*.*.*"
35 (merge-pathnames (make-pathname :directory '(:relative "odepack" :wild-inferiors)
36 :name :wild :type :wild)
40 :description "F2CL conversion of ODEPACK: Initial value solver for ODEs"
49 :default-component-class odepack-fortran-file
53 :depends-on ("nroc" "nsfc" "nnfc" "nnsc"))
58 :depends-on ("ddecbt" "dsolbt"))
60 :depends-on ("dgefa" "dgesl" "dgbfa" "dgbsl"))
63 :depends-on ("dvnorm" "dcopy"))
65 :depends-on ("dcopy" "dnrm2" "dcopy"))
71 :depends-on ("dgefa" "dgesl" "ddot"))
76 :depends-on ("idamax" "dscal" "daxpy"))
78 :depends-on ("daxpy"))
80 :depends-on ("idamax" "dscal" "daxpy"))
82 :depends-on ("daxpy" "ddot"))
84 :depends-on ("idamax"))
89 :depends-on ("xerrwd"))
92 :perform (compile-op :around (op c)
94 :common-as-array t :declare-common t)))
95 ;; This routine takes a slice of a double precision array and
96 ;; passes it to dprepi as a integer array. That won't work in
99 :depends-on ("dprepi"))
101 :depends-on ("dvnorm"))
103 :depends-on ("xerrwd" "dmnorm" "dstoda")
104 :perform (compile-op :around (op c)
105 (fortran-compile op c :common-as-array t :declare-common t)))
107 :depends-on ("drchek"))
109 :depends-on ("dstode"))
111 :depends-on ("dstode" "dewset"))
113 :depends-on ("dstodi" "dainvg"))
115 :depends-on ("dstodi" "dainvgs"))
117 :depends-on ("drchek" "dstoka")
118 :perform (compile-op :around (op c)
119 (fortran-compile op c :common-as-array t :declare-common t)))
121 :depends-on ("dstodpk"))
123 :depends-on ("dstodi"))
132 :depends-on ("jgroup" "odrv"))
134 :depends-on ("jgroup" "odrv"))
141 :depends-on ("droots"))
147 :depends-on ("dgesl" "ddot"))
149 :depends-on ("dspiom" "dspigmr" "dusol"))
161 :depends-on ("dmnorm"))
165 :depends-on ("dpkset" "dsolpk"))
167 :depends-on ("dsetpk" "dsolpk"))
169 :depends-on ("dumsum"))
178 :depends-on ("mdi" "mdm" "mdp" "mdu"))
189 :depends-on ("sro" "md"))
192 :depends-on ("ixsav"))
196 (defmethod perform ((op test-op) (c (eql (find-system "odepack"))))
197 (oos 'test-op "odedemo-lsode"))
203 ;;; Note: Each of the demos should probably be run in a separate Lisp
204 ;;; instance because some of the demos define functions with the same
205 ;;; name but different parameters. This will really confuse the
206 ;;; generated code, because the generated code uses knowledge of the
207 ;;; function to generate the call.
211 ;; Output matches Fortran code.
212 (defsystem odedemo-lsode
214 :depends-on ("odepack")
217 :default-component-class odepack-fortran-file
226 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsode"))))
227 (funcall (intern "OPKDEMO1" (find-package '#:odepack))))
230 ;; This won't work because opkdemo2 equivalences two arrays together.
231 ;; f2cl doesn't know how to handle that yet.
232 (defsystem odedemo-lsodes
233 :source-pathname (translate-logical-pathname "odepack:")
234 :binary-pathname (translate-logical-pathname "odepack:lib")
235 :source-extension "f"
237 :compiler-options (:common-as-array t)
238 :depends-on ("odepack")
240 ((:file "opkdemo2")))
247 ;; Output matches Fortran code.
248 (defsystem odedemo-lsoda
250 :depends-on ("odepack")
253 :default-component-class odepack-fortran-file
262 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsoda"))))
263 (funcall (intern "OPKDEMO3" (find-package '#:odepack))))
267 ;; Output matches Fortran code.
268 (defsystem odedemo-lsodar
270 :depends-on ("odepack")
273 :default-component-class odepack-fortran-file
282 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsodar"))))
283 (funcall (intern "OPKDEMO4" (find-package '#:odepack))))
288 ;; This test takes quite a while to run. Probably could be optimized
289 ;; more if we were more careful about array declarations. Assumption
292 ;; This seems to work, and the output matches the Fortran output,
293 ;; except the test with mf = 29 isn't printed out. Don't know why.
295 ;; The output is placed in demout in the directory where this is run.
296 ;; Compare this to demo-lsodpk.out
297 (defsystem odedemo-lsodpk
299 :depends-on ("odepack")
302 :default-component-class odepack-fortran-file
305 :depends-on ("gset" "cinit" "outweb")
306 :perform (compile-op :around (op c)
307 (fortran-compile op c :declare-common t)))
313 :depends-on ("webr"))
322 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsodpk"))))
323 (format *error-output* "Running odedemo-lsodpk. This make take some time.~%")
324 (finish-output *error-output*)
325 (funcall (intern "OPKDEMO5" (find-package '#:odepack))))
328 ;; This seems to work.
329 (defsystem odedemo-lsodkr
331 :depends-on ("odepack")
332 :depends-on ("odepack")
333 :default-component-class odepack-fortran-file
336 :perform (compile-op :around (op c)
337 (fortran-compile op c :declare-common t)))))
339 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsodkr"))))
340 (funcall (intern "OPKDEMO6" (find-package '#:odepack))))
344 ;; This runs and the expected output seems ok.
345 (defsystem odedemo-lsodi
346 :depends-on ("odepack")
350 :default-component-class odepack-fortran-file
353 :perform (compile-op :around (op c)
354 (fortran-compile op c :declare-common t))
355 :depends-on ("elkup"))
358 :depends-on ("gfun"))
365 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsodi"))))
366 (format *error-output* "Running odedemo-lsodi. This make take some time.~%")
367 (funcall (intern "OPKDEMO7" (find-package '#:odepack))))
369 (defsystem odedemo-lsoibt
370 :depends-on ("odepack")
374 :default-component-class odepack-fortran-file
377 :perform (compile-op :around (op c)
378 (fortran-compile op c :declare-common t))
393 (defmethod perform ((op test-op) (c (eql (find-system "odedemo-lsoibt"))))
394 (format *error-output* "Running odedemo-lsoibt. This make take some time.~%")
395 (funcall (intern "OPKDEMO7" (find-package '#:odepack))))
400 ;; Doesn't work. DIPREPI takes a double precision array and slices it
401 ;; up and passes it to DPREPI which wants integer arrays. That ain't
402 ;; gonna work in Lisp!
403 (defsystem odedemo-lsodis
404 :source-pathname (translate-logical-pathname "odepack:")
405 :binary-pathname (translate-logical-pathname "odepack:lib")
406 :source-extension "f"
408 :compiler-options (:common-as-array t :declare-common t)
409 :depends-on ("odepack")
411 ((:file "opkdemo9")))