示例#1
0
    def initialize(self, method):
        Pusher.initialize(self, method)

        backend_class = getattr(_internal, "MonomialPusher" 
                + method.get_dimensionality_suffix())
        self.backend = backend_class(method.mesh_data)

        # add monomial basis data ---------------------------------------------
        from hedge.polynomial import generic_vandermonde
        from pyrticle._internal import MonomialBasisFunction, lu

        for i, eg in enumerate(method.mesh_data.discr.element_groups):
            ldis = eg.local_discretization

            from pyrticle._internal import LocalMonomialDiscretization
            lmd = LocalMonomialDiscretization()

            lmd.basis.extend([MonomialBasisFunction(*idx)
                for idx in ldis.node_tuples()])

            mon_vdm_t = numpy.asarray(
                    generic_vandermonde(ldis.unit_nodes(), lmd.basis).T,
                    order="C")

            lmd.lu_vandermonde_t, lmd.lu_piv_vandermonde_t = lu(mon_vdm_t)
            self.backend.local_discretizations.append(lmd)

            self.backend.ldis_indices.extend([i]*len(eg.members))
示例#2
0
文件: grid.py 项目: ra2003/pyrticle
    def scaled_vandermonde(self, el, eog, points, basis):
        """The remapping procedure in rec_grid relies on a pseudoinverse
        minimizing the pointwise error on all found interpolation points.
        But if an element spans bricks with different resolution, the 
        high-res points get an unfair advantage, because there's so many
        more of them. Therefore, each point is weighted by its 
        corresponding cell volume, meaning that the corresponding row of
        the structured Vandermonde matrix must be scaled by this volume, 
        as computed by L{find_points_in_element}. This routine returns the
        scaled Vandermonde matrix.
        """

        from hedge.polynomial import generic_vandermonde
        vdm = generic_vandermonde([el.inverse_map(x) for x in points], basis)

        for i, weight in enumerate(eog.weight_factors):
            vdm[i] *= weight

        return vdm
示例#3
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)
示例#4
0
文件: grid.py 项目: gimac/pyrticle
    def scaled_vandermonde(self, el, eog, points, basis):
        """The remapping procedure in rec_grid relies on a pseudoinverse
        minimizing the pointwise error on all found interpolation points.
        But if an element spans bricks with different resolution, the 
        high-res points get an unfair advantage, because there's so many
        more of them. Therefore, each point is weighted by its 
        corresponding cell volume, meaning that the corresponding row of
        the structured Vandermonde matrix must be scaled by this volume, 
        as computed by L{find_points_in_element}. This routine returns the
        scaled Vandermonde matrix.
        """

        from hedge.polynomial import generic_vandermonde
        vdm = generic_vandermonde(
                [el.inverse_map(x) for x in points], 
                basis)

        for i, weight in enumerate(eog.weight_factors):
            vdm[i] *= weight

        return vdm
示例#5
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)
示例#6
0
    def matrix(self, eg):
        class ChebyshevMode:
            def __init__(self, n):
                from math import pi
                self.n = n
                if n == 0:
                    self.normalization = 1/pi
                else:
                    self.normalization = 1/(pi/2)

            def __call__(self, x):
                from math import acos, cos
                return cos(self.n*acos(x[0]))

        from hedge.discretization.local import IntervalDiscretization
        assert isinstance(eg.local_discretization, IntervalDiscretization)

        ldis = eg.local_discretization
        modes = [ChebyshevMode(i) for i in range(ldis.order+1)]

        from hedge.polynomial import generic_vandermonde
        vdm = generic_vandermonde(ldis.unit_nodes(), modes)

        return numpy.asarray(la.inv(vdm), order="C")
示例#7
0
    def equidistant_vandermonde(self):
        from hedge.polynomial import generic_vandermonde

        return generic_vandermonde(list(self.equidistant_unit_nodes()),
                                   list(self.basis_functions()))
示例#8
0
    def equidistant_vandermonde(self):
        from hedge.polynomial import generic_vandermonde

        return generic_vandermonde(
                list(self.equidistant_unit_nodes()),
                list(self.basis_functions()))
示例#9
0
文件: grid.py 项目: ra2003/pyrticle
    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)
示例#10
0
 def face_vandermonde(self):
     from hedge.polynomial import generic_vandermonde
     return generic_vandermonde(self.face_nodes,
                                list(self.ldis.face_basis()))
示例#11
0
 def vandermonde(self):
     from hedge.polynomial import generic_vandermonde
     return generic_vandermonde(self.volume_nodes,
                                list(self.ldis.basis_functions()))
示例#12
0
    def face_vandermonde(self):
        from hedge.polynomial import generic_vandermonde

        return generic_vandermonde(self.unit_face_nodes(), self.face_basis())
示例#13
0
 def face_vandermonde(self):
     from hedge.polynomial import generic_vandermonde
     return generic_vandermonde(
             self.face_nodes,
             list(self.ldis.face_basis()))
示例#14
0
 def vandermonde(self):
     from hedge.polynomial import generic_vandermonde
     return generic_vandermonde(
             self.volume_nodes,
             list(self.ldis.basis_functions()))
示例#15
0
    def face_vandermonde(self):
        from hedge.polynomial import generic_vandermonde

        return generic_vandermonde(
                self.unit_face_nodes(),
                self.face_basis())
示例#16
0
文件: grid.py 项目: gimac/pyrticle
    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)