pymor.operators.mpi
¶
Module Contents¶
Classes¶
MPI distributed 
Functions¶
Wrap MPI distributed local 

 class pymor.operators.mpi.MPIOperator(obj_id, mpi_range, mpi_source, with_apply2=False, pickle_local_spaces=True, space_type=MPIVectorSpace)[source]¶
Bases:
pymor.operators.interface.Operator
MPI distributed
Operator
.Given a singlerank implementation of an
Operator
, this wrapper class uses the event loop frompymor.tools.mpi
to allow an MPI distributed usage of theOperator
.Instances of
MPIOperator
can be used on rank 0 like any other (nondistributed)Operator
.Note, however, that the underlying
Operator
implementation needs to be MPI aware. For instance, the operator’sapply
method has to perform the necessary MPI communication to obtain all DOFs hosted on other MPI ranks which are required for the local operator evaluation.Instead of instantiating
MPIOperator
directly, it is usually preferable to usempi_wrap_operator
instead.Parameters
 obj_id
 mpi_range
Set to
True
if the range of theOperator
is MPI distributed. mpi_source
Set to
True
if the source of theOperator
is MPI distributed. with_apply2
Set to
True
if the operator implementation has its own MPI aware implementation ofapply2
andpairwise_apply2
. Otherwise, the default implementations usingapply
andinner
will be used. pickle_local_spaces
If
pickle_local_spaces
isFalse
, a unique identifier is computed for each local source/rangeVectorSpace
, which is then transferred to rank 0 instead of the trueVectorSpace
. This allows the usage ofMPIVectorArray
even when the localVectorSpaces
are not picklable. space_type
This class will be used to wrap the local
VectorArrays
returned by the local operators into an MPI distributedVectorArray
managed from rank 0. By default,MPIVectorSpace
will be used, other options areMPIVectorSpaceAutoComm
andMPIVectorSpaceNoComm
.
 apply(self, U, mu=None)[source]¶
Apply the operator to a
VectorArray
.Parameters
 U
VectorArray
of vectors to which the operator is applied. mu
The
parameter values
for which to evaluate the operator.
Returns
VectorArray
of the operator evaluations.
 as_range_array(self, mu=None)[source]¶
Return a
VectorArray
representation of the operator in its range space.In the case of a linear operator with
NumpyVectorSpace
assource
, this method returns for givenparameter values
mu
aVectorArray
V
in the operator’srange
, such thatV.lincomb(U.to_numpy()) == self.apply(U, mu)
for all
VectorArrays
U
.Parameters
 mu
The
parameter values
for which to return theVectorArray
representation.
Returns
 V
The
VectorArray
defined above.
 as_source_array(self, mu=None)[source]¶
Return a
VectorArray
representation of the operator in its source space.In the case of a linear operator with
NumpyVectorSpace
asrange
, this method returns for givenparameter values
mu
aVectorArray
V
in the operator’ssource
, such thatself.range.make_array(V.inner(U).T) == self.apply(U, mu)
for all
VectorArrays
U
.Parameters
 mu
The
parameter values
for which to return theVectorArray
representation.
Returns
 V
The
VectorArray
defined above.
 apply2(self, V, U, mu=None)[source]¶
Treat the operator as a 2form and apply it to V and U.
This method is usually implemented as
V.inner(self.apply(U))
. In particular, if the operator is a linear operator given by multiplication with a matrix M, thenapply2
is given as:op.apply2(V, U) = V^T*M*U.
In the case of complex numbers, note that
apply2
is antilinear in the first variable by definition ofinner
.Parameters
 V
VectorArray
of the left arguments V. U
VectorArray
of the right arguments U. mu
The
parameter values
for which to evaluate the operator.
Returns
A
NumPy array
with shape(len(V), len(U))
containing the 2form evaluations.
 pairwise_apply2(self, V, U, mu=None)[source]¶
Treat the operator as a 2form and apply it to V and U in pairs.
This method is usually implemented as
V.pairwise_inner(self.apply(U))
. In particular, if the operator is a linear operator given by multiplication with a matrix M, thenapply2
is given as:op.apply2(V, U)[i] = V[i]^T*M*U[i].
In the case of complex numbers, note that
pairwise_apply2
is antilinear in the first variable by definition ofpairwise_inner
.Parameters
 V
VectorArray
of the left arguments V. U
VectorArray
of the right arguments U. mu
The
parameter values
for which to evaluate the operator.
Returns
A
NumPy array
with shape(len(V),) == (len(U),)
containing the 2form evaluations.
 apply_adjoint(self, V, mu=None)[source]¶
Apply the adjoint operator.
For any given linear
Operator
op
,parameter values
mu
andVectorArrays
U
,V
in thesource
resp.range
we have:op.apply_adjoint(V, mu).dot(U) == V.inner(op.apply(U, mu))
Thus, when
op
is represented by a matrixM
,apply_adjoint
is given by leftmultplication of (the complex conjugate of)M
withV
.Parameters
 V
VectorArray
of vectors to which the adjoint operator is applied. mu
The
parameter values
for which to apply the adjoint operator.
Returns
VectorArray
of the adjoint operator evaluations.
 apply_inverse(self, V, mu=None, initial_guess=None, least_squares=False)[source]¶
Apply the inverse operator.
Parameters
 V
