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,184 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ from feectools.fem.basic import FemField
4
+ from feectools.fem.splines import SplineSpace
5
+ from feectools.fem.tensor import TensorFemSpace
6
+ from feectools.fem.vector import VectorFemSpace
7
+ from feectools.ddm.cart import DomainDecomposition
8
+
9
+ from numpy import linspace
10
+
11
+
12
+ def test_1d_1():
13
+ print ('>>> test_1d_1')
14
+
15
+ knots = [0., 0., 0., 1., 1., 1.]
16
+ p = 2
17
+ V = SplineSpace(p, knots=knots)
18
+ print (V)
19
+ F = FemField(V)
20
+
21
+ def test_1d_2():
22
+ print ('>>> test_1d_2')
23
+
24
+ p = 2
25
+ grid = linspace(0., 1., 5)
26
+ V = SplineSpace(p, grid=grid)
27
+ print (V)
28
+ F = FemField(V)
29
+
30
+ def test_1d_3():
31
+ print ('>>> test_1d_3')
32
+
33
+ p = 2
34
+ grid = linspace(0., 1., 5)
35
+ V1 = SplineSpace(p, grid=grid)
36
+ V2 = SplineSpace(p+1, grid=grid)
37
+
38
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False])
39
+ V = TensorFemSpace(domain_decomposition, V1, V2)
40
+ print (V)
41
+
42
+ def test_2d_1():
43
+ print ('>>> test_2d_1')
44
+
45
+ knots_1 = [0., 0., 0., 1., 1., 1.]
46
+ knots_2 = [0., 0., 0., 0.5, 1., 1., 1.]
47
+ p_1 = 2
48
+ p_2 = 2
49
+ V1 = SplineSpace(p_1, knots=knots_1)
50
+ V2 = SplineSpace(p_2, knots=knots_2)
51
+
52
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False])
53
+ V = TensorFemSpace(domain_decomposition, V1, V2)
54
+ print (V)
55
+ F = FemField(V)
56
+
57
+ def test_2d_2():
58
+ print ('>>> test_2d_2')
59
+
60
+ p_1 = 2
61
+ p_2 = 2
62
+ grid_1 = linspace(0., 1., 3)
63
+ grid_2 = linspace(0., 1., 5)
64
+ V1 = SplineSpace(p_1, grid=grid_1)
65
+ V2 = SplineSpace(p_2, grid=grid_2)
66
+
67
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False])
68
+ V = TensorFemSpace(domain_decomposition, V1, V2)
69
+ print (V)
70
+ F = FemField(V)
71
+
72
+ def test_2d_3():
73
+ print ('>>> test_2d_3')
74
+
75
+ p = 2
76
+ grid_1 = linspace(0., 1., 3)
77
+ grid_2 = linspace(0., 1., 5)
78
+
79
+ # ... first component
80
+ V1 = SplineSpace(p-1, grid=grid_1)
81
+ V2 = SplineSpace(p, grid=grid_2)
82
+
83
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False])
84
+ Vx = TensorFemSpace(domain_decomposition, V1, V2)
85
+ # ...
86
+
87
+ # ... second component
88
+ V1 = SplineSpace(p, grid=grid_1)
89
+ V2 = SplineSpace(p-1, grid=grid_2)
90
+
91
+
92
+ Vy = TensorFemSpace(domain_decomposition, V1, V2)
93
+ # ...
94
+
95
+ V = VectorFemSpace(Vx, Vy)
96
+ print (V)
97
+
98
+ def test_3d_1():
99
+ print ('>>> test_3d_1')
100
+
101
+ knots_1 = [0., 0., 0., 1., 1., 1.]
102
+ knots_2 = [0., 0., 0., 0.5, 1., 1., 1.]
103
+ knots_3 = [0., 0., 0.5, 1., 1.]
104
+ p_1 = 2
105
+ p_2 = 2
106
+ p_3 = 1
107
+ V1 = SplineSpace(p_1, knots=knots_1)
108
+ V2 = SplineSpace(p_2, knots=knots_2)
109
+ V3 = SplineSpace(p_3, knots=knots_3)
110
+
111
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells, V3.ncells], [False, False, False])
112
+ V = TensorFemSpace(domain_decomposition, V1, V2, V3)
113
+ print (V)
114
+ F = FemField(V)
115
+
116
+ def test_3d_2():
117
+ print ('>>> test_3d_2')
118
+
119
+ p_1 = 2
120
+ p_2 = 2
121
+ p_3 = 1
122
+ grid_1 = linspace(0., 1., 3)
123
+ grid_2 = linspace(0., 1., 5)
124
+ grid_3 = linspace(0., 1., 7)
125
+ V1 = SplineSpace(p_1, grid=grid_1)
126
+ V2 = SplineSpace(p_2, grid=grid_2)
127
+ V3 = SplineSpace(p_3, grid=grid_3)
128
+
129
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells, V3.ncells], [False, False, False])
130
+ V = TensorFemSpace(domain_decomposition, V1, V2, V3)
131
+ print (V)
132
+ F = FemField(V)
133
+
134
+ def test_3d_3():
135
+ print ('>>> test_3d_3')
136
+
137
+ p = 2
138
+ grid_1 = linspace(0., 1., 3)
139
+ grid_2 = linspace(0., 1., 5)
140
+ grid_3 = linspace(0., 1., 7)
141
+
142
+ # ... first component
143
+ V1 = SplineSpace(p-1, grid=grid_1)
144
+ V2 = SplineSpace(p, grid=grid_2)
145
+ V3 = SplineSpace(p, grid=grid_3)
146
+
147
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells, V3.ncells], [False, False, False])
148
+ Vx = TensorFemSpace(domain_decomposition, V1, V2, V3)
149
+ # ...
150
+
151
+ # ... second component
152
+ V1 = SplineSpace(p, grid=grid_1)
153
+ V2 = SplineSpace(p-1, grid=grid_2)
154
+ V3 = SplineSpace(p, grid=grid_3)
155
+
156
+ Vy = TensorFemSpace(domain_decomposition, V1, V2, V3)
157
+ # ...
158
+
159
+ # ... third component
160
+ V1 = SplineSpace(p, grid=grid_1)
161
+ V2 = SplineSpace(p, grid=grid_2)
162
+ V3 = SplineSpace(p-1, grid=grid_3)
163
+
164
+ Vz = TensorFemSpace(domain_decomposition, V1, V2, V3)
165
+ # ...
166
+
167
+ V = VectorFemSpace(Vx, Vy, Vz)
168
+ print (V)
169
+
170
+
171
+ ###############################################
172
+ if __name__ == '__main__':
173
+
174
+ test_1d_1()
175
+ test_1d_2()
176
+ test_1d_3()
177
+
178
+ test_2d_1()
179
+ test_2d_2()
180
+ test_2d_3()
181
+
182
+ test_3d_1()
183
+ test_3d_2()
184
+ test_3d_3()
@@ -0,0 +1,46 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ import pytest
4
+
5
+ from feectools.fem.basic import FemField
6
+ from feectools.fem.splines import SplineSpace
7
+ from feectools.fem.tensor import TensorFemSpace
8
+ from feectools.fem.vector import VectorFemSpace
9
+ from feectools.ddm.cart import DomainDecomposition
10
+ from feectools.ddm.mpi import mpi as MPI
11
+
12
+ from numpy import linspace
13
+
14
+ def test_2d_1():
15
+
16
+ p_1 = 2
17
+ p_2 = 2
18
+ grid_1 = linspace(0., 1., 10)
19
+ grid_2 = linspace(0., 1., 15)
20
+ comm = MPI.COMM_WORLD
21
+ rank = comm.Get_rank()
22
+
23
+ V1 = SplineSpace(p_1, grid=grid_1)
24
+ V2 = SplineSpace(p_2, grid=grid_2)
25
+
26
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False], comm=comm)
27
+ V = TensorFemSpace(domain_decomposition, V1, V2)
28
+
29
+ if rank == 0:
30
+ print(V.coeff_space.cart.nprocs)
31
+ for i in range(comm.Get_size()):
32
+ if rank == i:
33
+ print('rank ', rank)
34
+ print('TensorFemSpace ', V)
35
+ print('VectorSpace ')
36
+ print('> npts ::', V.coeff_space.npts)
37
+ print('> starts ::', V.coeff_space.starts)
38
+ print('> ends ::', V.coeff_space.ends)
39
+ print('', flush=True)
40
+ comm.Barrier()
41
+
42
+ F = FemField(V)
43
+
44
+ ###############################################
45
+ if __name__ == '__main__':
46
+ test_2d_2()
@@ -0,0 +1,150 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ import pytest
4
+ from numpy import linspace
5
+
6
+ from feectools.fem.basic import FemField
7
+ from feectools.fem.splines import SplineSpace
8
+ from feectools.fem.tensor import TensorFemSpace
9
+ from feectools.fem.vector import VectorFemSpace
10
+ from feectools.ddm.cart import DomainDecomposition
11
+ from feectools.linalg.block import BlockVector, BlockVectorSpace
12
+
13
+
14
+ def test_vector_space_2d():
15
+ p = 2
16
+ grid_1 = linspace(0., 1., 3)
17
+ grid_2 = linspace(0., 1., 5)
18
+
19
+ # ... first component
20
+ V1 = SplineSpace(p-1, grid=grid_1)
21
+ V2 = SplineSpace(p, grid=grid_2)
22
+
23
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells], [False, False])
24
+ Vx = TensorFemSpace(domain_decomposition, V1, V2)
25
+ # ...
26
+
27
+ # ... second component
28
+ V1 = SplineSpace(p, grid=grid_1)
29
+ V2 = SplineSpace(p-1, grid=grid_2)
30
+
31
+ Vy = TensorFemSpace(domain_decomposition, V1, V2)
32
+ # ...
33
+
34
+ V = VectorFemSpace(Vx, Vy)
35
+ F = FemField(V)
36
+
37
+ # Check properties of V from abstract interface
38
+ assert V.ldim == 2
39
+ assert V.periodic == (False, False)
40
+ assert V.mapping is None
41
+ assert isinstance(V.coeff_space, BlockVectorSpace)
42
+ assert not V.is_multipatch
43
+ assert V.is_vector_valued
44
+ assert V.symbolic_space is None
45
+ assert V.patch_spaces == (V,)
46
+ assert V.component_spaces == (Vx, Vy)
47
+ with pytest.raises(NotImplementedError):
48
+ getattr(V, 'axis_spaces')
49
+ assert V.is_multipatch == False
50
+ assert V.is_vector_valued == True
51
+
52
+ # Check other properties of V
53
+ assert V.nbasis == Vx.nbasis + Vy.nbasis
54
+ assert V.degree == [Vx.degree, Vy.degree]
55
+ assert V.multiplicity == [Vx.multiplicity, Vy.multiplicity]
56
+ assert V.pads == [Vx.pads, Vy.pads]
57
+ assert V.ncells == Vx.ncells == Vy.ncells
58
+ assert V.spaces == (Vx, Vy)
59
+
60
+ # Check properties of F
61
+ assert F.space == V
62
+ assert isinstance(F.coeffs, BlockVector)
63
+ assert len(F.fields) == 2
64
+ assert isinstance(F.fields[0], FemField)
65
+ assert isinstance(F.fields[1], FemField)
66
+ assert F.fields[0].space == Vx
67
+ assert F.fields[1].space == Vy
68
+ assert F.patch_fields == (F,)
69
+ assert F.component_fields == F.fields
70
+
71
+
72
+ def test_vector_space_3d():
73
+ p = 2
74
+ grid_1 = linspace(0., 1., 3)
75
+ grid_2 = linspace(0., 1., 5)
76
+ grid_3 = linspace(0., 1., 7)
77
+
78
+ # ... first component
79
+ V1 = SplineSpace(p-1, grid=grid_1)
80
+ V2 = SplineSpace(p, grid=grid_2)
81
+ V3 = SplineSpace(p, grid=grid_3)
82
+
83
+ domain_decomposition = DomainDecomposition([V1.ncells, V2.ncells, V3.ncells], [False, False, False])
84
+
85
+ Vx = TensorFemSpace(domain_decomposition, V1, V2, V3)
86
+ # ...
87
+
88
+ # ... second component
89
+ V1 = SplineSpace(p, grid=grid_1)
90
+ V2 = SplineSpace(p-1, grid=grid_2)
91
+ V3 = SplineSpace(p, grid=grid_3)
92
+
93
+ Vy = TensorFemSpace(domain_decomposition, V1, V2, V3)
94
+ # ...
95
+
96
+ # ... third component
97
+ V1 = SplineSpace(p, grid=grid_1)
98
+ V2 = SplineSpace(p, grid=grid_2)
99
+ V3 = SplineSpace(p-1, grid=grid_3)
100
+
101
+ Vz = TensorFemSpace(domain_decomposition, V1, V2, V3)
102
+ # ...
103
+
104
+ V = VectorFemSpace(Vx, Vy, Vz)
105
+ F = FemField(V)
106
+
107
+ # Check properties of V from abstract interface
108
+ assert V.ldim == 3
109
+ assert V.periodic == (False, False, False)
110
+ assert V.mapping is None
111
+ assert isinstance(V.coeff_space, BlockVectorSpace)
112
+ assert not V.is_multipatch
113
+ assert V.is_vector_valued
114
+ assert V.symbolic_space is None
115
+ assert V.patch_spaces == (V,)
116
+ assert V.component_spaces == (Vx, Vy, Vz)
117
+ with pytest.raises(NotImplementedError):
118
+ getattr(V, 'axis_spaces')
119
+ assert V.is_multipatch == False
120
+ assert V.is_vector_valued == True
121
+
122
+ # Check other properties of V
123
+ assert V.nbasis == Vx.nbasis + Vy.nbasis + Vz.nbasis
124
+ assert V.degree == [Vx.degree, Vy.degree, Vz.degree]
125
+ assert V.multiplicity == [Vx.multiplicity, Vy.multiplicity, Vz.multiplicity]
126
+ assert V.pads == [Vx.pads, Vy.pads, Vz.pads]
127
+ assert V.ncells == Vx.ncells == Vy.ncells == Vz.ncells
128
+ assert V.spaces == (Vx, Vy, Vz)
129
+
130
+ # Check properties of F
131
+ assert F.space == V
132
+ assert isinstance(F.coeffs, BlockVector)
133
+ assert len(F.fields) == 3
134
+ assert isinstance(F.fields[0], FemField)
135
+ assert isinstance(F.fields[1], FemField)
136
+ assert isinstance(F.fields[2], FemField)
137
+ assert F.fields[0].space == Vx
138
+ assert F.fields[1].space == Vy
139
+ assert F.fields[2].space == Vz
140
+ assert F.patch_fields == (F,)
141
+ assert F.component_fields == F.fields
142
+
143
+ ###############################################
144
+ if __name__ == '__main__':
145
+
146
+ print('>>> test_vector_space_2d')
147
+ test_vector_space_2d()
148
+
149
+ print ('>>> test_vector_space_3d')
150
+ test_vector_space_3d()
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ # Copyright 2018 Yaman Güçlü
3
+
4
+ import numpy as np
5
+
6
+ #===============================================================================
7
+ def horner( x, *poly_coeffs ):
8
+ """ Use Horner's Scheme to evaluate a polynomial
9
+ of coefficients *poly_coeffs at location x.
10
+ """
11
+ p = 0
12
+ for c in poly_coeffs[::-1]:
13
+ p = p*x + c
14
+ return p
15
+
16
+ #===============================================================================
17
+ def random_grid( domain, ncells, random_fraction ):
18
+ """ Create random grid over 1D domain with given number of cells.
19
+ """
20
+ # Create uniform grid on [0,1]
21
+ x = np.linspace( 0.0, 1.0, ncells+1 )
22
+
23
+ # Apply random displacement to all points, then sort grid
24
+ x += (np.random.random_sample( ncells+1 )-0.5) * (random_fraction/ncells)
25
+ x.sort()
26
+
27
+ # Apply linear transformation y=m*x+q to match domain limits
28
+ xa, xb = x[0], x[-1]
29
+ ya, yb = domain
30
+ m = ( yb-ya )/(xb-xa)
31
+ q = (xb*ya-xa*yb)/(xb-xa)
32
+ y = m*x + q
33
+
34
+ # Avoid possible round-off
35
+ y[0], y[-1] = domain
36
+
37
+ return y
38
+
39
+ #===============================================================================
40
+ def falling_factorial( x, n ):
41
+ """ Calculate falling factorial of x.
42
+ [https://en.wikipedia.org/wiki/Falling_and_rising_factorials]
43
+ """
44
+ c = 1
45
+ for k in range(n):
46
+ c *= x-k
47
+ return c