def make_listvectorarray(vec, count=1): if isinstance(vec, (list, tuple)): lva = ListVectorArray.make_array(subtype=(type(vec[0]), vec[0].dim), count=len(vec)) lva._list = list(vec) else: lva = ListVectorArray.make_array(subtype=(type(vec), vec.dim), count=1) lva._list[0] = vec return lva
def get(self, ind=None): assert self.check_ind(ind) ind = list(range(self._len)) if ind is None else [ind] if isinstance( ind, Number) else ind return ListVectorArray([self._load(i) for i in ind], subtype=self.subtype, copy=False)
def apply_inverse(self, V, ind=None, mu=None, least_squares=False): assert V in self.range assert V.check_ind(ind) assert not self.functional and not self.vector if V.dim == 0: if self.source.dim == 0 and least_squares: return ListVectorArray([NumpyVector(np.zeros(0), copy=False) for _ in range(V.len_ind(ind))], subtype=self.source.subtype) else: raise InversionError options = (self.solver_options.get('inverse') if self.solver_options else 'least_squares' if least_squares else None) if options and not least_squares: solver_type = options if isinstance(options, str) else options['type'] if solver_type.startswith('least_squares'): self.logger.warn('Least squares solver selected but "least_squares == False"') if ind is None: vectors = V._list elif isinstance(ind, Number): vectors = [V._list[ind]] else: vectors = (V._list[i] for i in ind) try: return ListVectorArray([NumpyVector(_apply_inverse(self._matrix, v._array.reshape((1, -1)), options=options).ravel(), copy=False) for v in vectors], subtype=self.source.subtype) except InversionError as e: if least_squares and options: solver_type = options if isinstance(options, str) else options['type'] if not solver_type.startswith('least_squares'): msg = str(e) \ + '\nNote: linear solver was selected for solving least squares problem (maybe not invertible?)' raise InversionError(msg) raise e
def random_list_array(dims, length, seed): if isinstance(dims, Number): dims = (dims, ) return ListVectorArray([ MPIVectorAutoComm(NumpyVector, tuple(dims), mpi.call(_random_vector, dims, seed + i)) for i in range(length) ], copy=False, subtype=(MPIVectorAutoComm, (NumpyVector, tuple(dims))))
def apply(self, U, ind=None, mu=None): assert U in self.source assert U.check_ind(ind) if self.vector: V = super().apply(U, ind=ind, mu=mu) return ListVectorArray([NumpyVector(v, copy=False) for v in V.data], subtype=self.range.subtype) if ind is None: vectors = U._list elif isinstance(ind, Number): vectors = [U._list[ind]] else: vectors = (U._list[i] for i in ind) V = [self._matrix.dot(v._array) for v in vectors] if self.functional: return NumpyVectorArray(V) if len(V) > 0 else self.range.empty() else: return ListVectorArray([NumpyVector(v, copy=False) for v in V], subtype=self.range.subtype)
def apply(self, U, ind=None, mu=None): assert U in self.source if ind is None: ind = range(len(U)) def apply_one_vector(u): v = Vector(self.range.dim, 0) self._impl.apply(u._impl, v) return WrappedVector(v) return ListVectorArray([apply_one_vector(U._list[i]) for i in ind], subtype=self.range.subtype)
def _discretize_fenics(xblocks, yblocks, grid_num_intervals, element_order): # assemble system matrices - FEniCS code ######################################## import dolfin as df mesh = df.UnitSquareMesh(grid_num_intervals, grid_num_intervals, 'crossed') V = df.FunctionSpace(mesh, 'Lagrange', element_order) u = df.TrialFunction(V) v = df.TestFunction(V) diffusion = df.Expression( '(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *' + '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))', lower0=0., upper0=0., open0=0, lower1=0., upper1=0., open1=0, element=df.FunctionSpace(mesh, 'DG', 0).ufl_element()) def assemble_matrix(x, y, nx, ny): diffusion.user_parameters['lower0'] = x / nx diffusion.user_parameters['lower1'] = y / ny diffusion.user_parameters['upper0'] = (x + 1) / nx diffusion.user_parameters['upper1'] = (y + 1) / ny diffusion.user_parameters['open0'] = (x + 1 == nx) diffusion.user_parameters['open1'] = (y + 1 == ny) return df.assemble( df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx) mats = [ assemble_matrix(x, y, xblocks, yblocks) for x in range(xblocks) for y in range(yblocks) ] mat0 = mats[0].copy() mat0.zero() h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx) l2_mat = df.assemble(u * v * df.dx) f = df.Constant(1.) * v * df.dx F = df.assemble(f) bc = df.DirichletBC(V, 0., df.DomainBoundary()) for m in mats: bc.zero(m) bc.apply(mat0) bc.apply(h1_mat) bc.apply(F) # wrap everything as a pyMOR discretization ########################################### # FEniCS wrappers from pymor.gui.fenics import FenicsVisualizer from pymor.operators.fenics import FenicsMatrixOperator from pymor.vectorarrays.fenics import FenicsVector # generic pyMOR classes from pymor.discretizations.basic import StationaryDiscretization from pymor.operators.constructions import LincombOperator, VectorFunctional from pymor.parameters.functionals import ProjectionParameterFunctional from pymor.parameters.spaces import CubicParameterSpace from pymor.vectorarrays.list import ListVectorArray # define parameter functionals (same as in pymor.analyticalproblems.thermalblock) def parameter_functional_factory(x, y): return ProjectionParameterFunctional( component_name='diffusion', component_shape=(yblocks, xblocks), coordinates=(yblocks - y - 1, x), name='diffusion_{}_{}'.format(x, y)) parameter_functionals = tuple( parameter_functional_factory(x, y) for x in range(xblocks) for y in range(yblocks)) # wrap operators ops = [FenicsMatrixOperator(mat0, V, V) ] + [FenicsMatrixOperator(m, V, V) for m in mats] op = LincombOperator(ops, (1., ) + parameter_functionals) rhs = VectorFunctional(ListVectorArray([FenicsVector(F, V)])) h1_product = FenicsMatrixOperator(h1_mat, V, V, name='h1_0_semi') l2_product = FenicsMatrixOperator(l2_mat, V, V, name='l2') # build discretization visualizer = FenicsVisualizer(V) parameter_space = CubicParameterSpace(op.parameter_type, 0.1, 1.) d = StationaryDiscretization(op, rhs, products={ 'h1_0_semi': h1_product, 'l2': l2_product }, parameter_space=parameter_space, visualizer=visualizer) return d
def as_vector(self, mu=None): if self.source.dim != 1 and self.range.dim != 1: raise TypeError('This operator does not represent a vector or linear functional.') return ListVectorArray([NumpyVector(self._matrix.ravel(), copy=True)])
def numpy_list_vector_array_factory(length, dim, seed): np.random.seed(seed) return ListVectorArray( [NumpyVector(v, copy=False) for v in np.random.random((length, dim))], subtype=(NumpyVector, dim), copy=False)