def __init__(self, order, dimension):
        """
        :arg order: A parameter correlated with the total degree of polynomials
            that are integrated exactly. (See also :attr:`exact_to`.)
        :arg dimension: The number of dimensions for the quadrature rule.
            Any positive integer.
        """
        s = order
        n = dimension
        d = 2*s + 1

        self.exact_to = d

        if dimension == 0:
            nodes = np.zeros((dimension, 1))
            weights = np.ones(1)

            Quadrature.__init__(self, nodes, weights)
            return

        from pytools import \
                generate_decreasing_nonnegative_tuples_summing_to, \
                generate_unique_permutations, \
                factorial, \
                wandering_element

        points_to_weights = {}

        for i in range(s + 1):
            weight = (-1)**i * 2**(-2*s) \
                    * (d + n - 2*i)**d \
                    / factorial(i) \
                    / factorial(d + n - i)

            for t in generate_decreasing_nonnegative_tuples_summing_to(s - i, n + 1):
                for beta in generate_unique_permutations(t):
                    denominator = d + n - 2*i
                    point = tuple(
                            _simplify_fraction((2*beta_i + 1, denominator))
                            for beta_i in beta)

                    points_to_weights[point] = \
                            points_to_weights.get(point, 0) + weight

        from operator import add

        vertices = ([-1 * np.ones((n,))]
                + [np.array(x)
                    for x in wandering_element(n, landscape=-1, wanderer=1)])

        nodes = []
        weights = []

        dim_factor = 2**n
        for p, w in points_to_weights.items():
            real_p = reduce(add, (a/b * v for (a, b), v in zip(p, vertices)))
            nodes.append(real_p)
            weights.append(dim_factor * w)

        Quadrature.__init__(self, np.array(nodes).T, np.array(weights))
Exemple #2
0
    def __init__(self, order, dimension):
        """
        :arg order: A parameter correlated with the total degree of polynomials
            that are integrated exactly. (See also :attr:`exact_to`.)
        :arg dimension: The number of dimensions for the quadrature rule.
            Any positive integer.
        """
        s = order
        n = dimension
        d = 2*s+1

        self.exact_to = d

        if dimension == 0:
            nodes = np.zeros((dimension, 1))
            weights = np.ones(1)

            Quadrature.__init__(self, nodes, weights)
            return

        from pytools import \
                generate_decreasing_nonnegative_tuples_summing_to, \
                generate_unique_permutations, \
                factorial, \
                wandering_element

        points_to_weights = {}

        for i in range(s+1):
            weight = (-1)**i * 2**(-2*s) \
                    * (d + n-2*i)**d \
                    / factorial(i) \
                    / factorial(d+n-i)

            for t in generate_decreasing_nonnegative_tuples_summing_to(s-i, n+1):
                for beta in generate_unique_permutations(t):
                    denominator = d+n-2*i
                    point = tuple(
                            _simplify_fraction((2*beta_i+1, denominator))
                            for beta_i in beta)

                    points_to_weights[point] = \
                            points_to_weights.get(point, 0) + weight

        from operator import add

        vertices = [-1 * np.ones((n,))] \
                + [np.array(x)
                        for x in wandering_element(n, landscape=-1, wanderer=1)]

        nodes = []
        weights = []

        dim_factor = 2**n
        for p, w in six.iteritems(points_to_weights):
            real_p = reduce(add, (a/b*v for (a, b), v in zip(p, vertices)))
            nodes.append(real_p)
            weights.append(dim_factor*w)

        Quadrature.__init__(self, np.array(nodes).T, np.array(weights))
Exemple #3
0
    def get_face_index_shuffle_lookup_map_for_nodes(self, face_nodes):
        first_face_vertex_node_index_lists = \
                self.geometry.face_vertices(self.vertex_indices())[0]

        def check_and_chop(pt):
            assert abs(pt[-1] - (-1)) < 1e-13
            return pt[:-1]

        unodes = self.unit_nodes()
        face_unit_vertices = [
            check_and_chop(unodes[i])
            for i in first_face_vertex_node_index_lists
        ]

        class FaceIndexShuffle:
            def __init__(self, vert_perm, idx_map):
                self.vert_perm = vert_perm
                self.idx_map = idx_map

            def __hash__(self):
                return hash(self.vert_perm)

            def __eq__(self, other):
                return self.vert_perm == other.vert_perm

            def __call__(self, indices):
                return tuple(indices[i] for i in self.idx_map)

        result = {}

        from pytools import generate_unique_permutations
        for vert_perm in generate_unique_permutations(
                tuple(range(self.dimensions))):
            permuted_face_unit_vertices = [
                face_unit_vertices[i] for i in vert_perm
            ]

            from hedge.tools.affine import identify_affine_map
            amap = identify_affine_map(face_unit_vertices,
                                       permuted_face_unit_vertices)

            from hedge.tools.indexing import find_index_map_from_node_sets
            imap = find_index_map_from_node_sets(
                face_nodes, [amap(node) for node in face_nodes])

            result[vert_perm] = FaceIndexShuffle(vert_perm, imap)

        return result
