Skip to content

Commit 7500839

Browse files
committed
WIP making ODEs work in Julia
1 parent d16e874 commit 7500839

File tree

47 files changed

+893
-283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+893
-283
lines changed

code/drasil-code/lib/Data/Drasil/ExternalLibraries/ODELibraries.hs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
module Data.Drasil.ExternalLibraries.ODELibraries (
33
-- * SciPy Library (Python)
44
scipyODEPckg, scipyODESymbols,
5+
-- DifferentialEquations.jl Library (Julia)
6+
jlODEPckg, jlODESymbols,
57
-- * Oslo Library (C#)
68
osloPckg, osloSymbols, arrayVecDepVar,
79
-- * Apache Commons (Java)
@@ -23,7 +25,7 @@ import Language.Drasil.Code (Lang(..), ExternalLibrary, Step, Argument,
2325
lockedNamedArg, inlineArg, inlineNamedArg, preDefinedArg, functionArg,
2426
customObjArg, recordArg, lockedParam, unnamedParam, customClass,
2527
implementation, constructorInfo, methodInfo, methodInfoNoReturn,
26-
appendCurrSol, populateSolList, assignArrayIndex, assignSolFromObj,
28+
appendCurrSol, populateSolList, populateSolList', assignArrayIndex, assignSolFromObj,
2729
initSolListFromArray, initSolListWithVal, solveAndPopulateWhile,
2830
returnExprList, fixedReturn',
2931
ExternalLibraryCall, externalLibCall, choiceStepsFill, choiceStepFill,
@@ -164,6 +166,88 @@ odeintFunc = quantfunc $ implVar "odeint_scipy" (nounPhrase
164166
"method that solves a system of ODE using lsoda from the FORTRAN library odepack.")
165167
(Array Real) (label "odeint")
166168

169+
-- DifferentialEquations.jl Library (Julia)
170+
jlODEPckg :: ODELibPckg
171+
jlODEPckg = mkODELibNoPath "DifferentialEquations.jl" "7.13.0" jlODE jlODECall [Julia]
172+
173+
jlODESymbols :: [QuantityDict]
174+
jlODESymbols = map qw [jlMthdArg, jlRelTolArg, jlAbsTolArg, jlSaveAtArg] ++
175+
map qw [jlR, jlP, t_span, jlSol, jlMthd, jlSp] ++
176+
map qw [jlODEProblem, jlF, jlODESolve, jlODEDP5]
177+
178+
jlODE :: ExternalLibrary
179+
jlODE = externalLib [
180+
mandatorySteps $ [
181+
callStep $ libFunctionWithResult jlODEImport
182+
jlODEProblem [
183+
functionArg jlF (map unnamedParam [Array Real, Real, Real])
184+
returnExprList, inlineArg (Array Real), preDefinedArg t_span] jlR,
185+
callStep $ libFunctionWithResult jlODEImport
186+
jlODEDP5 [] jlMthd,
187+
callStep $ libFunctionWithResult jlODEImport
188+
jlODESolve [lockedArg (sy jlR), lockedNamedArg jlMthdArg (sy jlMthd),
189+
inlineNamedArg jlRelTolArg Real, inlineNamedArg jlAbsTolArg Real,
190+
inlineNamedArg jlSaveAtArg Real] jlSol] ++
191+
populateSolList' jlSol jlSp] -- TODO: this should probably be populateSolList, but we don't have structs
192+
193+
jlODECall :: ODEInfo -> ExternalLibraryCall
194+
jlODECall info = [
195+
mandatoryStepsFill $ [
196+
callStepFill $ libCallFill (functionArgFill
197+
(map unnamedParamFill [depVar info, jlP, indepVar info])
198+
(returnExprListFill $ odeSyst info) : map (basicArgFill . matrix)
199+
[[initVal info], [[tInit info, tFinal info]]]),
200+
callStepFill $ libCallFill [],
201+
callStepFill $ libCallFill $ map basicArgFill
202+
[relTol $ odeOpts info, absTol $ odeOpts info, stepSize $ odeOpts info]] ++
203+
populateSolListFill (depVar info)]
204+
205+
jlODEImport :: String
206+
jlODEImport = "DifferentialEquations"
207+
208+
jlMthdArg, jlRelTolArg, jlAbsTolArg, jlSaveAtArg :: NamedArgument
209+
jlMthdArg = narg $ implVar "mthd_arg_jlODE" (nounPhrase
210+
"chosen method for solving ODE" "chosen methods for solving ODE")
211+
String (label "alg")
212+
jlRelTolArg = narg $ implVar "jl_arg_reltol" (nounPhrase
213+
"Chosen relative tolerance" "Chosen relative tolerances")
214+
Real (label "reltol")
215+
jlAbsTolArg = narg $ implVar "jl_arg_abstol" (nounPhrase
216+
"Chosen absolute tolerance" "Chosen absolute tolerances")
217+
Real (label "abstol")
218+
jlSaveAtArg = narg $ implVar "jl_arg_saveat" (nounPhrase
219+
"Chosen time step" "Chosen time step")
220+
Real (label "saveat")
221+
222+
jlR, jlP, t_span, jlSol, jlMthd, jlSp :: CodeVarChunk
223+
jlR = quantvar $ implVar "r" (nounPhrase "ODE struct" "ODE structs")
224+
odeT2 (label "r")
225+
jlP = quantvar $ implVar "params" (nounPhrase "param?" "params?")
226+
Void (label "p") -- TODO: this should be a struct of some sort
227+
t_span = quantvar $ implVar "t_span" (nounPhrase "Timespan" "Timespans")
228+
(Array Real) (label "t_span")
229+
jlSol = quantvar $ implVar "jl_solve" (nounPhrase "Solution" "Solutions")
230+
Void (label "sol") -- TODO: this should be a struct of some sort
231+
jlMthd = quantvar $ implVar "jl_method" (nounPhrase
232+
"chosen method for solving ODE" "chosen methods for solving ODE")
233+
String (label "algorithm")
234+
jlSp = quantvar $ implVar "sp_julia" (nounPhrase "ODE solution point"
235+
"ODE solution points") Real (label "sp")
236+
237+
jlF, jlODEProblem, jlODESolve, jlODEDP5 :: CodeFuncChunk
238+
jlF = quantfunc $ implVar "f_jlODE" (nounPhrase "function representing ODE system"
239+
"functions representing ODE system") (Array Real) (label "f")
240+
jlODEProblem = quantfunc $ implVar "jl_ode_problem" (nounPhrase
241+
"function for defining an ODE for jlODE"
242+
"functions for defining an ODE for jlODE") odeT2 (label "ODEProblem")
243+
jlODESolve = quantfunc $ implVar "jl_ode_solve" (nounPhrase
244+
"function for solving an ODE for jlODE"
245+
"functions for solving an ODE for jlODE") odeT2 (label "solve")
246+
jlODEDP5 = quantfunc $ implVar "jl_ode_dp5" (nounPhrase "DP5" "DP5s") odeT2 (label "DP5")
247+
248+
odeT2 :: Space
249+
odeT2 = Void -- TODO: this should be a struct/function? of some sort
250+
167251
-- Oslo Library (C#)
168252

169253
-- | [Oslo](https://www.microsoft.com/en-us/research/project/open-solving-library-for-odes/) ODE library package.

code/drasil-code/lib/Language/Drasil/Code.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module Language.Drasil.Code (
2020
inlineArg, inlineNamedArg, preDefinedArg, preDefinedNamedArg, functionArg,
2121
customObjArg, recordArg, lockedParam, unnamedParam, customClass,
2222
implementation, constructorInfo, methodInfo, methodInfoNoReturn,
23-
appendCurrSol, populateSolList, assignArrayIndex, assignSolFromObj,
23+
appendCurrSol, populateSolList, populateSolList', assignArrayIndex, assignSolFromObj,
2424
initSolListFromArray, initSolListWithVal, solveAndPopulateWhile,
2525
returnExprList, fixedReturn, fixedReturn', initSolWithVal,
2626
ExternalLibraryCall, StepGroupFill(..), StepFill(..), FunctionIntFill(..),
@@ -67,7 +67,7 @@ import Language.Drasil.Code.ExternalLibrary (ExternalLibrary, Step,
6767
inlineArg, inlineNamedArg, preDefinedArg, preDefinedNamedArg, functionArg,
6868
customObjArg, recordArg, lockedParam, unnamedParam, customClass,
6969
implementation, constructorInfo, methodInfo, methodInfoNoReturn,
70-
appendCurrSol, populateSolList, assignArrayIndex, assignSolFromObj,
70+
appendCurrSol, populateSolList, populateSolList', assignArrayIndex, assignSolFromObj,
7171
initSolListFromArray, initSolListWithVal, solveAndPopulateWhile,
7272
returnExprList, fixedReturn, fixedReturn', initSolWithVal)
7373
import Language.Drasil.Code.ExternalLibraryCall (ExternalLibraryCall,

code/drasil-code/lib/Language/Drasil/Code/ExternalLibrary.hs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module Language.Drasil.Code.ExternalLibrary (ExternalLibrary, Step(..),
99
lockedNamedArg, inlineArg, inlineNamedArg, preDefinedArg, preDefinedNamedArg,
1010
functionArg, customObjArg, recordArg, lockedParam, unnamedParam, customClass,
1111
implementation, constructorInfo, methodInfo, methodInfoNoReturn,
12-
appendCurrSol, populateSolList, assignArrayIndex, assignSolFromObj,
12+
appendCurrSol, populateSolList, populateSolList', assignArrayIndex, assignSolFromObj,
1313
initSolListFromArray, initSolListWithVal, solveAndPopulateWhile,
1414
returnExprList, fixedReturn, fixedReturn', initSolWithVal
1515
) where
@@ -260,6 +260,17 @@ populateSolList arr el fld = [statementStep (\cdchs es -> case (cdchs, es) of
260260
(_,_) -> error popErr)]
261261
where popErr = "Fill for populateSolList should provide one CodeChunk and no Exprs"
262262

263+
-- | Specifies a statement where a solution list is populated by iterating
264+
-- through a solution array.
265+
populateSolList' :: CodeVarChunk -> CodeVarChunk -> [Step]
266+
populateSolList' arr el = [statementStep (\cdchs es -> case (cdchs, es) of
267+
([s], []) -> FAsg s (Matrix [[]])
268+
(_,_) -> error popErr),
269+
statementStep (\cdchs es -> case (cdchs, es) of
270+
([s], []) -> FForEach el (sy arr) [FAppend (sy s) (sy el)]
271+
(_,_) -> error popErr)]
272+
where popErr = "Fill for populateSolList' should provide one CodeChunk and no Exprs"
273+
263274
-- | Specifies statements where every index of an array is assigned a value.
264275
assignArrayIndex :: Step
265276
assignArrayIndex = statementStep (\cdchs es -> case (cdchs, es) of

code/drasil-example/swhsnopcm/lib/Drasil/SWHSNoPCM/Body.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import Data.Drasil.Concepts.Thermodynamics (heatCapSpec, htFlux, phaseChange,
2525
temp, thermalAnalysis, thermalConduction, thermocon)
2626

2727
import Data.Drasil.ExternalLibraries.ODELibraries (scipyODESymbols, osloSymbols,
28-
arrayVecDepVar, apacheODESymbols, odeintSymbols)
28+
arrayVecDepVar, apacheODESymbols, odeintSymbols, jlODESymbols)
2929

3030
import qualified Data.Drasil.Quantities.Thermodynamics as QT (temp,
3131
heatCapSpec, htFlux, sensHeat)
@@ -94,8 +94,9 @@ symbolsAll :: [QuantityDict] --FIXME: Why is PCM (swhsSymbolsAll) here?
9494
--FOUND LOC OF ERROR: Instance Models
9595
symbolsAll = map qw symbols ++ map qw specParamValList ++
9696
[qw coilSAMax, qw tauW] ++ map qw [absTol, relTol] ++
97-
scipyODESymbols ++ osloSymbols ++ apacheODESymbols ++ odeintSymbols
98-
++ map qw [listToArray $ quantvar tempW, arrayVecDepVar noPCMODEInfo]
97+
scipyODESymbols ++ jlODESymbols ++ osloSymbols ++ apacheODESymbols ++
98+
odeintSymbols ++
99+
map qw [listToArray $ quantvar tempW, arrayVecDepVar noPCMODEInfo]
99100

100101
concepts :: [UnitalChunk]
101102
concepts = map ucw [density, tau, inSA, outSA,

code/drasil-example/swhsnopcm/lib/Drasil/SWHSNoPCM/Choices.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Language.Drasil.Code (Choices(..), CodeSpec, codeSpec, Comments(..),
88
ExtLib(..))
99

1010
import Data.Drasil.ExternalLibraries.ODELibraries (scipyODEPckg, osloPckg,
11-
apacheODEPckg, odeintPckg)
11+
apacheODEPckg, odeintPckg, jlODEPckg)
1212
import Drasil.SWHSNoPCM.Body (noPCMODEInfo, fullSI)
1313

1414
code :: CodeSpec
@@ -17,13 +17,14 @@ code = codeSpec fullSI choices []
1717

1818
choices :: Choices
1919
choices = defaultChoices {
20-
lang = [Python, Cpp, CSharp, Java],
20+
lang = [Python, Cpp, CSharp, Java, Julia],
2121
architecture = makeArchit Modular Program,
22-
dataInfo = makeData Unbundled (Store Bundled) Const,
22+
dataInfo = makeData Unbundled (Store Unbundled) Const,
2323
optFeats = makeOptFeats
2424
(makeDocConfig [CommentFunc, CommentClass, CommentMod] Quiet Hide)
2525
(makeLogConfig [] "log.txt")
2626
[SampleInput "../../datafiles/swhsnopcm/sampleInput.txt", ReadME],
2727
srsConstraints = makeConstraints Warning Warning,
28-
extLibs = [Math (makeODE [noPCMODEInfo] [scipyODEPckg, osloPckg, apacheODEPckg, odeintPckg])]
28+
extLibs = [Math (makeODE [noPCMODEInfo] [scipyODEPckg, osloPckg,
29+
apacheODEPckg, odeintPckg, jlODEPckg])]
2930
}

code/drasil-gool/lib/Drasil/GOOL/InterfaceCommon.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ convType (Func ps r) = funcType (map convType ps) (convType r)
502502
convType Void = void
503503
convType InFile = infile
504504
convType OutFile = outfile
505-
convType (Object _) = error "Objects not supported"
505+
convType (Object n) = error $ "convType: Objects not supported (name: '" ++ n ++ "')"
506506

507507
convScope :: (ScopeSym r) => ScopeData -> r (Scope r)
508508
convScope (SD {scopeTag = Global}) = global

code/drasil-gool/lib/Drasil/GOOL/LanguageRenderer/CommonPseudoOO.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ multiReturn f vs = do
418418
returnStmt $ mkStateVal IC.void $ f $ valueList vs'
419419

420420
listDec :: (CommonRenderSym r) => SVariable r -> r (Scope r) -> MSStatement r
421-
listDec v scp = IC.varDecDef v scp $ IC.litList (onStateValue variableType v) []
421+
listDec v scp = listDecDef v scp []
422422

423423
funcDecDef :: (OORenderSym r) => SVariable r -> r (Scope r) -> [SVariable r] ->
424424
MSBody r -> MSStatement r

code/drasil-gool/lib/Drasil/GOOL/LanguageRenderer/JuliaRenderer.hs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ import Drasil.GOOL.RendererClassesProc (ProcRenderSym, RenderFile(..),
4343
RenderMod(..), ModuleElim, ProcRenderMethod(..))
4444
import qualified Drasil.GOOL.RendererClassesProc as RC (module')
4545
import Drasil.GOOL.LanguageRenderer (printLabel, listSep, listSep',
46-
variableList, parameterList, forLabel, inLabel, tryLabel, catchLabel)
46+
variableList, parameterList, forLabel, inLabel, tryLabel, catchLabel,
47+
valueList)
4748
import qualified Drasil.GOOL.LanguageRenderer as R (sqrt, abs, log10, log,
4849
exp, sin, cos, tan, asin, acos, atan, floor, ceil, multiStmt, body,
4950
addComments, blockCmt, docCmt, commentedMod, listSetFunc, commentedItem,
@@ -60,7 +61,7 @@ import qualified Drasil.GOOL.LanguageRenderer.LanguagePolymorphic as G (
6061
emptyStmt, print, comment, valStmt, returnStmt, param, docFunc, throw, arg,
6162
argsList, ifCond, smartAdd, local, var)
6263
import qualified Drasil.GOOL.LanguageRenderer.CommonPseudoOO as CP (bool,
63-
boolRender, extVar, funcType, litArray, listDec, listDecDef, listAccessFunc,
64+
boolRender, extVar, funcType, listDec, listDecDef, listAccessFunc,
6465
listSetFunc, notNull, extFuncAppMixedArgs, functionDoc, listSize, listAdd,
6566
listAppend, intToIndex', indexToInt', inOutFunc, docInOutFunc', forLoopError,
6667
varDecDef, openFileR', openFileW', openFileA', multiReturn, multiAssign,
@@ -138,10 +139,11 @@ instance RenderFile JuliaCode where
138139
instance ImportSym JuliaCode where
139140
type Import JuliaCode = Doc
140141
langImport n = let modName = text n
141-
fileName = text $ n ++ '.' : jlExt
142+
in toCode $ importLabel <+> modName
143+
modImport n = let modName = text n
144+
fileName = text $ n ++ '.' : jlExt
142145
in toCode $ vcat [includeLabel <> parens (doubleQuotes fileName),
143-
importLabel <+> text "." <> modName] -- TODO: we want a dot only when the import is locally defined.
144-
modImport = langImport
146+
importLabel <+> text "." <> modName]
145147

146148
instance ImportElim JuliaCode where
147149
import' = unJLC
@@ -289,8 +291,8 @@ instance Literal JuliaCode where
289291
litFloat = jlLitFloat
290292
litInt = G.litInt
291293
litString = G.litString
292-
litArray = CP.litArray brackets
293-
litList = litArray
294+
litArray = litList
295+
litList = jlLitList
294296

295297
instance MathConstant JuliaCode where
296298
pi :: SValue JuliaCode
@@ -661,6 +663,14 @@ jlClassError = "Classes are not supported in Julia"
661663
jlLitFloat :: (CommonRenderSym r) => Float -> SValue r
662664
jlLitFloat f = mkStateVal float (text jlFloatConc <> parens (D.float f))
663665

666+
jlLitList :: (CommonRenderSym r) => VSType r -> [SValue r] -> SValue r
667+
jlLitList t' es = do
668+
t <- t'
669+
let lt' = listType t'
670+
elems <- sequence es
671+
let typeDec = if null es then RC.type' t else empty
672+
mkStateVal lt' (typeDec <> brackets (valueList elems))
673+
664674
jlCast :: (CommonRenderSym r) => VSType r -> SValue r -> SValue r
665675
jlCast t' v' = do
666676
t <- t'

code/drasil-lang/lib/Language/Drasil/CodeExpr/Class.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,5 @@ instance CodeExprC CodeExpr where
5757
"Actor space"
5858

5959
-- | Similar to 'apply', but takes a relation to apply to 'FCall'.
60-
applyWithNamedArgs f [] [] = sy f
6160
applyWithNamedArgs f ps ns = FCall (f ^. uid) ps (zip (map ((^. uid) . fst) ns)
6261
(map snd ns))

code/stable-website/index.html

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)