Exemple #1
0
 def volume_up_interpolation_matrix(self):
     from hedge.tools.linalg import leftsolve
     return numpy.asarray(
             leftsolve(
                 self.ldis.vandermonde(),
                 self.vandermonde()),
             order="C")
Exemple #2
0
    def make_pointwise_interpolation_matrix(self, eog, eg, el, ldis, svd, scaled_vdm,
            basis_subset=None):
        u, s, vt = svd

        point_count = u.shape[0]
        node_count = vt.shape[1]

        thresh = (numpy.finfo(float).eps * max(s.shape) * s[0])

        nonzero_flags = numpy.abs(s) >= thresh
        inv_s = numpy.zeros((len(s),), dtype=float)
        inv_s[nonzero_flags] = 1/s[nonzero_flags]

        if not nonzero_flags.all():
            from warnings import warn
            warn("grid dep: taking pseudoinverse of poorly conditioned matrix--"
                    "this should have been caught earlier")

        # compute the pseudoinverse of the structured Vandermonde matrix
        inv_s_diag = numpy.zeros(
                (node_count, point_count), 
                dtype=float)
        inv_s_diag[:len(s),:len(s)] = numpy.diag(inv_s)

        svdm_pinv = numpy.dot(numpy.dot(vt.T, inv_s_diag), u.T)

        # check that it's reasonable
        pinv_resid = la.norm(
            numpy.dot(svdm_pinv, scaled_vdm)
            - numpy.eye(node_count))

        if pinv_resid > 1e-8:
            from warnings import warn
            warn("rec_grid: bad pseudoinv precision, element=%d, "
                    "#nodes=%d, #sgridpts=%d, resid=%.5g centroid=%s"
                % (el.id, node_count, point_count, pinv_resid,
                        el.centroid(self.method.discretization.mesh.points)))

        el_vdm = ldis.vandermonde()
        if basis_subset is not None:
            el_vdm = el_vdm[:,basis_subset]
        imat = numpy.dot(el_vdm, svdm_pinv)

        if self.filter is not None:
            imat = numpy.dot(self.filter.get_filter_matrix(eg), imat)

        assert not numpy.isnan(imat).any(), \
                "encountered NaN in element %d's interpolation matrix" % el.id
        assert not numpy.isinf(imat).any(), \
                "encountered infinity in element %d's interpolation matrix" % el.id

        eog.interpolation_matrix = numpy.asarray(imat, order="F")

        if basis_subset is None:
            from hedge.tools import leftsolve
            eog.inverse_interpolation_matrix = numpy.asarray(
                    leftsolve(el_vdm, scaled_vdm), order="F")
Exemple #3
0
    def differentiation_matrices(self):
        """Return matrices that map the nodal values of a function
        to the nodal values of its derivative in each of the unit
        coordinate directions.
        """

        from hedge.tools import leftsolve

        # see doc/hedge-notes.tm
        v = self.vandermonde()
        return [leftsolve(v, vdiff) for vdiff in self.grad_vandermonde()]
Exemple #4
0
    def differentiation_matrices(self):
        """Return matrices that map the nodal values of a function
        to the nodal values of its derivative in each of the unit
        coordinate directions.
        """

        from hedge.tools import leftsolve
        # see doc/hedge-notes.tm
        v = self.vandermonde()
        return [
            numpy.asarray(leftsolve(v, vdiff), order="C")
            for vdiff in self.grad_vandermonde()
        ]
Exemple #5
0
    def matrix(self, eg):
        ldis = eg.local_discretization

        filter_coeffs = [self.mode_response_func(mid, ldis)
            for mid in ldis.generate_mode_identifiers()]

        # build filter matrix
        vdm = ldis.vandermonde()
        from hedge.tools import leftsolve
        mat = np.asarray(
            leftsolve(vdm,
                np.dot(vdm, np.diag(filter_coeffs))),
            order="C")

        return mat