Exemple #4
0
    def get_face_index_shuffle_lookup_map_for_nodes(self, face_nodes):
        first_face_vertex_node_index_lists = \
                self.geometry.face_vertices(self.vertex_indices())[0]

        def check_and_chop(pt):
            assert abs(pt[-1] - (-1)) < 1e-13
            return pt[:-1]

        unodes = self.unit_nodes()
        face_unit_vertices = [check_and_chop(unodes[i])
                for i in first_face_vertex_node_index_lists]

        class FaceIndexShuffle:
            def __init__(self, vert_perm, idx_map):
                self.vert_perm = vert_perm
                self.idx_map = idx_map

            def __hash__(self):
                return hash(self.vert_perm)

            def __eq__(self, other):
                return self.vert_perm == other.vert_perm

            def __call__(self, indices):
                return tuple(indices[i] for i in self.idx_map)

        result = {}

        from pytools import generate_unique_permutations
        for vert_perm in generate_unique_permutations(
                tuple(range(self.dimensions))):
            permuted_face_unit_vertices = [
                    face_unit_vertices[i] for i in vert_perm]

            from hedge.tools.affine import identify_affine_map
            amap = identify_affine_map(
                    face_unit_vertices, permuted_face_unit_vertices)

            from hedge.tools.indexing import find_index_map_from_node_sets
            imap = find_index_map_from_node_sets(
                    face_nodes, [amap(node) for node in face_nodes])

            result[vert_perm] = FaceIndexShuffle(vert_perm, imap)

        return result
Exemple #5
0
    def __init__(self, order, dimension):
        s = order
        n = dimension
        d = 2*s+1

        self.exact_to = d

        from pytools import \
                generate_decreasing_nonnegative_tuples_summing_to, \
                generate_unique_permutations, \
                factorial, \
                wandering_element

        points_to_weights = {}

        for i in xrange(s+1):
            weight = (-1)**i * 2**(-2*s) \
                    * (d + n-2*i)**d \
                    / factorial(i) \
                    / factorial(d+n-i)

            for t in generate_decreasing_nonnegative_tuples_summing_to(s-i, n+1):
                for beta in generate_unique_permutations(t):
                    denominator = d+n-2*i
                    point = tuple(
                            _simplify_fraction((2*beta_i+1, denominator))
                            for beta_i in beta)

                    points_to_weights[point] = points_to_weights.get(point, 0) + weight

        from operator import add

        vertices = [-1 * numpy.ones((n,))] \
                + [numpy.array(x) for x in wandering_element(n, landscape=-1, wanderer=1)]

        self.pos_points = []
        self.pos_weights = []
        self.neg_points = []
        self.neg_weights = []

        dim_factor = 2**n
        for p, w in points_to_weights.iteritems():
            real_p = reduce(add, (a/b*v for (a,b),v in zip(p, vertices)))
            if w > 0:
                self.pos_points.append(real_p)
                self.pos_weights.append(dim_factor*w)
            else:
                self.neg_points.append(real_p)
                self.neg_weights.append(dim_factor*w)

        self.points = numpy.array(self.pos_points + self.neg_points)
        self.weights = numpy.array(self.pos_weights + self.neg_weights)

        self.pos_points = numpy.array(self.pos_points)
        self.pos_weights = numpy.array(self.pos_weights)
        self.neg_points = numpy.array(self.neg_points)
        self.neg_weights = numpy.array(self.neg_weights)

        self.points = numpy.array(self.points)
        self.weights = numpy.array(self.weights)

        self.pos_info = zip(self.pos_points, self.pos_weights)
        self.neg_info = zip(self.neg_points, self.neg_weights)
Exemple #6
0
    def __init__(self, order, dimension):
        s = order
        n = dimension
        d = 2 * s + 1

        self.exact_to = d

        from pytools import \
                generate_decreasing_nonnegative_tuples_summing_to, \
                generate_unique_permutations, \
                factorial, \
                wandering_element

        points_to_weights = {}

        for i in xrange(s + 1):
            weight = (-1)**i * 2**(-2*s) \
                    * (d + n-2*i)**d \
                    / factorial(i) \
                    / factorial(d+n-i)

            for t in generate_decreasing_nonnegative_tuples_summing_to(
                    s - i, n + 1):
                for beta in generate_unique_permutations(t):
                    denominator = d + n - 2 * i
                    point = tuple(
                        _simplify_fraction((2 * beta_i + 1, denominator))
                        for beta_i in beta)

                    points_to_weights[point] = points_to_weights.get(
                        point, 0) + weight

        from operator import add

        vertices = [-1 * numpy.ones((n,))] \
                + [numpy.array(x) for x in wandering_element(n, landscape=-1, wanderer=1)]

        self.pos_points = []
        self.pos_weights = []
        self.neg_points = []
        self.neg_weights = []

        dim_factor = 2**n
        for p, w in points_to_weights.iteritems():
            real_p = reduce(add, (a / b * v for (a, b), v in zip(p, vertices)))
            if w > 0:
                self.pos_points.append(real_p)
                self.pos_weights.append(dim_factor * w)
            else:
                self.neg_points.append(real_p)
                self.neg_weights.append(dim_factor * w)

        self.points = numpy.array(self.pos_points + self.neg_points)
        self.weights = numpy.array(self.pos_weights + self.neg_weights)

        self.pos_points = numpy.array(self.pos_points)
        self.pos_weights = numpy.array(self.pos_weights)
        self.neg_points = numpy.array(self.neg_points)
        self.neg_weights = numpy.array(self.neg_weights)

        self.points = numpy.array(self.points)
        self.weights = numpy.array(self.weights)

        self.pos_info = zip(self.pos_points, self.pos_weights)
        self.neg_info = zip(self.neg_points, self.neg_weights)