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 OswaldInterpolationErrorOperator(EstimatorOperatorBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) assert self.subdomain == self.kk == self.jj self.range = BlockVectorSpace([self.global_space.subspaces[ii] for ii in self.neighborhood], 'OI_{}'.format(self.subdomain)) def _apply(self, U, mu=None): from dune.gdt import apply_oswald_interpolation_operator assert len(U) == 1 assert U in self.source result = self.range.zeros() result._blocks[self.neighborhood.index(self.subdomain)].axpy(1, U) 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[0].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]] return result