Exemple #6
0
    def matrix(self, eg):
        ldis = eg.local_discretization

        filter_coeffs = [
            self.mode_response_func(mid, ldis)
            for mid in ldis.generate_mode_identifiers()
        ]

        # build filter matrix
        vdm = ldis.vandermonde()
        from hedge.tools import leftsolve
        mat = np.asarray(leftsolve(vdm, np.dot(vdm, np.diag(filter_coeffs))),
                         order="C")

        return mat
Exemple #7
0
        def volume_to_face_up_interpolation_matrix(self):
            """Generate a matrix that maps volume nodal values to
            a vector of face nodal values on the quadrature grid, with
            faces immediately concatenated, i.e::

                [face 1 nodal data][face 2 nodal data]...
            """
            ldis = self.ldis

            face_maps = ldis.face_affine_maps()

            from pytools import flatten
            face_nodes = list(
                flatten([face_map(qnode) for qnode in self.face_nodes]
                        for face_map in face_maps))

            from hedge.polynomial import generic_vandermonde
            vdm = generic_vandermonde(face_nodes, list(ldis.basis_functions()))

            from hedge.tools.linalg import leftsolve
            return leftsolve(self.ldis.vandermonde(), vdm)
Exemple #8
0
        def volume_to_face_up_interpolation_matrix(self):
            """Generate a matrix that maps volume nodal values to
            a vector of face nodal values on the quadrature grid, with 
            faces immediately concatenated, i.e::

                [face 1 nodal data][face 2 nodal data]...
            """
            ldis = self.ldis

            face_maps = ldis.face_affine_maps()

            from pytools import flatten

            face_nodes = list(flatten([face_map(qnode) for qnode in self.face_nodes] for face_map in face_maps))

            from hedge.polynomial import generic_vandermonde

            vdm = generic_vandermonde(face_nodes, list(ldis.basis_functions()))

            from hedge.tools.linalg import leftsolve

            return leftsolve(self.ldis.vandermonde(), vdm)
Exemple #9
0
    def prepare_with_brick_interpolation(self):
        class TensorProductLegendreBasisFunc:
            def __init__(self, n):
                from hedge.polynomial import LegendreFunction
                self.funcs = [LegendreFunction(n_i) for n_i in n]

            def __call__(self, x):
                result = 1
                for f_i, x_i in zip(self.funcs, x):
                    result *= f_i(x_i)
                return result

        def make_legendre_basis(dimensions):
            from pytools import generate_nonnegative_integer_tuples_below
            return [
                TensorProductLegendreBasisFunc(n)
                for n in generate_nonnegative_integer_tuples_below(dimensions)
            ]

        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
            sum(len(eg.members) for eg in discr.element_groups))

        from pyrticle._internal import ElementOnGrid, BoxFloat

        total_points = 0

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points))

                scaled_tolerance = self.el_tolerance * la.norm(
                    el.map.matrix, 2)
                el_bbox.lower -= scaled_tolerance
                el_bbox.upper += scaled_tolerance

                # For each brick, find all element nodes that lie in it
                for brk in backend.bricks:
                    eog = ElementOnGrid()
                    eog.element_number = el.id

                    brk_bbox = brk.bounding_box()
                    brk_and_el = brk_bbox.intersect(el_bbox)

                    if brk_and_el.is_empty():
                        continue

                    el_nodes = []
                    el_node_indices = []
                    el_slice = discr.find_el_range(el.id)
                    el_length = el_slice.stop - el_slice.start
                    if brk_and_el == el_bbox:
                        # whole element in brick? fantastic.
                        el_nodes = discr.nodes[el_slice]
                        el_node_indices = range(el_length)
                    else:
                        # no? go through the nodes one by one.
                        for i, node in enumerate(discr.nodes[el_slice]):
                            # this containment check has to be exact,
                            # we positively cannot have nodes belong to
                            # two bricks
                            if brk_bbox.contains(node, threshold=0):
                                el_nodes.append(node)
                                el_node_indices.append(i)

                    idx_range = brk.index_range(brk_and_el)
                    lb = make_legendre_basis(idx_range.upper - idx_range.lower)

                    from hedge.polynomial import generic_vandermonde
                    brk_and_el_points = [
                        brk.point(c)
                        for c in self.iterator_type(brk, idx_range)
                    ]
                    svdm = generic_vandermonde(points=brk_and_el_points,
                                               functions=lb)
                    total_points += len(brk_and_el_points)

                    mixed_vdm_pre = generic_vandermonde(points=el_nodes,
                                                        functions=lb)

                    if len(el_nodes) < el_length:
                        mixed_vdm = numpy.zeros((el_length, len(lb)),
                                                dtype=float)
                        for i, vdm_row in enumerate(mixed_vdm_pre):
                            mixed_vdm[el_node_indices[i]] = vdm_row
                    else:
                        mixed_vdm = mixed_vdm_pre

                    from hedge.tools import leftsolve
                    eog.interpolation_matrix = numpy.asarray(leftsolve(
                        svdm, mixed_vdm),
                                                             order="Fortran")
                    #print eog.interpolation_matrix.shape
                    #raw_input()

                    eog.grid_nodes.extend(
                        brk.index(c)
                        for c in self.iterator_type(brk, idx_range))
                    eog.weight_factors = numpy.ones((len(eog.grid_nodes), ),
                                                    dtype=numpy.float64)
                    backend.elements_on_grid.append(eog)

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0] *
                                                (len(backend.bricks) + 1))

        # stats
        self.generate_point_statistics(0)
