feectools 0.1.5__tar.gz → 0.1.6__tar.gz
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-0.1.5/feectools.egg-info → feectools-0.1.6}/PKG-INFO +2 -1
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/fem_bilinear_form.py +30 -30
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/fem_common.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/fem_sum_form.py +2 -2
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/bsplines.py +92 -86
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/bsplines_kernels.py +10 -6
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/tests/test_bsplines.py +34 -34
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/tests/test_bsplines_kernel.py +8 -8
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/tests/test_bsplines_pyccel.py +180 -180
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/blocking_data_exchanger.py +16 -15
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/cart.py +39 -34
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/nonblocking_data_exchanger.py +31 -14
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/partition.py +12 -12
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/petsc.py +4 -4
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/test_cart_1d.py +4 -4
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/test_cart_2d.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/test_cart_3d.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/test_multicart_2d.py +7 -7
- {feectools-0.1.5 → feectools-0.1.6}/feectools/feec/derivatives.py +6 -6
- {feectools-0.1.5 → feectools-0.1.6}/feectools/feec/global_geometric_projectors.py +84 -72
- {feectools-0.1.5 → feectools-0.1.6}/feectools/feec/hodge.py +0 -1
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/grid.py +1 -1
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/partitioning.py +2 -2
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/projectors.py +6 -6
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/splines.py +31 -11
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tensor.py +30 -29
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/analytical_profiles_1d.py +4 -4
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_spline_histopolation.py +14 -14
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_spline_interpolation.py +11 -11
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_splines.py +14 -14
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_splines_par.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_vector_spaces.py +6 -6
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/utilities.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/vector.py +2 -2
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/basic.py +14 -13
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/block.py +17 -13
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/direct_solvers.py +30 -11
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/fft.py +5 -5
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kron.py +36 -29
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/solvers.py +6 -6
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/stencil.py +151 -123
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_block.py +117 -117
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_fft.py +7 -7
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_kron_stencil_matrix.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_linalg.py +78 -78
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_matrix_free.py +14 -14
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_solvers.py +15 -15
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_stencil_interface_matrix.py +9 -8
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_stencil_vector.py +57 -57
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/test_stencil_vector_space.py +3 -3
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/topetsc.py +49 -49
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/utilities.py +11 -11
- {feectools-0.1.5 → feectools-0.1.6}/feectools/utilities/quadratures.py +11 -10
- {feectools-0.1.5 → feectools-0.1.6}/feectools/utilities/utils.py +14 -14
- {feectools-0.1.5 → feectools-0.1.6/feectools.egg-info}/PKG-INFO +2 -1
- {feectools-0.1.5 → feectools-0.1.6}/feectools.egg-info/requires.txt +1 -0
- {feectools-0.1.5 → feectools-0.1.6}/pyproject.toml +2 -1
- {feectools-0.1.5 → feectools-0.1.6}/AUTHORS +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/LICENSE +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/README.md +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/accelerate/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/accelerate/accelerate.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/accelerate/compile_psydac.mk +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/essential_bc.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/api/settings.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/field_evaluation_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/core/tests/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/basic.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/interface_data_exchanger.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/mpi.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/tests/test_partition.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/ddm/utilities.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/feec/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/feec/dof_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/basic.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/lst_preconditioner.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/analytical_profiles_base.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/splines_error_bounds.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_dirichlet_projectors.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/fem/tests/test_tensor.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/axpy_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/inner_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/matvec_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/stencil2IJV_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/stencil2coo_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/kernels/transpose_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/sparse.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/stencil_dot_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/stencil_transpose_kernels.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/linalg/tests/utilities.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/utilities/__init__.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools/version.py +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools.egg-info/SOURCES.txt +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools.egg-info/dependency_links.txt +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools.egg-info/entry_points.txt +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/feectools.egg-info/top_level.txt +0 -0
- {feectools-0.1.5 → feectools-0.1.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feectools
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies.
|
|
5
5
|
Author-email: Psydac development team <psydac@googlegroups.com>
|
|
6
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>
|
|
@@ -42,6 +42,7 @@ Requires-Dist: matplotlib
|
|
|
42
42
|
Requires-Dist: pyyaml>=5.1
|
|
43
43
|
Requires-Dist: packaging
|
|
44
44
|
Requires-Dist: pyevtk
|
|
45
|
+
Requires-Dist: cunumpy
|
|
45
46
|
Requires-Dist: pyccel>=2.1.0
|
|
46
47
|
Requires-Dist: h5py
|
|
47
48
|
Requires-Dist: tblib
|
|
@@ -2,7 +2,7 @@ import sys
|
|
|
2
2
|
import os
|
|
3
3
|
import importlib
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import cunumpy as xp
|
|
6
6
|
|
|
7
7
|
from sympy import ImmutableDenseMatrix, Matrix, Symbol, sympify
|
|
8
8
|
from sympy.tensor.indexed import Indexed, IndexedBase
|
|
@@ -465,8 +465,8 @@ class DiscreteBilinearForm:
|
|
|
465
465
|
|
|
466
466
|
expr = self.kernel_expr.expr
|
|
467
467
|
target = self.kernel_expr.target
|
|
468
|
-
test_degree =
|
|
469
|
-
trial_degree =
|
|
468
|
+
test_degree = xp.array(self.test_basis.space.degree)
|
|
469
|
+
trial_degree = xp.array(self.trial_basis.space.degree)
|
|
470
470
|
test_space = self.spaces[1].coeff_space
|
|
471
471
|
trial_space = self.spaces[0].coeff_space
|
|
472
472
|
test_fem_space = self.spaces[1]
|
|
@@ -476,20 +476,20 @@ class DiscreteBilinearForm:
|
|
|
476
476
|
is_conformal = True
|
|
477
477
|
|
|
478
478
|
if isinstance(expr, (ImmutableDenseMatrix, Matrix)):
|
|
479
|
-
if not isinstance(test_degree[0],(list, tuple,
|
|
479
|
+
if not isinstance(test_degree[0],(list, tuple, xp.ndarray)):
|
|
480
480
|
test_degree = [test_degree]
|
|
481
481
|
|
|
482
|
-
if not isinstance(trial_degree[0],(list, tuple,
|
|
482
|
+
if not isinstance(trial_degree[0],(list, tuple, xp.ndarray)):
|
|
483
483
|
trial_degree = [trial_degree]
|
|
484
484
|
|
|
485
|
-
pads =
|
|
485
|
+
pads = xp.empty((len(test_degree),len(trial_degree),len(test_degree[0])), dtype=int)
|
|
486
486
|
for i in range(len(test_degree)):
|
|
487
487
|
for j in range(len(trial_degree)):
|
|
488
488
|
td = test_degree[i]
|
|
489
489
|
trd = trial_degree[j]
|
|
490
|
-
pads[i,j][:] =
|
|
490
|
+
pads[i,j][:] = xp.array([td, trd]).max(axis=0)
|
|
491
491
|
else:
|
|
492
|
-
pads =
|
|
492
|
+
pads = xp.maximum(test_degree, trial_degree)
|
|
493
493
|
|
|
494
494
|
if self._matrix is None and (is_broken or isinstance(expr, (ImmutableDenseMatrix, Matrix))):
|
|
495
495
|
self._matrix = BlockLinearOperator(trial_space, test_space)
|
|
@@ -714,8 +714,8 @@ class DiscreteBilinearForm:
|
|
|
714
714
|
bs, d, s, p, mult = construct_test_space_arguments(basis_v)
|
|
715
715
|
basis += bs
|
|
716
716
|
spans += s
|
|
717
|
-
degrees += [
|
|
718
|
-
pads += [
|
|
717
|
+
degrees += [xp.int64(a) for a in d]
|
|
718
|
+
pads += [xp.int64(a) for a in p]
|
|
719
719
|
if v.space.is_multipatch or v.space.is_vector_valued:
|
|
720
720
|
coeffs += (e._data for e in v.coeffs)
|
|
721
721
|
else:
|
|
@@ -1382,12 +1382,12 @@ class DiscreteBilinearForm:
|
|
|
1382
1382
|
I_1 = f'int(floor(i_1/{test_mult[0]})*{trial_mult[0]})' if max(test_mult[0], trial_mult[0]) > 1 else 'i_1'
|
|
1383
1383
|
I_2 = f'int(floor(i_2/{test_mult[1]})*{trial_mult[1]})' if max(test_mult[1], trial_mult[1]) > 1 else 'i_2'
|
|
1384
1384
|
I_3 = f'int(floor(i_3/{test_mult[2]})*{trial_mult[2]})' if max(test_mult[2], trial_mult[2]) > 1 else 'i_3'
|
|
1385
|
-
#MAX_P1 = max(int( ( MAX_P1 +
|
|
1386
|
-
#MAX_P2 = max(int( ( MAX_P2 +
|
|
1387
|
-
#MAX_P3 = max(int( ( MAX_P3 +
|
|
1388
|
-
n_cols_x1 = max( int(MAX_P1 + 1 +
|
|
1389
|
-
n_cols_x2 = max( int(MAX_P2 + 1 +
|
|
1390
|
-
n_cols_x3 = max( int(MAX_P3 + 1 +
|
|
1385
|
+
#MAX_P1 = max(int( ( MAX_P1 + xp.floor(MAX_P1 / test_mult[0]) * trial_mult[0] ) / 2 ), MAX_P1) if max(test_mult[0], trial_mult[0]) > 1 else MAX_P1
|
|
1386
|
+
#MAX_P2 = max(int( ( MAX_P2 + xp.floor(MAX_P2 / test_mult[1]) * trial_mult[1] ) / 2 ), MAX_P2) if max(test_mult[1], trial_mult[1]) > 1 else MAX_P2
|
|
1387
|
+
#MAX_P3 = max(int( ( MAX_P3 + xp.floor(MAX_P3 / test_mult[2]) * trial_mult[2] ) / 2 ), MAX_P3) if max(test_mult[2], trial_mult[2]) > 1 else MAX_P3
|
|
1388
|
+
n_cols_x1 = max( int(MAX_P1 + 1 + xp.floor(MAX_P1 / test_mult[0]) * trial_mult[0]), 2*MAX_P1+1 )
|
|
1389
|
+
n_cols_x2 = max( int(MAX_P2 + 1 + xp.floor(MAX_P2 / test_mult[1]) * trial_mult[1]), 2*MAX_P2+1 )
|
|
1390
|
+
n_cols_x3 = max( int(MAX_P3 + 1 + xp.floor(MAX_P3 / test_mult[2]) * trial_mult[2]), 2*MAX_P3+1 )
|
|
1391
1391
|
MAX_P1 = n_cols_x1 - MAX_P1 - 1
|
|
1392
1392
|
MAX_P2 = n_cols_x2 - MAX_P2 - 1
|
|
1393
1393
|
MAX_P3 = n_cols_x3 - MAX_P3 - 1
|
|
@@ -2024,9 +2024,9 @@ class DiscreteBilinearForm:
|
|
|
2024
2024
|
|
|
2025
2025
|
# keys_2[(u[0], v[1])][3] = (1,2) means that the fourth sub-expression corresponding to the trial-test-function-component-product
|
|
2026
2026
|
# u[0] * v[1] involves a first derivative in x2 direction of the trial function and a second derivative in x2 direction of the test function
|
|
2027
|
-
keys_1[block] =
|
|
2028
|
-
keys_2[block] =
|
|
2029
|
-
keys_3[block] =
|
|
2027
|
+
keys_1[block] = xp.array([(alpha_1, beta_1) for alpha_1, beta_1 in zip(x1_trial_keys[block], x1_test_keys[block])])
|
|
2028
|
+
keys_2[block] = xp.array([(alpha_2, beta_2) for alpha_2, beta_2 in zip(x2_trial_keys[block], x2_test_keys[block])])
|
|
2029
|
+
keys_3[block] = xp.array([(alpha_3, beta_3) for alpha_3, beta_3 in zip(x3_trial_keys[block], x3_test_keys[block])])
|
|
2030
2030
|
|
|
2031
2031
|
# Those are the function values in each direction of a particular component of the trial/test function
|
|
2032
2032
|
global_basis_u_1, global_basis_u_2, global_basis_u_3 = global_basis_u[u_i]
|
|
@@ -2056,9 +2056,9 @@ class DiscreteBilinearForm:
|
|
|
2056
2056
|
# of non-zero product.
|
|
2057
2057
|
# Hence, we assign zeros for each element, each quadrature point on the element, each test and trial function combination,
|
|
2058
2058
|
# and each (or even more than required) appearing partial derivative combination of these functions - in each direction
|
|
2059
|
-
test_trial_1 =
|
|
2060
|
-
test_trial_2 =
|
|
2061
|
-
test_trial_3 =
|
|
2059
|
+
test_trial_1 = xp.zeros((n_element_1, k1, test_v_p1 + 1, trial_u_p1 + 1, max_block_trial_x1_derivative+1, max_block_test_x1_derivative+1), dtype='float64')
|
|
2060
|
+
test_trial_2 = xp.zeros((n_element_2, k2, test_v_p2 + 1, trial_u_p2 + 1, max_block_trial_x2_derivative+1, max_block_test_x2_derivative+1), dtype='float64')
|
|
2061
|
+
test_trial_3 = xp.zeros((n_element_3, k3, test_v_p3 + 1, trial_u_p3 + 1, max_block_trial_x3_derivative+1, max_block_test_x3_derivative+1), dtype='float64')
|
|
2062
2062
|
|
|
2063
2063
|
# And that's how we fill the test_trial arrays
|
|
2064
2064
|
if self._pyccelize_test_trial_computation and assembly_backend['name'] == 'pyccel':
|
|
@@ -2068,7 +2068,7 @@ class DiscreteBilinearForm:
|
|
|
2068
2068
|
[max_block_trial_x1_derivative, max_block_trial_x2_derivative, max_block_trial_x3_derivative], [max_block_test_x1_derivative, max_block_test_x2_derivative, max_block_test_x3_derivative],
|
|
2069
2069
|
[test_trial_1, test_trial_2, test_trial_3]):
|
|
2070
2070
|
|
|
2071
|
-
args = tuple(
|
|
2071
|
+
args = tuple(xp.int64(a) if isinstance(a, int) else a for a in args)
|
|
2072
2072
|
|
|
2073
2073
|
test_trial_func(*args)
|
|
2074
2074
|
else:
|
|
@@ -2118,13 +2118,13 @@ class DiscreteBilinearForm:
|
|
|
2118
2118
|
# to store local information correctly. 2*degree+1 in the simplest case.
|
|
2119
2119
|
n_funs_x2 = n_element_2 + test_v_p2 + (test_mult[1]-1)*(n_element_2-1)
|
|
2120
2120
|
n_funs_x3 = n_element_3 + test_v_p3 + (test_mult[2]-1)*(n_element_3-1)
|
|
2121
|
-
n_cols_x2 = max( int(max_p_2 + 1 +
|
|
2122
|
-
n_cols_x3 = max( int(max_p_3 + 1 +
|
|
2121
|
+
n_cols_x2 = max( int(max_p_2 + 1 + xp.floor(max_p_2 / test_mult[1]) * trial_mult[1]), 2*max_p_2+1 )
|
|
2122
|
+
n_cols_x3 = max( int(max_p_3 + 1 + xp.floor(max_p_3 / test_mult[2]) * trial_mult[2]), 2*max_p_3+1 )
|
|
2123
2123
|
|
|
2124
|
-
a3[block] =
|
|
2125
|
-
a2[block] =
|
|
2124
|
+
a3[block] = xp.zeros((n_expr, n_funs_x3, n_cols_x3), dtype='float64')
|
|
2125
|
+
a2[block] = xp.zeros((n_expr, n_funs_x2, n_funs_x3, n_cols_x2, n_cols_x3), dtype='float64')
|
|
2126
2126
|
|
|
2127
|
-
coupling_terms[block] =
|
|
2127
|
+
coupling_terms[block] = xp.zeros((n_element_2, k2, n_element_3, k3, n_expr), dtype='float64')
|
|
2128
2128
|
|
|
2129
2129
|
# We gather the socalled new args - all other args are being obtained in a similar way using the old assembly implementation
|
|
2130
2130
|
new_args = (*list(test_trial_1s.values()),
|
|
@@ -2158,8 +2158,8 @@ class DiscreteBilinearForm:
|
|
|
2158
2158
|
|
|
2159
2159
|
threads_args = ()
|
|
2160
2160
|
|
|
2161
|
-
args = tuple(
|
|
2162
|
-
threads_args = tuple(
|
|
2161
|
+
args = tuple(xp.int64(a) if isinstance(a, int) else a for a in args)
|
|
2162
|
+
threads_args = tuple(xp.int64(a) if isinstance(a, int) else a for a in threads_args)
|
|
2163
2163
|
|
|
2164
2164
|
#---------- We now generate the assembly file ----------
|
|
2165
2165
|
|
|
@@ -2,7 +2,7 @@ from typing import Iterable
|
|
|
2
2
|
|
|
3
3
|
from sympy import Expr, ImmutableDenseMatrix, Matrix
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import cunumpy as xp
|
|
6
6
|
|
|
7
7
|
from sympde.expr.basic import BasicForm
|
|
8
8
|
from sympde.expr.evaluation import KernelExpression
|
|
@@ -215,8 +215,8 @@ def collect_spaces(space, *args):
|
|
|
215
215
|
|
|
216
216
|
#==============================================================================
|
|
217
217
|
def compute_diag_len(p, md, mc):
|
|
218
|
-
n = ((
|
|
219
|
-
n = n-
|
|
218
|
+
n = ((xp.ceil((p+1)/mc)-1)*md).astype('int')
|
|
219
|
+
n = n-xp.minimum(0, n-p)+p+1
|
|
220
220
|
return n.astype('int')
|
|
221
221
|
|
|
222
222
|
#==============================================================================
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import cunumpy as xp
|
|
2
2
|
|
|
3
3
|
from sympde.expr.expr import (
|
|
4
4
|
BilinearForm as sym_BilinearForm,
|
|
@@ -119,5 +119,5 @@ class DiscreteSumForm(BasicDiscrete):
|
|
|
119
119
|
return self._operator
|
|
120
120
|
else:
|
|
121
121
|
M = [form.assemble(**kwargs) for form in self.forms]
|
|
122
|
-
M =
|
|
122
|
+
M = sum(M)
|
|
123
123
|
return M
|
|
@@ -15,7 +15,8 @@ References:
|
|
|
15
15
|
- [2] SELALIB, Semi-Lagrangian Library. http://selalib.gforge.inria.fr
|
|
16
16
|
|
|
17
17
|
"""
|
|
18
|
-
import
|
|
18
|
+
import cunumpy as xp
|
|
19
|
+
from cunumpy.xp import array_backend
|
|
19
20
|
|
|
20
21
|
from feectools.core.bsplines_kernels import (find_span_p,
|
|
21
22
|
find_spans_p,
|
|
@@ -82,7 +83,7 @@ def find_span(knots, degree, x):
|
|
|
82
83
|
Knot span index.
|
|
83
84
|
"""
|
|
84
85
|
x = float(x)
|
|
85
|
-
knots =
|
|
86
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
86
87
|
return find_span_p(knots, degree, x)
|
|
87
88
|
|
|
88
89
|
#==============================================================================
|
|
@@ -114,12 +115,12 @@ def find_spans(knots, degree, x, out=None):
|
|
|
114
115
|
spans : array of ints
|
|
115
116
|
Knots span indexes.
|
|
116
117
|
"""
|
|
117
|
-
knots =
|
|
118
|
-
x =
|
|
118
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
119
|
+
x = xp.ascontiguousarray(x, dtype=float)
|
|
119
120
|
if out is None:
|
|
120
|
-
out =
|
|
121
|
+
out = xp.zeros_like(x, dtype=int)
|
|
121
122
|
else:
|
|
122
|
-
assert out.shape == x.shape and out.dtype ==
|
|
123
|
+
assert out.shape == x.shape and out.dtype == xp.dtype('int')
|
|
123
124
|
|
|
124
125
|
find_spans_p(knots, degree, x, out)
|
|
125
126
|
return out
|
|
@@ -153,13 +154,13 @@ def basis_funs(knots, degree, x, span, out=None):
|
|
|
153
154
|
1D array containing the values of ``degree + 1`` non-zero
|
|
154
155
|
Bsplines at location ``x``.
|
|
155
156
|
"""
|
|
156
|
-
knots =
|
|
157
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
157
158
|
# Get native float
|
|
158
159
|
x = float(x)
|
|
159
160
|
if out is None:
|
|
160
|
-
out =
|
|
161
|
+
out = xp.zeros(degree + 1, dtype=float)
|
|
161
162
|
else:
|
|
162
|
-
assert out.shape == (degree + 1,) and out.dtype ==
|
|
163
|
+
assert out.shape == (degree + 1,) and out.dtype == xp.dtype('float')
|
|
163
164
|
basis_funs_p(knots, degree, x, span, out)
|
|
164
165
|
return out
|
|
165
166
|
|
|
@@ -191,12 +192,12 @@ def basis_funs_array(knots, degree, span, x, out=None):
|
|
|
191
192
|
2D array of shape ``(len(x), degree + 1)`` containing the values of ``degree + 1`` non-zero
|
|
192
193
|
Bsplines at each location in ``x``.
|
|
193
194
|
"""
|
|
194
|
-
knots =
|
|
195
|
-
x =
|
|
195
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
196
|
+
x = xp.ascontiguousarray(x, dtype=float)
|
|
196
197
|
if out is None:
|
|
197
|
-
out =
|
|
198
|
+
out = xp.zeros(x.shape + (degree + 1,), dtype=float)
|
|
198
199
|
else:
|
|
199
|
-
assert out.shape == x.shape + (degree + 1,) and out.dtype ==
|
|
200
|
+
assert out.shape == x.shape + (degree + 1,) and out.dtype == xp.dtype('float')
|
|
200
201
|
basis_funs_array_p(knots, degree, x, span, out)
|
|
201
202
|
return out
|
|
202
203
|
|
|
@@ -238,13 +239,13 @@ def basis_funs_1st_der(knots, degree, x, span, out=None):
|
|
|
238
239
|
----------
|
|
239
240
|
.. [2] SELALIB, Semi-Lagrangian Library. http://selalib.gforge.inria.fr
|
|
240
241
|
"""
|
|
241
|
-
knots =
|
|
242
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
242
243
|
# Get native float to work on windows
|
|
243
244
|
x = float(x)
|
|
244
245
|
if out is None:
|
|
245
|
-
out =
|
|
246
|
+
out = xp.zeros(degree + 1, dtype=float)
|
|
246
247
|
else:
|
|
247
|
-
assert out.shape == (degree + 1,) and out.dtype ==
|
|
248
|
+
assert out.shape == (degree + 1,) and out.dtype == xp.dtype('float')
|
|
248
249
|
|
|
249
250
|
basis_funs_1st_der_p(knots, degree, x, span, out)
|
|
250
251
|
return out
|
|
@@ -289,13 +290,13 @@ def basis_funs_all_ders(knots, degree, x, span, n, normalization='B', out=None):
|
|
|
289
290
|
ders[i,j] = (d/dx)^i B_k(x) with k=(span-degree+j),
|
|
290
291
|
for 0 <= i <= n and 0 <= j <= degree+1.
|
|
291
292
|
"""
|
|
292
|
-
knots =
|
|
293
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
293
294
|
# Get native float to work on windows
|
|
294
295
|
x = float(x)
|
|
295
296
|
if out is None:
|
|
296
|
-
out =
|
|
297
|
+
out = xp.zeros((n + 1, degree + 1), dtype=float)
|
|
297
298
|
else:
|
|
298
|
-
assert out.shape == (n + 1, degree + 1) and out.dtype ==
|
|
299
|
+
assert out.shape == (n + 1, degree + 1) and out.dtype == xp.dtype('float')
|
|
299
300
|
|
|
300
301
|
basis_funs_all_ders_p(knots, degree, x, span, n, normalization == 'M', out)
|
|
301
302
|
return out
|
|
@@ -342,18 +343,18 @@ def collocation_matrix(knots, degree, periodic, normalization, xgrid, out=None,
|
|
|
342
343
|
values of each B-spline basis function :math:`B_j` at all locations :math:`x_i`.
|
|
343
344
|
"""
|
|
344
345
|
if xgrid.size == 1:
|
|
345
|
-
return
|
|
346
|
+
return xp.ones((1, 1), dtype=float)
|
|
346
347
|
|
|
347
|
-
knots =
|
|
348
|
-
xgrid =
|
|
348
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
349
|
+
xgrid = xp.ascontiguousarray(xgrid, dtype=float)
|
|
349
350
|
if out is None:
|
|
350
351
|
nb = len(knots) - degree - 1
|
|
351
352
|
if periodic:
|
|
352
353
|
nb -= degree + 1 - multiplicity
|
|
353
354
|
|
|
354
|
-
out =
|
|
355
|
+
out = xp.zeros((int(xgrid.shape[0]), int(nb)), dtype=float)
|
|
355
356
|
else:
|
|
356
|
-
assert out.shape == ((xgrid.shape[0], nb)) and out.dtype ==
|
|
357
|
+
assert out.shape == ((int(xgrid.shape[0]), int(nb))) and out.dtype == xp.dtype('float')
|
|
357
358
|
|
|
358
359
|
bool_normalization = normalization == "M"
|
|
359
360
|
multiplicity = int(multiplicity)
|
|
@@ -407,11 +408,11 @@ def histopolation_matrix(knots, degree, periodic, normalization, xgrid, multipli
|
|
|
407
408
|
two successive grid points.
|
|
408
409
|
"""
|
|
409
410
|
# Check that knots are ordered (but allow repeated knots)
|
|
410
|
-
if not
|
|
411
|
+
if not xp.all(xp.diff(knots) >= 0):
|
|
411
412
|
raise ValueError("Cannot accept knot sequence: {}".format(knots))
|
|
412
413
|
|
|
413
414
|
# Check that spline degree is non-negative integer
|
|
414
|
-
if not isinstance(degree, (int,
|
|
415
|
+
if not isinstance(degree, (int, xp.integer)):
|
|
415
416
|
raise TypeError("Degree {} must be integer, got type {} instead".format(degree, type(degree)))
|
|
416
417
|
if degree < 0:
|
|
417
418
|
raise ValueError("Cannot accept negative degree: {}".format(degree))
|
|
@@ -425,26 +426,26 @@ def histopolation_matrix(knots, degree, periodic, normalization, xgrid, multipli
|
|
|
425
426
|
raise ValueError("Cannot accept 'normalization' parameter: {}".format(normalization))
|
|
426
427
|
|
|
427
428
|
# Check that grid points are ordered, and do not allow repetitions
|
|
428
|
-
if not
|
|
429
|
+
if not xp.all(xp.diff(xgrid) > 0):
|
|
429
430
|
raise ValueError("Grid points must be ordered, with no repetitions: {}".format(xgrid))
|
|
430
431
|
|
|
431
|
-
knots =
|
|
432
|
-
xgrid =
|
|
432
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
433
|
+
xgrid = xp.ascontiguousarray(xgrid, dtype=float)
|
|
433
434
|
elevated_knots = elevate_knots(knots, degree, periodic, multiplicity=multiplicity)
|
|
434
435
|
|
|
435
436
|
normalization = normalization == "M"
|
|
436
437
|
|
|
437
438
|
if out is None:
|
|
438
439
|
if periodic:
|
|
439
|
-
out =
|
|
440
|
+
out = xp.zeros((len(xgrid), len(knots) - 2 * int(degree) - 2 + int(multiplicity)), dtype=float)
|
|
440
441
|
else:
|
|
441
|
-
out =
|
|
442
|
+
out = xp.zeros((len(xgrid) - 1, len(elevated_knots) - (int(degree) + 1) - 1 - 1), dtype=float)
|
|
442
443
|
else:
|
|
443
444
|
if periodic:
|
|
444
445
|
assert out.shape == (len(xgrid), len(knots) - 2 * degree - 2 + multiplicity)
|
|
445
446
|
else:
|
|
446
447
|
assert out.shape == (len(xgrid) - 1, len(elevated_knots) - (degree + 1) - 1 - 1)
|
|
447
|
-
assert out.dtype ==
|
|
448
|
+
assert out.dtype == xp.dtype('float')
|
|
448
449
|
multiplicity = int(multiplicity)
|
|
449
450
|
histopolation_matrix_p(knots, degree, periodic, normalization, xgrid, check_boundary, elevated_knots, out, multiplicity = multiplicity)
|
|
450
451
|
return out
|
|
@@ -475,11 +476,11 @@ def breakpoints(knots, degree, tol=1e-15, out=None):
|
|
|
475
476
|
breaks : numpy.ndarray (1D)
|
|
476
477
|
Abscissas of all breakpoints.
|
|
477
478
|
"""
|
|
478
|
-
knots =
|
|
479
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
479
480
|
if out is None:
|
|
480
|
-
out =
|
|
481
|
+
out = xp.zeros(len(knots), dtype=float)
|
|
481
482
|
else:
|
|
482
|
-
assert out.shape == knots.shape and out.dtype ==
|
|
483
|
+
assert out.shape == knots.shape and out.dtype == xp.dtype('float')
|
|
483
484
|
i_final = breakpoints_p(knots, degree, out, tol)
|
|
484
485
|
return out[:i_final]
|
|
485
486
|
|
|
@@ -513,10 +514,10 @@ def greville(knots, degree, periodic, out=None, multiplicity=1):
|
|
|
513
514
|
Abscissas of all Greville points.
|
|
514
515
|
|
|
515
516
|
"""
|
|
516
|
-
knots =
|
|
517
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
517
518
|
if out is None:
|
|
518
519
|
n = len(knots) - 2 * degree - 2 + multiplicity if periodic else len(knots) - degree - 1
|
|
519
|
-
out =
|
|
520
|
+
out = xp.zeros(int(n))
|
|
520
521
|
multiplicity = int(multiplicity)
|
|
521
522
|
greville_p(knots, degree, periodic, out, multiplicity)
|
|
522
523
|
return out
|
|
@@ -546,11 +547,11 @@ def elements_spans(knots, degree, out=None):
|
|
|
546
547
|
|
|
547
548
|
Examples
|
|
548
549
|
--------
|
|
549
|
-
>>> import
|
|
550
|
+
>>> import cunumpy as xp
|
|
550
551
|
>>> from feectools.core.bsplines import make_knots, elements_spans
|
|
551
552
|
|
|
552
553
|
>>> p = 3 ; n = 8
|
|
553
|
-
>>> grid =
|
|
554
|
+
>>> grid = xp.arange( n-p+1 )
|
|
554
555
|
>>> knots = make_knots( breaks=grid, degree=p, periodic=False )
|
|
555
556
|
>>> spans = elements_spans( knots=knots, degree=p )
|
|
556
557
|
>>> spans
|
|
@@ -562,14 +563,14 @@ def elements_spans(knots, degree, out=None):
|
|
|
562
563
|
2) This function could be written in two lines:
|
|
563
564
|
|
|
564
565
|
breaks = breakpoints( knots, degree )
|
|
565
|
-
spans =
|
|
566
|
+
spans = xp.searchsorted( knots, breaks[:-1], side='right' ) - 1
|
|
566
567
|
|
|
567
568
|
"""
|
|
568
|
-
knots =
|
|
569
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
569
570
|
if out is None:
|
|
570
|
-
out =
|
|
571
|
+
out = xp.zeros(len(knots), dtype=xp.int64)
|
|
571
572
|
else:
|
|
572
|
-
assert out.shape == knots.shape and out.dtype ==
|
|
573
|
+
assert out.shape == knots.shape and out.dtype == xp.dtype('int64')
|
|
573
574
|
i_final = elements_spans_p(knots, degree, out)
|
|
574
575
|
return out[:i_final]
|
|
575
576
|
|
|
@@ -616,7 +617,7 @@ def make_knots(breaks, degree, periodic, multiplicity=1, out=None):
|
|
|
616
617
|
|
|
617
618
|
# Consistency checks
|
|
618
619
|
assert len(breaks) > 1
|
|
619
|
-
assert all(
|
|
620
|
+
assert all( xp.diff(breaks) > 0 )
|
|
620
621
|
assert degree >= 0
|
|
621
622
|
assert 1 <= multiplicity and multiplicity <= degree + 1
|
|
622
623
|
# Cast potential numpy.int64 into python native int
|
|
@@ -625,12 +626,12 @@ def make_knots(breaks, degree, periodic, multiplicity=1, out=None):
|
|
|
625
626
|
if periodic:
|
|
626
627
|
assert len(breaks) > degree
|
|
627
628
|
|
|
628
|
-
breaks =
|
|
629
|
+
breaks = xp.ascontiguousarray(breaks, dtype=float)
|
|
629
630
|
if out is None:
|
|
630
|
-
out =
|
|
631
|
+
out = xp.zeros(multiplicity * len(breaks[1:-1]) + 2 + 2 * degree)
|
|
631
632
|
else:
|
|
632
633
|
assert out.shape == (multiplicity * len(breaks[1:-1]) + 2 + 2 * degree,) \
|
|
633
|
-
and out.dtype ==
|
|
634
|
+
and out.dtype == xp.dtype('float')
|
|
634
635
|
make_knots_p(breaks, degree, periodic, out, multiplicity)
|
|
635
636
|
|
|
636
637
|
return out
|
|
@@ -675,25 +676,25 @@ def elevate_knots(knots, degree, periodic, multiplicity=1, tol=1e-15, out=None):
|
|
|
675
676
|
Knots sequence of spline space of degree p+1.
|
|
676
677
|
"""
|
|
677
678
|
multiplicity = int(multiplicity)
|
|
678
|
-
knots =
|
|
679
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
679
680
|
if out is None:
|
|
680
681
|
if periodic:
|
|
681
|
-
out =
|
|
682
|
+
out = xp.zeros(knots.shape[0] + 2, dtype=float)
|
|
682
683
|
else:
|
|
683
684
|
shape = 2*(degree + 2)
|
|
684
685
|
if len(knots) - 2 * (degree + 1) > 0:
|
|
685
|
-
uniques = (
|
|
686
|
+
uniques = (xp.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
|
|
686
687
|
shape += multiplicity * (1 + uniques[0].shape[0])
|
|
687
|
-
out =
|
|
688
|
+
out = xp.zeros(shape, dtype=float)
|
|
688
689
|
else:
|
|
689
690
|
if periodic:
|
|
690
|
-
assert out.shape == (knots.shape[0] + 2,) and out.dtype ==
|
|
691
|
+
assert out.shape == (knots.shape[0] + 2,) and out.dtype == xp.dtype('float')
|
|
691
692
|
else:
|
|
692
693
|
shape = 2*(degree + 2)
|
|
693
694
|
if len(knots) - 2 * (degree + 1) > 0:
|
|
694
|
-
uniques = (
|
|
695
|
+
uniques = (xp.diff(knots[degree + 1:-degree - 1]) > tol).nonzero()
|
|
695
696
|
shape += multiplicity * (1 + uniques[0].shape[0])
|
|
696
|
-
assert out.shape == shape and out.dtype ==
|
|
697
|
+
assert out.shape == shape and out.dtype == xp.dtype('float')
|
|
697
698
|
|
|
698
699
|
elevate_knots_p(knots, degree, periodic, out, multiplicity, tol)
|
|
699
700
|
return out
|
|
@@ -750,13 +751,18 @@ def quadrature_grid(breaks, quad_rule_x, quad_rule_w):
|
|
|
750
751
|
assert min(quad_rule_x) >= -1
|
|
751
752
|
assert max(quad_rule_x) <= +1
|
|
752
753
|
|
|
753
|
-
breaks =
|
|
754
|
+
breaks = xp.ascontiguousarray(breaks, dtype=float)
|
|
754
755
|
|
|
755
|
-
|
|
756
|
-
|
|
756
|
+
if array_backend.backend == "cupy":
|
|
757
|
+
quad_rule_x = xp.ascontiguousarray(xp.array(quad_rule_x), dtype=float)
|
|
758
|
+
quad_rule_w = xp.ascontiguousarray( xp.array(quad_rule_w), dtype=float )
|
|
759
|
+
else:
|
|
760
|
+
quad_rule_x = xp.ascontiguousarray(quad_rule_x, dtype=float)
|
|
761
|
+
quad_rule_w = xp.ascontiguousarray( quad_rule_w, dtype=float )
|
|
762
|
+
|
|
757
763
|
|
|
758
|
-
out1 =
|
|
759
|
-
out2 =
|
|
764
|
+
out1 = xp.zeros((len(breaks) - 1, len(quad_rule_x)))
|
|
765
|
+
out2 = xp.zeros_like(out1)
|
|
760
766
|
|
|
761
767
|
quadrature_grid_p(breaks, quad_rule_x, quad_rule_w, out1, out2)
|
|
762
768
|
|
|
@@ -805,10 +811,10 @@ def basis_ders_on_quad_grid(knots, degree, quad_grid, nders, normalization, offs
|
|
|
805
811
|
|
|
806
812
|
Examples
|
|
807
813
|
--------
|
|
808
|
-
>>> knots =
|
|
814
|
+
>>> knots = xp.array([0.0, 0.0, 0.25, 0.5, 0.75, 1., 1.])
|
|
809
815
|
>>> degree = 2
|
|
810
816
|
>>> bk = breakpoints(knots, degree)
|
|
811
|
-
>>> grid =
|
|
817
|
+
>>> grid = xp.array([xp.linspace(bk[i], bk[i+1], 4, endpoint=False) for i in range(len(bk) - 1)])
|
|
812
818
|
>>> basis_ders_on_quad_grid(knots, degree, grid, 0, "B")
|
|
813
819
|
array([[[[0.5, 0.28125, 0.125, 0.03125]],
|
|
814
820
|
[[0.5, 0.6875 , 0.75 , 0.6875 ]],
|
|
@@ -819,12 +825,12 @@ def basis_ders_on_quad_grid(knots, degree, quad_grid, nders, normalization, offs
|
|
|
819
825
|
"""
|
|
820
826
|
offset = int(offset)
|
|
821
827
|
ne, nq = quad_grid.shape
|
|
822
|
-
knots =
|
|
823
|
-
quad_grid =
|
|
828
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
829
|
+
quad_grid = xp.ascontiguousarray(quad_grid, dtype=float)
|
|
824
830
|
if out is None:
|
|
825
|
-
out =
|
|
831
|
+
out = xp.zeros((ne, degree + 1, nders + 1, nq), dtype=float)
|
|
826
832
|
else:
|
|
827
|
-
assert out.shape == (ne, degree + 1, nders + 1, nq) and out.dtype ==
|
|
833
|
+
assert out.shape == (ne, degree + 1, nders + 1, nq) and out.dtype == xp.dtype('float')
|
|
828
834
|
basis_ders_on_quad_grid_p(knots, degree, quad_grid, nders, normalization == 'M', offset, out)
|
|
829
835
|
return out
|
|
830
836
|
|
|
@@ -863,11 +869,11 @@ def basis_integrals(knots, degree, out=None):
|
|
|
863
869
|
to (len(knots)-degree-1). In the periodic case the last (degree) values in
|
|
864
870
|
the array are redundant, as they are a copy of the first (degree) values.
|
|
865
871
|
"""
|
|
866
|
-
knots =
|
|
872
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
867
873
|
if out is None:
|
|
868
|
-
out =
|
|
874
|
+
out = xp.zeros(len(knots) - degree - 1, dtype=float)
|
|
869
875
|
else:
|
|
870
|
-
assert out.shape is (len(knots) - degree - 1,) and out.dtype ==
|
|
876
|
+
assert out.shape is (len(knots) - degree - 1,) and out.dtype == xp.dtype('float')
|
|
871
877
|
basis_integrals_p(knots, degree, out)
|
|
872
878
|
return out
|
|
873
879
|
|
|
@@ -905,12 +911,12 @@ def cell_index(breaks, i_grid, tol=1e-15, out=None):
|
|
|
905
911
|
``cell_index[i]`` is the index of the cell in which
|
|
906
912
|
``i_grid[i]`` belong.
|
|
907
913
|
"""
|
|
908
|
-
breaks =
|
|
909
|
-
i_grid =
|
|
914
|
+
breaks = xp.ascontiguousarray(breaks, dtype=float)
|
|
915
|
+
i_grid = xp.ascontiguousarray(i_grid, dtype=float)
|
|
910
916
|
if out is None:
|
|
911
|
-
out =
|
|
917
|
+
out = xp.zeros_like(i_grid, dtype=xp.int64)
|
|
912
918
|
else:
|
|
913
|
-
assert out.shape == i_grid.shape and out.dtype ==
|
|
919
|
+
assert out.shape == i_grid.shape and out.dtype == xp.dtype('int64')
|
|
914
920
|
status = cell_index_p(breaks, i_grid, tol, out)
|
|
915
921
|
if status == -1:
|
|
916
922
|
raise ValueError("Encountered a point that was outside of the domain")
|
|
@@ -961,13 +967,13 @@ def basis_ders_on_irregular_grid(knots, degree, i_grid, cell_index, nders, norma
|
|
|
961
967
|
. il: local basis function (0 <= il <= degree)
|
|
962
968
|
. id: derivative (0 <= id <= nders )
|
|
963
969
|
"""
|
|
964
|
-
knots =
|
|
965
|
-
i_grid =
|
|
970
|
+
knots = xp.ascontiguousarray(knots, dtype=float)
|
|
971
|
+
i_grid = xp.ascontiguousarray(i_grid, dtype=float)
|
|
966
972
|
if out is None:
|
|
967
973
|
nx = i_grid.shape[0]
|
|
968
|
-
out =
|
|
974
|
+
out = xp.zeros((nx, degree + 1, nders + 1), dtype=float)
|
|
969
975
|
else:
|
|
970
|
-
assert out.shape == (nx, degree + 1, nders + 1) and out.dtype ==
|
|
976
|
+
assert out.shape == (nx, degree + 1, nders + 1) and out.dtype == xp.dtype('float')
|
|
971
977
|
basis_ders_on_irregular_grid_p(knots, degree, i_grid, cell_index, nders, normalization == 'M', out)
|
|
972
978
|
return out
|
|
973
979
|
|
|
@@ -994,7 +1000,7 @@ def _refinement_matrix_one_stage(t, p, knots):
|
|
|
994
1000
|
|
|
995
1001
|
Returns
|
|
996
1002
|
-------
|
|
997
|
-
mat :
|
|
1003
|
+
mat : xp.array[:,:]
|
|
998
1004
|
h-refinement matrix.
|
|
999
1005
|
|
|
1000
1006
|
new_knots : array_like
|
|
@@ -1017,7 +1023,7 @@ def _refinement_matrix_one_stage(t, p, knots):
|
|
|
1017
1023
|
|
|
1018
1024
|
n = len(knots) - p - 1
|
|
1019
1025
|
|
|
1020
|
-
mat =
|
|
1026
|
+
mat = xp.zeros((n+1,n))
|
|
1021
1027
|
|
|
1022
1028
|
left = find_span( knots, p, t )
|
|
1023
1029
|
|
|
@@ -1037,7 +1043,7 @@ def _refinement_matrix_one_stage(t, p, knots):
|
|
|
1037
1043
|
# ...
|
|
1038
1044
|
|
|
1039
1045
|
# ...
|
|
1040
|
-
new_knots =
|
|
1046
|
+
new_knots = xp.zeros(n+1+p+1)
|
|
1041
1047
|
|
|
1042
1048
|
new_knots[:left+1] = knots[:left+1]
|
|
1043
1049
|
new_knots[left+1] = t
|
|
@@ -1058,7 +1064,7 @@ def hrefinement_matrix(ts, p, knots):
|
|
|
1058
1064
|
|
|
1059
1065
|
Parameters
|
|
1060
1066
|
----------
|
|
1061
|
-
ts:
|
|
1067
|
+
ts: xp.array
|
|
1062
1068
|
array containing the knots to be inserted
|
|
1063
1069
|
|
|
1064
1070
|
p: int
|
|
@@ -1069,18 +1075,18 @@ def hrefinement_matrix(ts, p, knots):
|
|
|
1069
1075
|
|
|
1070
1076
|
Returns
|
|
1071
1077
|
-------
|
|
1072
|
-
mat :
|
|
1078
|
+
mat : xp.array[:,:]
|
|
1073
1079
|
h-refinement matrix
|
|
1074
1080
|
|
|
1075
1081
|
Examples
|
|
1076
1082
|
--------
|
|
1077
|
-
>>> import
|
|
1083
|
+
>>> import cunumpy as xp
|
|
1078
1084
|
>>> from feectools.core.bsplines import make_knots
|
|
1079
1085
|
>>> from feectools.core.bsplines import hrefinement_matrix
|
|
1080
|
-
>>> grid =
|
|
1086
|
+
>>> grid = xp.linspace(0.,1.,5)
|
|
1081
1087
|
>>> degree = 2
|
|
1082
1088
|
>>> knots = make_knots(grid, degree, periodic=False)
|
|
1083
|
-
>>> ts =
|
|
1089
|
+
>>> ts = xp.array([0.1, 0.2, 0.4, 0.5, 0.7, 0.8])
|
|
1084
1090
|
>>> hrefinement_matrix(ts, p, knots)
|
|
1085
1091
|
array([[1. , 0. , 0. , 0. , 0. , 0. ],
|
|
1086
1092
|
[0.6 , 0.4 , 0. , 0. , 0. , 0. ],
|
|
@@ -1098,11 +1104,11 @@ def hrefinement_matrix(ts, p, knots):
|
|
|
1098
1104
|
|
|
1099
1105
|
m = len(ts)
|
|
1100
1106
|
n = len(knots) - p - 1
|
|
1101
|
-
out =
|
|
1107
|
+
out = xp.eye(n)
|
|
1102
1108
|
|
|
1103
1109
|
for i in range(m):
|
|
1104
1110
|
t = ts[i]
|
|
1105
1111
|
mat, knots = _refinement_matrix_one_stage(t, p, knots)
|
|
1106
|
-
out =
|
|
1112
|
+
out = xp.matmul(mat, out)
|
|
1107
1113
|
|
|
1108
1114
|
return out
|