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,440 @@
1
+ import pytest
2
+ import numpy as np
3
+
4
+ from feectools.ddm.mpi import mpi as MPI
5
+ from feectools.linalg.stencil import StencilVectorSpace, StencilVector
6
+ from feectools.ddm.cart import DomainDecomposition, CartDecomposition, find_mpi_type
7
+
8
+ # ===============================================================================
9
+ def compute_global_starts_ends(domain_decomposition, npts):
10
+ ndims = len(npts)
11
+ global_starts = [None] * ndims
12
+ global_ends = [None] * ndims
13
+
14
+ for axis in range(ndims):
15
+ es = domain_decomposition.global_element_starts[axis]
16
+ ee = domain_decomposition.global_element_ends[axis]
17
+
18
+ global_ends[axis] = ee.copy()
19
+ global_ends[axis][-1] = npts[axis] - 1
20
+ global_starts[axis] = np.array([0] + (global_ends[axis][:-1] + 1).tolist())
21
+
22
+ return global_starts, global_ends
23
+
24
+ # ===============================================================================
25
+ # SERIAL TESTS
26
+ # ===============================================================================
27
+
28
+ @pytest.mark.parametrize('dtype', [float, complex])
29
+ @pytest.mark.parametrize('n1', [1, 7])
30
+ @pytest.mark.parametrize('p1', [1, 2])
31
+ @pytest.mark.parametrize('s1', [1, 2])
32
+ @pytest.mark.parametrize('P1', [True, False])
33
+
34
+ def test_stencil_vector_space_1d_serial_init(dtype, n1, p1, s1, P1):
35
+ # Create domain decomposition
36
+ D = DomainDecomposition([n1], periods=[P1])
37
+
38
+ # Partition the points
39
+ npts = [n1]
40
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
41
+
42
+ # Create cart and vector space
43
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1], shifts=[s1])
44
+ V = StencilVectorSpace(C, dtype=dtype)
45
+
46
+ # Test properties of the vector space
47
+ assert V.dimension == n1
48
+ assert V.dtype == dtype
49
+ assert V.mpi_type == find_mpi_type(dtype)
50
+ assert V.shape == (n1 + 2 * p1*s1,)
51
+ assert not V.parallel
52
+ assert V.cart == C
53
+ assert V.npts == (n1,)
54
+ assert V.starts == (0,)
55
+ assert V.ends == (n1 - 1,)
56
+ assert V.parent_starts == (None,)
57
+ assert V.parent_ends == (None,)
58
+ assert V.pads == (p1,)
59
+ assert V.periods == (P1,)
60
+ assert V.shifts == (s1,)
61
+ assert V.ndim == 1
62
+ assert V.interfaces == type(type.__dict__)({})
63
+ # ===============================================================================
64
+
65
+ @pytest.mark.parametrize('dtype', [float, complex])
66
+ @pytest.mark.parametrize('n1', [1, 7])
67
+ @pytest.mark.parametrize('n2', [1, 5])
68
+ @pytest.mark.parametrize('p1', [1, 2])
69
+ @pytest.mark.parametrize('p2', [2])
70
+ @pytest.mark.parametrize('s1', [1, 2])
71
+ @pytest.mark.parametrize('s2', [2])
72
+ @pytest.mark.parametrize('P1', [True, False])
73
+ @pytest.mark.parametrize('P2', [True])
74
+
75
+ def test_stencil_vector_space_2d_serial_init(dtype, n1, n2, p1, p2, s1, s2, P1, P2):
76
+ # Create domain decomposition
77
+ D = DomainDecomposition([n1, n2], periods=[P1, P2])
78
+
79
+ # Partition the points
80
+ npts = [n1, n2]
81
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
82
+
83
+ # Create cart and vector space
84
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2], shifts=[s1, s2])
85
+ V = StencilVectorSpace(C, dtype=dtype)
86
+
87
+ # Test properties of the vector space
88
+ assert V.dimension == n1 * n2
89
+ assert V.dtype == dtype
90
+ assert V.mpi_type == find_mpi_type(dtype)
91
+ assert V.shape == ((n1 + 2 * p1*s1), (n2 + 2 * p2*s2))
92
+ assert not V.parallel
93
+ assert V.cart == C
94
+ assert V.npts == (n1, n2)
95
+ assert V.starts == (0, 0)
96
+ assert V.ends == (n1 - 1, n2 - 1)
97
+ assert V.parent_starts == (None, None)
98
+ assert V.parent_ends == (None, None)
99
+ assert V.pads == (p1, p2)
100
+ assert V.periods == (P1,P2)
101
+ assert V.shifts == (s1, s2)
102
+ assert V.ndim == 2
103
+ assert V.interfaces == type(type.__dict__)({})
104
+ # ===============================================================================
105
+
106
+ @pytest.mark.parametrize('dtype', [float, complex])
107
+ @pytest.mark.parametrize('n1', [1, 9])
108
+ @pytest.mark.parametrize('n2', [1, 7])
109
+ @pytest.mark.parametrize('n3', [5])
110
+ @pytest.mark.parametrize('p1', [1, 2])
111
+ @pytest.mark.parametrize('p2', [2])
112
+ @pytest.mark.parametrize('p3', [1])
113
+ @pytest.mark.parametrize('s1', [1, 2])
114
+ @pytest.mark.parametrize('s2', [2])
115
+ @pytest.mark.parametrize('s3', [1])
116
+
117
+ def test_stencil_vector_space_3d_serial_init(dtype, n1, n2, n3, p1, p2, p3, s1, s2, s3, P1=True, P2=False, P3=True):
118
+ # Create domain decomposition
119
+ D = DomainDecomposition([n1,n2,n3], periods=[P1, P2, P3])
120
+
121
+ # Partition the points
122
+ npts = [n1,n2, n3]
123
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
124
+
125
+ # Create cart and vector space
126
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2, p3], shifts=[s1, s2, s3])
127
+ V = StencilVectorSpace(C, dtype=dtype)
128
+
129
+ # Test properties of the vector space
130
+ assert V.dimension == n1*n2*n3
131
+ assert V.dtype == dtype
132
+ assert V.mpi_type == find_mpi_type(dtype)
133
+ assert V.shape == (n1 + 2 * p1*s1, n2 + 2 * p2*s2, n3 + 2 * p3*s3)
134
+ assert not V.parallel
135
+ assert V.cart == C
136
+ assert V.npts == (n1, n2, n3)
137
+ assert V.starts == (0, 0, 0)
138
+ assert V.ends == (n1 - 1, n2 - 1, n3 - 1)
139
+ assert V.parent_starts == (None, None, None)
140
+ assert V.parent_ends == (None, None, None)
141
+ assert V.pads == (p1, p2, p3)
142
+ assert V.periods == (P1, P2, P3)
143
+ assert V.shifts == (s1, s2, s3)
144
+ assert V.ndim == 3
145
+ assert V.interfaces == type(type.__dict__)({})
146
+ # ===============================================================================
147
+
148
+ @pytest.mark.parametrize('dtype', [float, complex])
149
+ @pytest.mark.parametrize('n1', [2])
150
+ @pytest.mark.parametrize('n2', [2])
151
+ @pytest.mark.parametrize('n3', [2])
152
+
153
+ def test_stencil_vector_space_3D_serial_parent(dtype, n1, n2, n3, P1=True, P2=False, P3=True):
154
+ # Create domain decomposition
155
+ D = DomainDecomposition([n1, n2, n3], periods=[P1, P2, P3])
156
+
157
+ # Partition the points for our domain and our reduced domain
158
+ npts_red = [1, 1, 1]
159
+ npts = [n1, n2, n3]
160
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
161
+
162
+ # Create a cart
163
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[1, 1, 1], shifts=[1, 1, 1])
164
+
165
+ # Create q reduced cart and vector space on it
166
+ Cred = C.reduce_npts(npts_red, global_starts, global_ends, [1, 1, 1])
167
+ V = StencilVectorSpace(Cred, dtype=dtype)
168
+
169
+ # Test properties of the vector space
170
+ assert V.dimension == 1
171
+ assert V.dtype == dtype
172
+ assert V.starts == (0, 0, 0)
173
+ assert V.ends == (n1-1, n2-1, n3-1)
174
+ assert V.parent_starts == (0, 0, 0)
175
+ assert V.parent_ends == (n1-1, n2-1, n3-1)
176
+ # ===============================================================================
177
+
178
+ @pytest.mark.parametrize('dtype', [float, complex])
179
+ @pytest.mark.parametrize('n1', [2, 9])
180
+ @pytest.mark.parametrize('n2', [2, 7])
181
+ @pytest.mark.parametrize('p1', [1, 2])
182
+ @pytest.mark.parametrize('p2', [2])
183
+ @pytest.mark.parametrize('s1', [1, 2])
184
+ @pytest.mark.parametrize('s2', [2])
185
+
186
+ def test_stencil_vector_space_2D_serial_zeros(dtype, n1, n2, p1, p2, s1, s2, P1=True, P2=False):
187
+ # Create domain decomposition
188
+ D = DomainDecomposition([n1, n2], periods=[P1, P2])
189
+
190
+ # Partition the points
191
+ npts = [n1, n2]
192
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
193
+
194
+ # Create cart and vector space
195
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2], shifts=[s1, s2])
196
+ V = StencilVectorSpace(C, dtype=dtype)
197
+
198
+ # Create a zero vector on this vector space
199
+ x = V.zeros()
200
+
201
+ # Test properties of the vector
202
+ assert x.space is V
203
+ assert x.dtype == dtype
204
+ assert x.starts == (0, 0)
205
+ assert x.ends == (n1-1, n2-1)
206
+ assert x._data.shape == (n1+2*p1*s1, n2+2*p2*s2)
207
+ assert x.pads == (p1, p2)
208
+ assert x._data.dtype == dtype
209
+ assert np.array_equal(x._data, np.zeros((n1+2*p1*s1, n2+2*p2*s2), dtype=dtype))
210
+ # ===============================================================================
211
+
212
+ @pytest.mark.parametrize('dtype', [float, complex])
213
+ @pytest.mark.parametrize('n1', [5, 9])
214
+ @pytest.mark.parametrize('n2', [5, 7])
215
+ @pytest.mark.parametrize('p1', [1, 2])
216
+ @pytest.mark.parametrize('p2', [2])
217
+ @pytest.mark.parametrize('s1', [1, 2])
218
+ @pytest.mark.parametrize('s2', [2])
219
+ @pytest.mark.parametrize('axis', [0, 1])
220
+ @pytest.mark.parametrize('ext', [-1, 1])
221
+
222
+ def test_stencil_vector_space_2D_serial_set_interface(dtype, n1, n2, p1, p2, s1, s2, axis, ext, P1=True, P2=False):
223
+ # Create domain decomposition
224
+ D = DomainDecomposition([n1, n2], periods=[P1, P2])
225
+
226
+ # Partition the points
227
+ npts = [n1, n2]
228
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
229
+
230
+ # Create cart and vector space
231
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2], shifts=[s1, s2])
232
+ V = StencilVectorSpace(C, dtype=dtype)
233
+
234
+ # Create an interface on this vector space
235
+ V.set_interface(axis, ext, C)
236
+ V_inter=V.interfaces[axis, ext]
237
+
238
+ # Test the propertiesof this interface
239
+ assert isinstance(V_inter, StencilVectorSpace)
240
+ assert V_inter.dimension == n1 * n2
241
+ assert V_inter.dtype == dtype
242
+ assert V_inter.mpi_type == find_mpi_type(dtype)
243
+ assert not V_inter.parallel
244
+ assert isinstance(V_inter.cart, CartDecomposition)
245
+ assert V_inter.npts == (n1, n2)
246
+ assert V_inter.parent_starts == (None, None)
247
+ assert V_inter.parent_ends == (None, None)
248
+ assert V_inter.pads == (p1, p2)
249
+ assert V_inter.periods == (P1, P2)
250
+ assert V_inter.shifts == (s1, s2)
251
+ assert V_inter.ndim == 2
252
+ assert V_inter.interfaces == type(type.__dict__)({})
253
+
254
+ if axis == 0:
255
+ assert V_inter.shape == ((p1+1 + 2 * p1 * s1), (n2 + 2 * p2 * s2))
256
+ if ext == 1:
257
+ assert V_inter.starts == (n1-1-p1, 0)
258
+ assert V_inter.ends == (n1-1, n2-1)
259
+ else:
260
+ assert V_inter.starts == (0, 0)
261
+ assert V_inter.ends == (p1, n2-1)
262
+ else:
263
+ assert V_inter.shape == ((n1 + 2 * p1 * s1), p2+1+2*p2*s2)
264
+ if ext == 1:
265
+ assert V_inter.starts == (0, n2-1-p2)
266
+ assert V_inter.ends == (n1-1, n2-1)
267
+ else:
268
+ assert V_inter.starts == (0, 0)
269
+ assert V_inter.ends == (n1-1, p2)
270
+ # ===============================================================================
271
+ # PARALLEL TESTS
272
+ # ===============================================================================
273
+
274
+ @pytest.mark.parametrize('dtype', [float, complex])
275
+ @pytest.mark.parametrize('n1', [15, 30])
276
+ @pytest.mark.parametrize('p1', [1, 2])
277
+ @pytest.mark.parametrize('s1', [1, 2])
278
+ @pytest.mark.parametrize('P1', [True, False])
279
+ @pytest.mark.parallel
280
+
281
+ def test_stencil_vector_space_1d_parallel_init(dtype, n1, p1, s1, P1):
282
+
283
+ comm = MPI.COMM_WORLD
284
+ # Create domain decomposition
285
+ D = DomainDecomposition([n1], periods=[P1], comm=comm)
286
+
287
+ # Partition the points
288
+ npts = [n1]
289
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
290
+
291
+ # Create cart and vector space
292
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1], shifts=[s1])
293
+ V = StencilVectorSpace(C, dtype=dtype)
294
+
295
+
296
+ # Test properties of the vector space
297
+ assert V.dimension == n1
298
+ assert V.dtype == dtype
299
+ assert V.mpi_type == find_mpi_type(dtype)
300
+ assert V.shape == (V.ends[0]+1-V.starts[0] + 2 * p1*s1,)
301
+ assert V.parallel
302
+ assert V.cart == C
303
+ assert V.npts == (n1,)
304
+ assert V.starts == C.starts
305
+ assert V.ends == C.ends
306
+ assert V.parent_starts == (None,)
307
+ assert V.parent_ends == (None,)
308
+ assert V.pads == (p1,)
309
+ assert V.periods == (P1,)
310
+ assert V.shifts == (s1,)
311
+ assert V.ndim == 1
312
+ assert V.interfaces == type(type.__dict__)({})
313
+ # ===============================================================================
314
+
315
+ @pytest.mark.parametrize('dtype', [float, complex])
316
+ @pytest.mark.parametrize('n1', [15, 30])
317
+ @pytest.mark.parametrize('n2', [20, 40])
318
+ @pytest.mark.parametrize('p1', [1, 2])
319
+ @pytest.mark.parametrize('p2', [2])
320
+ @pytest.mark.parametrize('s1', [1, 2])
321
+ @pytest.mark.parametrize('s2', [2])
322
+ @pytest.mark.parametrize('P1', [True, False])
323
+ @pytest.mark.parametrize('P2', [True])
324
+ @pytest.mark.parallel
325
+
326
+ def test_stencil_vector_space_2d_parallel_init(dtype, n1, n2, p1, p2, s1, s2, P1, P2):
327
+
328
+ comm = MPI.COMM_WORLD
329
+ # Create domain decomposition
330
+ D = DomainDecomposition([n1, n2], periods=[P1, P2], comm=comm)
331
+
332
+ # Partition the points
333
+ npts = [n1, n2]
334
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
335
+
336
+ # Create cart and vector space
337
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2], shifts=[s1, s2])
338
+ V = StencilVectorSpace(C, dtype=dtype)
339
+
340
+ # Test properties of the vector space
341
+ assert V.dimension == n1 * n2
342
+ assert V.dtype == dtype
343
+ assert V.mpi_type == find_mpi_type(dtype)
344
+ assert V.shape == ((V.ends[0]+1-V.starts[0] + 2 * p1*s1), (V.ends[1]+1-V.starts[1] + 2 * p2*s2))
345
+ assert V.parallel
346
+ assert V.cart == C
347
+ assert V.npts == (n1, n2)
348
+ assert V.starts == C.starts
349
+ assert V.ends == C.ends
350
+ assert V.parent_starts == (None, None)
351
+ assert V.parent_ends == (None, None)
352
+ assert V.pads == (p1, p2)
353
+ assert V.periods == (P1,P2)
354
+ assert V.shifts == (s1, s2)
355
+ assert V.ndim == 2
356
+ assert V.interfaces == type(type.__dict__)({})
357
+ # ===============================================================================
358
+
359
+ @pytest.mark.parametrize('dtype', [float, complex])
360
+ @pytest.mark.parametrize('n1', [15, 30])
361
+ @pytest.mark.parametrize('n2', [20, 40])
362
+ @pytest.mark.parametrize('n3', [10, 25])
363
+ @pytest.mark.parametrize('p1', [1, 2])
364
+ @pytest.mark.parametrize('p2', [1, 2])
365
+ @pytest.mark.parametrize('p3', [1])
366
+ @pytest.mark.parametrize('s1', [1, 2])
367
+ @pytest.mark.parametrize('s2', [1, 2])
368
+ @pytest.mark.parametrize('s3', [1])
369
+ @pytest.mark.parallel
370
+
371
+ def test_stencil_vector_space_3d_parallel_init(dtype, n1, n2, n3, p1, p2, p3, s1, s2, s3, P1=True, P2=False, P3=True):
372
+
373
+ comm = MPI.COMM_WORLD
374
+ # Create domain decomposition
375
+ D = DomainDecomposition([n1, n2, n3], periods=[P1, P2, P3], comm=comm)
376
+
377
+ # Partition the points
378
+ npts = [n1,n2, n3]
379
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
380
+
381
+ # Create cart and vector space
382
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[p1, p2, p3], shifts=[s1, s2, s3])
383
+ V = StencilVectorSpace(C, dtype=dtype)
384
+
385
+ # Test properties of the vector space
386
+ assert V.dimension == n1*n2*n3
387
+ assert V.dtype == dtype
388
+ assert V.mpi_type == find_mpi_type(dtype)
389
+ assert V.shape == (V.ends[0]+1-V.starts[0] + 2 * p1*s1, V.ends[1]+1-V.starts[1] + 2 * p2*s2, V.ends[2]+1-V.starts[2] + 2 * p3*s3)
390
+ assert V.parallel
391
+ assert V.cart == C
392
+ assert V.npts == (n1, n2, n3)
393
+ assert V.starts == C.starts
394
+ assert V.ends == C.ends
395
+ assert V.parent_starts == (None, None, None)
396
+ assert V.parent_ends == (None, None, None)
397
+ assert V.pads == (p1, p2, p3)
398
+ assert V.periods == (P1, P2, P3)
399
+ assert V.shifts == (s1, s2, s3)
400
+ assert V.ndim == 3
401
+ assert V.interfaces == type(type.__dict__)({})
402
+ # ===============================================================================
403
+
404
+ @pytest.mark.parametrize('dtype', [float, complex])
405
+ @pytest.mark.parametrize('n1', [15])
406
+ @pytest.mark.parametrize('n2', [20])
407
+ @pytest.mark.parallel
408
+
409
+ def test_stencil_vector_space_2D_parallel_parent(dtype, n1, n2, P1=True, P2=False):
410
+
411
+ comm = MPI.COMM_WORLD
412
+ # Create domain decomposition
413
+ D = DomainDecomposition([n1, n2], periods=[P1, P2], comm=comm)
414
+
415
+ # Partition the points for our domain and its reduced version
416
+ npts_red = [1, 1]
417
+ npts = [n1, n2]
418
+ global_starts, global_ends = compute_global_starts_ends(D, npts)
419
+
420
+ # Create the cart
421
+ C = CartDecomposition(D, npts, global_starts, global_ends, pads=[1, 1], shifts=[1, 1])
422
+
423
+ # Create the cart reduced and a vector space
424
+ Cred = C.reduce_npts(npts_red, global_starts, global_ends, [1, 1])
425
+ V = StencilVectorSpace(Cred, dtype=dtype)
426
+
427
+ # Test properties of the vector space
428
+ assert V.dimension == 1
429
+ assert V.dtype == dtype
430
+ assert V.starts == Cred.starts
431
+ assert V.ends == Cred.ends
432
+ assert V.parent_starts == Cred.parent_starts
433
+ assert V.parent_ends == Cred.parent_ends
434
+ # ===============================================================================
435
+ # SCRIPT FUNCTIONALITY
436
+ #===============================================================================
437
+ if __name__ == "__main__":
438
+ import sys
439
+
440
+ pytest.main(sys.argv)