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,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
|