FENICSFORMCOMPILERX(1)

๐Ÿ’– FENICSFORMCOMPILERX(1) โ€” bestie edition ๐Ÿ’–

okay so. you opened the manual page for fenicsformcompilerx, and the manual name is FFCx (FEniCS Form Compiler), so like. buckle up. this is the whole FFCx docs situation and we're gonna get through it together, no skipping, no summarizing, every last option and signature stays. slay. ๐ŸŽ€


โœจ NAME โœจ

fenicsformcompilerx โ€” FFCx Documentation, bestie.

The is a new version of the FEniCS Form Compiler. It is developed at https://github.com/FEniCS/ffcx ๐Ÿฆ‹

and here's the whole module roster, no cap, every single one:

  • ffcx โ€” FEniCS Form Compiler (FFCx).
  • ffcx.__main__ โ€” Run FFCx on a UFL file.
  • ffcx.analysis โ€” Compiler stage 1: Analysis.
  • ffcx.compiler โ€” Main interface for compilation of forms.
  • ffcx.element_interface โ€” Finite element interface.
  • ffcx.formatting โ€” Compiler stage 5: Code formatting.
  • ffcx.main โ€” Command-line interface to FFCx.
  • ffcx.naming โ€” Naming.
  • ffcx.codegeneration โ€” FFCx code generation.
  • ffcx.options โ€” Options.
  • ffcx.ir.representation โ€” Compiler stage 2: Code representation.
  • ffcx.ir.representationutils โ€” Utility functions for some code shared between representations.

๐Ÿงš FFCX ๐Ÿงš

FEniCS Form Compiler (FFCx). that's the whole vibe.

FFCx compiles finite element variational forms into C code. literally its entire personality. ๐Ÿ’…


๐ŸŒธ FFCX.__MAIN__ ๐ŸŒธ

Run FFCx on a UFL file. that's it, that's the job, it eats a UFL file and goes to work. ๐Ÿ‘‘


๐Ÿฆ‹ FFCX.ANALYSIS ๐Ÿฆ‹

Compiler stage 1: Analysis.

This module implements the analysis/preprocessing of variational forms, including automatic selection of elements, degrees and form representation type. it's giving very much the "figuring out what you actually meant" era of the pipeline. ๐Ÿ˜Œ

โญ Functions

  • analyze_ufl_objects(ufl_objects, scalar_type) โ€” Analyze ufl object(s).

โญ Classes

  • UFLData(form_data, unique_elements, ...) โ€” UFL data.

๐Ÿ’œ class ffcx.analysis.UFLData(...) ๐Ÿ’œ

class ffcx.analysis.UFLData(form_data: tuple[FormData, ...],
unique_elements: list[basix.ufl._ElementBase], element_numbers:
dict[basix.ufl._ElementBase, int], unique_coordinate_elements:
list[basix.ufl._ElementBase], expressions:
list[tuple[ufl.core.expr.Expr, npt.NDArray[np.floating],
ufl.core.expr.Expr]])

Bases: NamedTuple

UFL data. yes the class is literally named that. iconic.

Create new instance of UFLData(form_data, unique_elements, element_numbers, unique_coordinate_elements, expressions)

so here's every field, spelled out, because bestie we do not leave fields behind:

  • element_numbers: dict[basix.ufl._ElementBase, int] โ€” Mapping to unique numbers for all elements.
  • expressions: list[tuple[ufl.core.expr.Expr, npt.NDArray[np.floating], ufl.core.expr.Expr]] โ€” List of all expressions after post-processing, with evaluation points and original expression.
  • form_data: tuple[FormData, ...] โ€” FormData objects.
  • unique_coordinate_elements: list[basix.ufl._ElementBase] โ€” Unique coordinate elements across all forms and expressions.
  • unique_elements: list[basix.ufl._ElementBase] โ€” Unique elements across all forms and expressions.

๐Ÿ“ ffcx.analysis.analyze_ufl_objects(...) ๐Ÿ“

ffcx.analysis.analyze_ufl_objects(ufl_objects: list[Form | _ElementBase
| Mesh | tuple[Expr, ndarray[tuple[Any, ...], dtype[floating]]]],
scalar_type: DTypeLike) -> UFLData

Analyze ufl object(s). that's the task.

