feectools 0.1.0__py3-none-any.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.
- feectools/__init__.py +0 -0
- feectools/accelerate/__init__.py +0 -0
- feectools/accelerate/accelerate.py +220 -0
- feectools/accelerate/compile_psydac.mk +52 -0
- feectools/api/__init__.py +0 -0
- feectools/api/essential_bc.py +122 -0
- feectools/api/fem_bilinear_form.py +2226 -0
- feectools/api/fem_common.py +286 -0
- feectools/api/fem_sum_form.py +123 -0
- feectools/api/settings.py +82 -0
- feectools/core/__init__.py +11 -0
- feectools/core/bsplines.py +1107 -0
- feectools/core/bsplines_kernels.py +1349 -0
- feectools/core/field_evaluation_kernels.py +5015 -0
- feectools/core/tests/__init__.py +0 -0
- feectools/core/tests/test_bsplines.py +263 -0
- feectools/core/tests/test_bsplines_kernel.py +40 -0
- feectools/core/tests/test_bsplines_pyccel.py +752 -0
- feectools/ddm/__init__.py +3 -0
- feectools/ddm/basic.py +78 -0
- feectools/ddm/blocking_data_exchanger.py +348 -0
- feectools/ddm/cart.py +1835 -0
- feectools/ddm/interface_data_exchanger.py +122 -0
- feectools/ddm/mpi.py +109 -0
- feectools/ddm/nonblocking_data_exchanger.py +331 -0
- feectools/ddm/partition.py +207 -0
- feectools/ddm/petsc.py +112 -0
- feectools/ddm/tests/__init__.py +0 -0
- feectools/ddm/tests/test_cart_1d.py +138 -0
- feectools/ddm/tests/test_cart_2d.py +164 -0
- feectools/ddm/tests/test_cart_3d.py +158 -0
- feectools/ddm/tests/test_multicart_2d.py +173 -0
- feectools/ddm/tests/test_partition.py +124 -0
- feectools/ddm/utilities.py +24 -0
- feectools/feec/__init__.py +0 -0
- feectools/feec/derivatives.py +780 -0
- feectools/feec/dof_kernels.py +210 -0
- feectools/feec/global_geometric_projectors.py +1073 -0
- feectools/feec/hodge.py +148 -0
- feectools/fem/__init__.py +0 -0
- feectools/fem/basic.py +465 -0
- feectools/fem/grid.py +181 -0
- feectools/fem/partitioning.py +344 -0
- feectools/fem/projectors.py +160 -0
- feectools/fem/splines.py +559 -0
- feectools/fem/tensor.py +1393 -0
- feectools/fem/tests/__init__.py +0 -0
- feectools/fem/tests/analytical_profiles_1d.py +100 -0
- feectools/fem/tests/analytical_profiles_base.py +34 -0
- feectools/fem/tests/splines_error_bounds.py +155 -0
- feectools/fem/tests/test_spline_histopolation.py +120 -0
- feectools/fem/tests/test_spline_interpolation.py +182 -0
- feectools/fem/tests/test_splines.py +184 -0
- feectools/fem/tests/test_splines_par.py +46 -0
- feectools/fem/tests/test_vector_spaces.py +150 -0
- feectools/fem/tests/utilities.py +47 -0
- feectools/fem/vector.py +729 -0
- feectools/linalg/__init__.py +0 -0
- feectools/linalg/basic.py +1386 -0
- feectools/linalg/block.py +1451 -0
- feectools/linalg/direct_solvers.py +201 -0
- feectools/linalg/fft.py +258 -0
- feectools/linalg/kernels/__init__.py +0 -0
- feectools/linalg/kernels/axpy_kernels.py +57 -0
- feectools/linalg/kernels/inner_kernels.py +100 -0
- feectools/linalg/kernels/matvec_kernels.py +206 -0
- feectools/linalg/kernels/stencil2IJV_kernels.py +227 -0
- feectools/linalg/kernels/stencil2coo_kernels.py +179 -0
- feectools/linalg/kernels/transpose_kernels.py +263 -0
- feectools/linalg/kron.py +911 -0
- feectools/linalg/solvers.py +1914 -0
- feectools/linalg/sparse.py +114 -0
- feectools/linalg/stencil.py +2923 -0
- feectools/linalg/stencil_dot_kernels.py +317 -0
- feectools/linalg/stencil_transpose_kernels.py +372 -0
- feectools/linalg/tests/__init__.py +0 -0
- feectools/linalg/tests/test_block.py +1588 -0
- feectools/linalg/tests/test_fft.py +106 -0
- feectools/linalg/tests/test_kron_stencil_matrix.py +114 -0
- feectools/linalg/tests/test_linalg.py +1065 -0
- feectools/linalg/tests/test_matrix_free.py +128 -0
- feectools/linalg/tests/test_solvers.py +213 -0
- feectools/linalg/tests/test_stencil_interface_matrix.py +379 -0
- feectools/linalg/tests/test_stencil_vector.py +1036 -0
- feectools/linalg/tests/test_stencil_vector_space.py +440 -0
- feectools/linalg/topetsc.py +522 -0
- feectools/linalg/utilities.py +200 -0
- feectools/utilities/__init__.py +0 -0
- feectools/utilities/quadratures.py +113 -0
- feectools/utilities/utils.py +166 -0
- feectools/version.py +1 -0
- feectools-0.1.0.dist-info/METADATA +66 -0
- feectools-0.1.0.dist-info/RECORD +98 -0
- feectools-0.1.0.dist-info/WHEEL +5 -0
- feectools-0.1.0.dist-info/entry_points.txt +3 -0
- feectools-0.1.0.dist-info/licenses/AUTHORS +22 -0
- feectools-0.1.0.dist-info/licenses/LICENSE +21 -0
- feectools-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from math import sqrt
|
|
5
|
+
|
|
6
|
+
from feectools.linalg.basic import Vector
|
|
7
|
+
from feectools.linalg.stencil import StencilVector, StencilVectorSpace
|
|
8
|
+
from feectools.linalg.block import BlockVector, BlockVectorSpace
|
|
9
|
+
from feectools.linalg.topetsc import petsc_local_to_psydac, get_npts_per_block
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
'array_to_psydac',
|
|
13
|
+
'petsc_to_psydac',
|
|
14
|
+
'_sym_ortho',
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
#==============================================================================
|
|
18
|
+
def array_to_psydac(x, V):
|
|
19
|
+
"""
|
|
20
|
+
Convert a NumPy array to a Vector of the space V. This function is designed to be the inverse of the method .toarray() of the class Vector.
|
|
21
|
+
Note: This function works in parallel but it is very costly and should be avoided if performance is a priority.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
x : numpy.ndarray
|
|
26
|
+
Array to be converted. It only contains the true data, the ghost regions must not be included.
|
|
27
|
+
|
|
28
|
+
V : feectools.linalg.stencil.StencilVectorSpace or feectools.linalg.block.BlockVectorSpace
|
|
29
|
+
Space of the final Psydac Vector.
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
u : feectools.linalg.stencil.StencilVector or feectools.linalg.block.BlockVector
|
|
34
|
+
Element of space V, the coefficients of which (excluding ghost regions) are the entries of x. The ghost regions of u are up to date.
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
assert x.ndim == 1, 'Array must be 1D.'
|
|
39
|
+
if x.dtype==complex:
|
|
40
|
+
assert V.dtype==complex, 'Complex array cannot be converted to a real StencilVector'
|
|
41
|
+
assert x.size == V.dimension, 'Array must have the same global size as the space.'
|
|
42
|
+
|
|
43
|
+
u = V.zeros()
|
|
44
|
+
_array_to_psydac_recursive(x, u)
|
|
45
|
+
u.update_ghost_regions()
|
|
46
|
+
|
|
47
|
+
return u
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _array_to_psydac_recursive(x, u):
|
|
51
|
+
"""
|
|
52
|
+
Recursive function filling in the coefficients of each block of u.
|
|
53
|
+
"""
|
|
54
|
+
assert isinstance(u, Vector)
|
|
55
|
+
V = u.space
|
|
56
|
+
|
|
57
|
+
assert x.ndim == 1, 'Array must be 1D.'
|
|
58
|
+
if x.dtype==complex:
|
|
59
|
+
assert V.dtype==complex, 'Complex array cannot be converted to a real StencilVector'
|
|
60
|
+
assert x.size == V.dimension, 'Array must have the same global size as the space.'
|
|
61
|
+
|
|
62
|
+
if isinstance(V, BlockVectorSpace):
|
|
63
|
+
for i, V_i in enumerate(V.spaces):
|
|
64
|
+
x_i = x[:V_i.dimension]
|
|
65
|
+
x = x[V_i.dimension:]
|
|
66
|
+
u_i = u[i]
|
|
67
|
+
_array_to_psydac_recursive(x_i, u_i)
|
|
68
|
+
|
|
69
|
+
elif isinstance(V, StencilVectorSpace):
|
|
70
|
+
index_global = tuple(slice(s, e+1) for s, e in zip(V.starts, V.ends))
|
|
71
|
+
u[index_global] = x.reshape(V.npts)[index_global]
|
|
72
|
+
|
|
73
|
+
else:
|
|
74
|
+
raise NotImplementedError(f'Can only handle StencilVector or BlockVector spaces, got {type(V)} instead')
|
|
75
|
+
|
|
76
|
+
#==============================================================================
|
|
77
|
+
def petsc_to_psydac(x, Xh, out=None):
|
|
78
|
+
"""
|
|
79
|
+
Convert a PETSc.Vec object to a StencilVector or BlockVector. It assumes that PETSc was installed with the configuration for complex numbers.
|
|
80
|
+
Uses the index conversion functions in feectools.linalg.topetsc.py.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
x : PETSc.Vec
|
|
85
|
+
PETSc vector
|
|
86
|
+
|
|
87
|
+
Xh : feectools.linalg.stencil.StencilVectorSpace | feectools.linalg.block.BlockVectorSpace
|
|
88
|
+
Space of the coefficients of the Psydac vector.
|
|
89
|
+
|
|
90
|
+
out : feectools.linalg.stencil.StencilVector | feectools.linalg.block.BlockVector, optional
|
|
91
|
+
The Psydac vector where to store the result.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
u : feectools.linalg.stencil.StencilVector | feectools.linalg.block.BlockVector
|
|
96
|
+
Psydac vector. In the case of a BlockVector, the blocks must be StencilVector. The general case is not yet implemented.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
if isinstance(Xh, BlockVectorSpace):
|
|
100
|
+
if any([isinstance(Xh.spaces[b], BlockVectorSpace) for b in range(len(Xh.spaces))]):
|
|
101
|
+
raise NotImplementedError('Block of blocks not implemented.')
|
|
102
|
+
|
|
103
|
+
if out is not None:
|
|
104
|
+
assert isinstance(out, BlockVector)
|
|
105
|
+
assert out.space is Xh
|
|
106
|
+
u = out
|
|
107
|
+
else:
|
|
108
|
+
u = BlockVector(Xh)
|
|
109
|
+
|
|
110
|
+
comm = x.comm
|
|
111
|
+
dtype = Xh._dtype
|
|
112
|
+
localsize, globalsize = x.getSizes()
|
|
113
|
+
assert globalsize == u.shape[0], 'Sizes of global vectors do not match'
|
|
114
|
+
|
|
115
|
+
# Find shift for process k:
|
|
116
|
+
# ..get number of points for each block, each process and each dimension:
|
|
117
|
+
npts_local_per_block_per_process = np.array(get_npts_per_block(Xh)) #indexed [b,k,d] for block b and process k and dimension d
|
|
118
|
+
# ..get local sizes for each block and each process:
|
|
119
|
+
local_sizes_per_block_per_process = np.prod(npts_local_per_block_per_process, axis=-1) #indexed [b,k] for block b and process k
|
|
120
|
+
# ..sum the sizes over all the blocks and the previous processes:
|
|
121
|
+
index_shift = 0 + np.sum(local_sizes_per_block_per_process[:,:comm.Get_rank()], dtype=int) #global variable
|
|
122
|
+
|
|
123
|
+
for local_petsc_index in range(localsize):
|
|
124
|
+
block_index, psydac_index = petsc_local_to_psydac(Xh, local_petsc_index)
|
|
125
|
+
# Get value of local PETSc vector passing the global PETSc index
|
|
126
|
+
value = x.getValue(local_petsc_index + index_shift)
|
|
127
|
+
if value != 0:
|
|
128
|
+
u[block_index[0]]._data[psydac_index] = value if dtype is complex else value.real # PETSc always handles dtype specified in the installation configuration
|
|
129
|
+
|
|
130
|
+
elif isinstance(Xh, StencilVectorSpace):
|
|
131
|
+
|
|
132
|
+
if out is not None:
|
|
133
|
+
assert isinstance(out, StencilVector)
|
|
134
|
+
assert out.space is Xh
|
|
135
|
+
u = out
|
|
136
|
+
else:
|
|
137
|
+
u = StencilVector(Xh)
|
|
138
|
+
|
|
139
|
+
comm = x.comm
|
|
140
|
+
dtype = Xh.dtype
|
|
141
|
+
localsize, globalsize = x.getSizes()
|
|
142
|
+
assert globalsize == u.shape[0], 'Sizes of global vectors do not match'
|
|
143
|
+
|
|
144
|
+
# Find shift for process k:
|
|
145
|
+
# ..get number of points for each process and each dimension:
|
|
146
|
+
npts_local_per_block_per_process = np.array(get_npts_per_block(Xh))[0] #indexed [k,d] for process k and dimension d
|
|
147
|
+
# ..get local sizes for each process:
|
|
148
|
+
local_sizes_per_block_per_process = np.prod(npts_local_per_block_per_process, axis=-1) #indexed [k] for process k
|
|
149
|
+
# ..sum the sizes over all the previous processes:
|
|
150
|
+
index_shift = 0 + np.sum(local_sizes_per_block_per_process[:comm.Get_rank()], dtype=int) #global variable
|
|
151
|
+
|
|
152
|
+
for local_petsc_index in range(localsize):
|
|
153
|
+
block_index, psydac_index = petsc_local_to_psydac(Xh, local_petsc_index)
|
|
154
|
+
# Get value of local PETSc vector passing the global PETSc index
|
|
155
|
+
value = x.getValue(local_petsc_index + index_shift)
|
|
156
|
+
if value != 0:
|
|
157
|
+
u._data[psydac_index] = value if dtype is complex else value.real # PETSc always handles dtype specified in the installation configuration
|
|
158
|
+
|
|
159
|
+
else:
|
|
160
|
+
raise ValueError('Xh must be a StencilVectorSpace or a BlockVectorSpace')
|
|
161
|
+
|
|
162
|
+
u.update_ghost_regions()
|
|
163
|
+
|
|
164
|
+
return u
|
|
165
|
+
|
|
166
|
+
#==============================================================================
|
|
167
|
+
def _sym_ortho(a, b):
|
|
168
|
+
"""
|
|
169
|
+
Stable implementation of Givens rotation.
|
|
170
|
+
This function was taken from the scipy repository
|
|
171
|
+
https://github.com/scipy/scipy/blob/master/scipy/sparse/linalg/isolve/lsqr.py
|
|
172
|
+
|
|
173
|
+
Notes
|
|
174
|
+
-----
|
|
175
|
+
The routine 'SymOrtho' was added for numerical stability. This is
|
|
176
|
+
recommended by S.-C. Choi in [1]_. It removes the unpleasant potential of
|
|
177
|
+
``1/eps`` in some important places (see, for example text following
|
|
178
|
+
"Compute the next plane rotation Qk" in minres.py).
|
|
179
|
+
|
|
180
|
+
References
|
|
181
|
+
----------
|
|
182
|
+
.. [1] S.-C. Choi, "Iterative Methods for Singular Linear Equations
|
|
183
|
+
and Least-Squares Problems", Dissertation,
|
|
184
|
+
http://www.stanford.edu/group/SOL/dissertations/sou-cheng-choi-thesis.pdf
|
|
185
|
+
"""
|
|
186
|
+
if b == 0:
|
|
187
|
+
return np.sign(a), 0, abs(a)
|
|
188
|
+
elif a == 0:
|
|
189
|
+
return 0, np.sign(b), abs(b)
|
|
190
|
+
elif abs(b) > abs(a):
|
|
191
|
+
tau = a / b
|
|
192
|
+
s = np.sign(b) / sqrt(1 + tau * tau)
|
|
193
|
+
c = s * tau
|
|
194
|
+
r = b / s
|
|
195
|
+
else:
|
|
196
|
+
tau = b / a
|
|
197
|
+
c = np.sign(a) / sqrt(1+tau*tau)
|
|
198
|
+
s = c * tau
|
|
199
|
+
r = a / c
|
|
200
|
+
return c, s, r
|
|
File without changes
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
#! /usr/bin/python
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
This module contains some routines to generate quadrature points in 1D
|
|
6
|
+
it has also a routine uniform, which generates uniform points
|
|
7
|
+
with weights equal to 1
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from math import cos, pi
|
|
13
|
+
from numpy import zeros
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ('gauss_legendre', 'gauss_lobatto', 'quadrature')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def gauss_legendre(m, tol=1e-13):
|
|
20
|
+
"""
|
|
21
|
+
Compute Gauss-Legendre quadrature points and weights on [-1, 1].
|
|
22
|
+
|
|
23
|
+
Returns nodal abscissas {x} and weights {A} of a Gauss-Legendre m-point
|
|
24
|
+
quadrature over the canonical interval [-1, 1].
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
m : int
|
|
29
|
+
Number of quadrature points in the quadrature rule.
|
|
30
|
+
|
|
31
|
+
tol : float
|
|
32
|
+
Tolerance for the Newton-Raphson root-searching method.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
x : numpy.ndarray[float]
|
|
37
|
+
Abscissas of the quadrature points, in ascending order.
|
|
38
|
+
|
|
39
|
+
A : numpy.ndarray[float]
|
|
40
|
+
Weights of the quadrature points corresponding to the abscissas above.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
assert isinstance(m, int)
|
|
44
|
+
assert isinstance(tol, float)
|
|
45
|
+
assert m >= 1
|
|
46
|
+
assert tol >= 0
|
|
47
|
+
|
|
48
|
+
def legendre(t, m):
|
|
49
|
+
p0 = 1.0
|
|
50
|
+
p1 = t
|
|
51
|
+
for k in range(1, m):
|
|
52
|
+
p = ((2.0*k + 1.0)*t*p1 - k*p0)/(1.0 + k)
|
|
53
|
+
p0 = p1
|
|
54
|
+
p1 = p
|
|
55
|
+
dp = m*(p0 - t*p1)/(1.0 - t**2)
|
|
56
|
+
return p1, dp
|
|
57
|
+
|
|
58
|
+
A = zeros(m)
|
|
59
|
+
x = zeros(m)
|
|
60
|
+
nRoots = (m + 1) // 2 # Number of non-neg. roots
|
|
61
|
+
for i in range(nRoots):
|
|
62
|
+
t = cos(pi*(i + 0.75)/(m + 0.5)) # Approx. root
|
|
63
|
+
for j in range(30):
|
|
64
|
+
p, dp = legendre(t, m) # Newton-Raphson
|
|
65
|
+
dt = -p/dp # method
|
|
66
|
+
t = t + dt
|
|
67
|
+
if abs(dt) < tol:
|
|
68
|
+
x[i] = -t
|
|
69
|
+
x[m-i-1] = t
|
|
70
|
+
A[i] = 2.0/(1.0 - t**2)/(dp**2) # Eq.(6.25)
|
|
71
|
+
A[m-i-1] = A[i]
|
|
72
|
+
break
|
|
73
|
+
return x, A
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def gauss_lobatto(k):
|
|
77
|
+
"""
|
|
78
|
+
Returns nodal abscissas {x} and weights {A} of
|
|
79
|
+
Gauss-Legendre m-point quadrature.
|
|
80
|
+
"""
|
|
81
|
+
beta = .5 / np.sqrt(1-(2 * np.arange(1., k + 1)) ** (-2)) #3-term recurrence coeffs
|
|
82
|
+
beta[-1] = np.sqrt((k / (2 * k-1.)))
|
|
83
|
+
T = np.diag(beta, 1) + np.diag(beta, -1) # jacobi matrix
|
|
84
|
+
D, V = np.linalg.eig(T) # eigenvalue decomposition
|
|
85
|
+
xg = np.real(D); i = xg.argsort(); xg.sort() # nodes (= Legendres points)
|
|
86
|
+
w = 2 * (V[0, :]) ** 2; # weights
|
|
87
|
+
|
|
88
|
+
return xg, w[i]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def quadrature(a, k, method="legendre"):
|
|
92
|
+
"""
|
|
93
|
+
this routine generates a quad pts on the grid linspace(a,b,N)
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
if method == "legendre":
|
|
97
|
+
x, w = gauss_legendre(k)
|
|
98
|
+
elif method == "lobatto":
|
|
99
|
+
x, w = gauss_lobatto(k)
|
|
100
|
+
else:
|
|
101
|
+
raise NotImplemented("> Only Gauss-Legendre is implemented.")
|
|
102
|
+
|
|
103
|
+
grid = a
|
|
104
|
+
N = len(a)
|
|
105
|
+
xgl = np.zeros((N-1, k + 1))
|
|
106
|
+
wgl = np.zeros((N-1, k + 1))
|
|
107
|
+
for i in range (0, N-1):
|
|
108
|
+
xmin = grid[i];xmax = grid[i + 1];dx = 0.5 * (xmax-xmin)
|
|
109
|
+
tab = dx * x + dx + xmin
|
|
110
|
+
xgl[i, :] = tab[::-1]
|
|
111
|
+
wgl[i, :] = 0.5 * ( xmax - xmin ) * w
|
|
112
|
+
|
|
113
|
+
return xgl,wgl
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2018 Yaman Güçlü
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from numbers import Number
|
|
7
|
+
|
|
8
|
+
__all__ = (
|
|
9
|
+
'refine_array_1d',
|
|
10
|
+
'unroll_edges',
|
|
11
|
+
'split_space',
|
|
12
|
+
'split_field',
|
|
13
|
+
'animate_field'
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
#==============================================================================
|
|
17
|
+
def is_real(x):
|
|
18
|
+
"""Determine whether the given input represents a real number.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
x : Any
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
bool
|
|
27
|
+
True if x is real, False otherwise.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
return isinstance(x, Number) and np.isrealobj(x) and not isinstance(x, bool)
|
|
31
|
+
|
|
32
|
+
#===============================================================================
|
|
33
|
+
def refine_array_1d(x, n, remove_duplicates=True):
|
|
34
|
+
"""
|
|
35
|
+
Refines a 1D array by subdividing each interval (x[i], x[i+1]) into n identical parts.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
x : ndarray
|
|
40
|
+
1D array to be refined.
|
|
41
|
+
|
|
42
|
+
n : int
|
|
43
|
+
Number of subdivisions to be created in each interval (x[i], x[i+1]).
|
|
44
|
+
|
|
45
|
+
remove_duplicates : bool, default=True
|
|
46
|
+
If True, the refined array will not contain any duplicate points.
|
|
47
|
+
If False, the original internal grid points x[1:-1] will appear twice: this may
|
|
48
|
+
be useful to visualize fields that are discontinuous across cell boundaries.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
ndarray
|
|
53
|
+
Refined 1D array. The length of this array is `n * (len(x) - 1) + 1`
|
|
54
|
+
if remove_duplicates and `(n + 1) * (len(x) - 1)` if not.
|
|
55
|
+
"""
|
|
56
|
+
xr = []
|
|
57
|
+
if not remove_duplicates:
|
|
58
|
+
n += 1
|
|
59
|
+
for (a, b) in zip(x[:-1], x[1:]):
|
|
60
|
+
xr.extend(np.linspace(a, b, n, endpoint=not remove_duplicates))
|
|
61
|
+
if remove_duplicates:
|
|
62
|
+
xr.append(x[-1])
|
|
63
|
+
return np.array(xr)
|
|
64
|
+
|
|
65
|
+
#===============================================================================
|
|
66
|
+
def unroll_edges(domain, xgrid):
|
|
67
|
+
"""If necessary, "unroll" intervals that cross boundary of periodic domain.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
xA, xB = domain
|
|
71
|
+
|
|
72
|
+
assert all(np.diff(xgrid) >= 0)
|
|
73
|
+
assert xA < xB
|
|
74
|
+
assert xA <= xgrid[0]
|
|
75
|
+
assert xgrid[-1] <= xB
|
|
76
|
+
|
|
77
|
+
if xgrid[0] == xA and xgrid[-1] == xB:
|
|
78
|
+
return xgrid
|
|
79
|
+
|
|
80
|
+
elif xgrid[0] != xA:
|
|
81
|
+
return np.array([xgrid[-1] - (xB-xA), *xgrid])
|
|
82
|
+
|
|
83
|
+
elif xgrid[-1] != xB:
|
|
84
|
+
return np.array([*xgrid, xgrid[0] + (xB-xA)])
|
|
85
|
+
|
|
86
|
+
#===============================================================================
|
|
87
|
+
def roll_edges(domain, points):
|
|
88
|
+
"""If necessary, "roll" back intervals that cross boundary of periodic domain.
|
|
89
|
+
Changes are made in place to avoid duplicating the array
|
|
90
|
+
"""
|
|
91
|
+
xA, xB = domain
|
|
92
|
+
assert xA < xB
|
|
93
|
+
points -=xA
|
|
94
|
+
points %=(xB-xA)
|
|
95
|
+
points +=xA
|
|
96
|
+
|
|
97
|
+
#===============================================================================
|
|
98
|
+
def split_field(uh, spaces, out=None):
|
|
99
|
+
"""Split a field into a list of fields that corresponds to the spaces.
|
|
100
|
+
The split field function will allocate new memory if out is not passed.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
uh : FemField
|
|
105
|
+
The fem field.
|
|
106
|
+
|
|
107
|
+
spaces: <list, FemSpace>
|
|
108
|
+
List of spaces that split the field.
|
|
109
|
+
|
|
110
|
+
out: optional, <list, FemField>
|
|
111
|
+
List of fields to write the results to.
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
out : <list, FemField>
|
|
116
|
+
List of fem fields.
|
|
117
|
+
"""
|
|
118
|
+
from feectools.fem.basic import FemField
|
|
119
|
+
if out is None:
|
|
120
|
+
out = [FemField(S) for S in spaces]
|
|
121
|
+
|
|
122
|
+
flattened_fields = [f.fields if f.fields else [f] for f in out]
|
|
123
|
+
flattened_fields = [f for l in flattened_fields for f in l]
|
|
124
|
+
for f1,f2 in zip(flattened_fields, uh.fields):
|
|
125
|
+
assert f1.space is f2.space
|
|
126
|
+
f1.coeffs[:] = f2.coeffs[:]
|
|
127
|
+
|
|
128
|
+
return out
|
|
129
|
+
|
|
130
|
+
#===============================================================================
|
|
131
|
+
def animate_field(fields, domain, mapping, res=(150,150), vrange=None, cmap=None, interval=35, progress=False, figsize=(14,4)):
|
|
132
|
+
"""Animate a sequence of scalar fields over a geometry."""
|
|
133
|
+
from matplotlib import animation
|
|
134
|
+
import matplotlib.pyplot as plt
|
|
135
|
+
import tqdm
|
|
136
|
+
|
|
137
|
+
fields = list(fields)
|
|
138
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
139
|
+
ax.set_aspect('equal')
|
|
140
|
+
|
|
141
|
+
etas = [refine_array_1d( bounds, r ) for r,bounds in zip(res, zip(domain.min_coords, domain.max_coords))]
|
|
142
|
+
pcoords = np.array( [[mapping( e1,e2 ) for e2 in etas[1]] for e1 in etas[0]] )
|
|
143
|
+
xx = pcoords[:,:,0]
|
|
144
|
+
yy = pcoords[:,:,1]
|
|
145
|
+
|
|
146
|
+
# determine range of values from first field
|
|
147
|
+
num1 = np.array( [[fields[0].fields[0]( e1,e2 ) for e2 in etas[1]] for e1 in etas[0]] )
|
|
148
|
+
num2 = np.array( [[fields[0].fields[1]( e1,e2 ) for e2 in etas[1]] for e1 in etas[0]] )
|
|
149
|
+
num = np.hypot(num1, num2)
|
|
150
|
+
vrange = (num.min(), num.max())
|
|
151
|
+
|
|
152
|
+
quadmesh = plt.pcolormesh(xx, yy, num, shading='gouraud', cmap=cmap,
|
|
153
|
+
vmin=vrange[0], vmax=vrange[1], axes=ax)
|
|
154
|
+
fig.colorbar(quadmesh, ax=ax)
|
|
155
|
+
|
|
156
|
+
pbar = tqdm.tqdm(total=len(fields))
|
|
157
|
+
def anim_func(i):
|
|
158
|
+
num1 = np.array( [[fields[i].fields[0]( e1,e2 ) for e2 in etas[1]] for e1 in etas[0]] )
|
|
159
|
+
num2 = np.array( [[fields[i].fields[1]( e1,e2 ) for e2 in etas[1]] for e1 in etas[0]] )
|
|
160
|
+
C = np.hypot(num1, num2)
|
|
161
|
+
quadmesh.set_array(C)
|
|
162
|
+
pbar.update()
|
|
163
|
+
if i == len(fields) - 1:
|
|
164
|
+
pbar.close()
|
|
165
|
+
|
|
166
|
+
return animation.FuncAnimation(fig, anim_func, frames=len(fields), interval=interval)
|
feectools/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feectools
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies.
|
|
5
|
+
Author-email: Psydac development team <psydac@googlegroups.com>
|
|
6
|
+
Maintainer-email: Stefan Possanner <stefan.possanner@ipp.mpg.de>, Max Lindqvist <max.lindqvist@ipp.mpg.de>, Yaman Güçlü <yaman.guclu@gmail.com>, Martin Campos Pinto <martin.campos-pinto@ipp.mpg.de>, Ahmed Ratnani <ratnaniahmed@gmail.com>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2018-2023, Psydac Developers.
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://github.com/struphy-hub/psydac-for-struphy
|
|
30
|
+
Project-URL: Documentation, https://github.com/struphy-hub/psydac-for-struphy
|
|
31
|
+
Project-URL: Repository, https://github.com/struphy-hub/psydac-for-struphy
|
|
32
|
+
Keywords: FEM,IGA,B-spline,NURBS
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Requires-Python: >=3.10
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
License-File: AUTHORS
|
|
38
|
+
Requires-Dist: numpy>=1.16
|
|
39
|
+
Requires-Dist: scipy>=1.12
|
|
40
|
+
Requires-Dist: sympy>=1.5
|
|
41
|
+
Requires-Dist: matplotlib
|
|
42
|
+
Requires-Dist: pyyaml>=5.1
|
|
43
|
+
Requires-Dist: packaging
|
|
44
|
+
Requires-Dist: pyevtk
|
|
45
|
+
Requires-Dist: pyccel>=2.0.1
|
|
46
|
+
Requires-Dist: h5py
|
|
47
|
+
Requires-Dist: tblib
|
|
48
|
+
Provides-Extra: test
|
|
49
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "test"
|
|
50
|
+
Requires-Dist: pytest>=4.5; extra == "test"
|
|
51
|
+
Requires-Dist: pytest-xdist>=1.16; extra == "test"
|
|
52
|
+
Requires-Dist: pytest-testmon; extra == "test"
|
|
53
|
+
Requires-Dist: Pillow; extra == "test"
|
|
54
|
+
Provides-Extra: mpi
|
|
55
|
+
Requires-Dist: mpi4py>=4; extra == "mpi"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
# Welcome!
|
|
59
|
+
|
|
60
|
+
This is a fork of [Psydac](https://github.com/pyccel/psydac) that provides Finite Element Exterior Calculus (FEEC) for [Struphy](https://github.com/struphy-hub/struphy). It is a stripped-down version of the original repo with less functionality and fewer dependencies.
|
|
61
|
+
|
|
62
|
+
The latest version can be installed with
|
|
63
|
+
```
|
|
64
|
+
pip install -U feectools
|
|
65
|
+
```
|
|
66
|
+
See the [Struphy documentation](https://struphy-hub.github.io/struphy/index.html) for details on how to use.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
feectools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
feectools/version.py,sha256=Lgf9keBX7aG_JEFt6UYSyiFKcm-BYGtmk9ohpQhYpyk,20
|
|
3
|
+
feectools/accelerate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
feectools/accelerate/accelerate.py,sha256=pdkCJoiz7IfBbrNh78INKIGPm5kmauGEy7risiW3GRA,6731
|
|
5
|
+
feectools/accelerate/compile_psydac.mk,sha256=NE-NQPoYoZNKDd_eMgx_fVuh0AGbMNLU7NIx99RG8qs,1505
|
|
6
|
+
feectools/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
feectools/api/essential_bc.py,sha256=MDdUUFHRwe3Y_pBTX3YKvcxVK1JNWU3EnSTYMvBIprY,4340
|
|
8
|
+
feectools/api/fem_bilinear_form.py,sha256=nhYCipAQZn6OoZuGXBi7v3xi-af_0k71G25ohoziqkA,116758
|
|
9
|
+
feectools/api/fem_common.py,sha256=sIa6_66O95Gcuv41JMGp_K9pt7q_CxVzqlxIl-AjhjQ,10511
|
|
10
|
+
feectools/api/fem_sum_form.py,sha256=y3BXSsJad4jX45y-G4jXuJ4kN4GAivV3nnOjoZ5V3Wk,4801
|
|
11
|
+
feectools/api/settings.py,sha256=0oV7jm3MC6Cy2WR5AwC75VNSRIHyCKOCvJyyZZ1ZnaM,3442
|
|
12
|
+
feectools/core/__init__.py,sha256=uqpuv7LH4TVhngaglUs4EVQ7ZaF74Utt7p0Yih8r3XI,219
|
|
13
|
+
feectools/core/bsplines.py,sha256=3cg54HuHmWVI3eJClk8aGZLB9ZBPquovkxs_LW_F3_4,35848
|
|
14
|
+
feectools/core/bsplines_kernels.py,sha256=sygGjBf4ZdjQLaO7r6pF50G_rq11fAbNXToD76fMRpg,41880
|
|
15
|
+
feectools/core/field_evaluation_kernels.py,sha256=hGs40CHrtjEl12yPXjUf9CX38VhtgGyNtN7LxnueejE,213406
|
|
16
|
+
feectools/core/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
feectools/core/tests/test_bsplines.py,sha256=prD8-uGuValM5dsKTPb_Wuu-w7RmgyiugN20AMqa5-I,9375
|
|
18
|
+
feectools/core/tests/test_bsplines_kernel.py,sha256=gvoKizXtv-KV2q_8RX8sXWylltlKcx_PDlJwzXJ9WgE,1539
|
|
19
|
+
feectools/core/tests/test_bsplines_pyccel.py,sha256=0PJkjzIKpm8aoZm0tuUAjcZTw66NK7JeMiAsWsEuqa0,33880
|
|
20
|
+
feectools/ddm/__init__.py,sha256=g8T4cCNL0Stchi3l8QtQ5FnujdvgtfxXf1QhxatM_M4,51
|
|
21
|
+
feectools/ddm/basic.py,sha256=73xhS9QPH6ks44ptGJ3lHrLQdWgzxMsSGH6bSFQC0Rw,2511
|
|
22
|
+
feectools/ddm/blocking_data_exchanger.py,sha256=9gLIWM235QDcwwmqN4xPTtInldlP6I4Vu6kqZ-NLyeQ,13340
|
|
23
|
+
feectools/ddm/cart.py,sha256=rZncdhodsknDL6Cau3p0OxobFCXqWbh8S0F7z7aSDp8,74291
|
|
24
|
+
feectools/ddm/interface_data_exchanger.py,sha256=z-PQbao80S5BvEvku8vzZ464d9OBj7QCXsnvc0HJHjE,4801
|
|
25
|
+
feectools/ddm/mpi.py,sha256=twmesoFC2FbdFM41ykAgyhk0xHufMwsHjuJ6iw49sSs,2236
|
|
26
|
+
feectools/ddm/nonblocking_data_exchanger.py,sha256=RaLgxjscpa6-BSa2BbkRcUQInekzz4mVvQEJHpyKnKY,12939
|
|
27
|
+
feectools/ddm/partition.py,sha256=uEa0t4HQs6QT9e6bqqIVyytsd_pq5_bzhUrhXx7FU-g,6594
|
|
28
|
+
feectools/ddm/petsc.py,sha256=L30vNB5hfagIfR1MOTL4-ZkhdeayedJ1Wa8n5HrGsTE,3353
|
|
29
|
+
feectools/ddm/utilities.py,sha256=_vDaAQDCamDfiKHZz_CkIhhqkxEOyBJ8JpVCZa9PjeU,1044
|
|
30
|
+
feectools/ddm/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
feectools/ddm/tests/test_cart_1d.py,sha256=dBsiXaYpBr5J-eOvFJXIG6Jb3JPUWg9YUOClQMmEYBs,4694
|
|
32
|
+
feectools/ddm/tests/test_cart_2d.py,sha256=0BRrxCELxMmXKPrYhUyusrRBpF6TVzTVAVF6PpRrpFc,5545
|
|
33
|
+
feectools/ddm/tests/test_cart_3d.py,sha256=RP1rUmEoQ8wMWDA7nNAwV9q_v8efrVrd7L8DW4Pwckw,5601
|
|
34
|
+
feectools/ddm/tests/test_multicart_2d.py,sha256=iwjguH7q7BZi_eXFH4kZ_G7g-VfAoKF8QavIG-sQXn0,7581
|
|
35
|
+
feectools/ddm/tests/test_partition.py,sha256=vMEiko7Yhzkm21ZEBdGQNSlI9QevSpWzm2wQdDYYBuE,4015
|
|
36
|
+
feectools/feec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
feectools/feec/derivatives.py,sha256=8zcxxVwyXewwNFXuVKfJVQFD89oj9g4ab0aJ0zs_gOM,29204
|
|
38
|
+
feectools/feec/dof_kernels.py,sha256=ZyFG6x-coGq5iBnld82LAKPqH2HuCJUIzxi1EZzGTzA,8012
|
|
39
|
+
feectools/feec/global_geometric_projectors.py,sha256=zm2PGdGYa8V5HNn3ButsYtpRRUXkCtwi4A6DUoIIKZo,44259
|
|
40
|
+
feectools/feec/hodge.py,sha256=09bQ8ZtiGo6vQNp4W3oDdTKmw7HAOaON2tJNdMBpOa4,4693
|
|
41
|
+
feectools/fem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
+
feectools/fem/basic.py,sha256=n1SArxFiS1od9i6GXvhDMozR5obJQO9APbXhYO9-Kqs,14020
|
|
43
|
+
feectools/fem/grid.py,sha256=YmH8GElXxSU4G3O64tJZYAWKQ3aldK6vcmrbz_ngmFY,5428
|
|
44
|
+
feectools/fem/partitioning.py,sha256=eA4XFEVU3m6GsVI0pBK8coaIwmh9eD_MpKq7fgum1sA,16363
|
|
45
|
+
feectools/fem/projectors.py,sha256=DJ5bklXBdgzjBSXY5LFOtAab2YDQdbj3ovPjvfFyujA,5489
|
|
46
|
+
feectools/fem/splines.py,sha256=-C4u3ZrdJttnNqi49COQPChbmUKjwhKu0FJt-9Sy1Pc,17847
|
|
47
|
+
feectools/fem/tensor.py,sha256=vKLOFd1naEpTo2589ERC0ZvZ8mg13K_fcTCZ6A9ng1U,53123
|
|
48
|
+
feectools/fem/vector.py,sha256=z3SfLu2cnb33m4y889AJCaZHBhWariw8yvvpvwWu5OY,28396
|
|
49
|
+
feectools/fem/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
+
feectools/fem/tests/analytical_profiles_1d.py,sha256=6SqOasGUnjqKF0E4NqW6jBxVo1ZRqva5kSQkY_atcjA,2582
|
|
51
|
+
feectools/fem/tests/analytical_profiles_base.py,sha256=Dg6az-vRu7YGVLpcRM6dMckYQanqTrcvTUsh4cLY1Ls,868
|
|
52
|
+
feectools/fem/tests/splines_error_bounds.py,sha256=linE5oiSWTJMO5wHRORQrSyVBfRIX2Dw3Q1yQ-Hnevo,4862
|
|
53
|
+
feectools/fem/tests/test_spline_histopolation.py,sha256=9Q9iTiuafFmEPCSUKXjuEOLqLYPYdv9CXDYJUvNi-Dw,4105
|
|
54
|
+
feectools/fem/tests/test_spline_interpolation.py,sha256=RWeEZLjTSPwiJjF1KRjJbBTWJ605zqvBhwWMpqbr6xc,6585
|
|
55
|
+
feectools/fem/tests/test_splines.py,sha256=0nM2kxerz0E8RBKb6uKgX9zo4CfR_InVhvPTRbNvjXg,4506
|
|
56
|
+
feectools/fem/tests/test_splines_par.py,sha256=UYCylVICCGzB08ahBeTzb8gKJX1ZicUTYi-IFTkTjME,1299
|
|
57
|
+
feectools/fem/tests/test_vector_spaces.py,sha256=3aL7pz2N8NEk3Ke4JSh8LRZ468wiWcTmJqCa9ZDeWXc,4646
|
|
58
|
+
feectools/fem/tests/utilities.py,sha256=FfCGEouNSdKaUVP03YlZ3so3BvHo4DAQ4NGx15taVWA,1352
|
|
59
|
+
feectools/linalg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
+
feectools/linalg/basic.py,sha256=NwVolrYCpQKMOWt1l_4hBce1tTBDZEt2J-04lWy33cI,43677
|
|
61
|
+
feectools/linalg/block.py,sha256=Cgo82Tn9GFR4T4iSkPkM8vTUS-PjnPwyQmwWO8Q7qpk,53997
|
|
62
|
+
feectools/linalg/direct_solvers.py,sha256=yvNS__UJwhfWsaX4dFGDbvK5cyZD9VMzce68ZboG6K4,6139
|
|
63
|
+
feectools/linalg/fft.py,sha256=TNECOIDuZpjjRN2fX-WDbRfbPd6EgIi_SbOGcdgKV68,10348
|
|
64
|
+
feectools/linalg/kron.py,sha256=zWoeoToryg2dJq1KTV9fdEmZ8U0pJrI95ibZ7dkY3C4,31348
|
|
65
|
+
feectools/linalg/solvers.py,sha256=VqaVJadv_ALKIWwZQmFXAjF4D0ZlY_e4yu1Yo0J_sLM,62724
|
|
66
|
+
feectools/linalg/sparse.py,sha256=sFdPYBjdHIe9-eGTr4GK8fPrcr-UAKd3tkk_Npqu2D0,3405
|
|
67
|
+
feectools/linalg/stencil.py,sha256=KSAGVNo6Q2V5euEDBE_DRdhUhAOF8-UKwO1LIRLLUtQ,100798
|
|
68
|
+
feectools/linalg/stencil_dot_kernels.py,sha256=Ti5GxyUUSgW43l3cxamJlTuIXUah-yV94TIV2ugrzrk,11882
|
|
69
|
+
feectools/linalg/stencil_transpose_kernels.py,sha256=fvEw6dS-Lux9b3G-m83UGeXyS9xELpg0ErSy-NsSb_A,19270
|
|
70
|
+
feectools/linalg/topetsc.py,sha256=3csnt1tG1_5CLk6XzhcZmewjoVQ40wz_UzxcWusDZXg,21159
|
|
71
|
+
feectools/linalg/utilities.py,sha256=8CujOsy4-d0rWKiF8ARSIfeyK4QPSmuf3mnV3YxWCUY,8110
|
|
72
|
+
feectools/linalg/kernels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
+
feectools/linalg/kernels/axpy_kernels.py,sha256=r42Ub2DDOLj-0D_wNnsm82w5xRO1mw5AdECDzMpMqXg,1587
|
|
74
|
+
feectools/linalg/kernels/inner_kernels.py,sha256=QRIFtEFnlnAQ1nDmqVAOotfqzgFgHlqyvsc_KLbs0lo,2997
|
|
75
|
+
feectools/linalg/kernels/matvec_kernels.py,sha256=ZO5AgDjdIQv1k71oYY072lRiSFefj3ZygZZbTN7fA_0,8352
|
|
76
|
+
feectools/linalg/kernels/stencil2IJV_kernels.py,sha256=OAZc4X6MtJNJwrbwwrQcC2Co5Q3-jf7ixvsaT9Vigjw,8696
|
|
77
|
+
feectools/linalg/kernels/stencil2coo_kernels.py,sha256=2WO8Hyj81-0BGSBFCEDfGw7oASCvkDfm5f8buQWyVow,7317
|
|
78
|
+
feectools/linalg/kernels/transpose_kernels.py,sha256=R1mcqUA4fwH-s3MZD82KJGA9RyDzHOmFY0xRAxTUNPk,9875
|
|
79
|
+
feectools/linalg/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
+
feectools/linalg/tests/test_block.py,sha256=iq8BVojGCE13iCF2rZOsphkecWQdNKCCrJX9TtBhnvc,53004
|
|
81
|
+
feectools/linalg/tests/test_fft.py,sha256=pKATZEQyvd3DInJKB8C_Whq1xz1SxHfSxJefPFoZlCU,3868
|
|
82
|
+
feectools/linalg/tests/test_kron_stencil_matrix.py,sha256=U7PQR25a__nKZDC9dmvQVriPVpabrVkA0r170A7BszU,3757
|
|
83
|
+
feectools/linalg/tests/test_linalg.py,sha256=R88gKiFP2Ft8GQ1MCy3NtRiu1DQMpD746UX1ZrcMux8,35604
|
|
84
|
+
feectools/linalg/tests/test_matrix_free.py,sha256=Cyxyhn5135pcxW88ytV26numIW8jG7sm6O08fOfKa7o,4258
|
|
85
|
+
feectools/linalg/tests/test_solvers.py,sha256=uXPBugyGFQjyFlCdiPE5B2buVythdND9h1TYppnjzhA,7171
|
|
86
|
+
feectools/linalg/tests/test_stencil_interface_matrix.py,sha256=_Y_aIxR0uYLlzjga3at-vMNMEv8r3kMVnRgGKNja7_c,15197
|
|
87
|
+
feectools/linalg/tests/test_stencil_vector.py,sha256=77SUOGt-Wzx8yW413XNTxUVxsucBzWdMb9iPAb8Q0J0,36006
|
|
88
|
+
feectools/linalg/tests/test_stencil_vector_space.py,sha256=xPn0prKDFM5OuIXk01kcBYQSoo79gLEsq4sG2cXlFCo,16412
|
|
89
|
+
feectools/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
90
|
+
feectools/utilities/quadratures.py,sha256=hm0k97MXHQBRrX3NtqX0p1tFQgvmaGeHLIcneirsmps,3074
|
|
91
|
+
feectools/utilities/utils.py,sha256=vpuTk_mVtrqivIARxikj_9jLPz7VQCvQ9gy_k_Vh83I,5311
|
|
92
|
+
feectools-0.1.0.dist-info/licenses/AUTHORS,sha256=5g5Pg9AjaumZrgaAXG3WdjKtxHaRuYTYaRPgv6fnUvA,516
|
|
93
|
+
feectools-0.1.0.dist-info/licenses/LICENSE,sha256=E1UeOpPwmCqE57lN0WS24M0lYLNP3vi6dz41JlIZgBw,1081
|
|
94
|
+
feectools-0.1.0.dist-info/METADATA,sha256=XjrUwIraAGGJprc3TyTHW0Zt9ykfcRlsg3FB0sadxVk,3203
|
|
95
|
+
feectools-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
96
|
+
feectools-0.1.0.dist-info/entry_points.txt,sha256=OZEKfHA9qqruoFgVNXAeP_Oe-z4s26leAxUVuMBpv9A,113
|
|
97
|
+
feectools-0.1.0.dist-info/top_level.txt,sha256=tS-3BbPTNpe3Nn0E5O6jOXPKqAyGw_v_AbGUaDM0pUs,10
|
|
98
|
+
feectools-0.1.0.dist-info/RECORD,,
|