pymor.vectorarrays.mpi

Wrapper classes for building MPI distributed VectorArrays.

This module contains several wrapper classes which allow to transform single rank VectorArrays into MPI distributed VectorArrays which can be used on rank 0 like ordinary VectorArrays.

The implementations are based on the event loop provided by pymor.tools.mpi.

Module Contents

Classes

MPIVectorArray

MPI distributed VectorArray.

MPIVectorSpace

VectorSpace of MPIVectorArrays.

RegisteredLocalSpace

int([x]) -> integer

MPIVectorArrayNoComm

MPI distributed VectorArray.

MPIVectorSpaceNoComm

VectorSpace for MPIVectorArrayNoComm.

MPIVectorArrayAutoComm

MPI distributed VectorArray.

MPIVectorSpaceAutoComm

VectorSpace for MPIVectorArrayAutoComm.

Functions

_register_local_space

_get_local_space

_MPIVectorSpace_zeros

_MPIVectorSpace_dim

_MPIVectorSpace_check_local_spaces

_MPIVectorArray_axpy

_MPIVectorArray_real

_MPIVectorArray_imag

_MPIVectorSpaceAutoComm_dim

_MPIVectorArrayAutoComm_inner

_MPIVectorArrayAutoComm_pairwise_inner

_MPIVectorArrayAutoComm_norm

_MPIVectorArrayAutoComm_norm2

_MPIVectorArrayAutoComm_dofs

_MPIVectorArrayAutoComm_amax

Attributes

_local_space_registry

_local_space_to_id

class pymor.vectorarrays.mpi.MPIVectorArray(obj_id, space)[source]

Bases: pymor.vectorarrays.interface.VectorArray

MPI distributed VectorArray.

Given a local VectorArray on each MPI rank, this wrapper class uses the event loop from pymor.tools.mpi to build a global MPI distributed vector array from these local arrays.

Instances of MPIVectorArray can be used on rank 0 like any other (non-distributed) VectorArray.

Note, however, that the implementation of the local VectorArrays needs to be MPI aware. For instance, cls.inner must perform the needed MPI communication to sum up the local inner products and return the sums on rank 0.

Default implementations for all communication requiring interface methods are provided by MPIVectorArrayAutoComm (also see MPIVectorArrayNoComm).

Note that resource cleanup is handled by object.__del__. Please be aware of the peculiarities of destructors in Python!

The associated VectorSpace is MPIVectorSpace.

__len__(self)[source]

The number of vectors in the array.

__getitem__(self, ind)[source]

Return a VectorArray view onto a subset of the vectors in the array.

__delitem__(self, ind)[source]

Remove vectors from the array.

copy(self, deep=False)[source]

Returns a copy of the array.

All VectorArray implementations in pyMOR have copy-on-write semantics: if not specified otherwise by setting deep to True, the returned copy will hold a handle to the same array data as the original array, and a deep copy of the data will only be performed when one of the arrays is modified.

Note that for NumpyVectorArray, a deep copy is always performed when only some vectors in the array are copied.

Parameters

deep

Ensure that an actual copy of the array data is made (see above).

Returns

A copy of the VectorArray.

append(self, other, remove_from_other=False)[source]

Append vectors to the array.

Parameters

other

A VectorArray containing the vectors to be appended.

remove_from_other

If True, the appended vectors are removed from other. For list-like implementations this can be used to prevent unnecessary copies of the involved vectors.

scal(self, alpha)[source]

BLAS SCAL operation (in-place scalar multiplication).

This method calculates

self = alpha*self

If alpha is a scalar, each vector is multiplied by this scalar. Otherwise, alpha has to be a one-dimensional NumPy array of the same length as self containing the factors for each vector.

Parameters

alpha

The scalar coefficient or one-dimensional NumPy array of coefficients with which the vectors in self are multiplied.

axpy(self, alpha, x)[source]

BLAS AXPY operation.

This method forms the sum

self = alpha*x + self

If the length of x is 1, the same x vector is used for all vectors in self. Otherwise, the lengths of self and x have to agree. If alpha is a scalar, each x vector is multiplied with the same factor alpha. Otherwise, alpha has to be a one-dimensional NumPy array of the same length as self containing the coefficients for each x vector.

Parameters

alpha

The scalar coefficient or one-dimensional NumPy array of coefficients with which the vectors in x are multiplied.

x

A VectorArray containing the x-summands.

inner(self, other, product=None)[source]

Returns the inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.inner(V)

is equivalent to:

U.dofs(np.arange(U.dim)) @ V.dofs(np.arange(V.dim)).T

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using apply2, i.e. U.inner(V, product) is equivalent to:

product.apply2(U, V)

which in turn is, by default, implemented as:

U.inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i, j] = ( self[i], other[j] ).

