def test_to_matrix_Concatenation(): np.random.seed(0) A = np.random.randn(2, 3) B = np.random.randn(3, 4) C = A.dot(B) Aop = NumpyMatrixOperator(A) Bop = NumpyMatrixOperator(B) Cop = Concatenation([Aop, Bop]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(sps.csc_matrix(A)) Bop = NumpyMatrixOperator(B) Cop = Concatenation([Aop, Bop]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(A) Bop = NumpyMatrixOperator(sps.csc_matrix(B)) Cop = Concatenation([Aop, Bop]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(sps.csc_matrix(A)) Bop = NumpyMatrixOperator(sps.csc_matrix(B)) Cop = Concatenation([Aop, Bop]) assert_type_and_allclose(A, Aop, 'sparse')
def test_to_matrix_LincombOperator(): np.random.seed(0) A = np.random.randn(3, 3) B = np.random.randn(3, 2) a = np.random.randn() b = np.random.randn() C = a * A + b * B.dot(B.T) Aop = NumpyMatrixOperator(A) Bop = NumpyMatrixOperator(B) Cop = LincombOperator([Aop, Concatenation([Bop, Bop.T])], [a, b]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(sps.csc_matrix(A)) Bop = NumpyMatrixOperator(B) Cop = LincombOperator([Aop, Concatenation([Bop, Bop.T])], [a, b]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(A) Bop = NumpyMatrixOperator(sps.csc_matrix(B)) Cop = LincombOperator([Aop, Concatenation([Bop, Bop.T])], [a, b]) assert_type_and_allclose(C, Cop, 'dense') Aop = NumpyMatrixOperator(sps.csc_matrix(A)) Bop = NumpyMatrixOperator(sps.csc_matrix(B)) Cop = LincombOperator([Aop, Concatenation([Bop, Bop.T])], [a, b]) assert_type_and_allclose(C, Cop, 'sparse')
def test_to_matrix(): np.random.seed(0) A = np.random.randn(2, 2) B = np.random.randn(3, 3) C = np.random.randn(3, 3) X = np.bmat([[np.eye(2) + A, np.zeros((2, 3))], [np.zeros((3, 2)), B.dot(C.T)]]) C = sps.csc_matrix(C) Aop = NumpyMatrixOperator(A) Bop = NumpyMatrixOperator(B) Cop = NumpyMatrixOperator(C) Xop = BlockDiagonalOperator([ LincombOperator([IdentityOperator(NumpyVectorSpace(2)), Aop], [1, 1]), Concatenation(Bop, AdjointOperator(Cop)) ]) assert np.allclose(X, to_matrix(Xop)) assert np.allclose(X, to_matrix(Xop, format='csr').toarray()) np.random.seed(0) V = np.random.randn(10, 2) Vva = NumpyVectorArray(V.T) Vop = VectorArrayOperator(Vva) assert np.allclose(V, to_matrix(Vop)) Vop = VectorArrayOperator(Vva, transposed=True) assert np.allclose(V, to_matrix(Vop).T)
def action_Concatenation(self, op, range_basis, source_basis, product=None): if source_basis is not None and op.first.linear and not op.first.parametric: V = op.first.apply(source_basis) return self.apply(op.second, range_basis, V, product=product) elif range_basis is not None and op.second.linear and not op.second.parametric: if product: range_basis = product.apply(range_basis) V = op.second.apply_transpose(range_basis) return self.apply(op.first, V, source_basis) else: projected_first = self.apply(op.first, None, source_basis, product=None) projected_second = self.apply(op.second, range_basis, None, product=product) return Concatenation(projected_second, projected_first, name=op.name)
def action_Concatenation(self, op): if len(op.operators) == 1: return self.apply(op.operators[0]) range_basis, source_basis, product = self.range_basis, self.source_basis, self.product last, first = op.operators[0], op.operators[-1] if source_basis is not None and first.linear and not first.parametric: V = first.apply(source_basis) return type(self)(range_basis, V, product).apply( op.with_(operators=op.operators[:-1])) elif range_basis is not None and last.linear and not last.parametric: if product: range_basis = product.apply(range_basis) V = last.apply_adjoint(range_basis) return type(self)(V, source_basis, None).apply(op.with_(operators=op.operators[1:])) else: projected_first = type(self)(None, source_basis, product=None).apply(first) projected_last = type(self)(range_basis, None, product=product).apply(last) return Concatenation( (projected_last, ) + op.operators[1:-1] + (projected_first, ), name=op.name)
def project_operators(self): fom = self.fom RB = self.bases['RB'] product = self.products['RB'] if self.initial_data_product != product: # TODO there should be functionality for this somewhere else projection_matrix = RB.gramian(self.initial_data_product) projection_op = NumpyMatrixOperator(projection_matrix) inverse_projection_op = InverseOperator(projection_op, 'inverse_projection_op') pid = project(fom.initial_data, range_basis=RB, source_basis=None, product=self.initial_data_product) projected_initial_data = Concatenation([inverse_projection_op, pid]) else: projected_initial_data = project(fom.initial_data, range_basis=RB, source_basis=None, product=product) projected_operators = { 'mass': None if fom.mass is None or self.product_is_mass else project(fom.mass, RB, RB), 'operator': project(fom.operator, RB, RB), 'rhs': project(fom.rhs, RB, None) if fom.rhs is not None else None, 'initial_data': projected_initial_data, 'products': {k: project(v, RB, RB) for k, v in fom.products.items()}, 'output_functional': project(fom.output_functional, None, RB) if fom.output_functional else None } return projected_operators
def project_operators_to_subbasis(self, dims): rom = self._last_rom dim = dims['RB'] product = self.products['RB'] if self.initial_data_product != product: # TODO there should be functionality for this somewhere else pop = project_to_subbasis(rom.initial_data.operators[1], dim_range=dim, dim_source=None) inverse_projection_op = InverseOperator( project_to_subbasis(rom.initial_data.operators[0].operator, dim_range=dim, dim_source=dim), name='inverse_projection_op' ) projected_initial_data = Concatenation([inverse_projection_op, pop]) else: projected_initial_data = project_to_subbasis(rom.initial_data, dim_range=dim, dim_source=None) projected_operators = { 'mass': (None if rom.mass is None or self.product_is_mass else project_to_subbasis(rom.mass, dim, dim)), 'operator': project_to_subbasis(rom.operator, dim, dim), 'rhs': project_to_subbasis(rom.rhs, dim, None) if rom.rhs is not None else None, 'initial_data': projected_initial_data, 'products': {k: project_to_subbasis(v, dim, dim) for k, v in rom.products.items()}, 'output_functional': project_to_subbasis(rom.output_functional, None, dim) if rom.output_functional else None } return projected_operators
def jacobian(self, U, mu=None): mu = self.parse_parameter(mu) if len(self.interpolation_dofs) == 0: if self.source.type == self.range.type == NumpyVectorArray: return NumpyMatrixOperator(np.zeros((0, self.source.dim)), name=self.name + '_jacobian') else: return ZeroOperator(self.source, self.range, name=self.name + '_jacobian') elif hasattr(self, 'operator'): return EmpiricalInterpolatedOperator(self.operator.jacobian(U, mu=mu), self.interpolation_dofs, self.collateral_basis, self.triangular, self.name + '_jacobian') else: U_components = NumpyVectorArray(U.components(self.source_dofs), copy=False) JU = self.restricted_operator.jacobian(U_components, mu=mu) \ .apply(NumpyVectorArray(np.eye(len(self.source_dofs)), copy=False)) try: if self.triangular: interpolation_coefficients = solve_triangular(self.interpolation_matrix, JU.data.T, lower=True, unit_diagonal=True).T else: interpolation_coefficients = np.linalg.solve(self.interpolation_matrix, JU._array.T).T except ValueError: # this exception occurs when AU contains NaNs ... interpolation_coefficients = np.empty((len(JU), len(self.collateral_basis))) + np.nan J = self.collateral_basis.lincomb(interpolation_coefficients) if isinstance(J, NumpyVectorArray): J = NumpyMatrixOperator(J.data.T) else: J = VectorArrayOperator(J, copy=False) return Concatenation(J, ComponentProjection(self.source_dofs, self.source), name=self.name + '_jacobian')
def jacobian(self, U, mu=None): mu = self.parse_parameter(mu) options = self.solver_options.get('jacobian') if self.solver_options else None if len(self.interpolation_dofs) == 0: if isinstance(self.source, NumpyVectorSpace) and isinstance(self.range, NumpyVectorSpace): return NumpyMatrixOperator(np.zeros((self.range.dim, self.source.dim)), solver_options=options, source_id=self.source.id, range_id=self.range.id, name=self.name + '_jacobian') else: return ZeroOperator(self.range, self.source, name=self.name + '_jacobian') elif hasattr(self, 'operator'): return EmpiricalInterpolatedOperator(self.operator.jacobian(U, mu=mu), self.interpolation_dofs, self.collateral_basis, self.triangular, solver_options=options, name=self.name + '_jacobian') else: restricted_source = self.restricted_operator.source U_dofs = restricted_source.make_array(U.dofs(self.source_dofs)) JU = self.restricted_operator.jacobian(U_dofs, mu=mu) \ .apply(restricted_source.make_array(np.eye(len(self.source_dofs)))) try: if self.triangular: interpolation_coefficients = solve_triangular(self.interpolation_matrix, JU.to_numpy().T, lower=True, unit_diagonal=True).T else: interpolation_coefficients = solve(self.interpolation_matrix, JU.to_numpy().T).T except ValueError: # this exception occurs when AU contains NaNs ... interpolation_coefficients = np.empty((len(JU), len(self.collateral_basis))) + np.nan J = self.collateral_basis.lincomb(interpolation_coefficients) if isinstance(J.space, NumpyVectorSpace): J = NumpyMatrixOperator(J.to_numpy().T, range_id=self.range.id) else: J = VectorArrayOperator(J) return Concatenation([J, ComponentProjection(self.source_dofs, self.source)], solver_options=options, name=self.name + '_jacobian')
def __matmul__(self, other): if not isinstance(other, OperatorInterface): return NotImplemented from pymor.operators.constructions import Concatenation if isinstance(other, Concatenation): return NotImplemented else: return Concatenation((self, other))
def restricted(self, dofs): source_dofs = np.setdiff1d(np.union1d(self.grid.neighbours(0, 0)[dofs].ravel(), dofs), np.array([-1], dtype=np.int32), assume_unique=True) sub_grid = SubGrid(self.grid, entities=source_dofs) sub_boundary_info = SubGridBoundaryInfo(sub_grid, self.grid, self.boundary_info) op = self.with_(grid=sub_grid, boundary_info=sub_boundary_info, name='{}_restricted'.format(self.name)) sub_grid_indices = sub_grid.indices_from_parent_indices(dofs, codim=0) proj = ComponentProjection(sub_grid_indices, op.range) return Concatenation(proj, op), sub_grid.parent_indices(0)
def collect_functional_ranges(op, image): if isinstance(op, (LincombOperator, SelectionOperator)): for o in op.operators: collect_functional_ranges(o, image) elif isinstance(op, AdjointOperator): operator = Concatenation( op.range_product, op.operator) if op.range_product else op.operator collect_operator_ranges(operator, NumpyVectorArray(np.ones(1)), image) elif op.linear and not op.parametric: image.append(op.as_vector()) else: raise ImageCollectionError(op)
def action_Concatenation(self, op): if len(op.operators) == 1: return self.apply(op.operators[0]) range_basis, source_basis = self.range_basis, self.source_basis last, first = op.operators[0], op.operators[-1] if source_basis is not None and first.linear and not first.parametric: V = first.apply(source_basis) return project(op.with_(operators=op.operators[:-1]), range_basis, V) elif range_basis is not None and last.linear and not last.parametric: V = last.apply_adjoint(range_basis) return project(op.with_(operators=op.operators[1:]), V, source_basis) else: projected_first = project(first, None, source_basis) projected_last = project(last, range_basis, None) return Concatenation((projected_last,) + op.operators[1:-1] + (projected_first,), name=op.name)
def assemble_estimator_diffusive_flux_bb(grid, ii, subdomain_rt_spaces, lambda_hat, kappa, local_rt_projection): diffusive_flux_bb_product = make_diffusive_flux_bb_product( grid, ii, subdomain_rt_spaces[ii], lambda_hat, kappa=kappa, over_integrate=2) subdomain_walker = make_subdomain_walker(grid, ii) subdomain_walker.append(diffusive_flux_bb_product) subdomain_walker.walk() # subdomain_rt_spaces[ii].dof_communicator, matrix = DuneXTMatrixOperator(diffusive_flux_bb_product.matrix(), range_id='LOCALRT_{}'.format(ii), source_id='LOCALRT_{}'.format(ii)) return Concatenation([local_rt_projection.T, matrix, local_rt_projection], name='diffusive_flux_bb_{}'.format(ii))
def thermalblock_concatenation_factory(xblocks, yblocks, diameter, seed): from pymor.operators.constructions import Concatenation op, mu, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed) op = Concatenation(sp, op) return op, mu, U, V, sp, rp
def discretize(grid_and_problem_data, solver_options, mpi_comm): ################ Setup logger = getLogger('discretize_elliptic_block_swipdg.discretize') logger.info('discretizing ... ') grid, boundary_info = grid_and_problem_data['grid'], grid_and_problem_data[ 'boundary_info'] local_all_dirichlet_boundary_info = make_subdomain_boundary_info( grid, {'type': 'xt.grid.boundaryinfo.alldirichlet'}) local_subdomains, num_local_subdomains, num_global_subdomains = _get_subdomains( grid) local_all_neumann_boundary_info = make_subdomain_boundary_info( grid, {'type': 'xt.grid.boundaryinfo.allneumann'}) block_space = make_block_dg_space(grid) global_rt_space = make_rt_space(grid) subdomain_rt_spaces = [ global_rt_space.restrict_to_dd_subdomain_view(grid, ii) for ii in range(num_global_subdomains) ] local_patterns = [ block_space.local_space(ii).compute_pattern('face_and_volume') for ii in range(block_space.num_blocks) ] coupling_patterns = { 'in_in': {}, 'out_out': {}, 'in_out': {}, 'out_in': {} } coupling_matrices = { 'in_in': {}, 'out_out': {}, 'in_out': {}, 'out_in': {} } for ii in range(num_global_subdomains): ii_size = block_space.local_space(ii).size() for jj in grid.neighboring_subdomains(ii): jj_size = block_space.local_space(jj).size() if ii < jj: # Assemble primally (visit each coupling only once). coupling_patterns['in_in'][(ii, jj)] = block_space.local_space( ii).compute_pattern('face_and_volume') coupling_patterns['out_out'][( ii, jj)] = block_space.local_space(jj).compute_pattern( 'face_and_volume') coupling_patterns['in_out'][( ii, jj)] = block_space.compute_coupling_pattern( ii, jj, 'face') coupling_patterns['out_in'][( ii, jj)] = block_space.compute_coupling_pattern( jj, ii, 'face') coupling_matrices['in_in'][(ii, jj)] = Matrix( ii_size, ii_size, coupling_patterns['in_in'][(ii, jj)]) coupling_matrices['out_out'][(ii, jj)] = Matrix( jj_size, jj_size, coupling_patterns['out_out'][(ii, jj)]) coupling_matrices['in_out'][(ii, jj)] = Matrix( ii_size, jj_size, coupling_patterns['in_out'][(ii, jj)]) coupling_matrices['out_in'][(ii, jj)] = Matrix( jj_size, ii_size, coupling_patterns['out_in'][(ii, jj)]) boundary_patterns = {} for ii in grid.boundary_subdomains(): boundary_patterns[ii] = block_space.local_space(ii).compute_pattern( 'face_and_volume') ################ Assemble LHS and RHS lambda_, kappa = grid_and_problem_data['lambda'], grid_and_problem_data[ 'kappa'] if isinstance(lambda_, dict): lambda_funcs = lambda_['functions'] lambda_coeffs = lambda_['coefficients'] else: lambda_funcs = [ lambda_, ] lambda_coeffs = [ 1, ] logger.debug('block op ... ') ops, block_ops = zip(*(discretize_lhs( lf, grid, block_space, local_patterns, boundary_patterns, coupling_matrices, kappa, local_all_neumann_boundary_info, boundary_info, coupling_patterns, solver_options) for lf in lambda_funcs)) global_operator = LincombOperator(ops, lambda_coeffs, solver_options=solver_options, name='GlobalOperator') logger.debug('block op global done ') block_op = LincombOperator(block_ops, lambda_coeffs, name='lhs', solver_options=solver_options) logger.debug('block op done ') f = grid_and_problem_data['f'] if isinstance(f, dict): f_funcs = f['functions'] f_coeffs = f['coefficients'] else: f_funcs = [ f, ] f_coeffs = [ 1, ] rhss, block_rhss = zip(*(discretize_rhs( ff, grid, block_space, global_operator, block_ops, block_op) for ff in f_funcs)) global_rhs = LincombOperator(rhss, f_coeffs) block_rhs = LincombOperator(block_rhss, f_coeffs) solution_space = block_op.source ################ Assemble interpolation and reconstruction operators logger.info('discretizing interpolation ') # Oswald interpolation error operator oi_op = BlockDiagonalOperator([ OswaldInterpolationErrorOperator(ii, block_op.source, grid, block_space) for ii in range(num_global_subdomains) ], name='oswald_interpolation_error') # Flux reconstruction operator fr_op = LincombOperator([ BlockDiagonalOperator([ FluxReconstructionOperator(ii, block_op.source, grid, block_space, global_rt_space, subdomain_rt_spaces, lambda_xi, kappa) for ii in range(num_global_subdomains) ]) for lambda_xi in lambda_funcs ], lambda_coeffs, name='flux_reconstruction') ################ Assemble inner products and error estimator operators logger.info('discretizing inner products ') lambda_bar, lambda_hat = grid_and_problem_data[ 'lambda_bar'], grid_and_problem_data['lambda_hat'] mu_bar, mu_hat = grid_and_problem_data['mu_bar'], grid_and_problem_data[ 'mu_hat'] operators = {} local_projections = [] local_rt_projections = [] local_oi_projections = [] local_div_ops = [] local_l2_products = [] data = dict(grid=grid, block_space=block_space, local_projections=local_projections, local_rt_projections=local_rt_projections, local_oi_projections=local_oi_projections, local_div_ops=local_div_ops, local_l2_products=local_l2_products) for ii in range(num_global_subdomains): neighborhood = grid.neighborhood_of(ii) ################ Assemble local inner products local_dg_space = block_space.local_space(ii) # we want a larger pattern to allow for axpy with other matrices tmp_local_matrix = Matrix( local_dg_space.size(), local_dg_space.size(), local_dg_space.compute_pattern('face_and_volume')) local_energy_product_ops = [] local_energy_product_coeffs = [] for func, coeff in zip(lambda_funcs, lambda_coeffs): local_energy_product_ops.append( make_elliptic_matrix_operator(func, kappa, tmp_local_matrix.copy(), local_dg_space, over_integrate=0)) local_energy_product_coeffs.append(coeff) local_energy_product_ops.append( make_penalty_product_matrix_operator( grid, ii, local_all_dirichlet_boundary_info, local_dg_space, func, kappa, over_integrate=0)) local_energy_product_coeffs.append(coeff) local_l2_product = make_l2_matrix_operator(tmp_local_matrix.copy(), local_dg_space) del tmp_local_matrix local_assembler = make_system_assembler(local_dg_space) for local_product_op in local_energy_product_ops: local_assembler.append(local_product_op) local_assembler.append(local_l2_product) local_assembler.assemble() local_energy_product_name = 'local_energy_dg_product_{}'.format(ii) local_energy_product = LincombOperator([ DuneXTMatrixOperator(op.matrix(), source_id='domain_{}'.format(ii), range_id='domain_{}'.format(ii)) for op in local_energy_product_ops ], local_energy_product_coeffs, name=local_energy_product_name) operators[local_energy_product_name] = \ local_energy_product.assemble(mu_bar).with_(name=local_energy_product_name) local_l2_product = DuneXTMatrixOperator( local_l2_product.matrix(), source_id='domain_{}'.format(ii), range_id='domain_{}'.format(ii)) local_l2_products.append(local_l2_product) # assemble local elliptic product matrix = make_local_elliptic_matrix_operator(grid, ii, local_dg_space, lambda_bar, kappa) matrix.assemble() local_elliptic_product = DuneXTMatrixOperator( matrix.matrix(), range_id='domain_{}'.format(ii), source_id='domain_{}'.format(ii)) ################ Assemble local to global projections # assemble projection (solution space) -> (ii space) local_projection = BlockProjectionOperator(block_op.source, ii) local_projections.append(local_projection) # assemble projection (RT spaces on neighborhoods of subdomains) -> (local RT space on ii) ops = np.full(num_global_subdomains, None) for kk in neighborhood: component = grid.neighborhood_of(kk).index(ii) assert fr_op.range.subspaces[kk].subspaces[ component].id == 'LOCALRT_{}'.format(ii) ops[kk] = BlockProjectionOperator(fr_op.range.subspaces[kk], component) local_rt_projection = BlockRowOperator( ops, source_spaces=fr_op.range.subspaces, name='local_rt_projection_{}'.format(ii)) local_rt_projections.append(local_rt_projection) # assemble projection (OI spaces on neighborhoods of subdomains) -> (ii space) ops = np.full(num_global_subdomains, None) for kk in neighborhood: component = grid.neighborhood_of(kk).index(ii) assert oi_op.range.subspaces[kk].subspaces[ component].id == 'domain_{}'.format(ii) ops[kk] = BlockProjectionOperator(oi_op.range.subspaces[kk], component) local_oi_projection = BlockRowOperator( ops, source_spaces=oi_op.range.subspaces, name='local_oi_projection_{}'.format(ii)) local_oi_projections.append(local_oi_projection) ################ Assemble additional operators for error estimation # assemble local divergence operator local_rt_space = global_rt_space.restrict_to_dd_subdomain_view( grid, ii) local_div_op = make_divergence_matrix_operator_on_subdomain( grid, ii, local_dg_space, local_rt_space) local_div_op.assemble() local_div_op = DuneXTMatrixOperator( local_div_op.matrix(), source_id='LOCALRT_{}'.format(ii), range_id='domain_{}'.format(ii), name='local_divergence_{}'.format(ii)) local_div_ops.append(local_div_op) ################ Assemble error estimator operators -- Nonconformity operators['nc_{}'.format(ii)] = \ Concatenation([local_oi_projection.T, local_elliptic_product, local_oi_projection], name='nonconformity_{}'.format(ii)) ################ Assemble error estimator operators -- Residual if len(f_funcs) == 1: assert f_coeffs[0] == 1 local_div = Concatenation([local_div_op, local_rt_projection]) local_rhs = VectorFunctional( block_rhs.operators[0]._array._blocks[ii]) operators['r_fd_{}'.format(ii)] = \ Concatenation([local_rhs, local_div], name='r1_{}'.format(ii)) operators['r_dd_{}'.format(ii)] = \ Concatenation([local_div.T, local_l2_product, local_div], name='r2_{}'.format(ii)) ################ Assemble error estimator operators -- Diffusive flux operators['df_aa_{}'.format(ii)] = LincombOperator( [ assemble_estimator_diffusive_flux_aa( lambda_xi, lambda_xi_prime, grid, ii, block_space, lambda_hat, kappa, solution_space) for lambda_xi in lambda_funcs for lambda_xi_prime in lambda_funcs ], [ ProductParameterFunctional([c1, c2]) for c1 in lambda_coeffs for c2 in lambda_coeffs ], name='diffusive_flux_aa_{}'.format(ii)) operators['df_bb_{}'.format( ii)] = assemble_estimator_diffusive_flux_bb( grid, ii, subdomain_rt_spaces, lambda_hat, kappa, local_rt_projection) operators['df_ab_{}'.format(ii)] = LincombOperator( [ assemble_estimator_diffusive_flux_ab( lambda_xi, grid, ii, block_space, subdomain_rt_spaces, lambda_hat, kappa, local_rt_projection, local_projection) for lambda_xi in lambda_funcs ], lambda_coeffs, name='diffusive_flux_ab_{}'.format(ii)) ################ Final assembly logger.info('final assembly ') # instantiate error estimator min_diffusion_evs = np.array([ min_diffusion_eigenvalue(grid, ii, lambda_hat, kappa) for ii in range(num_global_subdomains) ]) subdomain_diameters = np.array( [subdomain_diameter(grid, ii) for ii in range(num_global_subdomains)]) if len(f_funcs) == 1: assert f_coeffs[0] == 1 local_eta_rf_squared = np.array([ apply_l2_product(grid, ii, f_funcs[0], f_funcs[0], over_integrate=2) for ii in range(num_global_subdomains) ]) else: local_eta_rf_squared = None estimator = EllipticEstimator(grid, min_diffusion_evs, subdomain_diameters, local_eta_rf_squared, lambda_coeffs, mu_bar, mu_hat, fr_op, oswald_interpolation_error=oi_op, mpi_comm=mpi_comm) l2_product = BlockDiagonalOperator(local_l2_products) # instantiate discretization neighborhoods = [ grid.neighborhood_of(ii) for ii in range(num_global_subdomains) ] local_boundary_info = make_subdomain_boundary_info( grid_and_problem_data['grid'], {'type': 'xt.grid.boundaryinfo.alldirichlet'}) d = DuneDiscretization(global_operator=global_operator, global_rhs=global_rhs, neighborhoods=neighborhoods, enrichment_data=(grid, local_boundary_info, lambda_, kappa, f, block_space), operator=block_op, rhs=block_rhs, visualizer=DuneGDTVisualizer(block_space), operators=operators, products={'l2': l2_product}, estimator=estimator, data=data) parameter_range = grid_and_problem_data['parameter_range'] logger.info('final assembly B') d = d.with_(parameter_space=CubicParameterSpace( d.parameter_type, parameter_range[0], parameter_range[1])) logger.info('final assembly C') return d, data
def discretize(grid_and_problem_data, T, nt): d, d_data = discretize_ell(grid_and_problem_data) assert isinstance(d.parameter_space, CubicParameterSpace) parameter_range = grid_and_problem_data['parameter_range'] block_space = d_data['block_space'] # assemble global L2 product l2_mat = d.global_operator.operators[0].matrix.copy( ) # to ensure matching pattern l2_mat.scal(0.) for ii in range(block_space.num_blocks): local_l2_product = d.l2_product._blocks[ii, ii] block_space.mapper.copy_local_to_global( local_l2_product.matrix, local_l2_product.matrix.pattern(), ii, l2_mat) mass = d.l2_product operators = { k: v for k, v in d.operators.items() if k not in d.special_operators } global_mass = DuneXTMatrixOperator(l2_mat) local_div_ops, local_l2_products, local_projections, local_rt_projections = \ d_data['local_div_ops'], d_data['local_l2_products'], d_data['local_projections'], d_data['local_rt_projections'] for ii in range(d_data['grid'].num_subdomains): local_div = Concatenation( [local_div_ops[ii], local_rt_projections[ii]]) operators['r_ud_{}'.format(ii)] = \ Concatenation([local_projections[ii].T, local_l2_products[ii], local_div], name='r_ud_{}'.format(ii)) operators['r_l2_{}'.format(ii)] = \ Concatenation([local_projections[ii].T, local_l2_products[ii], local_projections[ii]], name='r_l2_{}'.format(ii)) e = d.estimator estimator = ParabolicEstimator(e.min_diffusion_evs, e.subdomain_diameters, e.local_eta_rf_squared, e.lambda_coeffs, e.mu_bar, e.mu_hat, e.flux_reconstruction, e.oswald_interpolation_error) d = InstationaryDuneDiscretization( d.global_operator, d.global_rhs, global_mass, T, d.operator.source.zeros(1), d.operator, d.rhs, mass=mass, time_stepper=ImplicitEulerTimeStepper(nt=nt, solver_options='operator'), products=d.products, operators=operators, estimator=estimator, visualizer=DuneGDTVisualizer(block_space)) d = d.with_(parameter_space=CubicParameterSpace( d.parameter_type, parameter_range[0], parameter_range[1])) return d, d_data