VectorArray
of vectors to which the inverse operator is applied. mu
The
parameter values
for which to evaluate the inverse operator. initial_guess
VectorArray
with the same length asV
containing initial guesses for the solution. Some implementations ofapply_inverse
may ignore this parameter. IfNone
a solverdependent default is used. least_squares
If
True
, solve the least squares problem:u = argmin op(u)  v_2.
Since for an invertible operator the least squares solution agrees with the result of the application of the inverse operator, setting this option should, in general, have no effect on the result for those operators. However, note that when no appropriate
solver_options
are set for the operator, most implementations will choose a least squares solver by default which may be undesirable.
Returns
VectorArray
of the inverse operator evaluations.Raises
 InversionError
The operator could not be inverted.
 apply_inverse_adjoint(self, U, mu=None, initial_guess=None, least_squares=False)[source]¶
Apply the inverse adjoint operator.
Parameters
 U
VectorArray
of vectors to which the inverse adjoint operator is applied. mu
The
parameter values
for which to evaluate the inverse adjoint operator. initial_guess
VectorArray
with the same length asU
containing initial guesses for the solution. Some implementations ofapply_inverse_adjoint
may ignore this parameter. IfNone
a solverdependent default is used. least_squares
If
True
, solve the least squares problem:v = argmin op^*(v)  u_2.
Since for an invertible operator the least squares solution agrees with the result of the application of the inverse operator, setting this option should, in general, have no effect on the result for those operators. However, note that when no appropriate
solver_options
are set for the operator, most operator implementations will choose a least squares solver by default which may be undesirable.
Returns
VectorArray
of the inverse adjoint operator evaluations.Raises
 InversionError
The operator could not be inverted.
 jacobian(self, U, mu=None)[source]¶
Return the operator’s Jacobian as a new
Operator
.Parameters
 U
Length 1
VectorArray
containing the vector for which to compute the Jacobian. mu
The
parameter values
for which to compute the Jacobian.
Returns
Linear
Operator
representing the Jacobian.
 assemble(self, mu=None)[source]¶
Assemble the operator for given
parameter values
.The result of the method strongly depends on the given operator. For instance, a matrixbased operator will assemble its matrix, a
LincombOperator
will try to form the linear combination of its operators, whereas an arbitrary operator might simply return aFixedParameterOperator
. The only assured property of the assembled operator is that it no longer depends on aParameter
.Parameters
 mu
The
parameter values
for which to assemble the operator.
Returns
Parameterindependent, assembled
Operator
.
 _assemble_lincomb(self, operators, coefficients, identity_shift=0.0, solver_options=None, name=None)[source]¶
Try to assemble a linear combination of the given operators.
Returns a new
Operator
which represents the sumc_1*O_1 + ... + c_N*O_N + s*I
where
O_i
areOperators
,c_i
,s
scalar coefficients andI
the identity.This method is called in the
assemble
method ofLincombOperator
on the first of its operators. If an assembly of the given linear combination is possible, e.g. the linear combination of the system matrices of the operators can be formed, then the assembled operator is returned. Otherwise, the method returnsNone
to indicate that assembly is not possible.Parameters
 operators
List of
Operators
O_i
whose linear combination is formed. coefficients
List of the corresponding linear coefficients
c_i
. identity_shift
The coefficient
s
. solver_options
solver_options
for the assembled operator. name
Name of the assembled operator.
Returns
The assembled
Operator
if assembly is possible, otherwiseNone
.
 restricted(self, dofs)[source]¶
Restrict the operator range to a given set of degrees of freedom.
This method returns a restricted version
restricted_op
of the operator along with an arraysource_dofs
such that for anyVectorArray
U
inself.source
the following is true:self.apply(U, mu).dofs(dofs) == restricted_op.apply(NumpyVectorArray(U.dofs(source_dofs)), mu))
Such an operator is mainly useful for
empirical interpolation
where the evaluation of the original operator only needs to be known for few selected degrees of freedom. If the operator has a small stencil, only fewsource_dofs
will be needed to evaluate the restricted operator which can make its evaluation very fast compared to evaluating the original operator.Parameters
 dofs
Onedimensional
NumPy array
of degrees of freedom in the operatorrange
to which to restrict.
Returns
 restricted_op
The restricted operator as defined above. The operator will have
NumpyVectorSpace
(len(source_dofs))
assource
andNumpyVectorSpace
(len(dofs))
asrange
. source_dofs
Onedimensional
NumPy array
of source degrees of freedom as defined above.
 pymor.operators.mpi._MPIOperator_assemble_lincomb(operators, coefficients, identity_shift, name)[source]¶
 pymor.operators.mpi.mpi_wrap_operator(obj_id, mpi_range, mpi_source, with_apply2=False, pickle_local_spaces=True, space_type=MPIVectorSpace)[source]¶
Wrap MPI distributed local
Operators
to a globalOperator
on rank 0.Given MPI distributed local
Operators
referred to by theObjectId
obj_id
, return a newOperator
which manages these distributed operators from rank 0. This is done by instantiatingMPIOperator
. Additionally, the structure of the wrapped operators is preserved. E.g.LincombOperators
will be wrapped as aLincombOperator
ofMPIOperators
.Parameters
See : class:
MPIOperator
.Returns
The wrapped
Operator
.