Files
JuliaFEM.jl/src/dofs
Jukka Aho ec600459a9 refactor(dofs): align fields.jl docs and counting with DOF{Q,E} templates
Bring module prose in line with flat `dof_indices`, `@DOFSet`, and DOFHandler-era
helpers while tightening compile-time DOF arithmetic.

- Refresh docstrings: drop markdown bold noise; document `element_dofs` /
  `field_dof_range` instead of NamedTuple-shaped `dof_indices` accessors.
- Rewrite examples to prefer `@DOFSet`; spell out NamedTuple equivalence and drop
  Tuple-based migration snippets incompatible with DOFHandler.
- Implement `field_ndofs(::Type{<:DOF}, Topo)` / `ndofs(::DOFSet, Topo)` using
  `quantity_type` / `entity_type` and generator-style sums over `fieldtypes(S)`.
- Extend `quantity_type(::Type{<:DOF})` for raw `Float64`, `Vec`, `Tensor`, and
  `SymmetricTensor` fields alongside `AbstractField` wrappers.
- Allow `field_ndofs` on raw-quantity DOFs by sizing `T` directly (pressure on
  cells/faces, etc.).
- Remove `single_field` compatibility helper and duplicate element accessors now
  canonical in `src/elements/elements.jl`.
- Point LICENSE header at LICENSE.md.
2026-05-09 16:48:26 +03:00
..

src/dofs/

Type-stable degree-of-freedom infrastructure: the field specification language (DOF{Q, E}, @DOFSet), the global DOF numbering (DOFHandler), and the inverse DOF connectivity used by the matrix-free assembler.

The previous Dict-based DOFManager/register_fields!/count_field_dofs API has been removed. DOFManager is now an alias for DOFHandler for backward compatibility.

Contract and vocabulary: AGENTS.md (repository root). Executable examples: test/dofs/test_multifield_dof_system.jl and the DOF topic tests under test/dofs/runtests.jl.

Files

  • api.jlDOF{Quantity, Entity} abstract type, dof_size for the supported quantity types (Float64, Vec{D}, Tensor{2,D}), and the entity types (Vertex, Edge, Face, Cell).
  • fields.jl — the @DOFSet macro (NamedTuple of DOF{Q, E}) and field accessors (field_names, field_count, field_ndofs, field_dof_range, is_single_field).
  • dof_handler.jlDOFHandler{Mesh, S, NF}. One flat Vector{Int} per field stores the starting global DOF for each entity ID; total_dofs is computed once. create_elements!(mesh, ET) walks the mesh, assigns DOFs, builds the element vector and the inverse DOF connectivity in one pass.
  • dof_connectivity.jlDOFConnectivity. Maps each DOF to the elements and local-DOF positions that contribute to its row, which is what the DOF-based assembler iterates over.

DOF specification

DOF{Quantity, Entity} is purely a type-level marker; instances are never created. Quantity carries the per-entity DOF size via dof_size, and Entity selects the topological entity that owns it.

# Single field
S = @DOFSet{u::DOF{Displacement{3}, Vertex}}

# Multi-field (e.g. thermo-mechanical)
S = @DOFSet{T::DOF{Temperature, Vertex},
            u::DOF{Displacement{3}, Vertex}}

# `S` is a NamedTuple type with field types `DOF{Q, E}`.

@DOFSet is the preferred entry point. DOFSet is currently a type alias for NamedTuple, but using @DOFSet insulates calling code from that implementation detail.

Building elements and the handler

create_elements! is the only call most user code needs:

ET = Element{Hex8, Lagrange{1}, S}
elements, handler = create_elements!(mesh, ET)
# elements::Vector{Element{Hex8, Lagrange{1}, S, 24}}
# handler.dof_connectivity is already built.

DOFHandler exposes:

  • field_starts::NTuple{NF, Vector{Int}} — per-field starting DOF for each entity ID.
  • total_dofs::Int.
  • dof_connectivity::DOFConnectivity for the matrix-free path.

The compile-time DOF layout for the element template is generated by local_dof_layout(::Type{Element{K, P, S, N}}) (in src/elements/).

Element-level DOF utilities

These helpers operate on a single Element instance and are used inside assembly hot paths:

  • element_dofs(elem) — flat NTuple{N, UInt64}.
  • n_element_dofs(elem)N.
  • local_to_global_map(elem) — same as above, for clarity.
  • field_dof_range(elem, :field)UnitRange of local indices for one field block (compile-time constant).
  • extract_element_dofs(elem, u) — flat NamedTuple of scalars grouped by field.
  • extract_element_dofs_structured(elem, u) — values reinterpreted into the field's quantity type (e.g. Vec{3} per node).
  • interpolate_field, interpolate_fields, interpolate_field_value, interpolate_local_fields — point-evaluation utilities at quadrature points.

Multiple DOFs per Edge or Face

The topological facet id from AbstractFacetConnectivityMaps still identifies one mesh edge or mesh face. If the field quantity has dof_size(Q) > 1 (for example DOF{Vec{2,Float64}, Edge}), that entity owns several consecutive global DOFs starting at field_starts[field][entity_gid]. local_dof_layout and _make_element_dofs treat them as separate components on the same local entity index; assembly kernels that replicate a scalar facet measure per unknown should match component(layout_i) == component(layout_j) when filling diagonal blocks.

Hp-refinement, NURBS/IGA, or hierarchic enrichment imply either distinct Element{K, P, S, N} templates per patch (so N and layout stay compile-time constants) or precomputed facet tables built once when the mesh changes — not dynamic Dict lookups inside element quadrature loops.

Variable numbers of DOFs on different mesh edges (non-uniform p along edges) need matching counts on shared edges for conformity. A natural numbering stores one contiguous band per global edge with widths given by a CSR offset vector; see edge_dof_csr_offsets on AbstractFacetConnectivityMaps in src/mesh/hex8_facet_maps.jl. Wiring that into DOFHandler and local_dof_layout is future work when hp facet spaces are added.

Heterogeneous element types

create_elements! can be called repeatedly on the same mesh with different Element{K, P, S} types (for example a thermal S1 and a mechanical S2); the handler keeps DOFs of identically-named fields shared between the element types.

  • src/topology/Vertex, Edge, Face, Cell.
  • src/elements/Element{K, P, S, N} and local_dof_layout.
  • src/assemblers/DOFBasedCOOAssembler is the primary consumer of DOFConnectivity.
  • test/dofs/ — public test suite.