Skip to content

Commit

Permalink
add section about point evaluation in the manual
Browse files Browse the repository at this point in the history
  • Loading branch information
miklos1 committed Oct 26, 2015
1 parent 75bb4e7 commit 8f62f67
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/source/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ finite element problems in Firedrake.
solving-interface
boundary_conditions
extruded-meshes
point-evaluation

.. only:: html

Expand Down
116 changes: 116 additions & 0 deletions docs/source/point-evaluation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
.. only:: html

.. contents::

Point evaluation
================

Firedrake can evaluate :py:class:`~.Function`\s at arbitrary physical
points. This feature can be useful for the evaluation of the result
of a simulation. Two APIs are offered to this feature: a
Firedrake-specific one, and one from UFL.


Firedrake API
-------------

Firedrake offers a convenient API for evaluating functions at
arbitrary points via :func:`~.Function.at`:

.. code-block:: python
# evaluate f at a 1-dimensional point
f.at(0.3)
# evaluate f at two 1-dimensional points, or at one 2-dimensional point
# (depending on f's geometric dimension)
f.at(0.2, 0.4)
# evaluate f at one 2-dimensional point
f.at([0.2, 0.4])
# evaluate f at two 2-dimensional point
f.at([0.2, 0.4], [1.2, 0.5])
# evaluate f at two 2-dimensional point (same as above)
f.at([[0.2, 0.4], [1.2, 0.5]])
While in these examples we have only shown lists, other *iterables*
such as tuples and ``numpy`` arrays are also accepted. The following
are equivalent:

.. code-block:: python
f.at(0.2, 0.4)
f.at((0.2, 0.4))
f.at([0.2, 0.4])
f.at(numpy.array([0.2, 0.4]))
For a single point, the result is ``numpy`` array, or a tuple of
``numpy`` arrays in case *mixed* functions. When evaluating multiple
points, the result is a list of values for each point.


Points outside the domain
~~~~~~~~~~~~~~~~~~~~~~~~~

When any point is outside the domain of the function,
:py:class:`.PointNotInDomainError` exception is raised. If
``dont_raise=True`` is passed to :func:`~.Function.at`, the result is
``None``.

.. code-block:: python
mesh = UnitIntervalMesh(8)
f = mesh.coordinates
f.at(1.2) # raises exception
f.at(1.2, dont_raise=True) # returns None
f.at(0.5, 1.2) # raises exception
f.at(0.5, 1.2, dont_raise=True) # returns [0.5, None]
.. warning::

Point evaluation on *immersed manifolds* in not supported yet, due
to the difficulty of specifying a physical point on the manifold.


Evaluation with a distributed mesh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is limited support for point evaluation when running Firedrake
in parallel. There is no special API, but there are some restrictions:

* Point evaluation is a *collective* operation.
* Each process must ask for the same list of points.
* Each process will get the same values.


UFL API
-------

UFL reserves the function call operator for evaluation:

.. code-block:: python
f([0.2, 0.4])
will evaluate :math:`f` at :math:`(0.2, 0.4)`. UFL does not accept
multiple points at once, and cannot configure what to do with a point
which is not in the domain. The advantage of this syntax is that it
works on any :py:class:`~.ufl.core.expr.Expr`, for example:

.. code-block:: python
(f*sin(f)([0.2, 0.4])
will evaluate :math:`f \cdot \sin(f)` at :math:`(0.2, 0.4)`.
.. note::
The expression itself is not translated into C code. While the
evaluation of a function uses the same infrastructure as the
Firedrake API, which uses generated C code, the expression tree is
evaluated by UFL in Python.

0 comments on commit 8f62f67

Please sign in to comment.