scontact2.py 4.2 KB
Newer Older
1
2
3
4
5
6
from __future__ import division
from ctypes import *
import numpy
import signal
import os
import sys
7
import shutil
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

dir_path = os.path.dirname(os.path.realpath(__file__))
lib = CDLL(os.path.join(dir_path,"libscontact2.so"))

signal.signal(signal.SIGINT, signal.SIG_DFL)
coord_type = c_double*2


is_64bits = sys.maxsize > 2**32

def doubleVector2PyArray(ptr) :
    size = cast(ptr-(8 if is_64bits else 4), POINTER(c_size_t)).contents.value//8
    buf = (size*c_double).from_address(ptr)
    return numpy.ctypeslib.as_array(buf)

def tagVector2PyArray(ptr) :
    size = cast(ptr-(8 if is_64bits else 4), POINTER(c_size_t)).contents.value//4
    buf = (size*c_int).from_address(ptr)
    return numpy.ctypeslib.as_array(buf)


class ParticleProblem :

    def __init__(self) :
        lib.particleProblemNew.restype = c_void_p
        self._pp = c_void_p(lib.particleProblemNew())
        if self._pp == None :
            raise NameError("cannot create particle problem")

    def __del__(self):
        if(self._pp != None) :
            lib.particleProblemDelete(self._pp)

    def addParticle(self, x, r, m):
        lib.particleProblemAddParticle(self._pp, coord_type(*x), c_double(r), c_double(m))

    def getTagId(self, tag):
        lib.particleProblemGetTagId.restype = c_size_t
        return lib.particleProblemGetTagId(self._pp, tag.encode())

    def getTagId(self, tid):
        lib.particleProblemGetTagName.restype = c_char_p
        return lib.particleProblemGetTagName(self._pp, c_size_t(tid))

    def addBoundaryDisk(self, x0, r, tag) :
        lib.particleProblemAddBoundaryDisk.restype = c_size_t
        return lib.particleProblemAddBoundaryDisk(self._pp, coord_type(*x0), c_double(r), tag.encode())

    def addBoundarySegment(self, x0, x1, tag) :
        lib.particleProblemAddBoundarySegment.restype = c_size_t
        return lib.particleProblemAddBoundarySegment(self._pp, coord_type(*x0), coord_type(*x1), tag.encode())

    def write(self, filename) :
        lib.particleProblemWrite(self._pp, filename.encode())

    def iterate(self, alert, dt, tol=0.005, maxit=-1) :
        lib.particleProblemIterate(self._pp, c_double(alert), c_double(dt), c_double(tol), c_int(maxit))

    def solve(self, alert, dt, tol=0.005, maxit=-1) :
        lib.particleProblemSolve(self._pp, c_double(alert), c_double(dt), c_double(tol), c_int(maxit))

    def maxdt(self, alert) :
        lib.particleProblemMaxDt.restype = c_double
        return lib.particleProblemMaxDt(self._pp, c_double(alert))
    
    def load(self, filename) :
        lib.particleProblemLoad(self._pp, filename.encode())

    def useJacobi(self, jacobi, relax = 0.5) :
        lib.particleProblemUseJacobi(self._pp, c_int(jacobi), c_double(relax))

    def writeVtk(self, filename) :
        lib.particleProblemWriteVtk(self._pp, filename.encode())

    def writeBoundaryVtk(self, filename) :
        lib.particleProblemWriteBoundaryVtk(self._pp, filename.encode())

    def diskTag(self) :
        lib.particleProblemDiskTag.restype = c_void_p
        return tagVector2PyArray(lib.particleProblemDiskTag(self._pp))

    def segmentTag(self) :
        lib.particleProblemSegmentTag.restype = c_void_p
        return tagVector2PyArray(lib.particleProblemSegmentTag(self._pp))

    def velocity(self) :
        lib.particleProblemVelocity.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemVelocity(self._pp)).reshape([-1,2])

    def particles(self):
        lib.particleProblemParticle.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemParticle(self._pp)).reshape([-1,2])
  
    def disks(self) :
        lib.particleProblemDisk.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemDisk(self._pp)).reshape([-1,5])

    def segments(self) :
        lib.particleProblemSegment.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemSegment(self._pp)).reshape([-1,6])

    def position(self) :
        lib.particleProblemPosition.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemPosition(self._pp)).reshape([-1,2])

    def externalForces(self) :
        lib.particleProblemExternalForces.restype = c_void_p
        return doubleVector2PyArray(lib.particleProblemExternalForces(self._pp)).reshape([-1,2])