Exemple #10
0
    def make_pointwise_interpolation_matrix(self,
                                            eog,
                                            eg,
                                            el,
                                            ldis,
                                            svd,
                                            scaled_vdm,
                                            basis_subset=None):
        u, s, vt = svd

        point_count = u.shape[0]
        node_count = vt.shape[1]

        thresh = (numpy.finfo(float).eps * max(s.shape) * s[0])

        nonzero_flags = numpy.abs(s) >= thresh
        inv_s = numpy.zeros((len(s), ), dtype=float)
        inv_s[nonzero_flags] = 1 / s[nonzero_flags]

        if not nonzero_flags.all():
            from warnings import warn
            warn(
                "grid dep: taking pseudoinverse of poorly conditioned matrix--"
                "this should have been caught earlier")

        # compute the pseudoinverse of the structured Vandermonde matrix
        inv_s_diag = numpy.zeros((node_count, point_count), dtype=float)
        inv_s_diag[:len(s), :len(s)] = numpy.diag(inv_s)

        svdm_pinv = numpy.dot(numpy.dot(vt.T, inv_s_diag), u.T)

        # check that it's reasonable
        pinv_resid = la.norm(
            numpy.dot(svdm_pinv, scaled_vdm) - numpy.eye(node_count))

        if pinv_resid > 1e-8:
            from warnings import warn
            warn("rec_grid: bad pseudoinv precision, element=%d, "
                 "#nodes=%d, #sgridpts=%d, resid=%.5g centroid=%s" %
                 (el.id, node_count, point_count, pinv_resid,
                  el.centroid(self.method.discretization.mesh.points)))

        el_vdm = ldis.vandermonde()
        if basis_subset is not None:
            el_vdm = el_vdm[:, basis_subset]
        imat = numpy.dot(el_vdm, svdm_pinv)

        if self.filter is not None:
            imat = numpy.dot(self.filter.get_filter_matrix(eg), imat)

        assert not numpy.isnan(imat).any(), \
                "encountered NaN in element %d's interpolation matrix" % el.id
        assert not numpy.isinf(imat).any(), \
                "encountered infinity in element %d's interpolation matrix" % el.id

        eog.interpolation_matrix = numpy.asarray(imat, order="F")

        if basis_subset is None:
            from hedge.tools import leftsolve
            eog.inverse_interpolation_matrix = numpy.asarray(leftsolve(
                el_vdm, scaled_vdm),
                                                             order="F")
Exemple #11
0
 def face_up_interpolation_matrix(self):
     from hedge.tools.linalg import leftsolve
     return leftsolve(self.ldis.face_vandermonde(),
                      self.face_vandermonde())
