Git Product home page Git Product logo

nimsundials's People

Contributors

hugogranstrom avatar

Stargazers

 avatar

Watchers

 avatar  avatar

nimsundials's Issues

Using gitPull, cmake, when defined

Hi Hugo,
I have been trying to make it work under Linux more easily (as you know, I am still learning).
Despite I don't have a working solution yet I just want to let you know where I am.

In one hand, I am using gitPull to download a specific version from Sundials (v5.0.0-dev.1). Secondly, I use cmake and make to build the libraries. In Linux, everything gets done under sundials/build/usr/local/lib64.

For some reason I am not getting: nvector/nvector_serial2.h, cvode/cvode2.h, sundials/sundials_spgmr.h. So maybe, there is some cmake option that I am missing.

Now I am stuck with the following error (I translated from Spanish):

home/jose/.cache/nim/nim_sundials_d/nim_sundials.nim.c:219:77: error: name of type ‘CVRhsFn’ unknown
  219 | typedef N_CDECL_PTR(int, tyProc_dycob5keSi0v89cXsanNL9cA) (void* cvode_mem, CVRhsFn f, realtype t0, struct _generic_N_Vector* y0);
      |                                                                             ^~~~~~~

In the future, it would be nice to have also something like this:

when defined(osx):
  cDefine("WITH_COREAUDIO")
  {.passL: "-framework CoreAudio -framework AudioToolbox".}
  cCompile(src/"backend/coreaudio/*.cpp")
elif defined(Linux):
  {.passL: "-lpthread".}
  cDefine("WITH_OSS")
  cCompile(src/"backend/oss/*.cpp")
elif defined(Windows):
  {.passC: "-msse".}
  {.passL: "-lwinmm".}
  cDefine("WITH_WINMM")
  cCompile(src/"backend/winmm/*.cpp")
else:
  static: doAssert false

And now some code:

import os

import nimterop/[cimport, paths,git]

const
  version = "v5.0.0-dev.1"
  srcDir = currentSourcePath().parentDir()/"sundials"
  buildDir= srcDir/"build"
  installDir = "lib"
  installDirLib64 = buildDir/installDir/"usr/local/lib64"
  installDirInclude = buildDir/installDir/"usr/local/include"

static:
  # https://github.com/JuliaDiffEq/Sundials.jl
  gitPull("https://github.com/LLNL/sundials", outdir = srcDir, checkout = "tags/v5.0.0-dev.1")
  cDebug()
  cDisableCaching()


  cmake(buildDir,"Makefile","../.") #" -DCMAKE_INSTALL_PREFIX=" & buildDir & " -DCMAKE_INSTALL_LIBDIR=" & installDir )
  make(buildDir,"", "")
  make(buildDir,"prueba.txt", "DESTDIR=\"" & buildDir & "/lib" & "\" install")


#[
https://github.com/LLNL/sundials/blob/master/INSTALL_GUIDE.pdf

In Archlinux: https://git.archlinux.org/svntogit/community.git/tree/trunk/PKGBUILD?h=packages/sundials
cmake ../$pkgname-$pkgver \
  -DCMAKE_INSTALL_PREFIX=/usr \
  -DCMAKE_INSTALL_LIBDIR=lib \
  -DMPI_ENABLE=ON \
  -DPTHREAD_ENABLE=ON	\
  -DOPENMP_ENABLE=ON \
  -DF77_INTERFACE_ENABLE=ON \
  -DKLU_ENABLE=ON \
  -DKLU_LIBRARY_DIR=/usr/lib \
  -DEXAMPLES_INSTALL_PATH=/usr/share/sundials/examples
]#

cIncludeDir(installDirInclude)
#cIncludeDir(buildDir/"lib")
cIncludeDir(installDirLib64)

cPlugin:
    import strutils
    proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} =
        if sym.kind == nskType:
            if sym.name == "_N_VectorContent_Serial":
                sym.name = "N_VectorContent_Serial_Base"
        if sym.name == "ModifiedGS":
            sym.name = "cModifiedGS"
        if sym.name == "ClassicalGS":
            sym.name = "cClassicalGS"
        if sym.name == "_SpgmrMemRec":
            sym.name = "cSpgmrMemRec"
        if sym.name == "iS":
            sym.name = "ciS"
        sym.name = sym.name.strip(chars = {'_'})



