Skip to content

Commit d3d40c1

Browse files
committed
add helper and example
1 parent fc5c22c commit d3d40c1

File tree

3 files changed

+105
-26
lines changed

3 files changed

+105
-26
lines changed

fidimag/common/lib/helper_cython.pyx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import numpy as np
2+
cimport numpy as np
3+
4+
def normalise(a):
5+
"""
6+
normalise the given array a
7+
"""
8+
a.shape = (-1, 3)
9+
b = np.sqrt(a[:, 0] ** 2 + a[:, 1] ** 2 + a[:, 2] ** 2)
10+
ids = (b == 0)
11+
b[ids] = 1.0
12+
a[:, 0] /= b
13+
a[:, 1] /= b
14+
a[:, 2] /= b
15+
a.shape = (-1,)
16+
17+
def init_scalar(value, mesh, *args):
18+
19+
n = mesh.n
20+
21+
mesh_v = np.zeros(n)
22+
23+
if isinstance(value, (int, float)):
24+
mesh_v[:] = value
25+
elif hasattr(value, '__call__'):
26+
for i in range(n):
27+
mesh_v[i] = value(mesh.coordinates[i], *args)
28+
29+
elif isinstance(value, np.ndarray):
30+
if value.shape == mesh_v.shape:
31+
mesh_v[:] = value[:]
32+
else:
33+
raise ValueError("Array size must match the mesh size")
34+
35+
return mesh_v
36+
37+
def init_vector(m0, mesh, norm=False, *args):
38+
39+
n = mesh.n
40+
41+
spin = np.zeros((n, 3))
42+
43+
if isinstance(m0, list) or isinstance(m0, tuple):
44+
spin[:, :] = m0
45+
spin = np.reshape(spin, 3 * n, order='C')
46+
47+
elif hasattr(m0, '__call__'):
48+
v = m0(mesh.coordinates[0], *args)
49+
if len(v) != 3:
50+
raise Exception(
51+
'The length of the value in init_vector method must be 3.')
52+
for i in range(n):
53+
spin[i, :] = m0(mesh.coordinates[i], *args)
54+
spin = np.reshape(spin, 3 * n, order='C')
55+
56+
elif isinstance(m0, np.ndarray):
57+
if m0.shape == (3, ):
58+
spin[:] = m0 # broadcasting
59+
else:
60+
spin.shape = (-1)
61+
spin[:] = m0 # overwriting the whole thing
62+
63+
spin.shape = (-1,)
64+
65+
if norm:
66+
normalise(spin)
67+
68+
return spin
69+
70+
71+
# def init_vector_func_fast(m0, mesh, norm=False, *args):
72+
# """
73+
# A fast version of init_vector for functions that does
74+
# not perform any checking of input arguments.
75+
# """
76+
# v = m0(mesh.coordinates[0], *args)
77+
# for i in range(n):
78+
# spin[3*i:] = m0(&mesh, *args)
79+
# spin = np.reshape(spin, 3 * n, order='C')

fidimag/user/example.pyx

Lines changed: 0 additions & 12 deletions
This file was deleted.

setup.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
import glob
88
import re
99
import sys
10-
1110
#if sys.platform == 'darwin':
1211
# from distutils import sysconfig
1312
# vars = sysconfig.get_config_vars()
1413
# vars['LDSHARED'] = vars['LDSHARED'].replace('-bundle', '-dynamiclib')
1514

15+
class BuildError(Exception):
16+
pass
17+
18+
1619
if 'CC' in os.environ:
1720
print("Using CC={}".format(os.environ['CC']))
1821
else:
@@ -66,12 +69,7 @@ def glob_cfiles(path, excludes):
6669
sources.append(os.path.join(ATOM_DIR, 'clib.pyx'))
6770
sources += glob_cfiles(ATOM_DIR, excludes=["clib.c"])
6871

69-
user_sources = []
7072

71-
user_cy = glob.glob(os.path.join(USER_DIR, '*.pyx'))
72-
print("Found user Cython files: {}".format(user_cy))
73-
user_sources += user_cy
74-
sources += glob_cfiles(USER_DIR, excludes=user_cy)
7573

7674
common_sources = []
7775
common_sources.append(os.path.join(COMMON_DIR, 'common_clib.pyx'))
@@ -263,16 +261,30 @@ def glob_cfiles(path, excludes):
263261
extra_compile_args=com_args,
264262
extra_link_args=com_link,
265263
),
266-
Extension("fidimag.extensions.user",
267-
sources=user_sources,
268-
include_dirs=com_inc,
269-
libraries=com_libs,
270-
library_dirs=lib_paths, runtime_library_dirs=lib_paths,
271-
extra_compile_args=com_args,
272-
extra_link_args=com_link,
273-
),
274264
]
275265

266+
267+
for folder in glob.glob(os.path.join(USER_DIR, '*/')):
268+
module_name = folder.split('/')[-2]
269+
print(folder.split('/'))
270+
print('Found User Module: {}'.format(module_name))
271+
user_sources = glob.glob(folder + '/*.pyx')
272+
print('\tFound Cython sources: {}'.format(user_sources))
273+
if len(user_sources) != 1:
274+
raise BuildError("User Modules are only allowed one Cython .pyx file")
275+
user_sources += glob_cfiles(folder, excludes=user_sources)
276+
ext_modules.append(
277+
Extension("fidimag.extensions.user.{}".format(module_name),
278+
sources=user_sources,
279+
include_dirs=com_inc,
280+
libraries=com_libs,
281+
library_dirs=lib_paths, runtime_library_dirs=lib_paths,
282+
extra_compile_args=com_args,
283+
extra_link_args=com_link,
284+
),
285+
)
286+
287+
276288
setup(
277289
name='fidimag',
278290
version=version,

0 commit comments

Comments
 (0)