Parameters

  • ufl_objects โ€” UFL objects
  • scalar_type โ€” Scalar type that should be used for the analysis

Returns โ€” A named tuple UFLData.


๐Ÿ”ฅ FFCX.COMPILER ๐Ÿ”ฅ

Main interface for compilation of forms.

Breaks the compilation into several sequential stages. The output of each stage is the input of the next stage. it's a relay race and every leg hands off perfectly. ๐Ÿƒโ™€๏ธ๐Ÿ’จ

๐Ÿ‘‘ Compiler stages

  1. Language, parsing
    • Input: Python code or .ufl file
    • Output: UFL form

This stage consists of parsing and expressing a form in the UFL form language. This stage is handled by UFL.

  1. Analysis
    • Input: UFL form
    • Output: Preprocessed UFL form and FormData (metadata)

This stage preprocesses the UFL form and extracts form metadata. It may also perform simplifications on the form.

  1. Code representation
    • Input: Preprocessed UFL form and FormData (metadata)
    • Output: Intermediate Representation (IR)

This stage examines the input and generates all data needed for code generation. This includes generation of finite element basis functions, extraction of data for mapping of degrees of freedom and possible precomputation of integrals. Most of the complexity of compilation is handled in this stage. (the way that "most of the complexity" is just casually dropped here ๐Ÿ˜ญ)

The IR is stored as a dictionary, mapping names of UFCx functions to data needed for generation of the corresponding code.

  1. Code generation
    • Input: Intermediate Representation (IR)
    • Output: C code

This stage examines the IR and generates the actual C code for the body of each UFCx function.

The code is stored as a dictionary, mapping names of UFCx functions to strings containing the C code of the body of each function.

  1. Code formatting
    • Input: C code
    • Output: C code files

This stage examines the generated C++ code and formats it according to the UFCx format, generating as output one or more .h/.c files conforming to the UFCx format.

bestie note: yeah the numbering in the original really does start at 0 for parsing and the formatting stage is listed as stage 5. we're just honoring the original, no edits, periodt. ๐Ÿ™ˆ

๐Ÿงš Functions

  • compile_ufl_objects(ufl_objects, options[, ...]) โ€” Generate UFCx code for a given UFL objects.

๐ŸŒˆ ffcx.compiler.compile_ufl_objects(...) ๐ŸŒˆ

ffcx.compiler.compile_ufl_objects(ufl_objects: list[Any], options:
dict[str, int | float | DTypeLike], object_names: dict[int, str] | None
= None, namespace: str | None = None, visualise: bool = False) ->
tuple[list[str], tuple[str, ...]]

Generate UFCx code for a given UFL objects. the main character function, honestly. โญ

Parameters

  • ufl_objects โ€” Objects to be compiled. Accepts elements, forms, integrals or coordinate mappings.
  • object_names โ€” Map from object Python id to object name
  • namespace โ€” Convenience namespace/prefix for generated code.
  • options โ€” Options
  • visualise โ€” Toggle visualisation

Returns: tuple containing list of code file strings and tuple of associated file suffixes.

๐Ÿ’Ž FFCX.ELEMENT_INTERFACE ๐Ÿ’Ž

Finite element interface. Bestie, this is the little drawer where all the finite-element plumbing lives. ๐Ÿงš

๐ŸŒˆ Functions

  • basix_index(indices) โ€” Get the Basix index of a derivative. ๐Ÿ”ข
  • create_quadrature(cellname, degree, rule, ...) โ€” Create a quadrature rule. โœจ
  • map_edge_points(points, edge, cellname) โ€” Map points from a reference edge to a physical edge. ๐Ÿช„
  • map_facet_points(points, facet, cellname) โ€” Map points from a reference facet to a physical facet. ๐Ÿช„
  • reference_cell_vertices(cellname) โ€” Get the vertices of a reference cell. ๐Ÿ“

โœจ ffcx.element_interface.basix_index

ffcx.element_interface.basix_index(indices: tuple[int]) -> int

Get the Basix index of a derivative. Yeah that's the whole vibe โ€” hand it the indices and it hands back the index. ๐Ÿ’…

โœจ ffcx.element_interface.create_quadrature

ffcx.element_interface.create_quadrature(cellname: str, degree: int,
       rule: str, elements: list[_ElementBase]) -> tuple[ArrayLike, ArrayLike]

