diff options
author | Dominic Steinitz <dominic@steinitz.org> | 2018-03-15 16:31:00 +0000 |
---|---|---|
committer | Dominic Steinitz <dominic@steinitz.org> | 2018-03-15 16:31:00 +0000 |
commit | 2cb51cd3cbc111a0251560516e772b6cece5446d (patch) | |
tree | 5ed3a357e5ceda34e53b9e52c00730bcbc5f1b61 | |
parent | cdc2090e9b6c005249b3b40ebe022bcddc2b22ce (diff) |
Now calling a part of the Haskell ODE
-rw-r--r-- | packages/sundials/src/Main.hs | 32 | ||||
-rw-r--r-- | packages/sundials/src/helpers.c | 31 | ||||
-rw-r--r-- | packages/sundials/src/helpers.h | 2 | ||||
-rw-r--r-- | packages/sundials/sundials.cabal | 25 |
4 files changed, 66 insertions, 24 deletions
diff --git a/packages/sundials/src/Main.hs b/packages/sundials/src/Main.hs index 3d5f941..bab5710 100644 --- a/packages/sundials/src/Main.hs +++ b/packages/sundials/src/Main.hs | |||
@@ -55,6 +55,13 @@ vectorToC vec len ptr = do | |||
55 | ptr' <- newForeignPtr_ ptr | 55 | ptr' <- newForeignPtr_ ptr |
56 | V.copy (VM.unsafeFromForeignPtr0 ptr' len) vec | 56 | V.copy (VM.unsafeFromForeignPtr0 ptr' len) vec |
57 | 57 | ||
58 | foreign export ccall singleEq :: Double -> Double -> IO Double | ||
59 | |||
60 | singleEq :: Double -> Double -> IO Double | ||
61 | singleEq t u = return $ lamda * u + 1.0 / (1.0 + t * t) - lamda * atan t | ||
62 | where | ||
63 | lamda = -100.0 | ||
64 | |||
58 | solve :: (CDouble -> V.Vector CDouble -> V.Vector CDouble) -> | 65 | solve :: (CDouble -> V.Vector CDouble -> V.Vector CDouble) -> |
59 | V.Vector Double -> | 66 | V.Vector Double -> |
60 | CDouble -> | 67 | CDouble -> |
@@ -89,29 +96,6 @@ solve fun f0 lambda = unsafePerformIO $ do | |||
89 | realtype abstol = 1.0e-10; | 96 | realtype abstol = 1.0e-10; |
90 | realtype lamda = -100.0; /* stiffness parameter */ | 97 | realtype lamda = -100.0; /* stiffness parameter */ |
91 | 98 | ||
92 | /* Beginning of stolen code from the Fortran interface */ | ||
93 | |||
94 | N_Vector F2C_ARKODE_vec; | ||
95 | F2C_ARKODE_vec = NULL; | ||
96 | F2C_ARKODE_vec = N_VNewEmpty_Serial(NEQ); /* was *N */ | ||
97 | if (F2C_ARKODE_vec == NULL) return 1; | ||
98 | |||
99 | /* Check for required vector operations */ | ||
100 | if(F2C_ARKODE_vec->ops->nvgetarraypointer == NULL) { | ||
101 | fprintf(stderr, "Error: getarraypointer vector operation is not implemented.\n\n"); | ||
102 | return 1; | ||
103 | } | ||
104 | if(F2C_ARKODE_vec->ops->nvsetarraypointer == NULL) { | ||
105 | fprintf(stderr, "Error: setarraypointer vector operation is not implemented.\n\n"); | ||
106 | return 1; | ||
107 | } | ||
108 | if(F2C_ARKODE_vec->ops->nvcloneempty == NULL) { | ||
109 | fprintf(stderr, "Error: cloneempty vector operation is not implemented.\n\n"); | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | /* End of stolen code from the Fortran interface */ | ||
114 | |||
115 | /* Initial diagnostics output */ | 99 | /* Initial diagnostics output */ |
116 | printf("\nAnalytical ODE test problem:\n"); | 100 | printf("\nAnalytical ODE test problem:\n"); |
117 | printf(" lamda = %"GSYM"\n", lamda); | 101 | printf(" lamda = %"GSYM"\n", lamda); |
@@ -130,7 +114,7 @@ solve fun f0 lambda = unsafePerformIO $ do | |||
130 | /* right-hand side function in y'=f(t,y), the inital time T0, and */ | 114 | /* right-hand side function in y'=f(t,y), the inital time T0, and */ |
131 | /* the initial dependent variable vector y. Note: since this */ | 115 | /* the initial dependent variable vector y. Note: since this */ |
132 | /* problem is fully implicit, we set f_E to NULL and f_I to f. */ | 116 | /* problem is fully implicit, we set f_E to NULL and f_I to f. */ |
133 | flag = ARKodeInit(arkode_mem, NULL, f, T0, y); | 117 | flag = ARKodeInit(arkode_mem, NULL, FARKfi, T0, y); |
134 | if (check_flag(&flag, "ARKodeInit", 1)) return 1; | 118 | if (check_flag(&flag, "ARKodeInit", 1)) return 1; |
135 | 119 | ||
136 | /* Set routines */ | 120 | /* Set routines */ |
diff --git a/packages/sundials/src/helpers.c b/packages/sundials/src/helpers.c index d51310c..eab5ac9 100644 --- a/packages/sundials/src/helpers.c +++ b/packages/sundials/src/helpers.c | |||
@@ -8,6 +8,12 @@ | |||
8 | #include <sundials/sundials_types.h> /* definition of type realtype */ | 8 | #include <sundials/sundials_types.h> /* definition of type realtype */ |
9 | #include <sundials/sundials_math.h> | 9 | #include <sundials/sundials_math.h> |
10 | 10 | ||
11 | #include "farkode.h" | ||
12 | |||
13 | #include <HsFFI.h> | ||
14 | #include "Main_stub.h" | ||
15 | |||
16 | |||
11 | /* Check function return value... | 17 | /* Check function return value... |
12 | opt == 0 means SUNDIALS function allocates memory so check if | 18 | opt == 0 means SUNDIALS function allocates memory so check if |
13 | returned NULL pointer | 19 | returned NULL pointer |
@@ -56,6 +62,31 @@ int f(realtype t, N_Vector y, N_Vector ydot, void *user_data) | |||
56 | return 0; /* return with success */ | 62 | return 0; /* return with success */ |
57 | } | 63 | } |
58 | 64 | ||
65 | int FARK_IMP_FUN(realtype *T, realtype *Y, realtype *YDOT, | ||
66 | long int *IPAR, realtype *RPAR, int *IER) { | ||
67 | realtype t = *T; | ||
68 | realtype u = Y[0]; | ||
69 | realtype lamda = -100.0; | ||
70 | YDOT[0] = singleEq(t, u); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | /* C interface to user-supplied FORTRAN function FARKIFUN; see | ||
75 | farkode.h for further details */ | ||
76 | int FARKfi(realtype t, N_Vector y, N_Vector ydot, void *user_data) { | ||
77 | |||
78 | int ier; | ||
79 | realtype *ydata, *dydata; | ||
80 | FARKUserData ARK_userdata; | ||
81 | ydata = N_VGetArrayPointer(y); | ||
82 | dydata = N_VGetArrayPointer(ydot); | ||
83 | ARK_userdata = (FARKUserData) user_data; | ||
84 | |||
85 | FARK_IMP_FUN(&t, ydata, dydata, ARK_userdata->ipar, | ||
86 | ARK_userdata->rpar, &ier); | ||
87 | return(ier); | ||
88 | } | ||
89 | |||
59 | /* Jacobian routine to compute J(t,y) = df/dy. */ | 90 | /* Jacobian routine to compute J(t,y) = df/dy. */ |
60 | int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, | 91 | int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, |
61 | void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) | 92 | void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3) |
diff --git a/packages/sundials/src/helpers.h b/packages/sundials/src/helpers.h index 87b0c81..3b50163 100644 --- a/packages/sundials/src/helpers.h +++ b/packages/sundials/src/helpers.h | |||
@@ -21,6 +21,8 @@ int check_flag(void *flagvalue, const char *funcname, int opt); | |||
21 | /* f routine to compute the ODE RHS function f(t,y). */ | 21 | /* f routine to compute the ODE RHS function f(t,y). */ |
22 | int f(realtype t, N_Vector y, N_Vector ydot, void *user_data); | 22 | int f(realtype t, N_Vector y, N_Vector ydot, void *user_data); |
23 | 23 | ||
24 | int FARKfi(realtype t, N_Vector y, N_Vector ydot, void *user_data); | ||
25 | |||
24 | /* Jacobian routine to compute J(t,y) = df/dy. */ | 26 | /* Jacobian routine to compute J(t,y) = df/dy. */ |
25 | int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, | 27 | int Jac(realtype t, N_Vector y, N_Vector fy, SUNMatrix J, |
26 | void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); | 28 | void *user_data, N_Vector tmp1, N_Vector tmp2, N_Vector tmp3); |
diff --git a/packages/sundials/sundials.cabal b/packages/sundials/sundials.cabal index a68f33a..9b2db12 100644 --- a/packages/sundials/sundials.cabal +++ b/packages/sundials/sundials.cabal | |||
@@ -18,6 +18,16 @@ cabal-version: >=1.10 | |||
18 | 18 | ||
19 | extra-source-files: src/helpers.c, src/helpers.h | 19 | extra-source-files: src/helpers.c, src/helpers.h |
20 | 20 | ||
21 | executable ExportAndImport.dylib | ||
22 | main-is: ExportAndImport.hs | ||
23 | other-extensions: ForeignFunctionInterface | ||
24 | build-depends: base >=4.10 | ||
25 | hs-source-dirs: src | ||
26 | default-language: Haskell2010 | ||
27 | include-dirs: src | ||
28 | ghc-options: -O2 -shared -fPIC -dynamic | ||
29 | extra-libraries: HSrts-ghc8.2.2 | ||
30 | |||
21 | executable sundials | 31 | executable sundials |
22 | main-is: Main.hs | 32 | main-is: Main.hs |
23 | -- other-modules: | 33 | -- other-modules: |
@@ -31,3 +41,18 @@ executable sundials | |||
31 | default-language: Haskell2010 | 41 | default-language: Haskell2010 |
32 | extra-libraries: sundials_arkode | 42 | extra-libraries: sundials_arkode |
33 | C-sources: src/helpers.c src/helpers.h | 43 | C-sources: src/helpers.c src/helpers.h |
44 | |||
45 | executable hsundials.dylib | ||
46 | main-is: Main.hs | ||
47 | -- other-modules: | ||
48 | other-extensions: QuasiQuotes, TemplateHaskell, MultiWayIf, OverloadedStrings | ||
49 | build-depends: base >=4.10 && <4.11, | ||
50 | inline-c >=0.6 && <0.7, | ||
51 | vector >=0.12 && <0.13, | ||
52 | template-haskell >=2.12 && <2.13, | ||
53 | containers >=0.5 && <0.6 | ||
54 | hs-source-dirs: src | ||
55 | ghc-options: -O2 -shared -fPIC -dynamic | ||
56 | default-language: Haskell2010 | ||
57 | extra-libraries: sundials_arkode, HSrts-ghc8.2.2 | ||
58 | C-sources: src/helpers.c src/helpers.h | ||