const
    libsundials_nvecserial     = installDirLib64/"libsundials_nvecserial.so"
    libsundials_cvode          = installDirLib64/"libsundials_cvode.so"
    #libsundials_cvodes          = installDirLib64/"libsundials_cvodes.so"
    libsundials_sunlinsolspgmr = installDirLib64/"libsundials_sunlinsolspgmr.so"
    libsundials_sunmatrixdense = installDirLib64/"libsundials_sunmatrixdense.so"

cImport(installDirInclude/"sundials/sundials_config.h")
cImport(installDirInclude/"sundials/sundials_types.h")
cImport(installDirInclude/"sundials/sundials_math.h")

cImport(installDirInclude/"sundials/sundials_nvector.h")
#cImport(installDirInclude/"nvector/nvector_serial2.h")
cImport(installDirInclude/"nvector/nvector_serial.h", dynlib = "libsundials_nvecserial")

cImport(installDirInclude/"sundials/sundials_nonlinearsolver.h")
cImport(installDirInclude/"sundials/sundials_direct.h")
cImport(installDirInclude/"sundials/sundials_iterative.h")
cImport(installDirInclude/"sundials/sundials_matrix.h", dynlib="libsundials_cvode")
cImport(installDirInclude/"sundials/sundials_linearsolver.h", dynlib="libsundials_cvode")

#cImport(installDirInclude/"sundials/sundials_spgmr.h")
cImport(installDirInclude/"sunlinsol/sunlinsol_spgmr.h", dynlib="libsundials_sunlinsolspgmr")

cImport(installDirInclude/"sunmatrix/sunmatrix_dense.h", dynlib = "libsundials_sunmatrixdense")

cImport(installDirInclude/"cvode/cvode_ls.h", dynlib="libsundials_cvode")
#cImport(installDirInclude/"cvode/cvode2.h")
cImport(installDirInclude/"cvode/cvode.h", dynlib="libsundials_cvode")

# The following avoids importing twice the same definitions (already defined somewhere else).
#[
static:
   cSkipSymbol @["CV_ADAMS", "CV_BDF", "CV_NORMAL", "CV_ONE_STEP", "CV_SUCCESS", "CV_TSTOP_RETURN", "CV_ROOT_RETURN", "CV_WARNING",
   "CV_TOO_MUCH_WORK", "CV_TOO_MUCH_ACC", "CV_ERR_FAILURE", "CV_CONV_FAILURE", "CV_LINIT_FAIL", "CV_LSETUP_FAIL", "CV_LSOLVE_FAIL",
   "CV_RHSFUNC_FAIL", "CV_FIRST_RHSFUNC_ERR", "CV_REPTD_RHSFUNC_ERR", "CV_UNREC_RHSFUNC_ERR", "CV_RTFUNC_FAIL", "CV_NLS_INIT_FAIL",
   "CV_NLS_SETUP_FAIL", "CV_CONSTR_FAIL", "CV_MEM_FAIL", "CV_MEM_NULL", "CV_ILL_INPUT", "CV_NO_MALLOC", "CV_BAD_K", "CV_BAD_T",
   "CV_BAD_DKY", "CV_TOO_CLOSE", "CV_VECTOROP_ERR", "CVRhsFn", "CVRootFn", "CVEwtFn", "CVErrHandlerFn", "CVodeCreate"]

cImport(installDirInclude/"cvodes/cvodes.h", dynlib="libsundials_cvodes")
]#


template ptr2Array[T](p: pointer): auto = cast[ptr UncheckedArray[T]](p)
template array2Ptr[T](arr: openArray[T]): auto = addr(arr[0])

template `->`(a, b: untyped): untyped =
    a[].b

template NV_CONTENT_S(v: untyped): untyped = cast[N_VectorContent_Serial](v->content)
template NV_LENGTH_S(v: untyped): untyped = NV_CONTENT_S(v) -> length
template NV_OWN_DATA_S(v: untyped): untyped = NV_CONTENT_S(v) -> own_data
template NV_DATA_S(v: untyped): untyped = NV_CONTENT_S(v) -> data
template NV_Ith_S(v: untyped, i: sunindextype): untyped = ptr2Array[realtype](NV_DATA_S(v))[i]



type
    NVectorType* = object
        length*: int
        rawVector*: ref[N_Vector]

proc newNVector*(length: int): NVectorType =
    if length <= 0:
        raise newException(ValueError, "NVector length must be greater than 0")
    result.length = length
    result.rawVector = new N_Vector
    result.rawVector[] = N_VNew_Serial(result.length)