Create a quadrature rule. Cell name, degree, rule, elements in โ€” quadrature out. ๐ŸŽ€

โœจ ffcx.element_interface.map_edge_points

ffcx.element_interface.map_edge_points(points: ndarray[tuple[Any, ...],
       dtype[float64]], edge: int, cellname: str) -> ndarray[tuple[Any, ...],
       dtype[float64]]

Map points from a reference edge to a physical edge. Glow-up arc for your points, fr fr. ๐Ÿฆ‹

โœจ ffcx.element_interface.map_facet_points

ffcx.element_interface.map_facet_points(points: ndarray[tuple[Any, ...],
       dtype[float64]], facet: int, cellname: str) -> ndarray[tuple[Any, ...],
       dtype[float64]]

Map points from a reference facet to a physical facet. Same energy, facet edition. ๐Ÿ’–

โœจ ffcx.element_interface.reference_cell_vertices

ffcx.element_interface.reference_cell_vertices(cellname: str) ->
       ndarray[tuple[Any, ...], dtype[float64]]

Get the vertices of a reference cell. Corners, but make it math. ๐Ÿ”ท


๐ŸŽจ FFCX.FORMATTING ๐ŸŽจ

Compiler stage 5: Code formatting. We're at stage FIVE bestie, can you believe. ๐Ÿ˜ญ

This module implements the formatting of UFCx code from a given dictionary of generated C++ code for the body of each UFCx function. It relies on templates for UFCx code available as part of the module ufcx_utils. iykyk

๐ŸŒธ Functions

  • format_code(code_blocks) โ€” Format given code in UFCx format. โœจ
  • write_code(code, prefix, suffixes, output_dir) โ€” Write code to files. ๐Ÿ“

โœจ ffcx.formatting.format_code

ffcx.formatting.format_code(code_blocks: CodeBlocks) -> list[str]

Format given code in UFCx format.

Returns two strings with header and source file contents. Two strings. Header and source. Not one. Not three. Two. ๐Ÿ‘‘

โœจ ffcx.formatting.write_code

ffcx.formatting.write_code(code: list[str], prefix: str, suffixes:
       tuple[str, ...], output_dir: str) -> None

Write code to files. Literally what it says on the tin. ๐Ÿซถ


๐Ÿš€ FFCX.MAIN ๐Ÿš€

Command-line interface to FFCx.

Parse command-line arguments and generate code from input UFL form files. This is the main character. ๐ŸŒŸ

๐Ÿ’… Functions

  • main([args]) โ€” Run ffcx on a UFL file.

โœจ ffcx.main.main

ffcx.main.main(args: Sequence[str] | None = None) -> int

Run ffcx on a UFL file. That's it, that's the function. ๐ŸŽ€


๐Ÿท๏ธ FFCX.NAMING ๐Ÿท๏ธ

Naming. Because everything in code needs a name and the names have to be correct, and honestly? Respect. โœจ

๐Ÿ’œ Functions

  • compute_signature(ufl_objects, tag) โ€” Compute the signature hash. ๐Ÿ”
  • expression_name(expression, prefix) โ€” Get expression name.
  • form_name(original_form, form_id, prefix) โ€” Get form name.
  • integral_name(original_form, integral_type, ...) โ€” Get integral name.

โœจ ffcx.naming.compute_signature

ffcx.naming.compute_signature(ufl_objects: list[Form] | list[tuple[Expr,
       ndarray[tuple[Any, ...], dtype[floating]]]], tag: str) -> str

Compute the signature hash.

Based on the UFL type of the objects and an additional optional 'tag'. ๐Ÿ”

โœจ ffcx.naming.expression_name

ffcx.naming.expression_name(expression: tuple[Expr, ndarray[tuple[Any,
       ...], dtype[floating]]], prefix: str) -> str

Get expression name. ๐Ÿงš

โœจ ffcx.naming.form_name

ffcx.naming.form_name(original_form: Form, form_id: int, prefix: str) ->
       str

Get form name. ๐Ÿ“›

โœจ ffcx.naming.integral_name

ffcx.naming.integral_name(original_form: Form, integral_type: str,
       form_id: int, subdomain_id: Literal['everywhere'] | Integral |
       tuple[Integral, ...], prefix: str) -> str

