Source code for ufl.checks

"""Utility functions for checking properties of expressions."""

# Copyright (C) 2013-2016 Martin Sandve Aln├Žs
#
# This file is part of UFL (https://www.fenicsproject.org)
#
# SPDX-License-Identifier:    LGPL-3.0-or-later
#
# Modified by Anders Logg, 2008-2009

from ufl.core.expr import Expr
from ufl.core.terminal import FormArgument
from ufl.corealg.traversal import traverse_unique_terminals
from ufl.geometry import GeometricQuantity
from ufl.sobolevspace import H1


[docs]def is_python_scalar(expression): """Return True iff expression is of a Python scalar type.""" return isinstance(expression, (int, float, complex))
[docs]def is_ufl_scalar(expression): """Return True iff expression is scalar-valued, but possibly containing free indices.""" return isinstance(expression, Expr) and not expression.ufl_shape
[docs]def is_true_ufl_scalar(expression): """Return True iff expression is scalar-valued, with no free indices.""" return isinstance(expression, Expr) and not ( expression.ufl_shape or expression.ufl_free_indices )
[docs]def is_cellwise_constant(expr): """Return whether expression is constant over a single cell.""" # TODO: Implement more accurately considering e.g. derivatives? return all(e.is_cellwise_constant() for e in traverse_unique_terminals(expr))
[docs]def is_scalar_constant_expression(expr): """Check if an expression is a globally constant scalar expression.""" if is_python_scalar(expr): return True if expr.ufl_shape: return False # TODO: This does not consider gradients of coefficients, so false # negatives are possible. for e in traverse_unique_terminals(expr): # Return False if any single terminal is not constant if isinstance(e, FormArgument): # Accept only globally constant Arguments and Coefficients if e.ufl_element().embedded_superdegree > 0 or e.ufl_element() not in H1: return False elif isinstance(e, GeometricQuantity): # Reject all geometric quantities, they all vary over # cells return False # All terminals passed constant check return True