pairwise_inner(self, other, product=None)[source]

Returns the pairwise inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.pairwise_inner(V)

is equivalent to:

np.sum(U.dofs(np.arange(U.dim)) * V.dofs(np.arange(V.dim)), axis=-1)

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using pairwise_apply2, i.e. U.inner(V, product) is equivalent to:

product.pairwise_apply2(U, V)

which in turn is, by default, implemented as:

U.pairwise_inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i] = ( self[i], other[i] ).

lincomb(self, coefficients)[source]

Returns linear combinations of the vectors contained in the array.

Parameters

coefficients

A NumPy array of dimension 1 or 2 containing the linear coefficients. coefficients.shape[-1] has to agree with len(self).

Returns

A VectorArray result such that

result[i] = ∑ self[j] * coefficients[i,j]

in case coefficients is of dimension 2, otherwise len(result) == 1 and

result[0] = ∑ self[j] * coefficients[j].

_norm(self)[source]

Implementation of norm for the case that no product is given.

_norm2(self)[source]

Implementation of norm2 for the case that no product is given.

dofs(self, dof_indices)[source]

Extract DOFs of the vectors contained in the array.

Parameters

dof_indices

List or 1D NumPy array of indices of the DOFs that are to be returned.

Returns

A NumPy array result such that result[i, j] is the dof_indices[j]-th DOF of the i-th vector of the array.

amax(self)[source]

The maximum absolute value of the DOFs contained in the array.

Returns

max_ind

NumPy array containing for each vector a DOF index at which the maximum is attained.

max_val

NumPy array containing for each vector the maximum absolute value of its DOFs.

__del__(self)[source]
property real(self)[source]

Real part.

property imag(self)[source]

Imaginary part.

conj(self)[source]

Complex conjugation.

class pymor.vectorarrays.mpi.MPIVectorSpace(local_spaces)[source]

Bases: pymor.vectorarrays.interface.VectorSpace

VectorSpace of MPIVectorArrays.

Parameters

local_spaces

tuple of the different VectorSpaces of the local VectorArrays on the MPI ranks. Alternatively, the length of local_spaces may be 1, in which case the same VectorSpace is assumed for all ranks.

array_type[source]
make_array(self, obj_id)[source]

Create array from rank-local VectorArray instances.

Parameters

obj_id

ObjectId of the MPI distributed instances of cls wrapped by this array.

Returns

The newly created : class:MPIVectorArray.

zeros(self, count=1, reserve=0)[source]

Create a VectorArray of null vectors

Parameters

count

The number of vectors.

reserve

Hint for the backend to which length the array will grow.

Returns

A VectorArray containing count vectors with each component zero.

property dim(self)[source]
__eq__(self, other)[source]

Return self==value.

__repr__(self)[source]

Return repr(self).

class pymor.vectorarrays.mpi.RegisteredLocalSpace[source]

Bases: int

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4

__repr__(self)[source]

Return repr(self).

pymor.vectorarrays.mpi._local_space_registry[source]
pymor.vectorarrays.mpi._local_space_to_id[source]
pymor.vectorarrays.mpi._register_local_space(local_space)[source]
pymor.vectorarrays.mpi._get_local_space(local_spaces)[source]
pymor.vectorarrays.mpi._MPIVectorSpace_zeros(local_spaces=(None,), count=0, reserve=0)[source]
pymor.vectorarrays.mpi._MPIVectorSpace_dim(local_spaces)[source]
pymor.vectorarrays.mpi._MPIVectorSpace_check_local_spaces(local_spaces, obj_id)[source]
pymor.vectorarrays.mpi._MPIVectorArray_axpy(obj_id, alpha, x_obj_id)[source]
pymor.vectorarrays.mpi._MPIVectorArray_real(obj_id)[source]
pymor.vectorarrays.mpi._MPIVectorArray_imag(obj_id)[source]
class pymor.vectorarrays.mpi.MPIVectorArrayNoComm(obj_id, space)[source]

Bases: MPIVectorArray

MPI distributed VectorArray.

This is a subclass of MPIVectorArray which overrides all communication requiring interface methods to raise NotImplementedError.

This is mainly useful as a security measure when wrapping arrays for which simply calling the respective method on the wrapped arrays would lead to wrong results and MPIVectorArrayAutoComm cannot be used either (for instance in the presence of shared DOFs).

The associated VectorSpace is MPIVectorSpaceNoComm.

inner(self, other, product=None)[source]

Returns the inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.inner(V)

is equivalent to:

U.dofs(np.arange(U.dim)) @ V.dofs(np.arange(V.dim)).T

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using apply2, i.e. U.inner(V, product) is equivalent to:

product.apply2(U, V)

which in turn is, by default, implemented as:

U.inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i, j] = ( self[i], other[j] ).