Get integral name. And yes, subdomain_id can literally be the string 'everywhere' or an Integral or a tuple of Integrals. Iconic flexibility tbh. ๐Ÿ’…


โš™๏ธ FFCX.CODEGENERATION โš™๏ธ

FFCx code generation. The actual code-spitting-out part. Chef's kiss. ๐Ÿ‘จโ€๐Ÿณ๐Ÿ’‹

๐ŸŒˆ Functions

  • get_include_path() โ€” Return location of UFCx header files. ๐Ÿ“‚
  • get_signature() โ€” Return SHA-1 hash of the contents of ufcx.h. ๐Ÿ”‘

โœจ ffcx.codegeneration.get_include_path

ffcx.codegeneration.get_include_path()

Return location of UFCx header files. Where the headers at. ๐Ÿ“

โœจ ffcx.codegeneration.get_signature

ffcx.codegeneration.get_signature()

Return SHA-1 hash of the contents of ufcx.h.

In this implementation, the value is computed on import. On import, bestie, so it's already done by the time you ask. โšก


๐ŸŽ€ FFCX.OPTIONS ๐ŸŽ€

Options. The settings drawer. Every good tool has one. ๐Ÿ’–

๐Ÿฆ‹ Functions

  • get_language(options) โ€” Retrieve the language option from the options database. ๐Ÿ—ฃ๏ธ
  • get_options([priority_options]) โ€” Return (a copy of) the merged option values for FFCX. ๐Ÿงพ

โœจ ffcx.options.get_language

ffcx.options.get_language(options: dict[str, int | float | DTypeLike])
       -> str

Retrieve the language option from the options database.

Applies for internal languages the alias conversion. โœจ

โœจ ffcx.options.get_options

ffcx.options.get_options(priority_options: dict[str, DTypeLike | int |
       float] | None = None) -> dict[str, int | float | DTypeLike]

Return (a copy of) the merged option values for FFCX.

Parameters

  • priority_options โ€” take priority over all other option values (see notes) ๐Ÿ‘‘

Returns

  • merged option values โœจ

Note:

This function sets the log level from the merged option values prior to returning.

The ffcx_options.json files are cached on the first call. Subsequent calls to this function use this cache. ๐Ÿ—ƒ๏ธ

Priority ordering of options from highest to lowest is:

  1. priority_options (API and command line options) ๐Ÿ”ฅ
  2. $PWD/ffcx_options.json (local options) ๐Ÿ“
  3. $XDG_CONFIG_HOME/ffcx/ffcx_options.json (user options) ๐Ÿ 
  4. FFCX_DEFAULT_OPTIONS in ffcx.options ๐ŸŒฑ

XDG_CONFIG_HOME is ~/.config/ if the environment variable is not set.

Example ffcx_options.json file:

{ "epsilon": 1e-7 }
๐Ÿ’€ Heads up bestie: the priority order is not a suggestion, it's the whole entire ruleset. Highest wins. Periodt.

โœจ FFCX.IR.REPRESENTATION โœจ

okay bestie, welcome to compiler stage 2: code representation ๐ŸŽ€ this is where the intermediate representation (IR) of forms gets computed, and honestly it's giving main character energy ๐Ÿ’…

so this module computes the intermediate representations of forms. for each UFC function, we pull out exactly the data we'll need for code generation at a later stage. efficiency? iconic. โœจ

the representation has to conform strictly to the naming and order of functions in UFC โ€” no wiggle room, no cap ๐Ÿซถ so when you're code-generating the function "foo", you should literally only need to use the data stored in the intermediate representation under the key "foo". that's the whole vibe.


๐ŸŒธ Functions ๐ŸŒธ

  • basix_cell_from_string(string) โ€” turns a string into a Basix CellType ๐Ÿฆ‹
  • compute_ir(analysis, object_names, prefix, ...) โ€” computes the intermediate representation โœจ

๐Ÿงš Classes ๐Ÿงš

  • DataIR(integrals, forms, expressions) โ€” intermediate representation of data ๐Ÿ“ฆ
  • ExpressionIR(expression, ...) โ€” intermediate representation of a DOLFINx Expression ๐Ÿ’œ
  • FormIR(id, name, signature, rank, ...) โ€” intermediate representation of a form ๐Ÿ“
  • IntegralIR(expression, rank, ...) โ€” intermediate representation of an integral ๐Ÿงฎ
  • QuadratureIR(cell_shape, points, weights) โ€” intermediate representation of a quadrature rule โญ

