def project_operator(operator, source_basis, range_basis, product=None, name=None): '''Project operators to subspaces. Replaces `Operators` by `ProjectedOperators` and `LinearOperators` by `ProjectedLinearOperators`. Moreover, `LinearAffinelyDecomposedOperators` are projected by recursively projecting each of its components. See also `ProjectedOperator`. Parameters ---------- operator The `Operator` to project. source_basis The b_1, ..., b_N as a 2d-array. range_basis The c_1, ..., c_M as a 2d-array. product Either an 2d-array or a `Operator` representing the scalar product. If None, the euclidean product is chosen. name Name of the projected operator. ''' name = name or '{}_projected'.format(operator.name) if isinstance(operator, LinearAffinelyDecomposedOperator): proj_operators = tuple(project_operator(op, source_basis, range_basis, product, name='{}_projected'.format(op.name)) for op in operator.operators) if operator.operator_affine_part is not None: proj_operator_ap = project_operator(operator.operator_affine_part, source_basis, range_basis, product, name='{}_projected'.format(operator.operator_affine_part.name)) else: proj_operator_ap = None proj_operator = LinearAffinelyDecomposedOperator(proj_operators, proj_operator_ap, operator.functionals, name) proj_operator.rename_parameter(operator.parameter_name_map) return proj_operator elif isinstance(operator, LinearOperatorInterface): return ProjectedLinearOperator(operator, source_basis, range_basis, product, name) else: return ProjectedOperator(operator, source_basis, range_basis, product, name)
def discretize_elliptic_cg(analytical_problem, diameter=None, domain_discretizer=None, grid=None, boundary_info=None): '''Discretize an `EllipticProblem` using finite elements. Since operators are not assembled during instatiation, calling this function is cheap if the domain discretization proceeds quickly. Parameters ---------- analytical_problem The `EllipticProblem` to discretize. diameter If not None, is passed to the domain_discretizer. domain_discretizer Discretizer to be used for discretizing the analytical domain. This has to be function `domain_discretizer(domain_description, diameter=...)`. If further arguments should be passed to the discretizer, use functools.partial. If None, `discretize_domain_default` is used. grid Instead of using a domain discretizer, the grid can be passed directly. boundary_info A `BoundaryInfo` specifying the boundary types of the grid boundary entities. Must be provided is `grid` is provided. Returns ------- discretization The discretization that has been generated. data Dict with the following entries: grid The generated grid. boundary_info The generated `BoundaryInfo`. ''' assert isinstance(analytical_problem, EllipticProblem) assert grid is None or boundary_info is not None assert boundary_info is None or grid is not None assert grid is None or domain_discretizer is None if grid is None: domain_discretizer = domain_discretizer or discretize_domain_default if diameter is None: grid, boundary_info = domain_discretizer(analytical_problem.domain) else: grid, boundary_info = domain_discretizer(analytical_problem.domain, diameter=diameter) assert isinstance(grid, (OnedGrid, TriaGrid)) Operator = DiffusionOperatorP1 Functional = L2ProductFunctionalP1 p = analytical_problem if p.diffusion_functionals is not None or len(p.diffusion_functions) > 1: L0 = Operator(grid, boundary_info, diffusion_constant=0, name='diffusion_boundary_part') Li = tuple(Operator(grid, boundary_info, diffusion_function=df, dirichlet_clear_diag=True, name='diffusion_{}'.format(i)) for i, df in enumerate(p.diffusion_functions)) if p.diffusion_functionals is None: L = LinearAffinelyDecomposedOperator(Li, L0, name='diffusion') L.rename_parameter({'.coefficients': '.diffusion_coefficients'}) else: L = LinearAffinelyDecomposedOperator(Li, L0, p.diffusion_functionals, name='diffusion') else: L = Operator(grid, boundary_info, diffusion_function=p.diffusion_functions[0], name='diffusion') F = Functional(grid, p.rhs, boundary_info, dirichlet_data=p.dirichlet_data) import matplotlib.pyplot as pl if isinstance(grid, TriaGrid): def visualize(U): assert len(U) == 1 pl.tripcolor(grid.centers(2)[:, 0], grid.centers(2)[:, 1], grid.subentities(0, 2), U.data.ravel()) pl.colorbar() pl.show() else: def visualize(U): assert len(U) == 1 pl.plot(grid.centers(1), U.data.ravel()) pl.show() pass discretization = StationaryLinearDiscretization(L, F, visualizer=visualize, name='{}_CG'.format(p.name)) discretization.h1_product = Operator(grid, boundary_info) discretization.h1_norm = induced_norm(discretization.h1_product) discretization.l2_product = L2ProductP1(grid, boundary_info) if hasattr(p, 'parameter_space'): discretization.parameter_space = p.parameter_space return discretization, {'grid': grid, 'boundary_info': boundary_info}