pairwise_inner(self, other, product=None)[source]

Returns the pairwise inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.pairwise_inner(V)

is equivalent to:

np.sum(U.dofs(np.arange(U.dim)) * V.dofs(np.arange(V.dim)), axis=-1)

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using pairwise_apply2, i.e. U.inner(V, product) is equivalent to:

product.pairwise_apply2(U, V)

which in turn is, by default, implemented as:

U.pairwise_inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i] = ( self[i], other[i] ).

abstract _norm(self)[source]

Implementation of norm for the case that no product is given.

abstract _norm2(self)[source]

Implementation of norm2 for the case that no product is given.

abstract dofs(self, dof_indices)[source]

Extract DOFs of the vectors contained in the array.

Parameters

dof_indices

List or 1D NumPy array of indices of the DOFs that are to be returned.

Returns

A NumPy array result such that result[i, j] is the dof_indices[j]-th DOF of the i-th vector of the array.

abstract amax(self)[source]

The maximum absolute value of the DOFs contained in the array.

Returns

max_ind

NumPy array containing for each vector a DOF index at which the maximum is attained.

max_val

NumPy array containing for each vector the maximum absolute value of its DOFs.

class pymor.vectorarrays.mpi.MPIVectorSpaceNoComm(local_spaces)[source]

Bases: MPIVectorSpace

VectorSpace for MPIVectorArrayNoComm.

array_type[source]
property dim(self)[source]
class pymor.vectorarrays.mpi.MPIVectorArrayAutoComm(obj_id, space)[source]

Bases: MPIVectorArray

MPI distributed VectorArray.

This is a subclass of MPIVectorArray which provides default implementations for all communication requiring interface methods for the case when the wrapped array is not MPI aware.

Note, however, that depending on the model these default implementations might lead to wrong results (for instance in the presence of shared DOFs).

The associated VectorSpace is MPIVectorSpaceAutoComm.

inner(self, other, product=None)[source]

Returns the inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.inner(V)

is equivalent to:

U.dofs(np.arange(U.dim)) @ V.dofs(np.arange(V.dim)).T

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using apply2, i.e. U.inner(V, product) is equivalent to:

product.apply2(U, V)

which in turn is, by default, implemented as:

U.inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i, j] = ( self[i], other[j] ).

pairwise_inner(self, other, product=None)[source]

Returns the pairwise inner products between VectorArray elements.

If product is None, the Euclidean inner product between the dofs of self and other are returned, i.e.

U.pairwise_inner(V)

is equivalent to:

np.sum(U.dofs(np.arange(U.dim)) * V.dofs(np.arange(V.dim)), axis=-1)

(Note, that dofs is only intended to be called for a small number of DOF indices.)

If a product Operator is specified, this Operator is used to compute the inner products using pairwise_apply2, i.e. U.inner(V, product) is equivalent to:

product.pairwise_apply2(U, V)

which in turn is, by default, implemented as:

U.pairwise_inner(product.apply(V))

In the case of complex numbers, this is antilinear in the first argument, i.e. in ‘self’. Complex conjugation is done in the first argument because most numerical software in the community handles it this way: Numpy, DUNE, FEniCS, Eigen, Matlab and BLAS do complex conjugation in the first argument, only PetSc and deal.ii do complex conjugation in the second argument.

Parameters

other

A VectorArray containing the second factors.

product

If not None an Operator representing the inner product bilinear form.

Returns

A NumPy array result such that

result[i] = ( self[i], other[i] ).

_norm(self)[source]

Implementation of norm for the case that no product is given.

_norm2(self)[source]

Implementation of norm2 for the case that no product is given.

dofs(self, dof_indices)[source]

Extract DOFs of the vectors contained in the array.

Parameters

dof_indices

List or 1D NumPy array of indices of the DOFs that are to be returned.

Returns

A NumPy array result such that result[i, j] is the dof_indices[j]-th DOF of the i-th vector of the array.

amax(self)[source]

The maximum absolute value of the DOFs contained in the array.

Returns

max_ind

NumPy array containing for each vector a DOF index at which the maximum is attained.

max_val

NumPy array containing for each vector the maximum absolute value of its DOFs.

class pymor.vectorarrays.mpi.MPIVectorSpaceAutoComm(local_spaces)[source]

Bases: MPIVectorSpace

VectorSpace for MPIVectorArrayAutoComm.

array_type[source]
property dim(self)[source]
_get_dims(self)[source]
pymor.vectorarrays.mpi._MPIVectorSpaceAutoComm_dim(local_spaces)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_inner(self, other)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_pairwise_inner(self, other)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_norm(self)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_norm2(self)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_dofs(self, offsets, dof_indices)[source]
pymor.vectorarrays.mpi._MPIVectorArrayAutoComm_amax(self)[source]