From b9bf209dff4ade8448cd196bf4d7da275ac69d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaman=20G=C3=BC=C3=A7l=C3=BC?= Date: Fri, 1 Mar 2024 12:05:19 +0100 Subject: [PATCH] Avoid runtime warnings (#355) Avoid runtime warnings from third-party libraries: - Use Numpy `prod()` instead of deprecated `product()` - Do not put non-`Expr` objects inside SymPy `Matrix` -- this is obtained by using 3D `MutableDenseNDimArray` objects containing scalars, instead of 2D `Matrix` objects containing tuples --- psydac/api/ast/nodes.py | 112 ++++++++++++++++++++++--------------- psydac/api/ast/parser.py | 59 ++++++++++--------- psydac/api/utilities.py | 16 +++++- psydac/ddm/cart.py | 9 ++- psydac/ddm/partition.py | 13 +++-- psydac/ddm/petsc.py | 2 +- psydac/linalg/kron.py | 10 ++-- psydac/linalg/stencil.py | 2 +- psydac/linalg/utilities.py | 14 ++--- 9 files changed, 138 insertions(+), 99 deletions(-) diff --git a/psydac/api/ast/nodes.py b/psydac/api/ast/nodes.py index 4512bb03d..c33b72280 100644 --- a/psydac/api/ast/nodes.py +++ b/psydac/api/ast/nodes.py @@ -6,9 +6,11 @@ from sympy import Basic, Expr from sympy import AtomicExpr, S from sympy import Function -from sympy import Mul,Integer -from sympy.core.singleton import Singleton -from sympy.core.containers import Tuple +from sympy import Mul, Integer +from sympy.core.singleton import Singleton +from sympy.core.containers import Tuple +from sympy.utilities.iterables import iterable as is_iterable + from sympde.old_sympy_utilities import with_metaclass from sympde.topology import element_of @@ -1145,13 +1147,14 @@ class StencilMatrixLocalBasis(MatrixNode): """ def __new__(cls, u, v, pads, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) - rank = 2*len(pads) - tag = tag or random_string( 6 ) + rank = 2 * len(pads) name = (u, v) + tag = tag or random_string(6) + return Basic.__new__(cls, pads, rank, name, tag, dtype) @property @@ -1180,13 +1183,15 @@ class StencilMatrixGlobalBasis(MatrixNode): used to describe local dof over an element as a stencil matrix """ def __new__(cls, u, v, pads, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) - rank = 2*len(pads) - tag = tag or random_string( 6 ) + rank = 2 * len(pads) name = (u, v) + tag = tag or random_string(6) + return Basic.__new__(cls, pads, rank, name, tag, dtype) @property @@ -1215,13 +1220,15 @@ class StencilVectorLocalBasis(MatrixNode): used to describe local dof over an element as a stencil vector """ def __new__(cls, v, pads, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) rank = len(pads) - tag = tag or random_string( 6 ) name = v + tag = tag or random_string(6) + return Basic.__new__(cls, pads, rank, name, tag, dtype) @property @@ -1250,13 +1257,15 @@ class StencilVectorGlobalBasis(MatrixNode): used to describe local dof over an element as a stencil vector """ def __new__(cls, v, pads, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) rank = len(pads) - tag = tag or random_string( 6 ) name = v + tag = tag or random_string(6) + return Basic.__new__(cls, pads, rank, name, tag, dtype) @property @@ -1299,9 +1308,10 @@ def __new__(cls, trials, tests, expr, dim, tag=None, outer=None, pads = Pads(tests, trials, tests_degree, trials_degree, tests_multiplicity, trials_multiplicity) - rank = 2*dim - tag = tag or random_string( 6 ) - obj = Basic.__new__(cls, pads, rank, trials_multiplicity, tag, expr, dtype) + rank = 2 * dim + tag = tag or random_string(6) + + obj = Basic.__new__(cls, pads, rank, trials_multiplicity, tag, expr, dtype) obj._trials = trials obj._tests = tests obj._outer = outer @@ -1350,13 +1360,15 @@ class BlockStencilMatrixGlobalBasis(BlockLinearOperatorNode): used to describe local dof over an element as a block stencil matrix """ def __new__(cls, trials, tests, pads, multiplicity, expr, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) - rank = 2*len(pads) - tag = tag or random_string( 6 ) - obj = Basic.__new__(cls, pads, multiplicity, rank, tag, expr, dtype) + rank = 2 * len(pads) + tag = tag or random_string(6) + + obj = Basic.__new__(cls, pads, multiplicity, rank, tag, expr, dtype) obj._trials = trials obj._tests = tests return obj @@ -1400,14 +1412,16 @@ class BlockStencilVectorLocalBasis(BlockLinearOperatorNode): used to describe local dof over an element as a block stencil matrix """ def __new__(cls,tests, pads, expr, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) rank = len(pads) - tag = tag or random_string( 6 ) - obj = Basic.__new__(cls, pads, rank, tag, expr, dtype) - obj._tests = tests + tag = tag or random_string(6) + + obj = Basic.__new__(cls, pads, rank, tag, expr, dtype) + obj._tests = tests return obj @property @@ -1445,14 +1459,16 @@ class BlockStencilVectorGlobalBasis(BlockLinearOperatorNode): used to describe local dof over an element as a block stencil matrix """ def __new__(cls, tests, pads, multiplicity, expr, tag=None, dtype='real'): - if not isinstance(pads, (list, tuple, Tuple)): + + if not is_iterable(pads): raise TypeError('Expecting an iterable') pads = Tuple(*pads) rank = len(pads) - tag = tag or random_string( 6 ) - obj = Basic.__new__(cls, pads, multiplicity, rank, tag, expr, dtype) - obj._tests = tests + tag = tag or random_string(6) + + obj = Basic.__new__(cls, pads, multiplicity, rank, tag, expr, dtype) + obj._tests = tests return obj @property @@ -1494,8 +1510,10 @@ class ScalarLocalBasis(ScalarNode): This is used to describe scalar dof over an element """ def __new__(cls, u=None, v=None, tag=None, dtype='real'): - tag = tag or random_string( 6 ) - obj = Basic.__new__(cls, tag, dtype) + + tag = tag or random_string(6) + + obj = Basic.__new__(cls, tag, dtype) obj._test = v obj._trial = u return obj @@ -1515,6 +1533,7 @@ def trial(self): @property def test(self): return self._test + #============================================================================== class BlockScalarLocalBasis(ScalarNode): """ @@ -1522,7 +1541,8 @@ class BlockScalarLocalBasis(ScalarNode): """ def __new__(cls, trials=None, tests=None, expr=None, tag=None, dtype='real'): - tag = tag or random_string( 6 ) + tag = tag or random_string(6) + obj = Basic.__new__(cls, tag, dtype) obj._tests = tests obj._trials = trials @@ -1587,12 +1607,14 @@ class LocalSpanArray(SpanArray): """ _rank = 1 _positions = {index_element: 0} + #============================================================================== class GlobalThreadSpanArray(SpanArray): """ This represents the global span array of each thread """ _rank = 1 + #============================================================================== class GlobalThreadStarts(ArrayNode): """ @@ -2111,22 +2133,19 @@ def __new__(cls, iterable, index, *, stmts=None, mask=None, private=None, firstprivate=None, lastprivate=None, reduction=None): # ... - if not( isinstance(iterable, (list, tuple, Tuple)) ): + if not is_iterable(iterable): iterable = [iterable] - - iterable = Tuple(*iterable) # ... # ... replace GeometryExpressions by a list of expressions others = [i for i in iterable if not isinstance(i, GeometryExpressions)] geos = [i.expressions for i in iterable if isinstance(i, GeometryExpressions)] - iterable = others + flatten(geos) - iterable = Tuple(*iterable) + iterable = Tuple(*others, *flatten(geos)) # ... # ... - if not( isinstance(index, IndexNode) ): + if not isinstance(index, IndexNode): raise TypeError('Expecting an index node') # ... @@ -2135,7 +2154,7 @@ def __new__(cls, iterable, index, *, stmts=None, mask=None, iterator = [] generator = [] for a in iterable: - i,g = construct_itergener(a, index) + i, g = construct_itergener(a, index) iterator.append(i) generator.append(g) # ... @@ -2147,8 +2166,7 @@ def __new__(cls, iterable, index, *, stmts=None, mask=None, # ... if stmts is None: stmts = [] - - elif not isinstance(stmts, (tuple, list, Tuple)): + elif not is_iterable(stmts): stmts = [stmts] stmts = Tuple(*stmts) @@ -2263,10 +2281,10 @@ class ProductIteration(BaseNode): def __new__(cls, iterator, generator): # ... - if not( isinstance(iterator, ProductIterator) ): + if not isinstance(iterator, ProductIterator): raise TypeError('Expecting an ProductIterator') - if not( isinstance(generator, ProductGenerator) ): + if not isinstance(generator, ProductGenerator): raise TypeError('Expecting a ProductGenerator') # ... @@ -2285,11 +2303,12 @@ class SplitArray(BaseNode): """ """ def __new__(cls, target, positions, lengths): - if not isinstance(positions, (list, tuple, Tuple)): + + if not is_iterable(positions): positions = [positions] positions = Tuple(*positions) - if not isinstance(lengths, (list, tuple, Tuple)): + if not is_iterable(lengths): lengths = [lengths] lengths = Tuple(*lengths) @@ -2391,10 +2410,11 @@ class Block(Basic): """ def __new__(cls, body): - if not isinstance(body, (list, tuple, Tuple)): - body = [body] + if not is_iterable(body): + body = [body] body = Tuple(*body) + return Basic.__new__(cls, body) @property diff --git a/psydac/api/ast/parser.py b/psydac/api/ast/parser.py index eeeb2fafe..eb8ac0a79 100644 --- a/psydac/api/ast/parser.py +++ b/psydac/api/ast/parser.py @@ -9,17 +9,10 @@ from sympy import Abs, Not, floor from sympy import Symbol, Idx from sympy import Basic, Function +from sympy import MutableDenseNDimArray as MArray from sympy.simplify import cse_main from sympy.core.containers import Tuple - -from psydac.pyccel.ast.core import Assign, Product, AugAssign, For -from psydac.pyccel.ast.core import Variable, IndexedVariable, IndexedElement -from psydac.pyccel.ast.core import Slice, String, ValuedArgument -from psydac.pyccel.ast.core import EmptyNode, Import, While, Return, If -from psydac.pyccel.ast.core import CodeBlock, FunctionDef, Comment -from psydac.pyccel.ast.builtins import Range - from sympde.topology import (dx1, dx2, dx3) from sympde.topology import SymbolicExpr from sympde.topology import LogicalExpr, Jacobian @@ -30,6 +23,18 @@ from sympde.topology.derivatives import get_index_logical_derivatives +from psydac.pyccel.ast.core import Assign, Product, AugAssign, For +from psydac.pyccel.ast.core import Variable, IndexedVariable, IndexedElement +from psydac.pyccel.ast.core import Slice, String, ValuedArgument +from psydac.pyccel.ast.core import EmptyNode, Import, While, Return, If +from psydac.pyccel.ast.core import CodeBlock, FunctionDef, Comment +from psydac.pyccel.ast.builtins import Range + +from psydac.api.utilities import flatten +from psydac.api.ast.utilities import variables, math_atoms_as_str, get_name +from psydac.api.ast.utilities import build_pythran_types_header +from psydac.api.ast.utilities import build_pyccel_type_annotations + from .nodes import AtomicNode from .nodes import BasisAtom from .nodes import PhysicalBasisValue @@ -73,10 +78,6 @@ from .nodes import Zeros, ZerosLike, Array from .fem import expand, expand_hdiv_hcurl -from psydac.api.ast.utilities import variables, math_atoms_as_str, get_name -from psydac.api.utilities import flatten -from psydac.api.ast.utilities import build_pythran_types_header -from psydac.api.ast.utilities import build_pyccel_type_annotations #============================================================================== # TODO move it @@ -922,6 +923,7 @@ def _visit_Span(self, expr, **kwargs): target = {target: tuple(zip(*targets))} return target + # .................................................... def _visit_Pads(self, expr, **kwargs): dim = self.dim tests = expand(expr.tests) @@ -932,33 +934,37 @@ def _visit_Pads(self, expr, **kwargs): if expr.trials is not None: trials = expand(expr.trials) - pads = Matrix.zeros(len(tests),len(trials)) + pads = MArray.zeros(len(tests), len(trials), dim) for i in range(pads.shape[0]): for j in range(pads.shape[1]): label1 = SymbolicExpr(tests[i]).name label2 = SymbolicExpr(trials[j]).name - names = 'pad_{}_{}_1:{}'.format(label2, label1, str(dim+1)) + names = f'pad_{label2}_{label1}_1:{dim+1}' targets = variables(names, dtype='int') - pads[i,j] = Tuple(*targets) + pads[i, j, :] = targets self.insert_variables(*targets) if expr.test_index is not None and expr.trial_index is not None: - if expr.dim_index is not None:return pads[expr.test_index,expr.trial_index][expr.dim_index] - return pads[expr.test_index,expr.trial_index] + if expr.dim_index is not None: + return pads[expr.test_index, expr.trial_index, expr.dim_index] + return pads[expr.test_index, expr.trial_index] else: - pads = Matrix.zeros(len(tests),1) + pads = MArray.zeros(len(tests), 1, dim) for i in range(pads.shape[0]): - label1 = SymbolicExpr(tests[i]).name - names = 'pad_{}_1:{}'.format(label1, str(dim+1)) - targets = variables(names, dtype='int') - pads[i,0] = Tuple(*targets) + label1 = SymbolicExpr(tests[i]).name + names = f'pad_{label1}_1:{dim+1}' + targets = variables(names, dtype='int') + pads[i, 0, :] = targets self.insert_variables(*targets) if expr.test_index is not None: - if expr.dim_index is not None:return pads[expr.test_index,0][expr.dim_index] - return pads[expr.test_index,0] + if expr.dim_index is not None: + return pads[expr.test_index, 0, expr.dim_index] + return pads[expr.test_index, 0] + #... return pads + # .................................................... def _visit_TensorBasis(self, expr, **kwargs): # TODO label @@ -997,6 +1003,7 @@ def _visit_MatrixCoordsFromRank(self, expr, **kwargs): def _visit_MatrixRankFromCoords(self, expr, **kwargs): var = IndexedVariable('rank_from_coords', dtype='int', rank=self.dim) return var + # .................................................... def _visit_MatrixLocalBasis(self, expr, **kwargs): rank = self._visit(expr.rank) @@ -1006,8 +1013,8 @@ def _visit_MatrixLocalBasis(self, expr, **kwargs): var = IndexedVariable(name, dtype=dtype, rank=rank) self.insert_variables(var) return var - # .................................................... + # .................................................... def _visit_MatrixGlobalBasis(self, expr, **kwargs): rank = self._visit(expr.rank) target = SymbolicExpr(expr.target) @@ -1016,6 +1023,7 @@ def _visit_MatrixGlobalBasis(self, expr, **kwargs): var = IndexedVariable(name, dtype=dtype, rank=rank) self.insert_variables(var) return var + # .................................................... def _visit_Reset(self, expr, **kwargs): var = expr.var @@ -1155,6 +1163,7 @@ def _visit_Reduction(self, expr, **kwargs): lhs = self._visit(lhs) return self._visit(expr, op=op, lhs=lhs) + # .................................................... def _visit_ComputeLogical(self, expr, op=None, lhs=None, **kwargs): expr = expr.expr diff --git a/psydac/api/utilities.py b/psydac/api/utilities.py index 1afd5797d..c8080876b 100644 --- a/psydac/api/utilities.py +++ b/psydac/api/utilities.py @@ -1,7 +1,7 @@ # coding: utf-8 from sympy.core.containers import Tuple -from sympy import Matrix, ImmutableDenseMatrix +from sympy import Matrix, ImmutableDenseMatrix, MutableDenseNDimArray import inspect import sys @@ -13,11 +13,21 @@ #============================================================================== def flatten(args): + + types_to_flatten = ( + list, + tuple, + Tuple, + Matrix, + ImmutableDenseMatrix, + MutableDenseNDimArray, + ) + ls = [] def rec_flatten(args, ls): - if isinstance(args, (list, tuple, Tuple, Matrix, ImmutableDenseMatrix)): + if isinstance(args, types_to_flatten): for i in tuple(args): - rec_flatten(i,ls) + rec_flatten(i, ls) else: ls.append(args) rec_flatten(args, ls) diff --git a/psydac/ddm/cart.py b/psydac/ddm/cart.py index 0b3c7f699..13c94ac37 100644 --- a/psydac/ddm/cart.py +++ b/psydac/ddm/cart.py @@ -1,7 +1,6 @@ # coding: utf-8 import os -import itertools import numpy as np from itertools import product from mpi4py import MPI @@ -1530,10 +1529,10 @@ def _compute_interface_communication_infos( self, axis ): starts[axis] = starts[axis] if ext_plus == -1 else ends[axis]-pads_plus[axis]+diff ends[axis] = starts[axis]+pads_plus[axis]-diff if ext_plus == -1 else ends[axis] shape_k = [e-s+1 for s,e in zip(starts, ends)] - recv_counts[k] = np.product(shape_k) + recv_counts[k] = np.prod(shape_k) ranges = [(s+p*m, p*m+e+1) for s,e,p,m in zip(starts, ends, pads_plus, shifts_plus)] ranges[axis] = (shifts_plus[axis]*pads_plus[axis], shifts_plus[axis]*pads_plus[axis]+shape_k[axis]) - indices += [np.ravel_multi_index( ii, dims=recv_shape, order='C' ) for ii in itertools.product(*[range(*a) for a in ranges])] + indices += [np.ravel_multi_index( ii, dims=recv_shape, order='C' ) for ii in product(*[range(*a) for a in ranges])] elif self._local_rank_plus is not None: rank_plus = self._local_rank_plus @@ -1565,10 +1564,10 @@ def _compute_interface_communication_infos( self, axis ): starts[axis] = starts[axis] if ext_minus == -1 else ends[axis]-pads_minus[axis]+diff ends[axis] = starts[axis]+pads_minus[axis]-diff if ext_minus == -1 else ends[axis] shape_k = [e-s+1 for s,e in zip(starts, ends)] - recv_counts[k] = np.product(shape_k) + recv_counts[k] = np.prod(shape_k) ranges = [(s+p*m, p*m+e+1) for s,e,p,m in zip(starts, ends, pads_minus, shifts_minus)] ranges[axis] = (shifts_minus[axis]*pads_minus[axis], shifts_minus[axis]*pads_minus[axis]+shape_k[axis]) - indices += [np.ravel_multi_index( ii, dims=recv_shape, order='C' ) for ii in itertools.product(*[range(*a) for a in ranges])] + indices += [np.ravel_multi_index( ii, dims=recv_shape, order='C' ) for ii in product(*[range(*a) for a in ranges])] displacements[1:] = np.cumsum(recv_counts) # Store all information into dictionary diff --git a/psydac/ddm/partition.py b/psydac/ddm/partition.py index fa9fac82f..fb8519430 100644 --- a/psydac/ddm/partition.py +++ b/psydac/ddm/partition.py @@ -30,12 +30,12 @@ def partition_procs_per_patch(npts, size): such that k1<=k2. """ - npts = [np.product(nc) for nc in npts] - percentage = [nc/sum(npts) for nc in npts] + npts = [np.prod(nc) for nc in npts] + percentage = [nc / sum(npts) for nc in npts] sizes = np.array([int(p*size) for p in percentage]) - diff = [p*size-s for s,p in zip(sizes, percentage)] + diff = [p * size - s for s, p in zip(sizes, percentage)] indices = np.argsort(diff)[::-1] - rm = size-sum(sizes) + rm = size - sum(sizes) sizes[indices[:rm]] +=1 assert sum(sizes) == size @@ -58,10 +58,11 @@ def partition_procs_per_patch(npts, size): k = 0 for i,s in enumerate(sizes): - if s>0:continue + if s > 0: + continue sizes[i] = 1 ranges[i] = [ranks[k], ranks[k]] - k = (k+1)%size + k = (k+1) % size return sizes, ranges diff --git a/psydac/ddm/petsc.py b/psydac/ddm/petsc.py index 2262ee1d6..88a3b8abe 100644 --- a/psydac/ddm/petsc.py +++ b/psydac/ddm/petsc.py @@ -28,7 +28,7 @@ def __init__(self, cart): self._local_shape = tuple( e-s+1 for s,e in zip( cart._starts, cart._ends ) ) # Compute local size of local arrays in topology (without ghost regions) - self._local_size = np.product(self._local_shape) + self._local_size = np.prod(self._local_shape) @property diff --git a/psydac/linalg/kron.py b/psydac/linalg/kron.py index 2e2f8bb10..d68293c0c 100644 --- a/psydac/linalg/kron.py +++ b/psydac/linalg/kron.py @@ -107,7 +107,7 @@ def dot(self, x, out=None): for jj in np.ndindex(*pnrows): i_mats = [mat._data[s, j] for s,j,mat in zip(xx, jj, mats)] ii_jj = tuple(i+j for i,j in zip(ii, jj)) - v += x._data[ii_jj]*np.product(i_mats) + v += x._data[ii_jj] * np.prod(i_mats) out._data[xx] = v @@ -145,7 +145,7 @@ def __getitem__(self, key): cols = key[self.ndim:] mats = self.mats elements = [A[i,j] for A,i,j in zip(mats, rows, cols)] - return np.product(elements) + return np.prod(elements) def tostencil(self): @@ -183,7 +183,7 @@ def _tostencil(M, mats, nrows, nrows_extra, pads, xpads): for kk in np.ndindex( *ndiags ): values = [mat[i,k] for mat,i,k in zip(mats, ii, kk)] - M[(*ii, *kk)] = np.product(values) + M[(*ii, *kk)] = np.prod(values) # handle partly-multiplied rows new_nrows = nrows.copy() @@ -206,7 +206,7 @@ def _tostencil(M, mats, nrows, nrows_extra, pads, xpads): for kk in np.ndindex( *ndiags ): values = [mat[i,k] for mat,i,k in zip(mats, ii, kk)] - M[(*ii, *kk)] = np.product(values) + M[(*ii, *kk)] = np.prod(values) new_nrows[d] += er def tosparse(self): @@ -442,7 +442,7 @@ def _setup_solvers(self): # local and global sizes nglobals = self._domain.npts nlocals = ends - starts - self._localsize = np.product(nlocals) + self._localsize = np.prod(nlocals) mglobals = self._localsize // nlocals self._nlocals = nlocals diff --git a/psydac/linalg/stencil.py b/psydac/linalg/stencil.py index 2c8c6fa96..0c818af26 100644 --- a/psydac/linalg/stencil.py +++ b/psydac/linalg/stencil.py @@ -1869,7 +1869,7 @@ def _get_diagonal_indices(self): nrows = [e - s + 1 for s, e in zip(self.codomain.starts, self.codomain.ends)] ndim = self.domain.ndim - indices = [np.zeros(np.product(nrows), dtype=int) for _ in range(2 * ndim)] + indices = [np.zeros(np.prod(nrows), dtype=int) for _ in range(2 * ndim)] for l, xx in enumerate(np.ndindex(*nrows)): ii = [m * p + x for m, p, x in zip(dm, dp, xx)] diff --git a/psydac/linalg/utilities.py b/psydac/linalg/utilities.py index 515cef8c9..1f727075b 100644 --- a/psydac/linalg/utilities.py +++ b/psydac/linalg/utilities.py @@ -26,8 +26,8 @@ def array_to_psydac(x, Xh): for i in range(len(starts)): g = tuple(slice(s,e+1) for s,e in zip(starts[i], ends[i])) shape = tuple(ends[i]-starts[i]+1) - u[d][i][g] = x[:np.product(shape)].reshape(shape) - x = x[np.product(shape):] + u[d][i][g] = x[:np.prod(shape) ].reshape(shape) + x = x[ np.prod(shape):] else: starts = [np.array(V.starts) for V in Xh.spaces] @@ -36,8 +36,8 @@ def array_to_psydac(x, Xh): for i in range(len(starts)): g = tuple(slice(s,e+1) for s,e in zip(starts[i], ends[i])) shape = tuple(ends[i]-starts[i]+1) - u[i][g] = x[:np.product(shape)].reshape(shape) - x = x[np.product(shape):] + u[i][g] = x[:np.prod(shape) ].reshape(shape) + x = x[ np.prod(shape):] elif isinstance(Xh, StencilVectorSpace): @@ -46,7 +46,7 @@ def array_to_psydac(x, Xh): ends = np.array(Xh.ends) g = tuple(slice(s, e+1) for s,e in zip(starts, ends)) shape = tuple(ends-starts+1) - u[g] = x[:np.product(shape)].reshape(shape) + u[g] = x[:np.prod(shape)].reshape(shape) else: raise ValueError('Xh must be a StencilVectorSpace or a BlockVectorSpace') @@ -85,7 +85,7 @@ def petsc_to_psydac(vec, Xh): indices = np.array([np.ravel_multi_index( [s+x for s,x in zip(starts[i], xx)], dims=npts, order='C' ) for xx in np.ndindex(*shape)] ) vals = recvbuf[indices+inds] u[d][i]._data[idx] = vals.reshape(shape) - inds += np.product(npts) + inds += np.prod(npts) else: comm = u[0].space.cart.global_comm @@ -107,7 +107,7 @@ def petsc_to_psydac(vec, Xh): indices = np.array([np.ravel_multi_index( [s+x for s,x in zip(starts[i], xx)], dims=npts, order='C' ) for xx in np.ndindex(*shape)] ) vals = recvbuf[indices+inds] u[i]._data[idx] = vals.reshape(shape) - inds += np.product(npts) + inds += np.prod(npts) elif isinstance(Xh, StencilVectorSpace):