Skip to content

Expression parsers

Module for parsing mathematical expressions into finite element functions.

This module provides a utility function to parse string expressions or numerical values into finite element functions. It supports both symbolic expressions (as strings) and numerical values, converting them into appropriate FEniCSx finite element functions.

Functions:

Name Description
parse_expression

Parses a value into a finite element function.

parse_expression(value, space, export_func=False)

Parses a value into a finite element function.

This function converts a string expression or numerical value into a finite element function. If the input is a string, it is parsed as a symbolic expression and interpolated onto the provided function space. If the input is a numerical value, it is used to create a constant finite element function. If the input is NaN, the function returns None.

Parameters:

Name Type Description Default
value

The value to parse. Can be a string expression (e.g., "x**2 + 1") or a numerical value. If NaN, the function returns None.

required
space FunctionSpace

The finite element function space onto which the expression or value should be interpolated.

required
export_func bool

Flag indicating if the parameter function must be exported.

False

Returns:

Name Type Description
func Function or None

A finite element function representing the parsed expression or value. Returns None if the input value is NaN.

Example:

from dolfinx import fem
from gcrack.utils.expression_parsers import parse_expression
mesh = ...  # Create a mesh
V = fem.functionspace(mesh, ("Lagrange", 1))
# Parse a string expression
f1 = parse_expression("x**2 + 1", V)
# Parse a numerical value
f2 = parse_expression(5.0, V)
Source code in src/gcrack/utils/expression_parsers.py
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
def parse_expression(value, space: fem.FunctionSpace, export_func: bool = False):
    """Parses a value into a finite element function.

    This function converts a string expression or numerical value into a finite element function.
    If the input is a string, it is parsed as a symbolic expression and interpolated onto the provided function space.
    If the input is a numerical value, it is used to create a constant finite element function.
    If the input is NaN, the function returns None.

    Args:
        value:
            The value to parse.
            Can be a string expression (e.g., "x**2 + 1") or a numerical value.
            If NaN, the function returns None.
        space (fem.FunctionSpace):
            The finite element function space onto which the expression or value should be interpolated.
        export_func (bool):
            Flag indicating if the parameter function must be exported.


    Returns:
        func (fem.Function or None):
            A finite element function representing the parsed expression or value.
            Returns None if the input value is NaN.

    Example:

        from dolfinx import fem
        from gcrack.utils.expression_parsers import parse_expression
        mesh = ...  # Create a mesh
        V = fem.functionspace(mesh, ("Lagrange", 1))
        # Parse a string expression
        f1 = parse_expression("x**2 + 1", V)
        # Parse a numerical value
        f2 = parse_expression(5.0, V)
    """
    if isinstance(value, (int, float)):
        # Check if the DOF is imposed
        if isnan(value):
            return None
        # Define an FEM function (to control the BC)
        func = fem.Function(space)
        # Update the load
        with func.x.petsc_vec.localForm() as local_func:
            local_func.set(value)
        # Create the par_func if necessary
        if export_func:

            def par_func(xx):
                return value
    elif isinstance(value, str):
        # Parse the function
        x = sp.Symbol("x")
        # Parse the expression using sympy
        par_func = sp.utilities.lambdify(x, value, "numpy")
        # Create and interpolate the fem function
        func = fem.Function(space)
        func.interpolate(lambda xx: par_func(xx))
    else:
        raise ValueError("Unknown type passed to a parsed expression.")

    if not export_func:
        return func
    else:
        return func, par_func