fluid3.py 4.24 KB
Newer Older
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
1
# Marblesbag - Copyright (C) <2010-2018>
2
3
# <Universite catholique de Louvain (UCL), Belgium>
# <Universite de Montpellier, France>
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 	
# List of the contributors to the development of SLIM: see AUTHORS file.
# Description and complete License: see LICENSE file.
# 	
# This program (Marblesbag) is free software: 
# you can redistribute it and/or modify it under the terms of the GNU General 
# Public License as published by the Free Software Foundation, either version
# 3 of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program (see COPYING file).  If not, 
# see <http://www.gnu.org/licenses/>.

Matthieu Constant's avatar
Matthieu Constant committed
22
23
24
25
26
from ctypes import *
import numpy
import signal
import os

Matthieu Constant's avatar
Matthieu Constant committed
27

28
dir_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
29
lib = CDLL(os.path.join(dir_path,"libmbfluid3.so"))
Matthieu Constant's avatar
Matthieu Constant committed
30
31
32
33
34
35
36
37
38
39

signal.signal(signal.SIGINT, signal.SIG_DFL)


BNDCB = CFUNCTYPE(None,c_int,POINTER(c_double),POINTER(c_double))
class StrongBoundary(Structure):
    _fields_ = [("tag",c_char_p),("field",c_int),("apply",BNDCB)]

class fluid_problem :

Matthieu Constant's avatar
Matthieu Constant committed
40
    def __init__(self, mesh_file_name, g, mu, rho, alpha, strong_boundaries):
Matthieu Constant's avatar
Matthieu Constant committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
        nsb = len(strong_boundaries)
        class Bnd :
            def __init__(self, b) :
                self._b = b
            def apply(self, n, xp, vp) :
                x = numpy.frombuffer(cast(xp, POINTER(int(n)*2*c_double)).contents).reshape([n,2])
                v = numpy.frombuffer(cast(vp, POINTER(int(n)*c_double)).contents)
                if callable(self._b) :
                    v[:] = self._b(x)
                else :
                    v[:] = self._b

        asb = (StrongBoundary*nsb)(*[StrongBoundary(i[0].encode(),i[1],BNDCB(Bnd(i[2]).apply)) for i in strong_boundaries])
        self.asb = asb
        lib.fluid_problem_new.restype = c_void_p
Matthieu Constant's avatar
Matthieu Constant committed
56
        self._fp = c_void_p(lib.fluid_problem_new(mesh_file_name.encode(), c_double(g), c_double(mu), c_double(rho), c_double(alpha), nsb, asb))
Matthieu Constant's avatar
Matthieu Constant committed
57
58
59
60
61
62
63
        if self._fp == None :
            raise NameError("cannot create fluid problem")

    def __del__(self):
        if(self._fp != None) :
            lib.fluid_problem_free(self._fp)

Matthieu Constant's avatar
Matthieu Constant committed
64
65
    def adapt_mesh(self, lcmax, lcmin, n_el) :
        lib.fluid_problem_adapt_mesh(self._fp, c_double(lcmax), c_double(lcmin), c_double(n_el))
Matthieu Constant's avatar
Matthieu Constant committed
66
67
68
69

    def export(self, output_dir, t, it) :
        lib.fluid_problem_export(self._fp, output_dir.encode(), c_double(t), c_int(it))

Matthieu Constant's avatar
visu 3d    
Matthieu Constant committed
70
71
    def export_vtk(self, output_dir, t, it) :
        lib.fluid_problem_export_vtk(self._fp, output_dir.encode(), c_double(t), c_int(it))
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
72
73
74

    def import_vtk(self, filename) :
        lib.fluid_problem_import_vtk(self._fp, filename.encode())
Matthieu Constant's avatar
visu 3d    
Matthieu Constant committed
75
    
Matthieu Constant's avatar
Matthieu Constant committed
76
77
78
79
80
81
82
83
    def compute_node_force(self, dt) :
        def np2c(a) :
            return c_void_p(a.ctypes.data)
        forces = numpy.ndarray([self.n_particles,3],"d")
        lib.fluid_problem_compute_node_particle_force(self._fp, c_double(dt), np2c(forces))
        return forces

    def implicit_euler(self, dt) :
84
        return lib.fluid_problem_implicit_euler(self._fp, c_double(dt))
Matthieu Constant's avatar
Matthieu Constant committed
85

86
    def set_particles(self, mass, volume, position, velocity, elid=None):
Matthieu Constant's avatar
Matthieu Constant committed
87
88
        def np2c(a) :
            return c_void_p(numpy.ascontiguousarray(a).ctypes.data)
89
90
        def np2ci(a) :
            return c_void_p(numpy.require(a,"int","C").ctypes.data)
Matthieu Constant's avatar
Matthieu Constant committed
91
        self.n_particles = mass.shape[0]
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
        if elid is not None:
            lib.fluid_problem_set_particles(self._fp,c_int(mass.shape[0]),np2c(mass),np2c(volume),np2c(position),np2c(velocity),np2ci(elid))
        else :
            lib.fluid_problem_set_particles(self._fp,c_int(mass.shape[0]),np2c(mass),np2c(volume),np2c(position),np2c(velocity),None)

    def particle_element_id(self) :
        f = getattr(lib,"fluid_problem_particle_element_id")
        f.restype = c_void_p
        fs = getattr(lib,"fluid_problem_n_particles")
        fs.restype = c_int
        ptr = f(self._fp)
        size = fs(self._fp)
        buf = (size*c_int).from_address(ptr)
        return numpy.ctypeslib.as_array(buf)