Exemple #12
0
 def volume_up_interpolation_matrix(self):
     from hedge.tools.linalg import leftsolve
     return numpy.asarray(leftsolve(self.ldis.vandermonde(),
                                    self.vandermonde()),
                          order="C")
Exemple #13
0
 def face_up_interpolation_matrix(self):
     from hedge.tools.linalg import leftsolve
     return leftsolve(
                 self.ldis.face_vandermonde(),
                 self.face_vandermonde())
Exemple #14
0
    def prepare_with_brick_interpolation(self):
        class TensorProductLegendreBasisFunc:
            def __init__(self, n):
                from hedge.polynomial import LegendreFunction
                self.funcs = [LegendreFunction(n_i) for n_i in n]

            def __call__(self, x):
                result = 1
                for f_i, x_i in zip(self.funcs, x):
                    result *= f_i(x_i)
                return result

        def make_legendre_basis(dimensions):
            from pytools import generate_nonnegative_integer_tuples_below
            return [TensorProductLegendreBasisFunc(n)
                for n in generate_nonnegative_integer_tuples_below(dimensions)]

        discr = self.method.discretization
        backend = self.backend

        backend.elements_on_grid.reserve(
                sum(len(eg.members) for eg in discr.element_groups))

        from pyrticle._internal import ElementOnGrid, BoxFloat

        total_points = 0

        # Iterate over all elements
        for eg in discr.element_groups:
            ldis = eg.local_discretization

            for el in eg.members:
                el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points))

                scaled_tolerance = self.el_tolerance * la.norm(el.map.matrix, 2)
                el_bbox.lower -= scaled_tolerance
                el_bbox.upper += scaled_tolerance

                # For each brick, find all element nodes that lie in it
                for brk in backend.bricks:
                    eog = ElementOnGrid()
                    eog.element_number = el.id

                    brk_bbox = brk.bounding_box()
                    brk_and_el = brk_bbox.intersect(el_bbox)

                    if brk_and_el.is_empty():
                        continue

                    el_nodes = []
                    el_node_indices = []
                    el_slice = discr.find_el_range(el.id)
                    el_length = el_slice.stop-el_slice.start
                    if brk_and_el == el_bbox:
                        # whole element in brick? fantastic.
                        el_nodes = discr.nodes[el_slice]
                        el_node_indices = range(el_length)
                    else:
                        # no? go through the nodes one by one.
                        for i, node in enumerate(discr.nodes[el_slice]):
                            # this containment check has to be exact,
                            # we positively cannot have nodes belong to
                            # two bricks
                            if brk_bbox.contains(node, threshold=0):
                                el_nodes.append(node)
                                el_node_indices.append(i)

                    idx_range = brk.index_range(brk_and_el)
                    lb = make_legendre_basis(idx_range.upper-idx_range.lower)

                    from hedge.polynomial import generic_vandermonde
                    brk_and_el_points = [brk.point(c) 
                            for c in self.iterator_type(brk, idx_range)]
                    svdm = generic_vandermonde(
                            points=brk_and_el_points,
                            functions=lb)
                    total_points += len(brk_and_el_points)

                    mixed_vdm_pre = generic_vandermonde(
                            points=el_nodes, functions=lb)

                    if len(el_nodes) < el_length:
                        mixed_vdm = numpy.zeros((el_length, len(lb)),
                                dtype=float)
                        for i, vdm_row in enumerate(mixed_vdm_pre):
                            mixed_vdm[el_node_indices[i]] = vdm_row
                    else:
                        mixed_vdm = mixed_vdm_pre

                    from hedge.tools import leftsolve
                    eog.interpolation_matrix = numpy.asarray(
                            leftsolve(svdm, mixed_vdm),
                            order="Fortran")
                    #print eog.interpolation_matrix.shape
                    #raw_input()

                    eog.grid_nodes.extend(brk.index(c) 
                            for c in self.iterator_type(brk, idx_range))
                    eog.weight_factors = numpy.ones(
                            (len(eog.grid_nodes),), dtype=numpy.float64)
                    backend.elements_on_grid.append(eog)

        # we don't need no stinkin' extra points
        backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1))

        # stats
        self.generate_point_statistics(0)