This file is indexed.

/usr/lib/python2.7/dist-packages/FIAT/regge.py is in python-fiat 1.6.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# Copyright (C) 2015-2017 Lizao Li
#
# This file is part of FIAT.
#
# FIAT is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FIAT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FIAT. If not, see <http://www.gnu.org/licenses/>.

import numpy

from .finite_element import FiniteElement
from .dual_set import DualSet
from .polynomial_set import ONSymTensorPolynomialSet
from .functional import PointwiseInnerProductEvaluation as InnerProduct
from .functional import index_iterator
from .reference_element import UFCTriangle, UFCTetrahedron

class ReggeDual(DualSet):
    """
    """
    def __init__ (self, cell, degree):
        (dofs, ids) = self.generate_degrees_of_freedom(cell, degree)
        DualSet.__init__(self, dofs, cell, ids)

    def generate_degrees_of_freedom(self, cell, degree):
        """ 
        Suppose f is a k-face of the reference n-cell. Let t1,...,tk be a
        basis for the tangent space of f as n-vectors. Given a symmetric
        2-tensor field u on Rn. One set of dofs for Regge(r) on f is
        the moment of each of the (k+1)k/2 scalar functions 
          [u(t1,t1),u(t1,t2),...,u(t1,tk), 
           u(t2,t2), u(t2,t3),...,..., u(tk,tk)] 
        aginst scalar polynomials of degrees (r-k+1). Here this is
        implemented as pointwise evaluations of those scalar functions.

        Below is an implementation for dimension 2--3. In dimension 1, 
        Regge(r)=DG(r). It is awkward in the current FEniCS interface to
        implement the element uniformly for all dimensions due to its edge,
        facet=trig, cell style.
        """
        
        dofs = []
        ids = {}
        
        top = cell.get_topology()
        d = cell.get_spatial_dimension()
        if (d < 2) or (d > 3):
            raise("Regge elements only implemented for dimension 2--3.")
        
        # No vertex dof
        ids[0] = dict(list(zip(list(range(d+1)), ([] for i in range(d+1)))))
        # edge dofs
        (_dofs, _ids) = self._generate_edge_dofs(cell, degree, 0)
        dofs.extend(_dofs)
        ids[1] = _ids
        # facet dofs for 3D
        if d == 3:
            (_dofs, _ids) = self._generate_facet_dofs(cell, degree, len(dofs))
            dofs.extend(_dofs)
            ids[2] = _ids
        # Cell dofs
        (_dofs, _ids) = self._generate_cell_dofs(cell, degree, len(dofs))
        dofs.extend(_dofs)
        ids[d] = _ids
        return (dofs, ids)

    def _generate_edge_dofs(self, cell, degree, offset):
        """Generate dofs on edges."""
        dofs = []
        ids = {}
        for s in range(len(cell.get_topology()[1])):
            # Points to evaluate the inner product            
            pts = cell.make_points(1, s, degree + 2)
            # Evalute squared length of the tagent vector along an edge
            t = cell.compute_edge_tangent(s)
            # Fill dofs
            dofs += [InnerProduct(cell, t, t, p) for p in pts]
            # Fill ids
            i = len(pts) * s
            ids[s] = list(range(offset + i, offset + i + len(pts)))
        return (dofs, ids)

    def _generate_facet_dofs(self, cell, degree, offset):
        """Generate dofs on facets in 3D."""
        # Return empty if there is no such dofs
        dofs = []
        d = cell.get_spatial_dimension()
        ids = dict(list(zip(list(range(4)), ([] for i in range(4)))))
        if degree == 0:
            return (dofs, ids)
        # Compute dofs
        for s in range(len(cell.get_topology()[2])):
            # Points to evaluate the inner product
            pts = cell.make_points(2, s, degree + 2)
            # Let t1 and t2 be the two tangent vectors along a triangle
            # we evaluate u(t1,t1), u(t1,t2), u(t2,t2) at each point.
            (t1, t2) = cell.compute_face_tangents(s)
            # Fill dofs
            for p in pts:
                dofs += [InnerProduct(cell, t1, t1, p),
                         InnerProduct(cell, t1, t2, p),
                         InnerProduct(cell, t2, t2, p)]
            # Fill ids
            i = len(pts) * s * 3
            ids[s] = list(range(offset + i, offset + i + len(pts) * 3))
        return (dofs, ids)

    def _generate_cell_dofs(self, cell, degree, offset):
        """Generate dofs for cells."""
        # Return empty if there is no such dofs
        dofs = []
        d = cell.get_spatial_dimension()
        if (d == 2 and degree == 0) or (d == 3 and degree <= 1):
            return ([], {0: []})
        # Compute dofs. There is only one cell. So no need to loop here~ 
        # Points to evaluate the inner product
        pts = cell.make_points(d, 0, degree + 2)
        # Let {e1,..,ek} be the Euclidean basis. We evaluate inner products
        #   u(e1,e1), u(e1,e2), u(e1,e3), u(e2,e2), u(e2,e3),..., u(ek,ek)
        # at each point.
        e = numpy.eye(d)
        # Fill dofs
        for p in pts:
            dofs += [InnerProduct(cell, e[i], e[j], p)
                     for [i,j] in index_iterator((d, d)) if i <= j]
        # Fill ids
        ids = {0 :
               list(range(offset, offset + len(pts) * d * (d + 1) // 2))}
        return (dofs, ids)

class Regge(FiniteElement):
    """
    The Regge elements on triangles and tetrahedra: the polynomial space
    described by the full polynomials of degree k with degrees of freedom
    to ensure its pullback as a metric to each interior facet and edge is
    single-valued.
    """

    def __init__(self, cell, degree):
        # Check degree
        assert(degree >= 0), "Regge start at degree 0!"
        # Get dimension
        d = cell.get_spatial_dimension()
        # Construct polynomial basis for d-vector fields
        Ps = ONSymTensorPolynomialSet(cell, degree)
        # Construct dual space
        Ls = ReggeDual(cell, degree)
        # Set mapping
        mapping = "pullback as metric"
        # Call init of super-class
        FiniteElement.__init__(self, Ps, Ls, degree, mapping=mapping)

if __name__=="__main__":
    print("Test 0: Regge degree 0 in 2D.")
    T = UFCTriangle()
    R = Regge(T, 0)
    print("-----")
    pts = numpy.array([[0.0, 0.0]])
    ts = numpy.array([[0.0, 1.0],
                      [1.0, 0.0],
                      [-1.0, 1.0]])
    vals = R.tabulate(0, pts)[(0, 0)]
    for i in range(R.space_dimension()):
        print("Basis #{}:".format(i))
        for j in range(len(pts)):
            tut = [t.dot(vals[i, :, :, j].dot(t)) for t in ts]
            print("u(t,t) for edge tagents t at {} are: {}".format(
                pts[j], tut))
    print("-----")
    print("Expected result: a single 1 for each basis and zeros for others.")
    print("")

    print("Test 1: Regge degree 0 in 3D.")
    T = UFCTetrahedron()
    R = Regge(T, 0)
    print("-----")
    pts = numpy.array([[0.0, 0.0, 0.0]])
    ts = numpy.array([[1.0, 0.0, 0.0],
                      [0.0, 1.0, 0.0],
                      [0.0, 0.0, 1.0],
                      [1.0, -1.0, 0.0],
                      [1.0, 0.0, -1.0],
                      [0.0, 1.0, -1.0]])
    vals = R.tabulate(0, pts)[(0, 0, 0)]
    for i in range(R.space_dimension()):
        print("Basis #{}:".format(i))
        for j in range(len(pts)):
            tut = [t.dot(vals[i, :, :, j].dot(t)) for t in ts]
            print("u(t,t) for edge tagents t at {} are: {}".format(
                pts[j], tut))
    print("-----")
    print("Expected result: a single 1 for each basis and zeros for others.")
    print("")

    print("Test 2: association of dofs to mesh entities.")
    print("------")
    for k in range(0, 3):
        print("Degree {} in 2D:".format(k))
        T = UFCTriangle()
        R = Regge(T, k)
        print(R.entity_dofs())
        print("")
    for k in range(0, 3):
        print("Degree {} in 3D:".format(k))
        T = UFCTetrahedron()
        R = Regge(T, k)
        print(R.entity_dofs())        
        print("")