Skip to content

Commit

Permalink
Merge branch 'main' into connorjward/counted-mixin2
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjward authored Aug 2, 2023
2 parents d54bc18 + 4e32e86 commit c4a1cf3
Show file tree
Hide file tree
Showing 74 changed files with 412 additions and 2,146 deletions.
3 changes: 1 addition & 2 deletions demo/FEEC.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,4 @@
(sigma, u) = TrialFunctions(W)
(tau, v) = TestFunctions(W)

a = (inner(sigma, tau) - inner(d(tau), u) +
inner(d(sigma), v) + inner(d(u), d(v))) * dx
a = (inner(sigma, tau) - inner(d(tau), u) + inner(d(sigma), v) + inner(d(u), d(v))) * dx
6 changes: 3 additions & 3 deletions demo/HyperElasticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
c22 = Constant(cell)

# Deformation gradient
I = Identity(d)
F = I + grad(u)
Id = Identity(d)
F = Id + grad(u)
F = variable(F)
Finv = inv(F)
J = det(F)
Expand All @@ -66,7 +66,7 @@
I3_C = J**2

# Green strain tensor
E = (C - I) / 2
E = (C - Id) / 2

# Mapping of strain in fiber directions
Ef = A * E * A.T
Expand Down
8 changes: 5 additions & 3 deletions demo/MixedElasticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def skw(tau):
(sigma, u, gamma) = TrialFunctions(W)
(tau, v, eta) = TestFunctions(W)

a = (inner(sigma, tau) - tr(sigma) * tr(tau) +
dot(div(tau), u) - dot(div(sigma), v) +
inner(skw(tau), gamma) + inner(skw(sigma), eta)) * dx
a = (
inner(sigma, tau) - tr(sigma) * tr(tau) + dot(
div(tau), u
) - dot(div(sigma), v) + inner(skw(tau), gamma) + inner(skw(sigma), eta)
) * dx
3 changes: 1 addition & 2 deletions demo/VectorLaplaceGradCurl.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def HodgeLaplaceGradCurl(element, felement):
sigma, u = TrialFunctions(element)
f = Coefficient(felement)

a = (inner(tau, sigma) - inner(grad(tau), u) +
inner(v, grad(sigma)) + inner(curl(v), curl(u))) * dx
a = (inner(tau, sigma) - inner(grad(tau), u) + inner(v, grad(sigma)) + inner(curl(v), curl(u))) * dx
L = inner(v, f) * dx

return a, L
Expand Down
11 changes: 2 additions & 9 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,8 @@ ci =
fenics-ufl[test]

[flake8]
ignore = E501, W504,
# Line break before operator, no longer PEP8.
W503,
# Indentation, can trigger for valid code.
E129,
# ambiguous variable name
E741
builtins = ufl
exclude = .git,__pycache__,doc/sphinx/source/conf.py,build,dist,test
max-line-length = 120
exclude = doc/sphinx/source/conf.py,test

[pydocstyle]
# Work on removing these ignores
Expand Down
6 changes: 6 additions & 0 deletions test/test_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ def test_cells_2d(cell):
assert cell.num_peaks() == cell.num_vertices()


def test_tensorproductcell():
orig = ufl.TensorProductCell(ufl.interval, ufl.interval)
cell = orig.reconstruct()
assert cell.sub_cells() == orig.sub_cells()
assert cell.topological_dimension() == orig.topological_dimension()
assert cell.geometric_dimension() == orig.geometric_dimension()
6 changes: 6 additions & 0 deletions test/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,9 @@ def test_mse():

element = FiniteElement('GLL-Edge L2', interval, degree - 1)
assert element == eval(repr(element))


