Skip to content

Commit d058721

Browse files
heat eq, implicit scheme using fort lib
1 parent 3ace186 commit d058721

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

src/fdm_heat_eq_implitcit_1D_use_fort_lib.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,36 @@
33
import numpy
44

55
from src.utils import visu1D
6-
from ctypes import POINTER, c_int, c_float, cdll
6+
from ctypes import POINTER, c_int, c_double, cdll
77

88
"""
99
MacOS: Before running this script, please build fortran library [1]:
10-
gfortran -dynamiclib src/utils/tridiag.f90 -o src/tridiag.dylib
10+
src$ gfortran -shared -fPIC libs/tridiag.f90 -o tridiag.dylib
1111
There will be a file called 'tridiag.dylib' in the project src folder.
1212
Reference:
1313
[1] http://jean-pierre.moreau.pagesperso-orange.fr/Fortran/tridiag_f90.txt
1414
[2] https://stackoverflow.com/questions/19263879/speeding-up-element-wise-array-multiplication-in-python/19458585#19458585
1515
"""
1616
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
1717
FORTRAN_LIB_PATH = os.path.join(ROOT_DIR, 'tridiag.dylib')
18-
fortran = cdll.LoadLibrary(FORTRAN_LIB_PATH)
19-
fortran.tridiag.argtypes = [POINTER(c_float),
20-
POINTER(c_float),
21-
POINTER(c_float),
22-
POINTER(c_float),
23-
POINTER(c_float),
24-
POINTER(c_int),
25-
POINTER(c_int)]
26-
fortran.tridiag.restype = None
18+
fort_lib = cdll.LoadLibrary(FORTRAN_LIB_PATH)
19+
tri_diag = fort_lib.__getattr__("tridiag")
20+
tri_diag.argtypes = [POINTER(c_double),
21+
POINTER(c_double),
22+
POINTER(c_double),
23+
POINTER(c_double),
24+
POINTER(c_double),
25+
POINTER(c_int),
26+
POINTER(c_int)]
27+
tri_diag.restype = None
2728

2829
if __name__ == "__main__":
2930
# FDM, implicit scheme for the heat equation:
3031
# INPUT
3132
# Advection velocity:
3233
mu = 1 / 16
3334
# Grid size; Use periodic boundary conditions
34-
X, M, Tend = 1, 10, 0.5
35+
X, M, Tend = 1, 5000, 1
3536
h = 1 / (M + 1)
3637
Dt = 0.02
3738
x = numpy.linspace(0, X, M + 2) # x(1) =0, x(2) = h, , ..., x(M) = X -h; x(M+1) = X;
@@ -51,15 +52,17 @@
5152
B = numpy.zeros(M + 2)
5253
B[:] = 1.0 + 2.0 * mu
5354

55+
code = c_int(-1)
56+
n = c_int(M + 2)
57+
5458
while time < Tend:
5559
a, b, c = A, B, C
56-
code = -1
57-
fortran.tridiag(a.ctypes.data_as(POINTER(c_float)),
58-
b.ctypes.data_as(POINTER(c_float)),
59-
b.ctypes.data_as(POINTER(c_float)),
60-
wm.ctypes.data_as(POINTER(c_float)),
61-
wn.ctypes.data_as(POINTER(c_float)),
62-
c_int(M + 2), c_int(code))
60+
tri_diag(c.ctypes.data_as(POINTER(c_double)),
61+
b.ctypes.data_as(POINTER(c_double)),
62+
a.ctypes.data_as(POINTER(c_double)),
63+
wm.ctypes.data_as(POINTER(c_double)),
64+
wn.ctypes.data_as(POINTER(c_double)),
65+
n, code)
6366
wn = wm
6467

6568
time += Dt

src/libs/tridiag.f90

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ SUBROUTINE TRIDIAG(A, B, C, R, U, N, CODE) BIND(C, NAME='tridiag')
44
! M U = R, where A, B and C are the three main diagonals of matrix
55
! M(N,N), the other terms are 0. R is the right side vector.
66
!*****************************************************************
7-
USE ISO_C_BINDING, ONLY: C_FLOAT, C_INT
7+
USE ISO_C_BINDING, ONLY: C_DOUBLE, C_INT
88
IMPLICIT NONE
9-
INTEGER, PARAMETER :: NMAX = 100
10-
REAL(C_FLOAT), PARAMETER :: EPS = 1.0D-9
11-
REAL(C_FLOAT) :: BET, GAM(NMAX), A(N), B(N), C(N), R(N), U(N)
9+
REAL(C_DOUBLE), PARAMETER :: EPS = 1.0D-9
10+
REAL(C_DOUBLE) :: BET, GAM(N+1), A(N), B(N), C(N), R(N), U(N)
1211
INTEGER(C_INT) :: J, N, CODE
1312

1413
IF (B(1) <= EPS) THEN

0 commit comments

Comments
 (0)