class OswaldInterpolationErrorOperator(OperatorBase): linear = True def __init__(self, subdomain, solution_space, grid, block_space): self.subdomain, self.grid, self.block_space = subdomain, grid, block_space self.neighborhood = grid.neighborhood_of(subdomain) self.source = solution_space.subspaces[subdomain] self.range = BlockVectorSpace( [solution_space.subspaces[ii] for ii in self.neighborhood], 'OI_{}'.format(subdomain)) def apply(self, U, mu=None): assert U in self.source results = self.range.empty(reserve=len(U)) for u_i in range(len(U)): result = self.range.zeros() result._blocks[self.neighborhood.index(self.subdomain)].axpy( 1, U[u_i]) for i_ii, ii in enumerate(self.neighborhood): ii_neighborhood = self.grid.neighborhood_of(ii) ii_neighborhood_space = self.block_space.restricted_to_neighborhood( ii_neighborhood) subdomain_uh_with_neighborhood_support = make_discrete_function( ii_neighborhood_space, ii_neighborhood_space.project_onto_neighborhood([ U._list[u_i].impl if nn == self.subdomain else Vector( self.block_space.local_space(nn).size(), 0.) for nn in ii_neighborhood ], ii_neighborhood)) interpolated_u_vector = ii_neighborhood_space.project_onto_neighborhood( [ Vector(self.block_space.local_space(nn).size(), 0.) for nn in ii_neighborhood ], ii_neighborhood) interpolated_u = make_discrete_function( ii_neighborhood_space, interpolated_u_vector) apply_oswald_interpolation_operator( self.grid, ii, make_subdomain_boundary_info( self.grid, {'type': 'xt.grid.boundaryinfo.alldirichlet'}), subdomain_uh_with_neighborhood_support, interpolated_u) local_sizes = np.array([ ii_neighborhood_space.local_space(nn).size() for nn in ii_neighborhood ]) offsets = np.hstack(([0], np.cumsum(local_sizes))) ind = ii_neighborhood.index(ii) result._blocks[i_ii]._list[0].data[:] -= \ np.frombuffer(interpolated_u_vector)[offsets[ind]:offsets[ind+1]] results.append(result) return results
class FluxReconstructionOperator(OperatorBase): linear = True def __init__(self, subdomain, solution_space, grid, block_space, global_rt_space, subdomain_rt_spaces, lambda_xi, kappa): self.grid = grid self.block_space = block_space self.global_rt_space = global_rt_space self.subdomain_rt_spaces = subdomain_rt_spaces self.subdomain = subdomain self.neighborhood = grid.neighborhood_of(subdomain) self.lambda_xi = lambda_xi self.kappa = kappa self.source = solution_space.subspaces[subdomain] vector_type = solution_space.subspaces[0].vector_type self.range = BlockVectorSpace([ DuneXTVectorSpace(vector_type, subdomain_rt_spaces[ii].size(), 'LOCALRT_' + str(ii)) for ii in self.grid.neighborhood_of(subdomain) ], 'RT_{}'.format(subdomain)) def apply(self, U, mu=None): assert U in self.source result = self.range.empty(reserve=len(U)) local_subdomains, num_local_subdomains, num_global_subdomains = _get_subdomains( self.grid) for u_i in range(len(U)): subdomain_uhs_with_global_support = \ make_discrete_function( self.block_space, self.block_space.project_onto_neighborhood( [U._list[u_i].impl if nn == self.subdomain else Vector(self.block_space.local_space(nn).size(), 0.) for nn in range(num_global_subdomains)], [nn for nn in range(num_global_subdomains)] ) ) reconstructed_uh_kk_with_global_support = make_discrete_function( self.global_rt_space) apply_diffusive_flux_reconstruction_in_neighborhood( self.grid, self.subdomain, self.lambda_xi, self.kappa, subdomain_uhs_with_global_support, reconstructed_uh_kk_with_global_support) blocks = [ s.make_array([ self.subdomain_rt_spaces[ii].restrict( reconstructed_uh_kk_with_global_support.vector_copy()) ]) # NOQA for s, ii in zip(self.range.subspaces, self.grid.neighborhood_of(self.subdomain)) ] result.append(self.range.make_array(blocks)) return result