コード例 #1
0
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