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.
Files changed (98) hide show
  1. feectools/__init__.py +0 -0
  2. feectools/accelerate/__init__.py +0 -0
  3. feectools/accelerate/accelerate.py +220 -0
  4. feectools/accelerate/compile_psydac.mk +52 -0
  5. feectools/api/__init__.py +0 -0
  6. feectools/api/essential_bc.py +122 -0
  7. feectools/api/fem_bilinear_form.py +2226 -0
  8. feectools/api/fem_common.py +286 -0
  9. feectools/api/fem_sum_form.py +123 -0
  10. feectools/api/settings.py +82 -0
  11. feectools/core/__init__.py +11 -0
  12. feectools/core/bsplines.py +1107 -0
  13. feectools/core/bsplines_kernels.py +1349 -0
  14. feectools/core/field_evaluation_kernels.py +5015 -0
  15. feectools/core/tests/__init__.py +0 -0
  16. feectools/core/tests/test_bsplines.py +263 -0
  17. feectools/core/tests/test_bsplines_kernel.py +40 -0
  18. feectools/core/tests/test_bsplines_pyccel.py +752 -0
  19. feectools/ddm/__init__.py +3 -0
  20. feectools/ddm/basic.py +78 -0
  21. feectools/ddm/blocking_data_exchanger.py +348 -0
  22. feectools/ddm/cart.py +1835 -0
  23. feectools/ddm/interface_data_exchanger.py +122 -0
  24. feectools/ddm/mpi.py +109 -0
  25. feectools/ddm/nonblocking_data_exchanger.py +331 -0
  26. feectools/ddm/partition.py +207 -0
  27. feectools/ddm/petsc.py +112 -0
  28. feectools/ddm/tests/__init__.py +0 -0
  29. feectools/ddm/tests/test_cart_1d.py +138 -0
  30. feectools/ddm/tests/test_cart_2d.py +164 -0
  31. feectools/ddm/tests/test_cart_3d.py +158 -0
  32. feectools/ddm/tests/test_multicart_2d.py +173 -0
  33. feectools/ddm/tests/test_partition.py +124 -0
  34. feectools/ddm/utilities.py +24 -0
  35. feectools/feec/__init__.py +0 -0
  36. feectools/feec/derivatives.py +780 -0
  37. feectools/feec/dof_kernels.py +210 -0
  38. feectools/feec/global_geometric_projectors.py +1073 -0
  39. feectools/feec/hodge.py +148 -0
  40. feectools/fem/__init__.py +0 -0
  41. feectools/fem/basic.py +465 -0
  42. feectools/fem/grid.py +181 -0
  43. feectools/fem/partitioning.py +344 -0
  44. feectools/fem/projectors.py +160 -0
  45. feectools/fem/splines.py +559 -0
  46. feectools/fem/tensor.py +1393 -0
  47. feectools/fem/tests/__init__.py +0 -0
  48. feectools/fem/tests/analytical_profiles_1d.py +100 -0
  49. feectools/fem/tests/analytical_profiles_base.py +34 -0
  50. feectools/fem/tests/splines_error_bounds.py +155 -0
  51. feectools/fem/tests/test_spline_histopolation.py +120 -0
  52. feectools/fem/tests/test_spline_interpolation.py +182 -0
  53. feectools/fem/tests/test_splines.py +184 -0
  54. feectools/fem/tests/test_splines_par.py +46 -0
  55. feectools/fem/tests/test_vector_spaces.py +150 -0
  56. feectools/fem/tests/utilities.py +47 -0
  57. feectools/fem/vector.py +729 -0
  58. feectools/linalg/__init__.py +0 -0
  59. feectools/linalg/basic.py +1386 -0
  60. feectools/linalg/block.py +1451 -0
  61. feectools/linalg/direct_solvers.py +201 -0
  62. feectools/linalg/fft.py +258 -0
  63. feectools/linalg/kernels/__init__.py +0 -0
  64. feectools/linalg/kernels/axpy_kernels.py +57 -0
  65. feectools/linalg/kernels/inner_kernels.py +100 -0
  66. feectools/linalg/kernels/matvec_kernels.py +206 -0
  67. feectools/linalg/kernels/stencil2IJV_kernels.py +227 -0
  68. feectools/linalg/kernels/stencil2coo_kernels.py +179 -0
  69. feectools/linalg/kernels/transpose_kernels.py +263 -0
  70. feectools/linalg/kron.py +911 -0
  71. feectools/linalg/solvers.py +1914 -0
  72. feectools/linalg/sparse.py +114 -0
  73. feectools/linalg/stencil.py +2923 -0
  74. feectools/linalg/stencil_dot_kernels.py +317 -0
  75. feectools/linalg/stencil_transpose_kernels.py +372 -0
  76. feectools/linalg/tests/__init__.py +0 -0
  77. feectools/linalg/tests/test_block.py +1588 -0
  78. feectools/linalg/tests/test_fft.py +106 -0
  79. feectools/linalg/tests/test_kron_stencil_matrix.py +114 -0
  80. feectools/linalg/tests/test_linalg.py +1065 -0
  81. feectools/linalg/tests/test_matrix_free.py +128 -0
  82. feectools/linalg/tests/test_solvers.py +213 -0
  83. feectools/linalg/tests/test_stencil_interface_matrix.py +379 -0
  84. feectools/linalg/tests/test_stencil_vector.py +1036 -0
  85. feectools/linalg/tests/test_stencil_vector_space.py +440 -0
  86. feectools/linalg/topetsc.py +522 -0
  87. feectools/linalg/utilities.py +200 -0
  88. feectools/utilities/__init__.py +0 -0
  89. feectools/utilities/quadratures.py +113 -0
  90. feectools/utilities/utils.py +166 -0
  91. feectools/version.py +1 -0
  92. feectools-0.1.0.dist-info/METADATA +66 -0
  93. feectools-0.1.0.dist-info/RECORD +98 -0
  94. feectools-0.1.0.dist-info/WHEEL +5 -0
  95. feectools-0.1.0.dist-info/entry_points.txt +3 -0
  96. feectools-0.1.0.dist-info/licenses/AUTHORS +22 -0
  97. feectools-0.1.0.dist-info/licenses/LICENSE +21 -0
  98. 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,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ psydac-accelerate = feectools.accelerate.accelerate:main
3
+ psydac-mesh = feectools.cmd.mesh:main