summaryrefslogtreecommitdiff
path: root/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs')
-rw-r--r--packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs146
1 files changed, 104 insertions, 42 deletions
diff --git a/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs b/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs
index b6a59e2..67378cc 100644
--- a/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs
+++ b/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs
@@ -21,30 +21,57 @@
21-- 21--
22-- A simple example: 22-- A simple example:
23-- 23--
24-- <<diagrams/brusselator.png#diagram=brusselator&height=400&width=500>>
25--
24-- @ 26-- @
25-- import Numeric.Sundials.ARKode 27-- import Numeric.Sundials.ARKode.ODE
26-- import Numeric.LinearAlgebra 28-- import Numeric.LinearAlgebra
27-- import Graphics.Plot(mplot)
28-- 29--
29-- xdot t [x,v] = [v, -0.95*x - 0.1*v] 30-- import Plots as P
31-- import qualified Diagrams.Prelude as D
32-- import Diagrams.Backend.Rasterific
30-- 33--
31-- ts = linspace 100 (0,20 :: Double) 34-- brusselator :: Double -> [Double] -> [Double]
35-- brusselator _t x = [ a - (w + 1) * u + v * u * u
36-- , w * u - v * u * u
37-- , (b - w) / eps - w * u
38-- ]
39-- where
40-- a = 1.0
41-- b = 3.5
42-- eps = 5.0e-6
43-- u = x !! 0
44-- v = x !! 1
45-- w = x !! 2
32-- 46--
33-- sol = odeSolve xdot [10,0] ts 47-- lSaxis :: [[Double]] -> P.Axis B D.V2 Double
48-- lSaxis xs = P.r2Axis &~ do
49-- let ts = xs!!0
50-- us = xs!!1
51-- vs = xs!!2
52-- ws = xs!!3
53-- P.linePlot' $ zip ts us
54-- P.linePlot' $ zip ts vs
55-- P.linePlot' $ zip ts ws
34-- 56--
35-- main = mplot (ts : toColumns sol) 57-- main = do
58-- let res1 = odeSolve brusselator [1.2, 3.1, 3.0] (fromList [0.0, 0.1 .. 10.0])
59-- renderRasterific "diagrams/brusselator.png"
60-- (D.dims2D 500.0 500.0)
61-- (renderAxis $ lSaxis $ [0.0, 0.1 .. 10.0]:(toLists $ tr res1))
36-- @ 62-- @
37-- 63--
38-- <<diagrams/brusselator.png#diagram=brusselator&height=400&width=500>>
39--
40-- KVAERNO_4_2_3 64-- KVAERNO_4_2_3
41-- 65--
42-- \[ 66-- \[
43-- \begin{array}{c|cccc} 67-- \begin{array}{c|cccc}
44-- c_1 & 0.0 & 0.0 & 0.0 & 0.0 \\ 68-- 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
45-- c_2 & 0.4358665215 & 0.4358665215 & 0.0 & 0.0 \\ 69-- 0.871733043 & 0.4358665215 & 0.4358665215 & 0.0 & 0.0 \\
46-- c_3 & 0.490563388419108 & 7.3570090080892e-2 & 0.4358665215 & 0.0 \\ 70-- 1.0 & 0.490563388419108 & 7.3570090080892e-2 & 0.4358665215 & 0.0 \\
47-- c_4 & 0.308809969973036 & 1.490563388254106 & -1.235239879727145 & 0.4358665215 \\ 71-- 1.0 & 0.308809969973036 & 1.490563388254106 & -1.235239879727145 & 0.4358665215 \\
72-- \hline
73-- & 0.308809969973036 & 1.490563388254106 & -1.235239879727145 & 0.4358665215 \\
74-- & 0.490563388419108 & 7.3570090080892e-2 & 0.4358665215 & 0.0 \\
48-- \end{array} 75-- \end{array}
49-- \] 76-- \]
50-- 77--
@@ -52,8 +79,11 @@
52-- 79--
53-- \[ 80-- \[
54-- \begin{array}{c|cc} 81-- \begin{array}{c|cc}
55-- c_1 & 1.0 & 0.0 \\ 82-- 1.0 & 1.0 & 0.0 \\
56-- c_2 & -1.0 & 1.0 \\ 83-- 0.0 & -1.0 & 1.0 \\
84-- \hline
85-- & 0.5 & 0.5 \\
86-- & 1.0 & 0.0 \\
57-- \end{array} 87-- \end{array}
58-- \] 88-- \]
59-- 89--
@@ -61,20 +91,22 @@
61-- 91--
62-- \[ 92-- \[
63-- \begin{array}{c|ccccc} 93-- \begin{array}{c|ccccc}
64-- c_1 & 0.25 & 0.0 & 0.0 & 0.0 & 0.0 \\ 94-- 0.25 & 0.25 & 0.0 & 0.0 & 0.0 & 0.0 \\
65-- c_2 & 0.5 & 0.25 & 0.0 & 0.0 & 0.0 \\ 95-- 0.75 & 0.5 & 0.25 & 0.0 & 0.0 & 0.0 \\
66-- c_3 & 0.34 & -4.0e-2 & 0.25 & 0.0 & 0.0 \\ 96-- 0.55 & 0.34 & -4.0e-2 & 0.25 & 0.0 & 0.0 \\
67-- c_4 & 0.2727941176470588 & -5.036764705882353e-2 & 2.7573529411764705e-2 & 0.25 & 0.0 \\ 97-- 0.5 & 0.2727941176470588 & -5.036764705882353e-2 & 2.7573529411764705e-2 & 0.25 & 0.0 \\
68-- c_5 & 1.0416666666666667 & -1.0208333333333333 & 7.8125 & -7.083333333333333 & 0.25 \\ 98-- 1.0 & 1.0416666666666667 & -1.0208333333333333 & 7.8125 & -7.083333333333333 & 0.25 \\
99-- \hline
100-- & 1.0416666666666667 & -1.0208333333333333 & 7.8125 & -7.083333333333333 & 0.25 \\
101-- & 1.2291666666666667 & -0.17708333333333334 & 7.03125 & -7.083333333333333 & 0.0 \\
69-- \end{array} 102-- \end{array}
70-- \] 103-- \]
71----------------------------------------------------------------------------- 104-----------------------------------------------------------------------------
72module Numeric.Sundials.ARKode.ODE ( odeSolve 105module Numeric.Sundials.ARKode.ODE ( odeSolve
73 , odeSolveV 106 , odeSolveV
74 , odeSolveVWith 107 , odeSolveVWith
75 , getButcherTable 108 , ButcherTable(..)
76 , getBT 109 , butcherTable
77 , btGet
78 , ODEMethod(..) 110 , ODEMethod(..)
79 , StepControl(..) 111 , StepControl(..)
80 , SundialsDiagnostics(..) 112 , SundialsDiagnostics(..)
@@ -457,10 +489,11 @@ solveOdeC method jacH (absTols, relTol) fun f0 ts = unsafePerformIO $ do
457 ($vec-ptr:(long int *diagMut))[9] = ncfn; 489 ($vec-ptr:(long int *diagMut))[9] = ncfn;
458 490
459 /* Clean up and return */ 491 /* Clean up and return */
460 N_VDestroy(y); /* Free y vector */ 492 N_VDestroy(y); /* Free y vector */
493 N_VDestroy(tv); /* Free tv vector */
461 ARKodeFree(&arkode_mem); /* Free integrator memory */ 494 ARKodeFree(&arkode_mem); /* Free integrator memory */
462 SUNLinSolFree(LS); /* Free linear solver */ 495 SUNLinSolFree(LS); /* Free linear solver */
463 SUNMatDestroy(A); /* Free A matrix */ 496 SUNMatDestroy(A); /* Free A matrix */
464 497
465 return flag; 498 return flag;
466 } |] 499 } |]
@@ -482,22 +515,43 @@ solveOdeC method jacH (absTols, relTol) fun f0 ts = unsafePerformIO $ do
482 else do 515 else do
483 return $ Left res 516 return $ Left res
484 517
485btGet :: ODEMethod -> (Matrix Double, Vector Double) 518data ButcherTable = ButcherTable { am :: Matrix Double
486btGet method = case getBT method of 519 , cv :: Vector Double
487 Left c -> error $ show c -- FIXME 520 , bv :: Vector Double
488 Right ((v, w), sqp) -> ( subMatrix (0, 0) (s, s) $ 521 , b2v :: Vector Double
489 (B.arkSMax >< B.arkSMax) (V.toList v) 522 }
490 , subVector 0 s w) 523 deriving Show
491 where 524
492 s = fromIntegral $ sqp V.! 0 525data ButcherTable' a = ButcherTable' { am' :: V.Vector a
526 , cv' :: V.Vector a
527 , bv' :: V.Vector a
528 , b2v' :: V.Vector a
529 }
530 deriving Show
531
532butcherTable :: ODEMethod -> ButcherTable
533butcherTable method =
534 case getBT method of
535 Left c -> error $ show c -- FIXME
536 Right (ButcherTable' v w x y, sqp) ->
537 ButcherTable { am = subMatrix (0, 0) (s, s) $ (B.arkSMax >< B.arkSMax) (V.toList v)
538 , cv = subVector 0 s w
539 , bv = subVector 0 s x
540 , b2v = subVector 0 s y
541 }
542 where
543 s = fromIntegral $ sqp V.! 0
493 544
494getBT :: ODEMethod -> Either Int ((V.Vector Double, V.Vector Double), V.Vector Int) 545getBT :: ODEMethod -> Either Int (ButcherTable' Double, V.Vector Int)
495getBT method = case getButcherTable method of 546getBT method = case getButcherTable method of
496 Left c -> Left $ fromIntegral c 547 Left c ->
497 Right ((v, w), sqp) -> Right $ ((coerce v, coerce w), V.map fromIntegral sqp) 548 Left $ fromIntegral c
549 Right (ButcherTable' a b c d, sqp) ->
550 Right $ ( ButcherTable' (coerce a) (coerce b) (coerce c) (coerce d)
551 , V.map fromIntegral sqp )
498 552
499getButcherTable :: ODEMethod 553getButcherTable :: ODEMethod
500 -> Either CInt ((V.Vector CDouble, V.Vector CDouble), V.Vector CInt) 554 -> Either CInt (ButcherTable' CDouble, V.Vector CInt)
501getButcherTable method = unsafePerformIO $ do 555getButcherTable method = unsafePerformIO $ do
502 -- ARKode seems to want an ODE in order to set and then get the 556 -- ARKode seems to want an ODE in order to set and then get the
503 -- Butcher tableau so here's one to keep it happy 557 -- Butcher tableau so here's one to keep it happy
@@ -515,8 +569,12 @@ getButcherTable method = unsafePerformIO $ do
515 btSQPMut <- V.thaw btSQP 569 btSQPMut <- V.thaw btSQP
516 btAs :: V.Vector CDouble <- createVector (B.arkSMax * B.arkSMax) 570 btAs :: V.Vector CDouble <- createVector (B.arkSMax * B.arkSMax)
517 btAsMut <- V.thaw btAs 571 btAsMut <- V.thaw btAs
518 btCs :: V.Vector CDouble <- createVector B.arkSMax 572 btCs :: V.Vector CDouble <- createVector B.arkSMax
519 btCsMut <- V.thaw btCs 573 btBs :: V.Vector CDouble <- createVector B.arkSMax
574 btB2s :: V.Vector CDouble <- createVector B.arkSMax
575 btCsMut <- V.thaw btCs
576 btBsMut <- V.thaw btBs
577 btB2sMut <- V.thaw btB2s
520 let funIO :: CDouble -> Ptr T.SunVector -> Ptr T.SunVector -> Ptr () -> IO CInt 578 let funIO :: CDouble -> Ptr T.SunVector -> Ptr T.SunVector -> Ptr () -> IO CInt
521 funIO x y f _ptr = do 579 funIO x y f _ptr = do
522 fImm <- fun x <$> getDataFromContents dim y 580 fImm <- fun x <$> getDataFromContents dim y
@@ -576,7 +634,9 @@ getButcherTable method = unsafePerformIO $ do
576 } 634 }
577 635
578 for (i = 0; i < s; i++) { 636 for (i = 0; i < s; i++) {
579 ($vec-ptr:(double *btCsMut))[i] = ci[i]; 637 ($vec-ptr:(double *btCsMut))[i] = ci[i];
638 ($vec-ptr:(double *btBsMut))[i] = bi[i];
639 ($vec-ptr:(double *btB2sMut))[i] = b2i[i];
580 } 640 }
581 641
582 /* Clean up and return */ 642 /* Clean up and return */
@@ -590,7 +650,9 @@ getButcherTable method = unsafePerformIO $ do
590 x <- V.freeze btAsMut 650 x <- V.freeze btAsMut
591 y <- V.freeze btSQPMut 651 y <- V.freeze btSQPMut
592 z <- V.freeze btCsMut 652 z <- V.freeze btCsMut
593 return $ Right ((x, z), y) 653 u <- V.freeze btBsMut
654 v <- V.freeze btB2sMut
655 return $ Right (ButcherTable' { am' = x, cv' = z, bv' = u, b2v' = v }, y)
594 else do 656 else do
595 return $ Left res 657 return $ Left res
596 658