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,114 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
from scipy.sparse import sparray, csr_array, bsr_array
|
|
4
|
+
from scipy.sparse import spmatrix, csr_matrix, bsr_matrix
|
|
5
|
+
|
|
6
|
+
from feectools.linalg.basic import LinearOperator
|
|
7
|
+
from feectools.linalg.basic import VectorSpace, Vector, LinearOperator
|
|
8
|
+
from feectools.linalg.stencil import StencilVector
|
|
9
|
+
from feectools.linalg.block import BlockVector
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
'SparseMatrixLinearOperator',
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
class SparseMatrixLinearOperator(LinearOperator):
|
|
16
|
+
"""
|
|
17
|
+
LinearOperator representation of a sparse matrix.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
domain : VectorSpace
|
|
22
|
+
The domain of the operator.
|
|
23
|
+
|
|
24
|
+
codomain : VectorSpace
|
|
25
|
+
The codomain of the operator.
|
|
26
|
+
|
|
27
|
+
sparse_matrix : scipy.sparse.sparray | scipy.sparse.spmatrix
|
|
28
|
+
The sparse SciPy matrix representing the operator. Recommended formats are
|
|
29
|
+
CSR and BSR. Any other format will be converted to CSR (csr_array).
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, domain, codomain, sparse_matrix):
|
|
33
|
+
|
|
34
|
+
assert isinstance(domain, VectorSpace)
|
|
35
|
+
assert isinstance(codomain, VectorSpace)
|
|
36
|
+
assert isinstance(sparse_matrix, (sparray, spmatrix))
|
|
37
|
+
|
|
38
|
+
if not isinstance(sparse_matrix,
|
|
39
|
+
(csr_array, csr_matrix,
|
|
40
|
+
bsr_array, bsr_matrix)):
|
|
41
|
+
sparse_matrix = sparse_matrix.tocsr()
|
|
42
|
+
|
|
43
|
+
if domain.parallel:
|
|
44
|
+
raise NotImplementedError('Parallel SparseMatrixLinearOperator not supported yet.')
|
|
45
|
+
|
|
46
|
+
self._domain = domain
|
|
47
|
+
self._codomain = codomain
|
|
48
|
+
self._matrix = sparse_matrix
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def domain(self):
|
|
52
|
+
return self._domain
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def codomain(self):
|
|
56
|
+
return self._codomain
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def dtype(self):
|
|
60
|
+
return self._matrix.dtype
|
|
61
|
+
|
|
62
|
+
def toarray(self):
|
|
63
|
+
return self._matrix.toarray()
|
|
64
|
+
|
|
65
|
+
def tosparse(self):
|
|
66
|
+
return self._matrix
|
|
67
|
+
|
|
68
|
+
def transpose(self, conjugate=False):
|
|
69
|
+
if conjugate:
|
|
70
|
+
return SparseMatrixLinearOperator(self.codomain, self.domain, self._matrix.getH().tocsr())
|
|
71
|
+
else:
|
|
72
|
+
return SparseMatrixLinearOperator(self.codomain, self.domain, self._matrix.T.tocsr())
|
|
73
|
+
|
|
74
|
+
def dot(self, v, out=None):
|
|
75
|
+
assert isinstance(v, Vector)
|
|
76
|
+
assert v.space is self.domain
|
|
77
|
+
|
|
78
|
+
if out is not None:
|
|
79
|
+
assert isinstance(out, Vector)
|
|
80
|
+
assert out.space is self.codomain
|
|
81
|
+
out *= 0
|
|
82
|
+
else:
|
|
83
|
+
out = self.codomain.zeros()
|
|
84
|
+
|
|
85
|
+
self._dot_recursive(v, out=out)
|
|
86
|
+
|
|
87
|
+
return out
|
|
88
|
+
|
|
89
|
+
def _dot_recursive(self, v, out, ind_V=0, ind_W=0):
|
|
90
|
+
V = v.space
|
|
91
|
+
W = out.space
|
|
92
|
+
|
|
93
|
+
if isinstance(v, StencilVector):
|
|
94
|
+
index_global_W = tuple(slice(s, e+1) for s, e in zip(W.starts, W.ends))
|
|
95
|
+
index_global_V = tuple(slice(s, e+1) for s, e in zip(V.starts, V.ends))
|
|
96
|
+
|
|
97
|
+
dim_W = W.dimension
|
|
98
|
+
dim_V = V.dimension
|
|
99
|
+
|
|
100
|
+
out[index_global_W].flat += self._matrix[ind_W:ind_W+dim_W, ind_V:ind_V+dim_V] @ v[index_global_V].flat
|
|
101
|
+
|
|
102
|
+
elif isinstance(v, BlockVector):
|
|
103
|
+
|
|
104
|
+
offset_i = ind_W
|
|
105
|
+
for (i, Wi) in enumerate(W.spaces):
|
|
106
|
+
|
|
107
|
+
offset_j = ind_V
|
|
108
|
+
for (j, Vj) in enumerate(V.spaces):
|
|
109
|
+
|
|
110
|
+
self._dot_recursive(v[j], out[i], ind_V=offset_j, ind_W=offset_i)
|
|
111
|
+
|
|
112
|
+
offset_j += Vj.dimension
|
|
113
|
+
|
|
114
|
+
offset_i += Wi.dimension
|