pyharm 0.4.3__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyharm/__init__.py +39 -0
- pyharm/_check_types.py +144 -0
- pyharm/_constants.py +52 -0
- pyharm/_data_types.py +43 -0
- pyharm/_err.py +181 -0
- pyharm/_get_empty_array.py +17 -0
- pyharm/_get_module_constants.py +29 -0
- pyharm/_lib.py +29 -0
- pyharm/crd.py +1724 -0
- pyharm/glob.py +147 -0
- pyharm/integ.py +250 -0
- pyharm/leg.py +527 -0
- pyharm/libcharm.cp313-win_amd64.pyd +0 -0
- pyharm/misc.py +176 -0
- pyharm/sha.py +180 -0
- pyharm/shc.py +1545 -0
- pyharm/shs.py +478 -0
- pyharm-0.4.3.dist-info/AUTHORS +8 -0
- pyharm-0.4.3.dist-info/COPYING +339 -0
- pyharm-0.4.3.dist-info/DELVEWHEEL +2 -0
- pyharm-0.4.3.dist-info/METADATA +198 -0
- pyharm-0.4.3.dist-info/RECORD +26 -0
- pyharm-0.4.3.dist-info/WHEEL +5 -0
- pyharm-0.4.3.dist-info/top_level.txt +1 -0
- pyharm.libs/fftw3-0876e9d73cb2654b89b30b17bc9d4219.dll +0 -0
- pyharm.libs/libomp140.x86_64-48ba39bf721e43bdfc8218e072786992.dll +0 -0
pyharm/__init__.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyHarm is a Python wrapper for CHarm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# start delvewheel patch
|
|
7
|
+
def _delvewheel_patch_1_9_0():
|
|
8
|
+
import os
|
|
9
|
+
if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'pyharm.libs'))):
|
|
10
|
+
os.add_dll_directory(libs_dir)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_delvewheel_patch_1_9_0()
|
|
14
|
+
del _delvewheel_patch_1_9_0
|
|
15
|
+
# end delvewheel patch
|
|
16
|
+
|
|
17
|
+
import os as _os
|
|
18
|
+
from ._lib import _load_lib
|
|
19
|
+
|
|
20
|
+
# Name of the shared CHarm library to load
|
|
21
|
+
_libcharmname = 'libcharm'
|
|
22
|
+
|
|
23
|
+
# Directory of "_libcharmname"
|
|
24
|
+
_libcharmdir = _os.path.join(_os.path.dirname(__file__), '')
|
|
25
|
+
|
|
26
|
+
# Load the shared CHarm library
|
|
27
|
+
_libcharm = _load_lib(_libcharmdir, _libcharmname)
|
|
28
|
+
|
|
29
|
+
# Prefix to be added to the CHarm function names. Depends on the format of
|
|
30
|
+
# floating point numbers used to compile CHarm (single or double precision).
|
|
31
|
+
_CHARM = 'charm_'
|
|
32
|
+
|
|
33
|
+
# Prefix to be added to the PyHarm functions when calling "__repr__" methods
|
|
34
|
+
_pyharm = 'pyharm'
|
|
35
|
+
|
|
36
|
+
# The "err" module is intentionally not imported, as users do not interact with
|
|
37
|
+
# it in PyHarm.
|
|
38
|
+
from . import crd, glob, integ, leg, misc, sha, shc, shs
|
|
39
|
+
__all__ = ['crd', 'glob', 'integ', 'leg', 'misc', 'sha', 'shc', 'shs']
|
pyharm/_check_types.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Internal checks of data types passed by users to PyHarm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import numpy as _np
|
|
7
|
+
from ._data_types import _pyharm_ints, _pyharm_flt_all, _pyharm_flt
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _check_int_scalar(x, s):
|
|
11
|
+
"""
|
|
12
|
+
Checks whether "x" is an instance of one of the classes in `_pyharm_ints`
|
|
13
|
+
and if so, whether it is a scalar in order to represent the quantity named
|
|
14
|
+
`s`.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
x : any data type
|
|
19
|
+
Data to check
|
|
20
|
+
s : str
|
|
21
|
+
String with the name of the data that is being checked with the first
|
|
22
|
+
letter being uppercase (e.g. 'The \'crd_type\' variable').
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
if not isinstance(x, _pyharm_ints):
|
|
26
|
+
msg = f'{s} must be an instance of one of the following classes: '
|
|
27
|
+
msg += f'{_pyharm_ints}.'
|
|
28
|
+
raise TypeError(msg)
|
|
29
|
+
|
|
30
|
+
if not _np.isscalar(x):
|
|
31
|
+
raise ValueError(f'{s} must be a scalar.')
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _check_flt_scalar(x, s):
|
|
35
|
+
"""
|
|
36
|
+
Checks whether `x` is an instance of one of the classes in
|
|
37
|
+
`_pyharm_flt_all` and if so, whether it is a scalar to represent
|
|
38
|
+
the quantity named `s`.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
x : any data type
|
|
43
|
+
Data to check
|
|
44
|
+
s : str
|
|
45
|
+
String with the name of the data that is being checked with the first
|
|
46
|
+
letter being uppercase (e.g. 'Scaling parameter').
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
if not isinstance(x, _pyharm_flt_all):
|
|
50
|
+
msg = f'{s} must be an instance of one of the following classes: '
|
|
51
|
+
msg += f'{_pyharm_flt_all}.'
|
|
52
|
+
raise TypeError(msg)
|
|
53
|
+
|
|
54
|
+
if not _np.isscalar(x):
|
|
55
|
+
raise ValueError(f'{s} must be a scalar.')
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _check_deg_ord(x, do):
|
|
59
|
+
"""
|
|
60
|
+
Checks whether `x` satisfies all conditions to represent harmonic degree
|
|
61
|
+
(`do == 'degree'`) or harmonic order (`do == 'order'`).
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
x : any data type
|
|
66
|
+
do : str
|
|
67
|
+
Either 'degree' or 'order'
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Check whether "x" is of a correct integer class and whether it is
|
|
71
|
+
# a scalar
|
|
72
|
+
_check_int_scalar(x, f'Spherical harmonic {do}')
|
|
73
|
+
if do != 'degree' and do != 'order':
|
|
74
|
+
msg = f'The \'do\' variable must be set either to \'degree\' '
|
|
75
|
+
msg += f'or to \'order\'.'
|
|
76
|
+
raise ValueError(msg)
|
|
77
|
+
|
|
78
|
+
if x < 0:
|
|
79
|
+
msg = f'Spherical harmonic {do} cannot be smaller than zero.'
|
|
80
|
+
raise ValueError(msg)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _check_radius(x):
|
|
84
|
+
"""
|
|
85
|
+
Checks whether `x` satisfies all conditions to represent spherical radius.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
x : any data type
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
_check_flt_scalar(x, 'Spherical radius')
|
|
93
|
+
|
|
94
|
+
if x <= 0.0:
|
|
95
|
+
raise ValueError('Spherical radius must be larger than zero.')
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _check_flt_ndarray(x, n, s):
|
|
99
|
+
"""
|
|
100
|
+
Checks whether `x` satisfies all conditions to represent an nD floating
|
|
101
|
+
point numpy array that can safely enter CHarm in order to represent
|
|
102
|
+
quantity named `s`.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
x : any data type
|
|
107
|
+
Object to be checked
|
|
108
|
+
n : integer
|
|
109
|
+
Required number of dimensions of the nD floating point array
|
|
110
|
+
s : str
|
|
111
|
+
String with the name of the object that is being checked with the first
|
|
112
|
+
letter being uppercase (e.g., 'Latitudes')
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
# Must be a "_np.ndarray"
|
|
116
|
+
if not isinstance(x, _np.ndarray):
|
|
117
|
+
msg = f'{s} must be an instance of one of the following classes: '
|
|
118
|
+
msg += f'{_np.ndarray}.'
|
|
119
|
+
raise TypeError(msg)
|
|
120
|
+
|
|
121
|
+
# Must be of the correct "dtype"
|
|
122
|
+
if x.dtype != _pyharm_flt:
|
|
123
|
+
msg = f'{s} must be of the following \'dtype\': {_pyharm_flt}.'
|
|
124
|
+
raise ValueError(msg)
|
|
125
|
+
|
|
126
|
+
# Must have the correct number of dimensions
|
|
127
|
+
if x.ndim != n:
|
|
128
|
+
msg = f'{s} must be of the following dimension: \'ndim={n}\'.'
|
|
129
|
+
raise ValueError(msg)
|
|
130
|
+
|
|
131
|
+
# Must be C-contiguous
|
|
132
|
+
if not x.flags.c_contiguous:
|
|
133
|
+
msg = f'{s} must be C-contiguous in memory (see the \'order\' flag '
|
|
134
|
+
msg += f'of numpy arrays).'
|
|
135
|
+
raise ValueError(msg)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _check_pointer(pointer, func_name, lib_name):
|
|
139
|
+
|
|
140
|
+
if not pointer:
|
|
141
|
+
msg = f'Function call to \'{func_name}\' from the CHarm library '
|
|
142
|
+
msg += f'\'{lib_name}\' returned a NULL pointer.'
|
|
143
|
+
raise ValueError(msg)
|
|
144
|
+
|
pyharm/_constants.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generated automatically. Do not modify!
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
_globals = {
|
|
6
|
+
'CHARM_SHA_CELL_AQ': 0,
|
|
7
|
+
'CHARM_CRD_CELL_GRID': -2,
|
|
8
|
+
'CHARM_CRD_CELL_SCATTERED': -1,
|
|
9
|
+
'CHARM_CRD_POINT_SCATTERED': 1,
|
|
10
|
+
'CHARM_CRD_POINT_GRID': 2,
|
|
11
|
+
'CHARM_CRD_POINT_GRID_GL': 3,
|
|
12
|
+
'CHARM_CRD_POINT_GRID_DH1': 4,
|
|
13
|
+
'CHARM_CRD_POINT_GRID_DH2': 5,
|
|
14
|
+
'CHARM_ERR_MAX_FILE': 4096,
|
|
15
|
+
'CHARM_ERR_MAX_FUNC': 256,
|
|
16
|
+
'CHARM_ERR_MAX_MSG': 4096,
|
|
17
|
+
'CHARM_ERR_MAX_LEVEL': 10,
|
|
18
|
+
'CHARM_ERR_MALLOC_FAILURE': 'Memory allocation failure.',
|
|
19
|
+
'CHARM_ERR_FFTW_INIT_FAILURE': 'FFTW failed to initialize OpenMP threads.',
|
|
20
|
+
'CHARM_FAILURE': -1,
|
|
21
|
+
'CHARM_SUCCESS': 0,
|
|
22
|
+
'CHARM_EMEM': 1,
|
|
23
|
+
'CHARM_EFUNCARG': 2,
|
|
24
|
+
'CHARM_EFILEIO': 3,
|
|
25
|
+
'CHARM_EFFTWINIT': 4,
|
|
26
|
+
'CHARM_EMPIPROCESS': 5,
|
|
27
|
+
'CHARM_EXTERN': None,
|
|
28
|
+
'CHARM_CDECL': None,
|
|
29
|
+
'CHARM_SHC__NMAX_MODEL': -18446744073709551615,
|
|
30
|
+
'CHARM_SHC__NMAX_ERROR': -18446744073709551614,
|
|
31
|
+
'CHARM_SHC_WRITE_N': 0,
|
|
32
|
+
'CHARM_SHC_WRITE_M': 1,
|
|
33
|
+
'CHARM_VERSION_MAJOR': 0,
|
|
34
|
+
'CHARM_VERSION_MINOR': 4,
|
|
35
|
+
'CHARM_VERSION_PATCH': 3,
|
|
36
|
+
'CHARM_VERSION_STRING': '0.4.3',
|
|
37
|
+
'CHARM_LEG_PMNJ': 0,
|
|
38
|
+
'CHARM_LEG_PMJN': 1,
|
|
39
|
+
'GRAD_0': 0,
|
|
40
|
+
'GRAD_1': -1,
|
|
41
|
+
'GRAD_2': -2,
|
|
42
|
+
'GRAD_LL': 0,
|
|
43
|
+
'GRAD_LR': 1,
|
|
44
|
+
'GRAD_LP': 2,
|
|
45
|
+
'GRAD_RR': 3,
|
|
46
|
+
'GRAD_RP': 4,
|
|
47
|
+
'GRAD_PP': 5,
|
|
48
|
+
'GRAD_P': 2,
|
|
49
|
+
'GRAD_L': 0,
|
|
50
|
+
'GRAD_R': 1,
|
|
51
|
+
}
|
|
52
|
+
|
pyharm/_data_types.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Defines data types that:
|
|
3
|
+
|
|
4
|
+
* users can pass to PyHarm,
|
|
5
|
+
* PyHarm passes to CHarm, and
|
|
6
|
+
* CHarm returns to PyHarm.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as _np
|
|
10
|
+
import ctypes as _ct
|
|
11
|
+
|
|
12
|
+
# Data types that user can pass to PyHarm to represent integers
|
|
13
|
+
_pyharm_ints = (int, _np.integer)
|
|
14
|
+
|
|
15
|
+
# Data types that user can pass to PyHarm to represent floating point
|
|
16
|
+
# numbers. Note that "PY_FLOAT" already contains the comma, so no comma
|
|
17
|
+
# between "float," and "_np.float64".
|
|
18
|
+
_pyharm_flt_all = (float, _np.float64,) + _pyharm_ints
|
|
19
|
+
|
|
20
|
+
# Floating point data types for numpy ndarrays. A *single* data type must be
|
|
21
|
+
# defined here! The reason is that it avoids making any internal copies of
|
|
22
|
+
# data entered by the user, as this could be a problem for large arrays.
|
|
23
|
+
_pyharm_flt = _np.float64
|
|
24
|
+
|
|
25
|
+
# This is the data type, to which PyHarm converts the C's "double" (or "float"
|
|
26
|
+
# if in single precision) returned by CHarm
|
|
27
|
+
_charm_flt = _np.float64
|
|
28
|
+
|
|
29
|
+
# C's "int" entering CHarm
|
|
30
|
+
_ct_int = _ct.c_int
|
|
31
|
+
|
|
32
|
+
# C's "unsigned int" entering CHarm
|
|
33
|
+
_ct_uint = _ct.c_uint
|
|
34
|
+
|
|
35
|
+
# C's "size_t" entering CHarm
|
|
36
|
+
_ct_size_t = _ct.c_size_t
|
|
37
|
+
|
|
38
|
+
# C's "unsigned long int" entering CHarm
|
|
39
|
+
_ct_ulong = _ct.c_ulong
|
|
40
|
+
|
|
41
|
+
# C's "double" (or "float" if in single precision) entering CHarm
|
|
42
|
+
_ct_flt = _ct.c_double
|
|
43
|
+
|
pyharm/_err.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Implements the "err" module of PyHarm.
|
|
2
|
+
#
|
|
3
|
+
# NOTE: Unlike in CHarm, users do *not* interact with the "err" module in
|
|
4
|
+
# PyHarm!
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import ctypes as _ct
|
|
8
|
+
from . import _libcharm, _libcharmname, _CHARM
|
|
9
|
+
from ._get_module_constants import _get_module_constants
|
|
10
|
+
from ._constants import _globals
|
|
11
|
+
from ._data_types import _ct_int
|
|
12
|
+
from ._check_types import _check_pointer
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Get the module constants from "_constants.py" and add them to the module's
|
|
16
|
+
# namespace
|
|
17
|
+
_get_module_constants('CHARM_ERR_')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Character to represent the C's termination character
|
|
21
|
+
NULL_CHAR = '\0'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _Err(_ct.Structure):
|
|
25
|
+
"""
|
|
26
|
+
Private class to represent the `charm_err` structure of CHarm.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
_fields_ = [('level', _ct.c_uint),
|
|
30
|
+
('file', _ct.POINTER(_ct.POINTER(_ct.c_char))),
|
|
31
|
+
('line', _ct.POINTER(_ct.c_uint)),
|
|
32
|
+
('func', _ct.POINTER(_ct.POINTER(_ct.c_char))),
|
|
33
|
+
('code', _ct_int),
|
|
34
|
+
('msg', _ct.POINTER(_ct.c_char)),
|
|
35
|
+
('saturated', _ct.c_bool)]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CHarmError(Exception):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def init():
|
|
43
|
+
"""
|
|
44
|
+
Creates an empty instance of the `_Err` class.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
out : _Err
|
|
49
|
+
An instance of the `_Err` class.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
func = _libcharm[_CHARM + 'err_init']
|
|
53
|
+
func.restype = _ct.POINTER(_Err)
|
|
54
|
+
func.argtypes = None
|
|
55
|
+
|
|
56
|
+
err = func()
|
|
57
|
+
_check_pointer(err, _CHARM + 'err_init', _libcharmname)
|
|
58
|
+
|
|
59
|
+
return err
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def free(a):
|
|
63
|
+
"""
|
|
64
|
+
Frees the memory associated with an instance `a` of the `_Err` class.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
|
|
69
|
+
a : _Err
|
|
70
|
+
An instance of the `_Err` class to be freed.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
if a is not None:
|
|
74
|
+
func = _libcharm[_CHARM + 'err_free']
|
|
75
|
+
func.restype = None
|
|
76
|
+
func.argtypes = [_ct.POINTER(_Err)]
|
|
77
|
+
func(a)
|
|
78
|
+
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def isempty(a):
|
|
83
|
+
"""
|
|
84
|
+
Returns `True` if an instance of the `_Err` class `a` is empty or `False`
|
|
85
|
+
otherwise.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
a : _Err
|
|
90
|
+
An instance of the `_Err` class to be checked
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
out : bool
|
|
95
|
+
`True` if `a` is empty, `False` otherwise.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
func = _libcharm[_CHARM + 'err_isempty']
|
|
99
|
+
func.restype = _ct.c_bool
|
|
100
|
+
func.argtypes = [_ct.POINTER(_Err)]
|
|
101
|
+
|
|
102
|
+
return func(a)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def reset(a):
|
|
106
|
+
"""
|
|
107
|
+
Resets an instance `a` of the `_Err` class.
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
a : _Err
|
|
112
|
+
An instance of the `_Err` class to be reset.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
out : _Err
|
|
117
|
+
`a` reset to empty values
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
func = _libcharm[_CHARM + 'err_reset']
|
|
121
|
+
func.restype = None
|
|
122
|
+
func.argtypes = [_ct.POINTER(_Err)]
|
|
123
|
+
|
|
124
|
+
return func(a)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def handler(a, terminate):
|
|
128
|
+
"""
|
|
129
|
+
This is a Python implementation of the CHarm's `charm_err_handler`
|
|
130
|
+
function. This Python implementation allows better error handling in
|
|
131
|
+
Python.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
a : _Err
|
|
136
|
+
An instance of the `_Err` class to be handled.
|
|
137
|
+
terminate : bool
|
|
138
|
+
If `True` and `a` is not empty, the execution of the program
|
|
139
|
+
terminates. If `False` and `a` is not empty, the error is printed and
|
|
140
|
+
the program continues in code execution. If `False` and `a` is empty,
|
|
141
|
+
nothing happens.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
if isempty(a):
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
e = a.contents
|
|
148
|
+
|
|
149
|
+
err_msg = f'\n'
|
|
150
|
+
err_msg += f'Error code: {e.code} ' \
|
|
151
|
+
'Traceback (most recent call last)\n'
|
|
152
|
+
err_msg += f'\n'
|
|
153
|
+
|
|
154
|
+
for l in range(e.level - 1, -1, -1):
|
|
155
|
+
|
|
156
|
+
f = e.file[l][:MAX_FILE].decode()
|
|
157
|
+
idx1 = f.find(NULL_CHAR)
|
|
158
|
+
|
|
159
|
+
func = e.func[l][:MAX_FUNC].decode()
|
|
160
|
+
idx2 = func.find(NULL_CHAR)
|
|
161
|
+
|
|
162
|
+
err_msg += f' File \'{f[:idx1]}\', line: {e.line[l]}, '
|
|
163
|
+
err_msg += f'function: \'{func[:idx2]}\'\n\n'
|
|
164
|
+
|
|
165
|
+
if e.saturated:
|
|
166
|
+
err_msg += ' Warning: The error structure is '
|
|
167
|
+
err_msg += 'saturated. Most recent function calls may therefore '
|
|
168
|
+
err_msg += 'not be reported.\n'
|
|
169
|
+
err_msg += f'\n'
|
|
170
|
+
|
|
171
|
+
msg = e.msg[:MAX_MSG].decode()
|
|
172
|
+
idx = msg.find(NULL_CHAR)
|
|
173
|
+
err_msg += f'Error message: {msg[:idx]}\n'
|
|
174
|
+
|
|
175
|
+
if terminate:
|
|
176
|
+
raise CHarmError(err_msg)
|
|
177
|
+
else:
|
|
178
|
+
print(err_msg)
|
|
179
|
+
|
|
180
|
+
return
|
|
181
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import numpy as _np
|
|
2
|
+
from ._data_types import _pyharm_flt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _get_empty_array():
|
|
6
|
+
"""
|
|
7
|
+
Private function to return something that PyHarm considers to be an empty
|
|
8
|
+
numpy array.
|
|
9
|
+
|
|
10
|
+
Returns
|
|
11
|
+
-------
|
|
12
|
+
out : numpy floating point array
|
|
13
|
+
Empty numpy ndarray
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
return _np.array([], dtype=_pyharm_flt, order='C')
|
|
17
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from ._constants import _globals
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _get_module_constants(prefix):
|
|
6
|
+
"""
|
|
7
|
+
Private function to dynamically add global constants from the `_globals`
|
|
8
|
+
dictionary inside `_constants.py` to the module's namespace. The variables
|
|
9
|
+
are added under a modified name following the pattern:
|
|
10
|
+
|
|
11
|
+
CHARM_CRD_CELLS_GRID --> CELLS_GRID
|
|
12
|
+
|
|
13
|
+
where `prefix = 'CHARM_CRD_'` is the input variable.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
prefix : str
|
|
18
|
+
Prefix to be removed from the keys in `_globals` before adding to the
|
|
19
|
+
module's namespace. Should be, e.g., 'CHARM_CRD_', 'CHARM_SHA_', etc.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
namespace = sys._getframe(1).f_globals
|
|
23
|
+
|
|
24
|
+
for name, value in _globals.items():
|
|
25
|
+
if name.startswith(prefix):
|
|
26
|
+
namespace[name[len(prefix):]] = value
|
|
27
|
+
|
|
28
|
+
return
|
|
29
|
+
|
pyharm/_lib.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import numpy as _np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _load_lib(libdir, libname):
|
|
6
|
+
"""
|
|
7
|
+
Private function to load a shared library 'libname' from directory
|
|
8
|
+
'libdir'.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
libdir : str
|
|
13
|
+
Path to the shared library
|
|
14
|
+
libname : str
|
|
15
|
+
Name of the shared library
|
|
16
|
+
|
|
17
|
+
Returns
|
|
18
|
+
-------
|
|
19
|
+
out : ctypes.CDLL
|
|
20
|
+
The CHarm shared library
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
return _np.ctypeslib.load_library(libname, libdir)
|
|
25
|
+
except OSError:
|
|
26
|
+
fullpath = os.path.join(libdir, libname)
|
|
27
|
+
msg = f'Failed to load the shared library \'{fullpath}\'.'
|
|
28
|
+
raise OSError(msg)
|
|
29
|
+
|