# create newNVector(length) and for over arr, NV_Ith_S(result, i) = arr[i] to keep it in memory.
proc newNVector*(arr: openArray[realtype]): NVectorType =
    if arr.len <= 0:
        raise newException(ValueError, "NVector length must be greater than 0")
    result.length = arr.len
    result.rawVector = new N_Vector
    result.rawVector[] = N_VNew_Serial(result.length)
    for i in 0 ..< result.length:
        NV_Ith_S(result.rawVector[], i) = arr[i]

proc newNVector*(v: N_Vector): NVectorType =
    result = newNVector(NV_LENGTH_S(v).int)
    N_VScale_Serial(1.0, v, result.rawVector[])

proc clone*(v: NVectorType): NVectorType =
    result = newNVector(v.length)
    N_VScale_Serial(1.0, v.rawVector[], result.rawVector[])


proc `[]`*(v: NVectorType, i: int): realtype =
    if v.length <= i:
        raise newException(ValueError, "index i is out of range. `[]`")
    NV_Ith_S(v.rawVector[], i)

proc `[]=`*(v: NVectorType, i: int, c: realtype) =
    if v.length <= i:
        raise newException(ValueError, "index i is out of range. `[]`")
    NV_Ith_S(v.rawVector[], i) = c

proc `$`*(v: NVectorType): string =
    result = "NVector("
    for i in 0 ..< v.length:
        result = result & $v[i] & ", "
    result = result & ")"

proc `@`*(v: NVectorType): seq[realtype] =
    for i in 0 ..< v.length:
        result.add(v[i])

proc `==`*(a, b: NVectorType): bool =
    let length = a.length
    if length != b.length:
        raise newException(ValueError, "NVectors must have same lengths for `==`")
    let aData = ptr2Array[realtype](NV_DATA_S(a.rawVector[]))
    let bData = ptr2Array[realtype](NV_DATA_S(b.rawVector[]))
    for i in 0 ..< length:
        if aData[i] != bData[i]:
            return false
    return true

proc `+`*(a, b: NVectorType): NVectorType =
    if a.length != b.length:
        raise newException(ValueError, "NVector must be of same length for addition")
    result = newNVector(a.length)
    N_VLinearSum_Serial(1.0, a.rawVector[], 1.0, b.rawVector[], result.rawVector[])

proc `+`*(v: NVectorType, c: realtype): NVectorType =
    result = newNVector(v.length)
    N_VAddConst_Serial(v.rawVector[], c, result.rawVector[])

proc `+`*(c: realtype, v: NVectorType): NVectorType =
    result = newNVector(v.length)
    N_VAddConst_Serial(v.rawVector[], c, result.rawVector[])

proc `+=`*(a: var NVectorType, b: NVectorType) =
    if a.length != b.length:
        raise newException(ValueError, "NVector must be of same length for addition")
    N_VLinearSum_Serial(1.0, a.rawVector[], 1.0, b.rawVector[], a.rawVector[])

proc `+=`*(v: var NVectorType, c: realtype) =
    N_VAddConst_Serial(v.rawVector[], c, v.rawVector[])


proc `-`*(a, b: NVectorType): NVectorType =
    if a.length != b.length:
        raise newException(ValueError, "NVector must be of same length for addition")
    result = newNVector(a.length)
    N_VLinearSum_Serial(1.0, a.rawVector[], -1.0, b.rawVector[], result.rawVector[])

proc `-`*(v: NVectorType, c: realtype): NVectorType =
    result = newNVector(v.length)
    N_VAddConst_Serial(v.rawVector[], -c, result.rawVector[])

# TODO
#[
proc `-`*(c: realtype, v: NVectorType): NVectorType =
    result = newNVector(v.length)
    N_VAddConst_Serial(v.rawVector[], c, result.rawVector[])
]#

proc `-=`*(a: var NVectorType, b: NVectorType) =
    if a.length != b.length:
        raise newException(ValueError, "NVector must be of same length for addition")
    N_VLinearSum_Serial(1.0, a.rawVector[], -1.0, b.rawVector[], a.rawVector[])

proc `-=`*(v: var NVectorType, c: realtype) =
    N_VAddConst_Serial(v.rawVector[], -c, v.rawVector[])

proc `*`*(v: NVectorType, c: realtype): NVectorType =
    result = newNVector(v.length)
    N_VScale_Serial(c, v.rawVector[], result.rawVector[])
