class RestrictedDuneSpaceOperator(OperatorBase): linear = False def __init__(self, impl, range_dofs): self._impl = impl self._range_dofs = range_dofs self.source = NumpyVectorSpace(impl.dimSource) self.range = NumpyVectorSpace(len(range_dofs)) self.name = 'DuneBurgersSpaceOperator_restricted' self._source_vec = dune_module.Vector(impl.dimSource, 0.) self._range_vec = dune_module.Vector(impl.dimRange, 0.) self._source_array = np.frombuffer(self._source_vec.buffer()) self._range_array = np.frombuffer(self._range_vec.buffer()) self.build_parameter_type({'exponent': tuple()}, local_global=True) def apply(self, U, ind=None, mu=None): assert U in self.source mu = self.parse_parameter(mu) exponent = float(mu['exponent']) U = U.data if ind is None else \ U.data[ind] if hasattr(ind, '__len__') else \ U.data[ind:ind + 1] R = self.range.zeros(len(U)) R_array = R.data for i, u in enumerate(U): self._source_array[:] = u self._range_array[:] = 0 self._impl.apply(self._source_vec, self._range_vec, exponent, 1.) R_array[i] = self._range_array[:][self._range_dofs] return R
class RestrictedFenicsOperator(Operator): linear = False def __init__(self, op, restricted_range_dofs): self.source = NumpyVectorSpace(op.source.dim) self.range = NumpyVectorSpace(len(restricted_range_dofs)) self.op = op self.restricted_range_dofs = restricted_range_dofs def apply(self, U, mu=None): assert U in self.source UU = self.op.source.zeros(len(U)) for uu, u in zip(UU._list, U.to_numpy()): uu.real_part.impl[:] = np.ascontiguousarray(u) VV = self.op.apply(UU, mu=mu) V = self.range.zeros(len(VV)) for v, vv in zip(V.to_numpy(), VV._list): v[:] = vv.real_part.impl[self.restricted_range_dofs] return V def jacobian(self, U, mu=None): assert U in self.source and len(U) == 1 UU = self.op.source.zeros() UU._list[0].real_part.impl[:] = np.ascontiguousarray( U.to_numpy()[0]) JJ = self.op.jacobian(UU, mu=mu) return NumpyMatrixOperator( JJ.matrix.array()[self.restricted_range_dofs, :])
class RestrictedFenicsOperator(OperatorBase): linear = False def __init__(self, op, restricted_range_dofs): self.source = NumpyVectorSpace(op.source.dim) self.range = NumpyVectorSpace(len(restricted_range_dofs)) self.op = op self.restricted_range_dofs = restricted_range_dofs self.build_parameter_type(op) def apply(self, U, mu=None): assert U in self.source UU = self.op.source.zeros(len(U)) for uu, u in zip(UU._list, U.data): uu.real_part.impl[:] = u VV = self.op.apply(UU, mu=mu) V = self.range.zeros(len(VV)) for v, vv in zip(V.data, VV._list): v[:] = vv.real_part.impl[self.restricted_range_dofs] return V def jacobian(self, U, mu=None): assert U in self.source and len(U) == 1 UU = self.op.source.zeros() UU._list[0].real_part.impl[:] = U.data[0] JJ = self.op.jacobian(UU, mu=mu) return NumpyMatrixOperator( JJ.matrix.array()[self.restricted_range_dofs, :])