/usr/lib/python2.7/dist-packages/ufl/cell.py is in python-ufl 2016.2.0-2.
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 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | # -*- coding: utf-8 -*-
"Types for representing a cell."
# Copyright (C) 2008-2016 Martin Sandve Alnæs
#
# This file is part of UFL.
#
# UFL 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.
#
# UFL 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 UFL. If not, see <http://www.gnu.org/licenses/>.
#
# Modified by Anders Logg, 2009.
# Modified by Kristian B. Oelgaard, 2009
# Modified by Marie E. Rognes 2012
# Modified by Andrew T. T. McRae, 2014
# Modified by Massimiliano Leoni, 2016
from six.moves import reduce
from six import string_types
import numbers
from ufl.utils.py23 import as_native_str
from ufl.utils.py23 import as_native_strings
from ufl.log import error
from ufl.core.ufl_type import attach_operators_from_hash_data
# Export list for ufl.classes
__all_classes__ = as_native_strings(["AbstractCell", "Cell", "TensorProductCell"])
# --- The most abstract cell class, base class for other cell types
class AbstractCell(object):
"Representation of an abstract finite element cell with only the dimensions known."
__slots__ = as_native_strings((
"_topological_dimension",
"_geometric_dimension",
))
def __init__(self, topological_dimension, geometric_dimension):
# Validate dimensions
if not isinstance(geometric_dimension, numbers.Integral):
error("Expecting integer geometric_dimension.")
if not isinstance(topological_dimension, numbers.Integral):
error("Expecting integer topological_dimension.")
if topological_dimension > geometric_dimension:
error("Topological dimension cannot be larger than geometric dimension.")
# Store validated dimensions
self._topological_dimension = topological_dimension
self._geometric_dimension = geometric_dimension
def topological_dimension(self):
"Return the dimension of the topology of this cell."
return self._topological_dimension
def geometric_dimension(self):
"Return the dimension of the space this cell is embedded in."
return self._geometric_dimension
def is_simplex(self):
"Return True if this is a simplex cell."
raise NotImplementedError("Implement this to allow important checks and optimizations.")
def has_simplex_facets(self):
"Return True if all the facets of this cell are simplex cells."
raise NotImplementedError("Implement this to allow important checks and optimizations.")
def __lt__(self, other):
"Define an arbitrarily chosen but fixed sort order for all cells."
if not isinstance(other, AbstractCell):
return NotImplemented
# Sort by gdim first, tdim next, then whatever's left
# depending on the subclass
s = (self.geometric_dimension(), self.topological_dimension())
o = (other.geometric_dimension(), other.topological_dimension())
if s != o:
return s < o
return self._ufl_hash_data_() < other._ufl_hash_data_()
def __unicode__(self):
# Only in python 2
return str(self).decode("utf-8")
# --- Basic topological properties of known basic cells
# Mapping from cell name to number of cell entities of each
# topological dimension
num_cell_entities = {"vertex": (1,),
"interval": (2, 1),
"triangle": (3, 3, 1),
"quadrilateral": (4, 4, 1),
"tetrahedron": (4, 6, 4, 1),
"hexahedron": (8, 12, 6, 1)}
# Mapping from cell name to topological dimension
cellname2dim = dict((k, len(v)-1) for k, v in num_cell_entities.items())
# Mapping from cell name to facet name
# Note: This is not generalizable to product elements but it's still
# in use a couple of places.
cellname2facetname = {"interval": "vertex",
"triangle": "interval",
"quadrilateral": "interval",
"tetrahedron": "triangle",
"hexahedron": "quadrilateral"}
# --- Basic cell representation classes
# @six.python_2_unicode_compatible
@attach_operators_from_hash_data
class Cell(AbstractCell):
"Representation of a named finite element cell with known structure."
__slots__ = as_native_strings(("_cellname",))
def __init__(self, cellname, geometric_dimension=None):
"Initialize basic cell description."
self._cellname = cellname
# The topological dimension is defined by the cell type, so
# the cellname must be among the known ones, so we can find
# the known dimension, unless we have a product cell, in which
# the given dimension is used
topological_dimension = len(num_cell_entities[cellname]) - 1
# The geometric dimension defaults to equal the topological
# dimension unless overridden for embedded cells
if geometric_dimension is None:
geometric_dimension = topological_dimension
# Initialize and validate dimensions
AbstractCell.__init__(self, topological_dimension, geometric_dimension)
# --- Overrides of AbstractCell methods ---
def reconstruct(self, geometric_dimension=None):
if geometric_dimension is None:
geometric_dimension = self._geometric_dimension
return Cell(self._cellname, geometric_dimension=geometric_dimension)
def is_simplex(self):
" Return True if this is a simplex cell."
return self.num_vertices() == self.topological_dimension() + 1
def has_simplex_facets(self):
"Return True if all the facets of this cell are simplex cells."
return self.is_simplex() or self.cellname() == "quadrilateral"
# --- Specific cell properties ---
def cellname(self):
"Return the cellname of the cell."
return self._cellname
def num_vertices(self):
"The number of cell vertices."
return num_cell_entities[self.cellname()][0]
def num_edges(self):
"The number of cell edges."
return num_cell_entities[self.cellname()][1]
def num_facets(self):
"The number of cell facets."
tdim = self.topological_dimension()
return num_cell_entities[self.cellname()][tdim-1]
# --- Facet properties ---
def num_facet_edges(self):
"The number of facet edges."
# This is used in geometry.py
fn = cellname2facetname[self.cellname()]
return num_cell_entities[fn][1]
# --- Special functions for proper object behaviour ---
def __str__(self):
gdim = self.geometric_dimension()
tdim = self.topological_dimension()
s = self.cellname()
if gdim > tdim:
s += "%dD" % gdim
return s
def __repr__(self):
# For standard cells, return name of builtin cell object if
# possible. This reduces the size of the repr strings for
# domains, elements, etc. as well
gdim = self.geometric_dimension()
tdim = self.topological_dimension()
name = self.cellname()
if gdim == tdim and name in cellname2dim:
r = name
else:
r = "Cell(%s, %s)" % (repr(name), repr(gdim))
return as_native_str(r)
def _ufl_hash_data_(self):
return (self._geometric_dimension, self._topological_dimension,
self._cellname)
# @six.python_2_unicode_compatible
@attach_operators_from_hash_data
class TensorProductCell(AbstractCell):
__slots__ = as_native_strings(("_cells",))
def __init__(self, *cells, **kwargs):
keywords = list(kwargs.keys())
if keywords and keywords != ["geometric_dimension"]:
raise ValueError(
"TensorProductCell got an unexpected keyword argument '%s'" %
keywords[0])
self._cells = tuple(as_cell(cell) for cell in cells)
tdim = sum([cell.topological_dimension() for cell in self._cells])
if kwargs:
gdim = kwargs["geometric_dimension"]
else:
gdim = sum([cell.geometric_dimension() for cell in self._cells])
AbstractCell.__init__(self, tdim, gdim)
def cellname(self):
"Return the cellname of the cell."
return " * ".join([cell._cellname for cell in self._cells])
def reconstruct(self, geometric_dimension=None):
if geometric_dimension is None:
geometric_dimension = self._geometric_dimension
return TensorProductCell(*(self._cells), geometric_dimension=geometric_dimension)
def is_simplex(self):
"Return True if this is a simplex cell."
if len(self._cells) == 1:
return self._cells[0].is_simplex()
return False
def has_simplex_facets(self):
"Return True if all the facets of this cell are simplex cells."
if len(self._cells) == 1:
return self._cells[0].has_simplex_facets()
return False
def num_vertices(self):
"The number of cell vertices."
return reduce(lambda x, y: x * y, [c.num_vertices() for c in self._cells])
def num_edges(self):
"The number of cell edges."
error("Not defined for TensorProductCell.")
def num_facets(self):
"The number of cell facets."
return sum(c.num_facets() for c in self._cells if c.topological_dimension() > 0)
def sub_cells(self):
"Return list of cell factors."
return self._cells
def __str__(self):
gdim = self.geometric_dimension()
tdim = self.topological_dimension()
reprs = ", ".join(repr(c) for c in self._cells)
if gdim == tdim:
gdimstr = ""
else:
gdimstr = ", geometric_dimension=%d" % gdim
r = "TensorProductCell(%s%s)" % (reprs, gdimstr)
return r
def __repr__(self):
return str(self)
def _ufl_hash_data_(self):
return tuple(c._ufl_hash_data_() for c in self._cells) + (self._geometric_dimension,)
# --- Utility conversion functions
# Mapping from topological dimension to reference cell name for
# simplices
_simplex_dim2cellname = {0: "vertex",
1: "interval",
2: "triangle",
3: "tetrahedron"}
# Mapping from topological dimension to reference cell name for
# hypercubes
_hypercube_dim2cellname = {0: "vertex",
1: "interval",
2: "quadrilateral",
3: "hexahedron"}
def simplex(topological_dimension, geometric_dimension=None):
"Return a simplex cell of given dimension."
return Cell(_simplex_dim2cellname[topological_dimension],
geometric_dimension)
def hypercube(topological_dimension, geometric_dimension=None):
"Return a hypercube cell of given dimension."
return Cell(_hypercube_dim2cellname[topological_dimension],
geometric_dimension)
def as_cell(cell):
"""Convert any valid object to a Cell or return cell if it is already a Cell.
Allows an already valid cell, a known cellname string, or a tuple of cells for a product cell.
"""
if isinstance(cell, AbstractCell):
return cell
elif isinstance(cell, string_types):
return Cell(cell)
elif isinstance(cell, tuple):
return TensorProductCell(cell)
else:
error("Invalid cell %s." % cell)
|