proc `*`*(c: realtype, v: NVectorType): NVectorType =
    result = newNVector(v.length)
    N_VScale_Serial(c, v.rawVector[], result.rawVector[])


template CVodeProc*(name, body: untyped): untyped {.dirty.} =
    proc `name`(t: realtype, y_raw: N_Vector, ydot_raw: N_Vector, user_data: pointer): cint {.cdecl.} =
        let y = newNVector(y_raw)
        var ydot = newNVector(ydot_raw)
        body
        NV_DATA_S(ydot_raw) = NV_DATA_S(ydot.rawVector[])
    proc `name`(t: realtype, y: NVectorType): NVectorType =
        var ydot = newNVector(y.length)
        body
        result = ydot


echo "\n\n\n\nLet the real testing begin:"
echo "Addition:"
var v1 = newNVector([1.0, 2.0, 3.0])
var v2 = newNVector([4.0, 5.0, 6.0])
var vsum = v1 + v2
N_VPrint_Serial(vsum.rawVector[])
N_VPrint_Serial((1.0 + v1 + 1.0).rawVector[])
echo "Inplace Addition:"
v2 += v1
N_VPrint_Serial(v2.rawVector[])
v2 += 2.2
N_VPrint_Serial(v2.rawVector[])
echo v2 == v1

echo v2
echo v2[2]
echo -1.0 * v2


proc f(t: realtype, y_raw: N_Vector, ydot_raw: N_Vector, user_data: pointer): cint {.cdecl.} =
    let y = newNVector(y_raw)
    var ydot = newNVector(ydot_raw)
    ydot = clone(y)
    NV_DATA_S(ydot_raw) = NV_DATA_S(ydot.rawVector[])
    #NV_Ith_S(ydot_raw, 0) = NV_Ith_S(y_raw, 0)
    #NV_Ith_S(ydot_raw, 1) = NV_Ith_S(y_raw, 1)
    #NV_Ith_S(ydot_raw, 2) = NV_Ith_S(y_raw, 2)

CVodeProc f2:
    #ydot = 1/(t+1) * y
    ydot = y

var cvode_mem: pointer = nil
cvode_mem = CVodeCreate(CV_ADAMS)
var t0 = 0.0
var y0 = newNVector([1.0, 1.0, 1.0])
var A: SUNMatrix = nil#SUNDenseMatrix(3, 3)
let reltol = 1e-8
let abstol = 1e-8
var flag = CVodeInit(cvode_mem, f2, t0, y0.rawVector[])
flag = CVodeSStolerances(cvode_mem, reltol, abstol)
var LS = SUNLinSol_SPGMR(y0.rawVector[], 0, 0)
flag = CVodeSetLinearSolver(cvode_mem, LS, A)
var t: realtype = 0.0
var tout = 1.0
flag = CVode(cvode_mem, tout, y0.rawVector[], addr(t), CV_NORMAL)

import math
var correct = newNVector(@[exp(1.0), exp(1.0), exp(1.0)])
echo "Answer", y0
echo "Error: ", correct - y0
echo "f2: ", f2(10.0, y0)
echo "Seq: ", @y0
CVodeFree(addr(cvode_mem))
flag = SUNLinSolFree(LS)
SUNMatDestroy(A)

# tout should be openArray[realtype]
proc CVodeSolve*(f: proc(t: realtype, y_raw: N_Vector, ydot_raw: N_Vector, user_data: pointer): cint {.cdecl.}, y0: NVectorType, t0, tout: realtype, abstol = 1e-8, reltol = 1e-8): NVectorType =
    var cvode_mem = CVodeCreate(CV_ADAMS)
    var A: SUNMatrix = nil #SUNDenseMatrix(neqs, neqs)
    var flag = CVodeInit(cvode_mem, f, t0, y0.rawVector[])
    flag = CVodeSStolerances(cvode_mem, reltol, abstol)
    var LS = SUNLinSol_SPGMR(y0.rawVector[], 0, 0)
    flag = CVodeSetLinearSolver(cvode_mem, LS, A)
    var t = 0.0
    var y = newNVector(y0.length)
    flag = CVode(cvode_mem, tout, y.rawVector[], addr(t), CV_NORMAL)
    CVodeFree(addr(cvode_mem))
    flag = SUNLinSolFree(LS)
    SUNMATDestroy(A)
    result = y

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.