fenics / ufl Goto Github PK
View Code? Open in Web Editor NEWUFL - Unified Form Language
Home Page: https://fenicsproject.org
License: GNU Lesser General Public License v3.0
UFL - Unified Form Language
Home Page: https://fenicsproject.org
License: GNU Lesser General Public License v3.0
Can we tag ufl at current master/HEAD as 2021.1.0?
The MultiFunction
based map_dag
visitors in UFL provide a caching (and hence efficient) API for implementing post-order visits of a UFL DAG. The core function is map_expr_dags
(the relevant part is here https://github.com/FEniCS/ufl/blob/master/ufl/corealg/map_dag.py#L64).
Most of the transformations in the UFL pipeline are bottom up (post-order) and so are well-served by this infrastructure. Some, however, are pre-order (or at least partially pre-order). Examples include the restriction propagation (which hand-codes a post-order visit of a restricted subtree https://github.com/FEniCS/ufl/blob/master/ufl/algorithms/apply_restrictions.py#L36)
This can lead to unintended performance bugs where one, by necessity, hand-codes the DAG recursion to get a pre-order visit. This will blow up the perceived size of the DAG, the avoidance of which was one of the major motiviating factors for the ReuseTransformer
-> MultiFunction + map_expr_dag
transition.
Unfortunately, providing a caching pre-order visit requires that the visitor object sees the cache (the post-order visit cache can be managed completely from the outside). In the latter case the MultiFunction
does not implement its own recursion and instead is used for type-based method dispatch on the first argument.
In tsfc, this issue is solved by having a more general visitor implementation (https://github.com/firedrakeproject/tsfc/blob/master/gem/node.py#L187). One writes singledispatch
recursive functions that take the cache-manager as a parameter. Recursion is done by __call__
ing this parameter on children as necessary.
Here's an example from tsfc using this pattern to manage abs
-simplification (from https://github.com/firedrakeproject/tsfc/blob/master/tsfc/ufl_utils.py#L250)
@singledispatch
def _simplify_abs(o, self, in_abs):
"""Single-dispatch function to simplify absolute values.
:arg o: UFL node
:arg self: Callback handler for recursion
:arg in_abs: Is ``o`` inside an absolute value?
When ``in_abs`` we must return a non-negative value, potentially
by wrapping the returned node with ``Abs``.
"""
raise AssertionError("UFL node expected, not %s" % type(o))
@_simplify_abs.register(Expr)
def _simplify_abs_expr(o, self, in_abs):
# General case, only wrap the outer expression (if necessary)
operands = [self(op, False) for op in o.ufl_operands]
result = ufl_reuse_if_untouched(o, *operands)
if in_abs:
result = Abs(result)
return result
...
@_simplify_abs.register(Abs)
def _simplify_abs_abs(o, self, in_abs):
return self(o.ufl_operands[0], True)
def simplify_abs(expression):
"""Simplify absolute values in a UFL expression. Its primary
purpose is to "neutralise" CellOrientation nodes that are
surrounded by absolute values and thus not at all necessary."""
mapper = MemoizerArg(_simplify_abs)
return mapper(expression, False)
The MemoizerArg
manages the caching and recursion, the visitor just needs to implement appropriate handlers for all of the nodes (and recurse where necessary).
This supports caching in both pre- and post-order traversal because the dispatch functions see the memoizer object.
We could implement something like this for UFL, I think one can probably provide backwards-compat to the existing MultiFunction
setup.
Any other better suggestions? The current functional interface of map_expr_dag
precludes stashing the callbacks on the MultiFunction
object easily.
Currently UFL groups integrals by domain
, integral_type
, subdomain_id
into IntegralData
objects.
The form compiler then uses this to generate different kernels.
However, forms with different metadata are grouped, and in FFCx, this can potentially produce an error (see: #Issue 394).
Ideally, we would like to have one kernel by metadata (and possibly a quadrature rule per kernel).
Our proposal is to modify build_integral_data, to group integrals by metadata.
@wence- Any thoughts on that? Would it be ok for tsfc?
Built-in functionality to use with Python>=3.8, ref:
https://docs.python.org/3/library/importlib.metadata.html
Context
Python 3.7 EOL is happening in 2 months: https://endoflife.date/python
and the usage of pkg_resources
with ufl
causes a lot of deprecation warnings:
python3 -Wd -c "import pkg_resources"
/usr/local/lib/python3.10/dist-packages/pkg_resources/__init__.py:121: DeprecationWarning: pkg_resources is deprecated as an API
warnings.warn("pkg_resources is deprecated as an API", DeprecationWarning)
/usr/local/lib/python3.10/dist-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('mpl_toolkits')`.
Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
declare_namespace(pkg)
/usr/local/lib/python3.10/dist-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('sphinxcontrib')`.
Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
declare_namespace(pkg)
As Legacy DOLFIN does not support main branch of UFL, this is safe from a DOLFIN perspective, as DOLFINx, requires Python>=3.8 (https://github.com/FEniCS/dolfinx/blob/main/python/setup.py).
As far as I can tell, Firedrake still supports Python 3.7.
Rename master
as main
as this is now the convention.
Hello UFL users and developers,
This post is taken from the fenics forum with an adapted minimal working example.
I'm trying to use a fenics code to reproduce the results of this paper as part of a validation process.
This is a fluid mechanics paper that involves a specific decomposition : q(x,r,theta,t)=q_0(x,r)+epsilon q_1(x,r)e^(imtheta+(sigma+i omega)t) Going from the Navier-Stokes equations Nd_tq+M(q)=0 and obtaining a base flow q_0 from M(q_0)=0, this allows for computation of the perturbations as a generalised eigenvalue problem dM/dq(q_0)q_1=(sigma+i omega)Nq_1
The nonlinear operator M is well--known in the case of the Navier Stokes equations but in this decomposition it is complex (q_1 is complex as well). The core of the problem is computing dM/dq.
I've read here that the UFL can handle complex values. The code below is an attempt to leverage automatic differentiation to obtain dM/dq(q_0)
from ufl import *
from ufl.classes import TestFunction, TrialFunction
from ufl.algorithms.compute_form_data import compute_form_data
# Physical parameters
m=-1
Re=200
cell = triangle
FE_vector=VectorElement("Lagrange",cell,2,3)
FE_scalar=FiniteElement("Lagrange",cell,1)
FE_TH = MixedElement([FE_vector,FE_scalar])
# Test and trial functions
test = TestFunction(FE_TH)
trial = TrialFunction(FE_TH)
# Initial conditions
q = Coefficient(FE_TH)
# Gradient with x[0] is x, x[1] is r, x[2] is theta
def grad(v,m):
return as_tensor([[v[0].dx(0), v[0].dx(1), m*1j*v[0]],
[v[1].dx(0), v[1].dx(1), m*1j*v[1]-v[2]],
[v[2].dx(0), v[2].dx(1), m*1j*v[2]+v[1]]])
def div(v,m): return v[0].dx(0) + v[1].dx(1) + m*1j*v[2]
# Navier Stokes variational form
def NS_form(m):
u,p=split(q)
test_u,test_m=split(test)
#mass (variational formulation)
M = div(u,m)*test_m*dx
#set_trace()
#momentum (different test functions and IBP)
M += dot(grad(u,m)*u, test_u) *dx # Convection
M += 1/Re*inner(grad(u,m), grad(test_u,m))*dx # Diffusion
M -= dot(p, div(test_u,m))*dx # Pressure
return M
pert_form=compute_form_data(NS_form(m),complex_mode=True)
With my installation, UFL bundled into dolfin 2019.1.0
installed using docker
I obtain the resulting traceback :
Traceback (most recent call last):
File "MWE_ufl.py", line 46, in <module>
pert_form=compute_form_data(NS_form(m),complex_mode=True)
File "/usr/local/lib/python3.6/dist-packages/ufl/algorithms/compute_form_data.py", line 418, in compute_form_data
check_form_arity(preprocessed_form, self.original_form.arguments(), complex_mode) # Currently testing how fast this is
File "/usr/local/lib/python3.6/dist-packages/ufl/algorithms/check_arities.py", line 177, in check_form_arity
check_integrand_arity(itg.integrand(), arguments, complex_mode)
File "/usr/local/lib/python3.6/dist-packages/ufl/algorithms/check_arities.py", line 159, in check_integrand_arity
arg_tuples = map_expr_dag(rules, expr, compress=False)
File "/usr/local/lib/python3.6/dist-packages/ufl/corealg/map_dag.py", line 37, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress)
File "/usr/local/lib/python3.6/dist-packages/ufl/corealg/map_dag.py", line 86, in map_expr_dags
r = handlers[v._ufl_typecode_](v, *[vcache[u] for u in v.ufl_operands])
File "/usr/local/lib/python3.6/dist-packages/ufl/algorithms/check_arities.py", line 48, in sum
raise ArityMismatch("Adding expressions with non-matching form arguments {0} vs {1}.".format(_afmt(a), _afmt(b)))
ufl.algorithms.check_arities.ArityMismatch: Adding expressions with non-matching form arguments ('v_0',) vs ('conj(v_0)',).
I would be grateful on any insight as to why this error arises, how to go around it, or more generally how to handle complex values in UFL (I've found few examples) and how to solve my problem.
The code consists of several deprecated ways of defining coefficients, arguments etc (used in old ufl files).
For instance:
Currently, Real elements report that they are in L2. They should however be in
The standard Discontinuous Galerkin formulation of the scalar Poisson equation
has terms like
which in UFL is expressed as
inner(jump(v, n), avg(grad(u))) * dS
and all is well.
For the case in which the equation is vector valued, however, jump(v, n)
or jump(v)
is used, so the inner product is not well-defined any more.
The (one?) correct DG formulation for the vector Poisson equation uses the term
where
I tried implementing this with
inner(jump(outer(v, n)), avg(grad(u))) * dS
but, with the current UFL implementation,
Lines 441 to 452 in 64c846a
this returns [notice the wrong "-" instead of a "+"]
Add tests for downstream FFCx and DOLFINx upon pull requests.
suppose in a complex valued inverse problem we have:
x = SpatialCoordinate(mesh)
functional = f(x)*dx
where f(x)
is some UFL expression which might be a function of x. Now, the adjoint will need to compute:
conj(derivative(functional, mesh)
Which is currently an error since CoordinateDerivative
must be the outermost operator on any expression. If we push the conj
inside the derivative then this is also an error because then the conjugate is not applied to the det(J)
which results from integral scaling. In combination with the CoordinateDerivative
this causes unconjugated test functions, which is an error.
Answers on a postcard please.
Hi all, I found the maximum element value of the assemble matrix of inner(curl(u), curl(v))*dx increases with the mesh size, while inner(u, v)*dx does not. Is it normal?
from fenics import *
mesh = UnitSquareMesh(40, 40)
V = FunctionSpace(mesh, "N1curl", 1)
u = TrialFunction(V)
v = TestFunction(V)
a = inner(curl(u), curl(v)) * dx
A = assemble(a)
A.array().max()
Running ufl tests highlights the issue:
python3 -m pytest -xvs test/
====================================================================================================== test session starts ======================================================================================================
platform linux -- Python 3.8.10, pytest-7.1.3, pluggy-1.0.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: ...
plugins: forked-1.4.0, xdist-2.5.0
collected 561 items
test/test_algorithms.py::test_extract_arguments_vs_fixture PASSED
test/test_algorithms.py::test_extract_coefficients_vs_fixture PASSED
test/test_algorithms.py::test_extract_elements_and_extract_unique_elements PASSED
test/test_algorithms.py::test_pre_and_post_traversal PASSED
test/test_algorithms.py::test_expand_indices Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_algorithms.py::test_adjoint PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/Constant.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/ConvectionJacobi.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/ConvectionJacobi2.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/ConvectionVector.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/Elasticity.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/EnergyNorm.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/Equation.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/ExplicitConvection.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/FEEC.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/FunctionOperators.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/H1norm.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/HarmonicMap.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/HarmonicMap2.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/Heat.py] PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/HornSchunck.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
test/test_analyse_demos.py::test_demo_files[/home/ia397/Projects/fenics/ufl/demo/HyperElasticity.py] Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
Expr.ufl_domain() is deprecated, please use extract_unique_domain(expr) instead.
PASSED
ufl 2022.1.0 got released, bringing in modernization of the API. That's great, except some projects will still be using old dolfin.
For instance, the dolfin demos include demo/documented/poisson/cpp/Poisson.ufl, which uses FiniteElement
. That's been removed from ufl 2022.1.0 (there is FiniteElementBase
instead), and so running old ffc fails:
$ ffc -l dolfin -s -O -r auto Poisson.ufl
Traceback (most recent call last):
File "/build/dolfin/cmake/scripts/generate-form-files.py", line 90, in <module>
ret = ffc.main(args)
File "/usr/lib/python3/dist-packages/ffc/main.py", line 215, in main
resultcode = _compile_files(args, parameters, enable_profile)
File "/usr/lib/python3/dist-packages/ffc/main.py", line 248, in _compile_files
ufd = load_ufl_file(filename)
File "/usr/lib/python3/dist-packages/ufl/algorithms/formfiles.py", line 181, in load_ufl_file
namespace = execute_ufl_code(uflcode)
File "/usr/lib/python3/dist-packages/ufl/algorithms/formfiles.py", line 82, in execute_ufl_code
exec(uflcode, namespace)
File "<string>", line 24, in <module>
NameError: name 'FiniteElement' is not defined
(this is after patching old ffc with its own copy of cellname2facetname).
I think that means it's not feasible to keep patching ffc (and dolfin) to keep up with latest ufl. Should ufl be renamed as uflx at this point, as was done for the ffcโffcx transition?
I would like to do something like a = ufl.pow(b, 2)
. This returns module 'ufl' has no attribute 'pow'
. However I can implement the desired functionality using b ** 2
This may be merely a problem with documentation. I see it listed under "basic nonlinear functions" here https://fenics.readthedocs.io/projects/ufl/en/latest/manual/form_language.html?highlight=square#basic-nonlinear-functions
Thank you!
currently none of the tests touches https://github.com/FEniCS/ufl/blob/main/ufl/formatting/ufl2unicode.py
Currently the following code runs without error. It shouldn't.
import ufl.utils
print(ufl.dx())
Following on from #168.
Taking the derivative of a form containing a vector coefficient w.r.t. a scalar coefficient and supplying a coefficient derivative map results in an error, e.g.:
test.py
:
from ufl import (triangle, FiniteElement, VectorElement, TestFunction, Coefficient, inner, dx, derivative)
V = FiniteElement("Lagrange", triangle, 1)
VV = VectorElement("Lagrange", triangle, 1)
dv = TestFunction(V)
df = Coefficient(VV)
g = Coefficient(VV)
f = Coefficient(VV)
u = Coefficient(V)
cd = {f: df}
integrand = inner(f, g)
F = integrand*dx
J = derivative(F, u, dv, cd)
forms = [F, J]
ffcx test.py
results in:
ufl.log.UFLException: Component and shape length don't match.
I have a fix that's working for my usage case that I'll put in a PR for comment.
I think we should start using property decorators, as it would make alot of the code more readable.
I've created this issue to take note of things we'd like to do to the FiniteElementBase class now that we're working on moving element definitions into Basix/finat
__init__
and instead have abstractmethod
s and abstractproperty
sabstractmethod
s to abstractproperty
sfamily
, degree
and quad_scheme
from the base classsymmetry
method needs thinking about__add__
and __mul__
need removing from base classChanges required to support vertex cells led to questions about the design decision of having VectorElement
and TensorElement
be subclasses of MixedElement
.
Originally posted by @wence- in #30 :
I would advocate keeping
MixedElement
only for a "bag of unrelated elements" and create newVector/TensorElement
classes that rank-augment an existingFiniteElement
object. One could then go one step further and just makeVectorElement
a functional constructor for aTensorElement
.
Currently, the test directory is included in flake8's excludes. This should be removed and the tests should be made to pass flake8
The following code
import ufl
coord_element = ufl.VectorElement("Lagrange", ufl.quadrilateral, 1)
mesh = ufl.Mesh(coord_element)
element = ufl.FiniteElement("RTCF", ufl.quadrilateral, 1)
V = ufl.FunctionSpace(mesh, element)
v = ufl.TrialFunction(V)
form = ufl.inner(1, ufl.div(v)) * ufl.dx
form_data = ufl.algorithms.compute_form_data(
form,
do_apply_function_pullbacks=True,
do_apply_integral_scaling=True,
do_apply_geometry_lowering=True,
preserve_geometry_types=(ufl.classes.Jacobian,),
do_apply_restrictions=True,
do_append_everywhere_integrals=False)
print(form_data.preprocessed_form)
produces an output containing grad(J)
instead of transforming the Jacobian derivatives to reference_grad(J)
. Is this the desired behaviour? Should these global derivatives not have been transformed to reference derivatives after preprocessing? I discovered this whilst investigating FEniCS/ffcx#373.
I'm trying to update firedrake to comply with ufl's api on ufl.domain
/ufl.domains
and I noticed that the new functions extract_unique_domain
/extract_domains
cannot be applied to ufl.form
and ufl.functionspace.FunctionSpace
.
The git mailmap has not been updated since 2016, and should either be updated or deleted.
Any preferences?
Legacy code with should be removed in favor of using the measure initializer
Lines 286 to 297 in a7426bd
The docstrings of ufl.operators.dot does not match the actual documentation of the function,
i.e.
UFL operator: Take the dot product of a and b. The complex conjugate of the second argument is taken.
and
"UFL operator: Take the dot product of a and b. This won't take the complex conjugate of the second argument."
Is there any specific reason for the following code:
ufl/ufl/algorithms/apply_geometry_lowering.py
Lines 184 to 198 in 4fd9a80
import gmsh
import numpy as np
import ufl
from dolfinx import fem, io
from mpi4py import MPI
# Generate a mesh with non-affine cells
gdim = 2
mesh_comm = MPI.COMM_WORLD
model_rank = 0
if mesh_comm.rank == model_rank:
gmsh.initialize()
rectangle = gmsh.model.occ.addRectangle(0, 0, 0, 1, 1, tag=1)
obstacle = gmsh.model.occ.addDisk(0.5, 0.5, 0, 0.3, 0.3)
fluid = gmsh.model.occ.cut([(gdim, rectangle)], [(gdim, obstacle)])
gmsh.model.occ.synchronize()
volumes = gmsh.model.getEntities(dim=gdim)
gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]], 1)
gmsh.option.setNumber("Mesh.Algorithm", 8)
gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2)
gmsh.option.setNumber("Mesh.RecombineAll", 1)
gmsh.option.setNumber("Mesh.SubdivisionAlgorithm", 1)
gmsh.model.mesh.generate(gdim)
domain, _, _ = io.gmshio.model_to_mesh(
gmsh.model, mesh_comm, model_rank, gdim=gdim)
gmsh.finalize()
Ve = fem.FunctionSpace(domain, ("DG", 0))
elmVol_ufl = ufl.CellVolume(domain)
elmVol_expr = fem.Expression(elmVol_ufl, Ve.element.interpolation_points())
elmVol = fem.Function(Ve, name="Element Volume (expression)")
elmVol.interpolate(elmVol_expr)
q_degree = 3
vol2 = fem.Function(Ve)
fem.petsc.assemble_vector(vol2.vector, fem.form(
1*ufl.TestFunction(Ve)*ufl.dx(metadata={"quadrature_degree": q_degree})))
vol2.x.scatter_forward()
print(vol2.x.array - elmVol.x.array)
assert np.allclose(vol2.x.array, elmVol.x.array)
vol2.name = "ElementVolume (assembly)"
with io.XDMFFile(domain.comm, "cell_vol.xdmf", "w") as xdmf:
xdmf.write_mesh(domain)
xdmf.write_function(elmVol)
xdmf.write_function(vol2)
Concerns: https://github.com/FEniCS/ufl/blob/main/ufl/finiteelement/finiteelementbase.py#L199
This is cute for two spaces but is confusing and a bit useless for three or more spaces, see e.g. this recent thread on Slack:
https://fenicsproject.slack.com/archives/C1AFSEWKU/p1622793170035800
I would be in favour of removing/deprecating this code path and perhaps the +
overload as well
https://github.com/FEniCS/ufl/blob/main/ufl/finiteelement/finiteelementbase.py#L192
Do the docs (doc/sphinx) for ufl need to be updated? I suspect they're configured to an old version of sphinx. requirements.txt declares sphinx==1.7.0
, but the sphinx version available to me at the moment is 3.4.3.
When I run make html
from doc/sphinx, it fails with No module named 'sphinx.apidoc'
,
$ make html
sphinx-build -b html -d build/doctrees source build/html
Running Sphinx v3.4.3
making output directory... done
WARNING: html_static_path entry '_static' does not exist
Extension error:
Handler <function run_apidoc at 0x7f8e5e7a80d0> for event 'builder-inited' threw an exception (exception: No module named 'sphinx.apidoc')
make: *** [Makefile:55: html] Error 2
doc/sphinx/source/conf.py uses (l.298)
from sphinx.apidoc import main
I guess sphinx.apidoc
must have appeared in sphinx 1.7.0, and is no longer available. sphinxcontrib.apidoc
is available on my system, but substituting sphinx.apidoc
for sphinxcontrib.apidoc
is not the solution (exception: cannot import name 'main' from 'sphinxcontrib.apidoc'
)
as_native_str
should not be needed now we are fully Python3
It would be very useful to have a lazy version of replace, which only gets applied when the expression tree is traversed.
Example:
Say I have an expression expr
which contains a ufl.ConstantValue
named c
as a parameter. If I want to have the derivative of expr
wrt. c
I can do so by creating a ufl.Coefficient
named f
and doing:
ufl.replace(expr, {c: f})
ufl.derivative(expr, f)
However this traverses the expression tree twice.
(This issue would also be fixed by implementing derivative wrt. ufl.ConstantValue
, but there are more examples where this is desirable). This came up as a discussion point when reviewing a recent Firedrake PR. Tagging @dham .
The below code gives the error ufl.log.UFLException: Unexpected complex value in real expression.
Should it be expected to work?
import ufl
cell = ufl.triangle
x = ufl.SpatialCoordinate(cell)
f = x[0] + x[0] * 1j
# f = ufl.Constant(x[0] + x[0] * 1j) # this works
# f = ufl.real(f) # this doesn't work either
ufl.algorithms.remove_complex_nodes.remove_complex_nodes(f)
Currently, the base class for finite element is called FiniteElementBase
while the base class for cells is called AbstractCell
.
We should decide on a consistent naming for base classes. I'm in favour of the ObjectNameBase
but am open to better opinions.
This report is for class PermutationSymbol(ConstantValue) in ufl/ufl/constantvalue.py, in line 387:
Line 387 in 94badf8
Consider a second order and 3d PermutationSymbol, current code gives
self.ufl_shape = (dim,) * dim = (3, 3, 3),
which should be (3,3), actually.
So, this line should be changed to as in class Identity(ConstantValue):
Line 349 in 94badf8
flake8's E741 is for ambiguous variable names. Instead of skipping this, we should rename variables to better names.
When constructing a VectorElement based from a scalar FiniteElement, the quadrature scheme of that element is dropped.
This is not the case for TensorElement, although one would expect the same behavior for both types.
The reason lies in the call to FiniteElementBase.__init__
in line 298 of ufl/finiteelement/mixedelement.py
, which sets quad_scheme
to None
if it is not given explicitly. This call is not present in the constructor of TensorElement
.
After 04 Oct 2026 (Python 3.10 end of life), we should start using typing.Self
to annotate function input types (ie undo 86a2140).
The change of API in ufl 2023.1 (2023.1.1.post0) breaks old dolfin.
It also breaks old ffc. ufl.log.WARNING
was removed in ufl 2023 and is used by ffc. But ffc can be easily patched to treat any instance of WARNING as either INFO or ERROR.
dolfin cannot be so easily patched. The problem is not only ufl.log.WARNING. For instance demo_poisson.py gives
$ python3 demo_poisson.py
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Traceback (most recent call last):
File "/projects/fenics/build/tests/dolfin/demo-python/documented/poisson/demo_poisson.py", line 170, in <module>
solve(a == L, u, bc)
File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/fem/solving.py", line 233, in solve
_solve_varproblem(*args, **kwargs)
File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/fem/solving.py", line 268, in _solve_varproblem
problem = LinearVariationalProblem(eq.lhs, eq.rhs, u, bcs,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/fem/problem.py", line 58, in __init__
L = Form(L, form_compiler_parameters=form_compiler_parameters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/fem/form.py", line 82, in __init__
self.set_cell_domains(subdomains)
TypeError: set_cell_domains(): incompatible function arguments. The following argument types are supported:
1. (self: dolfin.cpp.fem.Form, arg0: dolfin.cpp.mesh.MeshFunctionSizet) -> None
Invoked with: <dolfin.fem.form.Form object at 0x7f67280289b0>, [None]
Should ufl be patched (as version 2023.2, say) to restore support for old dolfin?
Or should the new namespace be changed from ufl to uflx ? This was done previously when ffc was changed to ffcx
I found a useful case that is not correctly handled by ufl.split
.
Consider the simple code snapshot below. Both broken_case
and working_case
return a vector-like expression, however ufl.split
is unable to correctly extract the list of components for the broken case.
import dolfin as dl
import ufl
def broken_case():
print("Construct a vector using as_vector")
a = dl.Constant(1.)
b = dl.Constant(2.)
return ufl.as_vector( (a,b) )
def working_case():
print("Construct a vector constant")
return dl.Constant( (1., 2.) )
v = working_case()
print( ufl.split(v) )
v = broken_case()
print( ufl.split(v) )
which produces the output.
Construct a vector constant
(Indexed(Coefficient(FunctionSpace(None, VectorElement(FiniteElement('Real', None, 0), dim=2)), 0), MultiIndex((FixedIndex(0),))), Indexed(Coefficient(FunctionSpace(None, VectorElement(FiniteElement('Real', None, 0), dim=2)), 0), MultiIndex((FixedIndex(1),))))
Construct a vector using as_vector
Don't know how to split [f_1, f_2].
Traceback (most recent call last):
File "my_tesst.py", line 18, in <module>
print( ufl.split(v) )
File "/Users/uvilla/anaconda3/envs/fenics-2019.1/lib/python3.7/site-packages/ufl/split_functions.py", line 61, in split
error("Don't know how to split %s." % (v,))
File "/Users/uvilla/anaconda3/envs/fenics-2019.1/lib/python3.7/site-packages/ufl/log.py", line 172, in error
raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Don't know how to split [f_1, f_2].
On the other hand:
v = broken_case()
a,b= v
produces the desired effect.
Then, my question is: Would make sense to replace this error line with return v
?
Hi i have met a very basic bug, or at least a strange behaviour, involving ufl
Here is a very minimal code showing the issue:
from dolfin import *
mesh = RectangleMesh(Point(0., 0.), Point(1, 1), 1, 1, "crossed")
V = VectorFunctionSpace(mesh, 'CG', degree=2)
u_ = TestFunction(V)
x = SpatialCoordinate(mesh)
Working
first_form = inner(Constant((1,1)), u_) * x[0] * dx
print("First form", first_form)
Not working
dx1 = x[0] * dx
second_form = inner(Constant((1,1)), u_) * dx1
print("Second form", second_form)
No operation is defined between the Conj operator and a ufl-form even though one could expect these two syntax to be equivalent
For largely historical reasons, UFL supports loading and executing .ufl
files. This hides from the user that they can can exploit the full features of a Python program, and prevents the mixing of UFL and form compiler features in a single program, e.g. UFL and specifics of FFCx cannot be synthesised in the generation process.
This change should have no impact on Python libraries that use UFL. It should only impact static libraries that pre-compile code from .ufl
input.
UFL still uses long-form license in every file.
Hello everyone, I have a vector function to be interpolated into the RT space and do it like this f.interpolate(lambda x: (g1(x), g2(x)) without luck.
When adding an UFL type using the @ufl_type
decorator this seems to lead to errors in, for example, the Transformer
class from ufl.algorithms
. Example, somewhere in some external (to ufl) code:
import ufl
from ufl.core.ufl_type import ufl_type
@ufl_type(is_scalar=True)
class BoundaryId(ufl.geometry.GeometricFacetQuantity):
"""UFL boundary id: can be used in a conditional to fix the desired boundary id."""
__slots__ = ()
name = "facetid"
This leads to an index error in
ufl/ufl/algorithms/transformer.py
Line 89 in 4e3868d
all_ufl_classes
:
from ufl.classes import all_ufl_classes
all_ufl_classes.add(BoundaryId)
However, this can cause problems when other Python modules using UFL are included before these two lines, because it can mess up the index order in all_ufl_classes
. So the result is, that all other modules using UFL should be included after this statement.
So the question is: What is the correct way of adding external UFL types (besides using @ufl_type
)? Or is this a bug and the modification of the UFL internal lists and sets should be done inside the @ufl_type
functions?
See https://github.com/FEniCS/dolfinx/actions/runs/5407842569/jobs/9826291336.
Is it essential?
There's a bit of a mismatch in the documentation vs code for naming of the atan2
function. In the documentation the function is listed as atan2
but it is defined in the code as atan_2
. I guess the documentation needs fixing?
I think this has been the case for several releases (2021, 2019, 2017 at least).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.