def test_withmapping():
base = FiniteElement("CG", interval, 1)
element = WithMapping(base, "identity")
assert element == eval(repr(element))
71 changes: 29 additions & 42 deletions ufl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# flake8: noqa
"""The Unified Form Language is an embedded domain specific language
for definition of variational forms intended for finite element
discretization. More precisely, it defines a fixed interface for choosing
Expand All @@ -11,19 +9,19 @@
* To import the language, type::
from ufl import *
import ufl
* To import the underlying classes an UFL expression tree is built
from, type
::
from ufl.classes import *
import ufl.classes
* Various algorithms for working with UFL expression trees can be
accessed by
::
from ufl.algorithms import *
import ufl.algorithms
Classes and algorithms are considered implementation details and
should not be used in form definitions.
Expand Down Expand Up @@ -219,7 +217,7 @@
- rhs, lhs
- system
- functional
- replace, replace_integral_domains
- replace
- adjoint
- action
- energy_norm,
Expand All @@ -246,7 +244,7 @@
__version__ = importlib.metadata.version("fenics-ufl")

# README
# Imports here should be what the user sees when doing "from ufl import *",
# Imports here should be what the user sees
# which means we should _not_ import f.ex. "Grad", but "grad".
# This way we expose the language, the operation "grad", but less
# of the implementation, the particular class "Grad".
Expand All @@ -272,20 +270,19 @@
from ufl.sobolevspace import L2, H1, H2, HDiv, HCurl, HEin, HDivDiv, HInf

# Finite elements classes
from ufl.finiteelement import FiniteElementBase, FiniteElement, \
MixedElement, VectorElement, TensorElement, EnrichedElement, \
NodalEnrichedElement, RestrictedElement, TensorProductElement, \
HDivElement, HCurlElement, BrokenElement, WithMapping
from ufl.finiteelement import (
FiniteElementBase, FiniteElement, MixedElement, VectorElement, TensorElement, EnrichedElement,
NodalEnrichedElement, RestrictedElement, TensorProductElement, HDivElement, HCurlElement, BrokenElement,
WithMapping)

# Hook to extend predefined element families
from ufl.finiteelement.elementlist import register_element, show_elements # , ufl_elements
from ufl.finiteelement.elementlist import register_element, show_elements

# Function spaces
from ufl.functionspace import FunctionSpace, MixedFunctionSpace

# Arguments
from ufl.argument import Argument, Coargument, TestFunction, TrialFunction, \
Arguments, TestFunctions, TrialFunctions
from ufl.argument import Argument, Coargument, TestFunction, TrialFunction, Arguments, TestFunctions, TrialFunctions

# Coefficients
from ufl.coefficient import Coefficient, Cofunction, Coefficients
Expand All @@ -311,43 +308,34 @@

# Special functions for expression base classes
# (ensure this is imported, since it attaches operators to Expr)
import ufl.exproperators as __exproperators
import ufl.exproperators as __exproperators # noqa: F401

# Containers for expressions with value rank > 0
from ufl.tensors import as_tensor, as_vector, as_matrix, relabel
from ufl.tensors import as_tensor, as_vector, as_matrix
from ufl.tensors import unit_vector, unit_vectors, unit_matrix, unit_matrices

# Operators
from ufl.operators import rank, shape, \
conj, real, imag, \
outer, inner, dot, cross, perp, \
det, inv, cofac, \
transpose, tr, diag, diag_vector, \
dev, skew, sym, \
sqrt, exp, ln, erf, \
cos, sin, tan, \
acos, asin, atan, atan_2, \
cosh, sinh, tanh, \
bessel_J, bessel_Y, bessel_I, bessel_K, \
eq, ne, le, ge, lt, gt, And, Or, Not, \
conditional, sign, max_value, min_value, \
variable, diff, \
Dx, grad, div, curl, rot, nabla_grad, nabla_div, Dn, exterior_derivative, \
jump, avg, cell_avg, facet_avg, \
elem_mult, elem_div, elem_pow, elem_op
from ufl.operators import (
rank, shape, conj, real, imag, outer, inner, dot, cross, perp,
det, inv, cofac, transpose, tr, diag, diag_vector, dev, skew, sym,
sqrt, exp, ln, erf, cos, sin, tan, acos, asin, atan, atan_2, cosh, sinh, tanh,
bessel_J, bessel_Y, bessel_I, bessel_K, eq, ne, le, ge, lt, gt, And, Or, Not,
conditional, sign, max_value, min_value, variable, diff,
Dx, grad, div, curl, rot, nabla_grad, nabla_div, Dn, exterior_derivative,
jump, avg, cell_avg, facet_avg, elem_mult, elem_div, elem_pow, elem_op)

# Measure classes
from ufl.measure import Measure, register_integral_type, integral_types, custom_integral_types

# Form class
from ufl.form import Form, BaseForm, FormSum, ZeroBaseForm, replace_integral_domains
from ufl.form import Form, BaseForm, FormSum, ZeroBaseForm

# Integral classes
from ufl.integral import Integral

# Representations of transformed forms
from ufl.formoperators import replace, derivative, action, energy_norm, rhs, lhs,\
system, functional, adjoint, sensitivity_rhs, extract_blocks #, dirichlet_functional
from ufl.formoperators import (replace, derivative, action, energy_norm, rhs, lhs,
system, functional, adjoint, sensitivity_rhs, extract_blocks)

# Predefined convenience objects
from ufl.objects import (
Expand All @@ -356,8 +344,7 @@
i, j, k, l, p, q, r, s,
dx, ds, dS, dP,
dc, dC, dO, dI, dX,
ds_b, ds_t, ds_tb, ds_v, dS_h, dS_v
)
ds_b, ds_t, ds_tb, ds_v, dS_h, dS_v)

# Useful constants
from math import e, pi
Expand All @@ -380,15 +367,15 @@
'BrokenElement', "WithMapping",
'register_element', 'show_elements',
'FunctionSpace', 'MixedFunctionSpace',
'Argument','Coargument', 'TestFunction', 'TrialFunction',
'Argument', 'Coargument', 'TestFunction', 'TrialFunction',
'Arguments', 'TestFunctions', 'TrialFunctions',
'Coefficient', 'Cofunction', 'Coefficients',
'Matrix', 'Adjoint', 'Action',
'Constant', 'VectorConstant', 'TensorConstant',
'split',
'PermutationSymbol', 'Identity', 'zero', 'as_ufl',
'Index', 'indices',
'as_tensor', 'as_vector', 'as_matrix', 'relabel',
'as_tensor', 'as_vector', 'as_matrix',
'unit_vector', 'unit_vectors', 'unit_matrix', 'unit_matrices',
'rank', 'shape', 'conj', 'real', 'imag',
'outer', 'inner', 'dot', 'cross', 'perp',
Expand All @@ -405,9 +392,9 @@
'Dx', 'grad', 'div', 'curl', 'rot', 'nabla_grad', 'nabla_div', 'Dn', 'exterior_derivative',
'jump', 'avg', 'cell_avg', 'facet_avg',
'elem_mult', 'elem_div', 'elem_pow', 'elem_op',
'Form','FormSum', 'ZeroBaseForm',
'Form', 'BaseForm', 'FormSum', 'ZeroBaseForm',
'Integral', 'Measure', 'register_integral_type', 'integral_types', 'custom_integral_types',
'replace', 'replace_integral_domains', 'derivative', 'action', 'energy_norm', 'rhs', 'lhs', 'extract_blocks',
'replace', 'derivative', 'action', 'energy_norm', 'rhs', 'lhs', 'extract_blocks',
'system', 'functional', 'adjoint', 'sensitivity_rhs',
'dx', 'ds', 'dS', 'dP',
'dc', 'dC', 'dO', 'dI', 'dX',
Expand Down
19 changes: 5 additions & 14 deletions ufl/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ class Action(BaseForm):
"_arguments",
"_hash")

def __getnewargs__(self):
return (self._left, self._right)

def __new__(cls, *args, **kw):
left, right = args

Expand Down Expand Up @@ -107,20 +104,18 @@ def equals(self, other):
return False
if self is other:
return True
return (self._left == other._left and self._right == other._right)
return self._left == other._left and self._right == other._right

def __str__(self):
return "Action(%s, %s)" % (str(self._left), str(self._right))
return f"Action({self._left}, {self._right})"

def __repr__(self):
return self._repr

def __hash__(self):
"Hash code for use in dicts "
if self._hash is None:
self._hash = hash(("Action",
hash(self._right),
hash(self._left)))
self._hash = hash(("Action", hash(self._right), hash(self._left)))
return self._hash


Expand All @@ -133,14 +128,10 @@ def _check_function_spaces(left, right):
right, *_ = right.ufl_operands

if isinstance(right, (Form, Action, Matrix, ZeroBaseForm)):
if (left.arguments()[-1].ufl_function_space().dual()
!= right.arguments()[0].ufl_function_space()):

if left.arguments()[-1].ufl_function_space().dual() != right.arguments()[0].ufl_function_space():
raise TypeError("Incompatible function spaces in Action")
elif isinstance(right, (Coefficient, Cofunction, Argument)):
if (left.arguments()[-1].ufl_function_space()
!= right.ufl_function_space()):

if left.arguments()[-1].ufl_function_space() != right.ufl_function_space():
raise TypeError("Incompatible function spaces in Action")
else:
raise TypeError("Incompatible argument in Action: %s" % type(right))
Expand Down
7 changes: 2 additions & 5 deletions ufl/adjoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ class Adjoint(BaseForm):
"ufl_operands",
"_hash")

def __getnewargs__(self):
return (self._form)

def __new__(cls, *args, **kw):
form = args[0]
# Check trivial case: This is not a ufl.Zero but a ZeroBaseForm!
Expand Down Expand Up @@ -77,10 +74,10 @@ def equals(self, other):
return False
if self is other:
return True
return (self._form == other._form)
return self._form == other._form

def __str__(self):
return "Adjoint(%s)" % str(self._form)
return f"Adjoint({self._form})"

def __repr__(self):
return self._repr
Expand Down
21 changes: 1 addition & 20 deletions ufl/algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,7 @@ def evaluate(self, x, mapping, component, index_values):
index_values) for o in self.ufl_operands)

def __str__(self):
ops = [parstr(o, self) for o in self.ufl_operands]
if False:
# Implementation with line splitting:
limit = 70
delimop = " + \\\n + "
op = " + "
s = ops[0]
n = len(s)
for o in ops[1:]:
m = len(o)
if n + m > limit:
s += delimop
n = m
else:
s += op
n += m
s += o
return s
# Implementation with no line splitting:
return " + ".join(ops)
return " + ".join([parstr(o, self) for o in self.ufl_operands])


@ufl_type(num_ops=2,
Expand Down
7 changes: 2 additions & 5 deletions ufl/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"estimate_total_polynomial_degree",
"sort_elements",
"compute_form_data",
"purge_list_tensors",
"apply_transformer",
"ReuseTransformer",
"load_ufl_file",
Expand Down Expand Up @@ -102,7 +101,7 @@
from ufl.algorithms.expand_compounds import expand_compounds
# from ufl.algorithms.estimate_degrees import SumDegreeEstimator
from ufl.algorithms.estimate_degrees import estimate_total_polynomial_degree
from ufl.algorithms.expand_indices import expand_indices, purge_list_tensors
from ufl.algorithms.expand_indices import expand_indices

# Utilities for transforming complete Forms into other Forms
from ufl.algorithms.formtransformations import compute_form_adjoint
Expand All @@ -123,6 +122,4 @@
from ufl.algorithms.formfiles import load_ufl_file
from ufl.algorithms.formfiles import load_forms

# Utilities for UFL object printing
# from ufl.formatting.printing import integral_info, form_info
from ufl.formatting.printing import tree_format
from ufl.utils.formatting import tree_format
8 changes: 0 additions & 8 deletions ufl/algorithms/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ def unique_tuple(objects):

# --- Utilities to extract information from an expression ---

def __unused__extract_classes(a):
"""Build a set of all unique Expr subclasses used in a.
The argument a can be a BaseForm, Integral or Expr."""
return set(o._ufl_class_
for e in iter_expressions(a)
for o in unique_pre_traversal(e))


def extract_type(a, ufl_types):
"""Build a set of all objects found in a whose class is in ufl_types.
The argument a can be a BaseForm, Integral or Expr."""
Expand Down
Loading

0 comments on commit c4a1cf3

Please sign in to comment.