๐Ÿ’– class ffcx.ir.representation.DataIR(integrals: list[IntegralIR], forms: list[FormIR], expressions: list[ExpressionIR])

Bases: NamedTuple

intermediate representation of data ๐Ÿซถ

  • Creates a new instance of DataIR(integrals, forms, expressions)

Fields, bestie (yes the aliases are literally just field numbers, don't @ me):

  • expressions: list[ExpressionIR] โ€” alias for field number 2
  • forms: list[FormIR] โ€” alias for field number 1
  • integrals: list[IntegralIR] โ€” alias for field number 0

๐Ÿ’– class ffcx.ir.representation.ExpressionIR(expression: CommonExpressionIR, original_coefficient_positions: list[int], coefficient_names: list[str], constant_names: list[str], name_from_uflfile: str)

Bases: NamedTuple

intermediate representation of a DOLFINx Expression ๐Ÿ‘‘

  • Creates a new instance of ExpressionIR(expression, original_coefficient_positions, coefficient_names, constant_names, name_from_uflfile)
  • coefficient_names: list[str] โ€” alias for field number 2
  • constant_names: list[str] โ€” alias for field number 3
  • expression: CommonExpressionIR โ€” alias for field number 0
  • name_from_uflfile: str โ€” alias for field number 4
  • original_coefficient_positions: list[int] โ€” alias for field number 1

๐Ÿ’– class ffcx.ir.representation.FormIR(id: int, name: str, signature: str, rank: int, num_coefficients: int, name_from_uflfile: str, original_coefficient_positions: list[int], coefficient_names: list[str], num_constants: int, constant_ranks: list[int], constant_shapes: list[list[int]], constant_names: list[str], finite_element_hashes: list[int], integral_names: dict[str, list[str]], integral_domains: dict[str, list[basix.CellType]], subdomain_ids: dict[str, list[int]])

Bases: NamedTuple

intermediate representation of a form ๐Ÿ“ (this one's a whole meal, seventeen fields fr fr)

  • Creates a new instance of FormIR(id, name, signature, rank, num_coefficients, name_from_uflfile, original_coefficient_positions, coefficient_names, num_constants, constant_ranks, constant_shapes, constant_names, finite_element_hashes, integral_names, integral_domains, subdomain_ids)

okay so the fields, all sixteen-plus of them, slay:

  • coefficient_names: list[str] โ€” alias for field number 7
  • constant_names: list[str] โ€” alias for field number 11
  • constant_ranks: list[int] โ€” alias for field number 9
  • constant_shapes: list[list[int]] โ€” alias for field number 10
  • finite_element_hashes: list[int] โ€” alias for field number 12
  • id: int โ€” alias for field number 0
  • integral_domains: dict[str, list[CellType]] โ€” alias for field number 14
  • integral_names: dict[str, list[str]] โ€” alias for field number 13
  • name: str โ€” alias for field number 1
  • name_from_uflfile: str โ€” alias for field number 5
  • num_coefficients: int โ€” alias for field number 4
  • num_constants: int โ€” alias for field number 8
  • original_coefficient_positions: list[int] โ€” alias for field number 6
  • rank: int โ€” alias for field number 3
  • signature: str โ€” alias for field number 2
  • subdomain_ids: dict[str, list[int]] โ€” alias for field number 15

๐Ÿ’– class ffcx.ir.representation.IntegralIR(expression: CommonExpressionIR, rank: int, enabled_coefficients: list[bool], part: TensorPart)

Bases: NamedTuple

intermediate representation of an integral ๐Ÿงฎ

  • Creates a new instance of IntegralIR(expression, rank, enabled_coefficients, part)
  • enabled_coefficients: list[bool] โ€” alias for field number 2
  • expression: CommonExpressionIR โ€” alias for field number 0
  • part: TensorPart โ€” alias for field number 3
  • rank: int โ€” alias for field number 1

๐Ÿ’– class ffcx.ir.representation.QuadratureIR(cell_shape: str, points: npt.NDArray[np.float64], weights: npt.NDArray[np.float64])

Bases: NamedTuple

intermediate representation of a quadrature rule โญ

  • Creates a new instance of QuadratureIR(cell_shape, points, weights)
  • cell_shape: str โ€” alias for field number 0
  • points: ndarray[tuple[Any, ...], dtype[float64]] โ€” alias for field number 1
  • weights: ndarray[tuple[Any, ...], dtype[float64]] โ€” alias for field number 2

๐Ÿฆ‹ Functions (the detailed version) ๐Ÿฆ‹

  • ffcx.ir.representation.basix_cell_from_string(string: str) -> CellType โ€” convert a string to a Basix CellType โœจ
  • ffcx.ir.representation.compute_ir(analysis: UFLData, object_names: dict[int, str], prefix: str, options: dict[str, DTypeLike | int | float | bool], visualise: bool) -> DataIR โ€” compute intermediate representation ๐Ÿ’…

๐ŸŒธ FFCX.IR.REPRESENTATIONUTILS ๐ŸŒธ

Okay bestie, this one is short and sweet โ€” it's literally just the little helper functions that both representations are out here sharing, because sharing is caring ๐Ÿซถ

Utility functions for some code shared between representations.


โœจ Functions โœจ

Here's the whole squad of helper functions, in a lil' list because tables are not the vibe:

  • create_quadrature_points_and_weights(...[, ...]) โ€” Create quadrature rule and return points and weights.
  • integral_type_to_entity_dim(integral_type, tdim) โ€” Given integral_type and domain tdim, return the tdim of the integration entity.
  • map_integral_points(points, integral_type, ...) โ€” Map points from reference entity to its parent reference cell.

๐ŸŽ€ Classes ๐ŸŽ€

Just the one icon in this club, and honestly? She's enough:

  • QuadratureRule(points, weights[, tensor_factors]) โ€” A quadrature rule.

๐Ÿ’– class ffcx.ir.representationutils.QuadratureRule(points, weights, tensor_factors=None) ๐Ÿ’–

Bases: object

A quadrature rule. That's the whole concept, no cap. She's a container, she holds the points and the weights (and optionally tensor_factors), and she does it beautifully. โœจ

Initialise. (Yes bestie, you just call her with points, weights, and optionally tensor_factors โ€” that's the constructor, that's it, that's the move.)

  • id() โ€” Return unique deterministic identifier.
Note: This identifier is used to provide unique names to tables and symbols in generated code. So like, if you were wondering why it needs to be deterministic?? That's why. Same input, same name, every single time, so the generated code doesn't go off-script and start renaming things on you. ๐Ÿ’…

๐Ÿฆ‹ The free-floating functions ๐Ÿฆ‹

ffcx.ir.representationutils.create_quadrature_points_and_weights(integral_type, cell, degree, rule, elements, use_tensor_product=False)

Create quadrature rule and return points and weights. Hand her the integral_type, the cell, the degree, the rule, the elements, and (if you're feeling fancy) flip use_tensor_product to True โ€” default is False, periodt โ€” and she'll hand you back the points and the weights. Obsessed. ๐Ÿ’–

ffcx.ir.representationutils.integral_type_to_entity_dim(integral_type, tdim)

Given integral_type and domain tdim, return the tdim of the integration entity. Translation: you tell her what kind of integral and what dimension the domain is, and she tells you the dimension of the actual thing you're integrating over. Lowkey the most useful lil' lookup in the building. ๐ŸŒˆ

ffcx.ir.representationutils.map_integral_points(points, integral_type, cell, entity)

Map points from reference entity to its parent reference cell. Like, the points live on the little reference entity, but they gotta be expressed in terms of the bigger parent reference cell? Yeah. She does that. She's the translator of the geometry world. ๐Ÿงš


  • Index <>
  • Module Index <>
  • Search Page <>

๐Ÿ‘‘ Author

FEniCS Project โ€” the whole gorgeous collective. ๐Ÿ’œ

2026, FEniCS Project โ€” yeah, 2026, they're ahead of the game, we love that for them.


And that's the whole page bestie, you made it to the end!! ๐Ÿฅณ This was FENICSFORMCOMPILERX(1) โ€” version 0.11.0, dated Aug 25, 2026, from the FEniCS Project. Go forth and compile them forms, you absolute main character. Slay, fr fr. ๐Ÿ’…โœจ๐Ÿฆ‹๐ŸŒธ๐Ÿ’–

๐Ÿ“ฆ where this page comes from