Agent skill

Fenics Fem

by Cai-aa in Cai-aa/CAE-Agent-Hub

A skill your agent uses to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and…

MITAuto-check passedResearch & Science

Install Fenics Fem

skills CLI
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .claude/skills/fenics-fem && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
fenics-fem
GitHub stars
1k
Token cost
~4.8k tokens
SKILL.md length
455 words
Files
3
Skills in repo
57
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and…

  • Works in 3 steps: Poisson Equation on Unit Square → Linear Elasticity → gmsh Mesh Generation and Import into…
  • Solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation
  • SKILL.md covers When to Use, Background & Key Concepts, Environment Setup and Core Workflow, plus 5 more sections
  • Calls conda, python and docker

What it does

Fenics Fem is an agent skill from Cai-aa/CAE-Agent-Hub. Use this Skill to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and paraview export.

Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `UPSTREAM.md`).

It sits in Research & Science, covering Physical and earth sciences. The licence is MIT.

When your agent uses it

  • Solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation
  • Mesh generation with gmsh
  • Poisson/elasticity problems
  • Boundary conditions

Example prompts

  • “/fenics-fem”

Requirements

  • Python 3
  • Docker

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. Poisson Equation on Unit Square
  2. Linear Elasticity
  3. gmsh Mesh Generation and Import into dolfinx

What it can do on your machine

Read from SKILL.md and the folder at commit 194ef49. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • conda
    • python
    • docker

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.fenicsproject.org
    • fenicsproject.org
    • gmsh.info
    • paraview.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Fenics Fem loads about 4.8k tokens when it runs. Until then it costs about 53 tokens; SKILL.md has 455 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~53
When it runs · the whole SKILL.md, loaded when a task matches
~4.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Cai-aa/CAE-Agent-Hub at commit 194ef49, republished under its MIT licence (© Cai-aa). 455 words, ~4,839 tokens.

Download SKILL.mdSave it as .claude/skills/fenics-fem/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
fenics-fem
description
Use this Skill to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and paraview export.
tags
physics, finite-element, FEniCS, PDE, numerical-methods
version
1.0.0
license
MIT
platforms
claude-code, codex, gemini-cli, cursor
dependencies.python
fenics-dolfinx>=0.6, gmsh>=4.11, pyvista>=0.39, numpy>=1.23, petsc4py>=3.18
last_updated
2026-03-17
status
stable

FEniCS Finite Element Method for PDEs

TL;DR — Solve partial differential equations with the Finite Element Method (FEM) using FEniCS/dolfinx. Derive the weak form, generate meshes with gmsh, apply Dirichlet/Neumann boundary conditions, solve Poisson or elasticity problems, and export results to XDMF/VTK for ParaView.


When to Use

Use this Skill when you need to:

  • Solve elliptic, parabolic, or hyperbolic PDEs on complex geometries
  • Implement custom weak forms for multi-physics problems
  • Apply mixed Dirichlet/Neumann/Robin boundary conditions
  • Perform convergence studies on successively refined meshes
  • Export solutions for publication-quality visualization in ParaView

Do not use this Skill when:

  • You need a quick 1D finite-difference solution → use SciPy solve_bvp
  • You want a spectral method for periodic domains → use pseudo-spectral libraries
  • You need GPU-accelerated large-scale CFD → consider OpenFOAM or Fluidity

Background & Key Concepts

Variational (Weak) Form

The FEM converts a strong-form PDE into an integral equation by multiplying by a test function v and integrating by parts. For Poisson's equation:

Strong form: −∇²u = f in Ω, u = uD on ΓD, ∇u·n = g on ΓN

Weak form: Find u ∈ H¹(Ω) such that for all v ∈ H¹₀(Ω): ∫_Ω ∇u·∇v dx = ∫_Ω f v dx + ∫_ΓN g v ds

Function Spaces
Spacedolfinx nameUse case
Continuous Galerkin deg 1("Lagrange", 1)Scalar fields, temperature
Continuous Galerkin deg 2("Lagrange", 2)Higher accuracy, elasticity displacement
Discontinuous Galerkin("DG", 0)Cell-wise constants, flux
Nédélec (edge elements)("Nedelec1st", 1)Electromagnetics, H(curl)
Convergence and Error

For Lagrange P1 elements on a quasi-uniform mesh of size h:

  • L² error: O(h²) (one order above approximation degree)
  • H¹ error: O(h)

Environment Setup

bash
# Recommended: use conda with conda-forge (dolfinx + gmsh are complex to compile)
conda create -n fenics-env python=3.11 -y
conda activate fenics-env
conda install -c conda-forge fenics-dolfinx mpich petsc4py gmsh pyvista -y

# Verify installation
python -c "import dolfinx; print('dolfinx version:', dolfinx.__version__)"
python -c "import gmsh; print('gmsh version:', gmsh.__version__)"

# For Docker users (simplest approach)
docker pull dolfinx/dolfinx:stable
docker run -it --rm -v $(pwd):/work dolfinx/dolfinx:stable bash

Core Workflow

Step 1 — Poisson Equation on Unit Square
python
"""
Solve −∇²u = f on the unit square [0,1]×[0,1]
with homogeneous Dirichlet BC u=0 on ∂Ω.

Manufactured solution: u_exact = sin(πx)sin(πy)
Source term:           f = 2π² sin(πx)sin(πy)
"""

from mpi4py import MPI
import numpy as np
from dolfinx import mesh, fem, io
from dolfinx.fem.petsc import LinearProblem
import ufl


def solve_poisson_unit_square(n_cells: int = 32, degree: int = 1) -> dict:
    """
    Solve the Poisson equation −∇²u = f on the unit square.

    Args:
        n_cells: Number of cells in each direction (total cells = 2*n_cells²).
        degree:  Polynomial degree of Lagrange finite elements.

    Returns:
        Dictionary with keys: uh (solution), L2_error, H1_error.
    """
    # --- Mesh ---
    domain = mesh.create_unit_square(
        MPI.COMM_WORLD, n_cells, n_cells, mesh.CellType.triangle
    )

    # --- Function space ---
    V = fem.functionspace(domain, ("Lagrange", degree))

    # --- Exact solution for manufactured source term ---
    x = ufl.SpatialCoordinate(domain)
    u_exact_expr = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    f_expr       = 2.0 * ufl.pi**2 * u_exact_expr

    # --- Dirichlet BC: u = 0 on all boundaries ---
    def boundary_all(x):
        return (
            np.isclose(x[0], 0.0) | np.isclose(x[0], 1.0) |
            np.isclose(x[1], 0.0) | np.isclose(x[1], 1.0)
        )

    boundary_dofs = fem.locate_dofs_geometrical(V, boundary_all)
    u0 = fem.Function(V)
    u0.x.array[:] = 0.0
    bc = fem.dirichletbc(u0, boundary_dofs)

    # --- Variational problem ---
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
    L = f_expr * v * ufl.dx

    # --- Solve ---
    problem = LinearProblem(a, L, bcs=[bc],
                            petsc_options={"ksp_type": "cg", "pc_type": "hypre"})
    uh = problem.solve()

    # --- Compute errors ---
    diff = uh - u_exact_expr
    L2_error = float(fem.assemble_scalar(fem.form(ufl.inner(diff, diff) * ufl.dx)) ** 0.5)
    H1_error = float(fem.assemble_scalar(
        fem.form(ufl.inner(ufl.grad(diff), ufl.grad(diff)) * ufl.dx)
    ) ** 0.5)

    print(f"n_cells={n_cells}, degree={degree}: "
          f"L2={L2_error:.2e}, H1={H1_error:.2e}")
    return {"uh": uh, "L2_error": L2_error, "H1_error": H1_error}


def convergence_study() -> None:
    """Run convergence study with successive mesh refinement."""
    print("Convergence study for Poisson on unit square:")
    print(f"{'N':>6}  {'L2 error':>12}  {'H1 error':>12}  {'L2 rate':>8}")
    prev_L2 = None
    for n in [4, 8, 16, 32, 64]:
        result = solve_poisson_unit_square(n_cells=n, degree=1)
        L2 = result["L2_error"]
        rate = (np.log(prev_L2 / L2) / np.log(2.0)) if prev_L2 else float("nan")
        print(f"{n:>6}  {L2:>12.4e}  {result['H1_error']:>12.4e}  {rate:>8.2f}")
        prev_L2 = L2
Step 2 — Linear Elasticity
python
"""
Solve linear elasticity on a 2D beam under body force (gravity).

Strong form: −div(σ(u)) = f in Ω
σ(u) = λ tr(ε(u)) I + 2μ ε(u)   (Hooke's law, Lamé form)
ε(u) = ½(∇u + ∇uᵀ)             (small-strain tensor)
"""

from mpi4py import MPI
import numpy as np
from dolfinx import mesh, fem, io
from dolfinx.fem.petsc import LinearProblem
import ufl


def solve_linear_elasticity(
    nx: int = 40,
    ny: int = 10,
    E: float = 210e9,     # Young's modulus (Pa), steel
    nu: float = 0.3,      # Poisson's ratio
    rho: float = 7850.0,  # Density (kg/m³)
    g: float = 9.81,      # Gravitational acceleration (m/s²)
    output_xdmf: str = "elasticity.xdmf",
) -> None:
    """
    Solve 2D linear elasticity (plane stress) on a rectangular beam.

    The left end is clamped (u=0), a body force f=(0,-ρg) is applied.
    Exports solution to XDMF for ParaView.

    Args:
        nx:          Cells in x direction.
        ny:          Cells in y direction.
        E:           Young's modulus in Pa.
        nu:          Poisson's ratio.
        rho:         Material density in kg/m³.
        g:           Gravity magnitude in m/s².
        output_xdmf: Output file path.
    """
    # Lamé parameters
    lam = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))
    mu  = E / (2.0 * (1.0 + nu))

    domain = mesh.create_rectangle(
        MPI.COMM_WORLD,
        [np.array([0.0, 0.0]), np.array([1.0, 0.25])],
        [nx, ny],
        cell_type=mesh.CellType.triangle,
    )

    # Vector function space (displacement u ∈ R²)
    V = fem.functionspace(domain, ("Lagrange", 1, (2,)))

    # Strain and stress tensors
    def epsilon(u):
        return ufl.sym(ufl.nabla_grad(u))

    def sigma(u):
        return lam * ufl.nabla_div(u) * ufl.Identity(2) + 2 * mu * epsilon(u)

    # Body force: gravity
    f = fem.Constant(domain, np.array([0.0, -rho * g]))

    # Clamped BC on left boundary x=0
    def left_boundary(x):
        return np.isclose(x[0], 0.0)

    boundary_dofs = fem.locate_dofs_geometrical(V, left_boundary)
    u_D = fem.Function(V)
    u_D.x.array[:] = 0.0
    bc = fem.dirichletbc(u_D, boundary_dofs)

    # Variational formulation
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = ufl.inner(sigma(u), epsilon(v)) * ufl.dx
    L = ufl.inner(f, v) * ufl.dx

    # Solve
    problem = LinearProblem(a, L, bcs=[bc],
                            petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
    uh = problem.solve()
    uh.name = "Displacement"

    # Compute von Mises stress for visualization
    s = sigma(uh) - (1.0 / 3) * ufl.tr(sigma(uh)) * ufl.Identity(2)
    von_mises = ufl.sqrt(1.5 * ufl.inner(s, s))
    W = fem.functionspace(domain, ("DG", 0))
    vm_expr = fem.Expression(von_mises, W.element.interpolation_points())
    vm_func = fem.Function(W)
    vm_func.interpolate(vm_expr)
    vm_func.name = "VonMises"

    # Export to XDMF
    with io.XDMFFile(MPI.COMM_WORLD, output_xdmf, "w") as xdmf:
        xdmf.write_mesh(domain)
        xdmf.write_function(uh)
        xdmf.write_function(vm_func)

    max_disp = np.max(np.abs(uh.x.array))
    print(f"Max displacement: {max_disp:.4e} m")
    print(f"Solution written to {output_xdmf}")


if __name__ == "__main__":
    solve_linear_elasticity()
Show full SKILL.md (185 more words)Show less
Step 3 — gmsh Mesh Generation and Import into dolfinx
python
"""
Use gmsh to generate a structured mesh of a disk with a hole,
then import into dolfinx for FEM analysis.
"""

import gmsh
import numpy as np
from mpi4py import MPI
from dolfinx.io.gmshio import model_to_mesh
from dolfinx import fem, io
import ufl
from dolfinx.fem.petsc import LinearProblem


def create_annular_mesh(
    r_inner: float = 0.2,
    r_outer: float = 1.0,
    mesh_size: float = 0.05,
    output_msh: str = "annulus.msh",
) -> None:
    """
    Create a 2D annular mesh (disk with circular hole) using gmsh.

    Args:
        r_inner:   Inner radius (hole).
        r_outer:   Outer radius.
        mesh_size: Target mesh element size.
        output_msh: Output .msh file path.
    """
    gmsh.initialize()
    gmsh.model.add("annulus")

    # Outer disk
    outer = gmsh.model.occ.addDisk(0, 0, 0, r_outer, r_outer)
    # Inner disk (hole)
    inner = gmsh.model.occ.addDisk(0, 0, 0, r_inner, r_inner)

    # Boolean cut: outer minus inner
    gmsh.model.occ.cut([(2, outer)], [(2, inner)])
    gmsh.model.occ.synchronize()

    # Mesh size field
    gmsh.model.mesh.setSize(gmsh.model.getEntities(0), mesh_size)

    # Physical groups (needed for dolfinx boundary conditions)
    surfaces = gmsh.model.getEntities(2)
    for _, tag in surfaces:
        gmsh.model.addPhysicalGroup(2, [tag], tag)
        gmsh.model.setPhysicalName(2, tag, f"domain_{tag}")

    curves = gmsh.model.getBoundary(surfaces, oriented=False)
    for dim, tag in curves:
        gmsh.model.addPhysicalGroup(1, [abs(tag)], abs(tag))
        gmsh.model.setPhysicalName(1, abs(tag), f"boundary_{abs(tag)}")

    gmsh.model.mesh.generate(2)
    gmsh.model.mesh.optimize("Netgen")
    gmsh.write(output_msh)
    gmsh.finalize()
    print(f"Annular mesh written to {output_msh}")


def solve_poisson_annulus(msh_file: str = "annulus.msh") -> None:
    """
    Import gmsh mesh and solve Poisson equation on the annular domain.

    BC: u=1 on inner boundary, u=0 on outer boundary.
    """
    gmsh.initialize()
    gmsh.open(msh_file)

    domain, cell_tags, facet_tags = model_to_mesh(
        gmsh.model, MPI.COMM_WORLD, 0, gdim=2
    )
    gmsh.finalize()

    V = fem.functionspace(domain, ("Lagrange", 2))

    # Locate facets for BCs by geometric criterion
    def inner_boundary(x):
        return np.sqrt(x[0]**2 + x[1]**2) < 0.25

    def outer_boundary(x):
        return np.sqrt(x[0]**2 + x[1]**2) > 0.9

    dofs_inner = fem.locate_dofs_geometrical(V, inner_boundary)
    dofs_outer = fem.locate_dofs_geometrical(V, outer_boundary)

    u_inner = fem.Function(V); u_inner.x.array[:] = 1.0
    u_outer = fem.Function(V); u_outer.x.array[:] = 0.0

    bcs = [
        fem.dirichletbc(u_inner, dofs_inner),
        fem.dirichletbc(u_outer, dofs_outer),
    ]

    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
    L = fem.Constant(domain, 0.0) * v * ufl.dx  # Laplace: f=0

    problem = LinearProblem(a, L, bcs=bcs)
    uh = problem.solve()
    uh.name = "u"

    with io.XDMFFile(MPI.COMM_WORLD, "annulus_solution.xdmf", "w") as xdmf:
        xdmf.write_mesh(domain)
        xdmf.write_function(uh)
    print("Annulus Laplace solution saved to annulus_solution.xdmf")

Advanced Usage

Steady Stokes Flow (Velocity-Pressure)
python
"""
Solve the steady Stokes equations (viscous flow at Re→0) on a channel.

−μ ∇²u + ∇p = f
∇·u = 0

Uses Taylor-Hood P2/P1 elements (LBB-stable mixed formulation).
"""

from mpi4py import MPI
import numpy as np
from dolfinx import mesh, fem
from dolfinx.fem.petsc import LinearProblem
import ufl


def solve_stokes_channel(
    nx: int = 64,
    ny: int = 16,
    mu: float = 1.0,      # dynamic viscosity
    U_max: float = 1.0,   # max inlet velocity
) -> None:
    """
    Solve steady Stokes flow in a 2D channel.
    Parabolic inlet profile, no-slip walls, stress-free outlet.
    """
    domain = mesh.create_rectangle(
        MPI.COMM_WORLD,
        [np.array([0.0, 0.0]), np.array([4.0, 1.0])],
        [nx, ny],
        cell_type=mesh.CellType.triangle,
    )

    # Taylor-Hood P2/P1 elements
    P2 = fem.functionspace(domain, ("Lagrange", 2, (2,)))
    P1 = fem.functionspace(domain, ("Lagrange", 1))

    # Mixed space
    V_el = ufl.VectorElement("Lagrange", domain.ufl_cell(), 2)
    Q_el = ufl.FiniteElement("Lagrange", domain.ufl_cell(), 1)
    W = fem.functionspace(domain, ufl.MixedElement([V_el, Q_el]))

    (u, p) = ufl.TrialFunctions(W)
    (v, q) = ufl.TestFunctions(W)

    f = fem.Constant(domain, np.array([0.0, 0.0]))

    a = (mu * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
         - ufl.div(v) * p * ufl.dx
         + q * ufl.div(u) * ufl.dx)
    L = ufl.inner(f, v) * ufl.dx

    # No-slip on top and bottom walls
    def walls(x):
        return np.isclose(x[1], 0.0) | np.isclose(x[1], 1.0)

    # Parabolic inlet profile: u_x = 4*U_max*y*(1-y), u_y=0
    def inlet_velocity(x):
        vals = np.zeros((2, x.shape[1]))
        vals[0] = 4.0 * U_max * x[1] * (1.0 - x[1])
        return vals

    def inlet(x):
        return np.isclose(x[0], 0.0)

    W0, _ = W.sub(0).collapse()
    dofs_walls = fem.locate_dofs_geometrical((W.sub(0), W0), walls)
    dofs_inlet = fem.locate_dofs_geometrical((W.sub(0), W0), inlet)

    u_no_slip = fem.Function(W0); u_no_slip.x.array[:] = 0.0
    u_inflow  = fem.Function(W0); u_inflow.interpolate(inlet_velocity)

    bcs = [
        fem.dirichletbc(u_no_slip, dofs_walls,  W.sub(0)),
        fem.dirichletbc(u_inflow,  dofs_inlet,  W.sub(0)),
    ]

    problem = LinearProblem(a, L, bcs=bcs,
                            petsc_options={"ksp_type": "minres", "pc_type": "hypre"})
    wh = problem.solve()
    print("Stokes channel flow solved. Extract wh.sub(0) for velocity, wh.sub(1) for pressure.")
Time-Dependent Heat Equation
python
"""
Solve the unsteady heat equation with backward Euler time integration.
∂u/∂t − α∇²u = 0  (α = thermal diffusivity)
"""

from mpi4py import MPI
import numpy as np
from dolfinx import mesh, fem
from dolfinx.fem.petsc import LinearProblem
import ufl


def solve_heat_equation(
    nx: int = 40,
    alpha: float = 0.01,
    T_final: float = 1.0,
    dt: float = 0.01,
) -> None:
    """Solve 2D heat equation with Gaussian initial condition."""
    domain = mesh.create_unit_square(MPI.COMM_WORLD, nx, nx)
    V = fem.functionspace(domain, ("Lagrange", 1))

    u_n = fem.Function(V)
    x = fem.Expression(
        ufl.exp(-50.0 * ((ufl.SpatialCoordinate(domain)[0] - 0.5)**2
                         + (ufl.SpatialCoordinate(domain)[1] - 0.5)**2)),
        V.element.interpolation_points()
    )
    u_n.interpolate(x)

    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    dt_const = fem.Constant(domain, dt)

    a = (u * v + dt_const * alpha * ufl.inner(ufl.grad(u), ufl.grad(v))) * ufl.dx
    L = u_n * v * ufl.dx

    problem = LinearProblem(a, L, bcs=[],
                            petsc_options={"ksp_type": "cg", "pc_type": "hypre"})

    t = 0.0
    n_steps = int(T_final / dt)
    for step in range(n_steps):
        t += dt
        uh = problem.solve()
        u_n.x.array[:] = uh.x.array[:]
        if step % 20 == 0:
            max_u = np.max(np.abs(uh.x.array))
            print(f"t={t:.3f}: max(u)={max_u:.4f}")
    print("Heat equation time integration complete.")

Troubleshooting

ErrorCauseFix
PETSc error: KSP divergedIll-conditioned system or wrong BCCheck BCs; try LU solver: "ksp_type": "preonly", "pc_type": "lu"
dolfinx.fem.functionspace not foundOld API (dolfinx < 0.6)Use FunctionSpace(domain, ("CG", 1)) for older versions
gmsh: no surfaces foundForgot synchronize() after OCC operationsCall gmsh.model.occ.synchronize() before meshing
Negative Jacobian warningPoor mesh qualityCall gmsh.model.mesh.optimize("Netgen")
MixedElement import errorChanged API in dolfinx 0.7+Use basix.ufl.mixed_element or BlockedElement
XDMF file not readable in ParaViewH5 file missingBoth .xdmf and .h5 files must be in the same directory
Slow solve for large meshesDense direct solverSwitch to iterative solver with HYPRE preconditioner

External Resources


Examples

Example 1 — Full Poisson Convergence Study
python
if __name__ == "__main__":
    print("=== Poisson Convergence Study ===")
    convergence_study()
    print()
    print("=== Poisson on Unit Square (n=64) ===")
    result = solve_poisson_unit_square(n_cells=64, degree=2)
    print(f"L2 error with P2 elements: {result['L2_error']:.2e}")
Example 2 — Cantilever Beam Under Gravity
python
if __name__ == "__main__":
    print("=== Linear Elasticity: Steel Cantilever Beam ===")
    solve_linear_elasticity(
        nx=80, ny=20,
        E=210e9,    # Steel Young's modulus
        nu=0.3,
        rho=7850.0,
        g=9.81,
        output_xdmf="steel_beam.xdmf",
    )
    print("Open steel_beam.xdmf in ParaView to visualize displacement and von Mises stress.")
Example 3 — gmsh Annulus Mesh and Laplace Solve
python
if __name__ == "__main__":
    print("=== gmsh Annular Mesh + Laplace Equation ===")
    create_annular_mesh(r_inner=0.2, r_outer=1.0, mesh_size=0.05)
    solve_poisson_annulus("annulus.msh")
    print("Open annulus_solution.xdmf in ParaView.")

Changelog

VersionDateChange
1.0.02026-03-17Initial release — Poisson, elasticity, Stokes, heat equation, gmsh integration

© Cai-aa, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files in Skill/abaqus/reference/fenics-fem of Cai-aa/CAE-Agent-Hub.

  • SKILL.md
  • UPSTREAM.md
  • UPSTREAM_LICENSE

Open the folder on GitHubat commit 194ef49

Compare with similar skills

Fenics Fem next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Fenics Fem compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Fenics Fem this skillCai-aa/CAE-Agent-Hub1k—~4.8kAutomated safety check: PassMIT
AstropyzLanqing/codex-claude-academic-skills4.7k13 repos~2.9kAutomated safety check: PassBSD-3-Clause
PymatgenzLanqing/codex-claude-academic-skills4.7k11 repos~5kAutomated safety check: PassMIT
Cantera Ignition DelayK-Dense-AI/scientific-agent-skills48k1 repos~2.2kAutomated safety check: PassMIT
Weathertrpc-group/trpc-agent-go1.9k8 repos~591Automated safety check: PassApache-2.0
Pymol VisualizationChatMol/ChatMol373—~1.2kAutomated safety check: PassMIT

Similar skills

  • Astropy

    zLanqing/codex-claude-academic-skills

    Comprehensive Python library for astronomy and astrophysics.

    4.7k GitHub starsUsed in 13 repos~2.9k tokens
    Research & ScienceAuto-check passed
  • Pymatgen

    zLanqing/codex-claude-academic-skills

    Materials science toolkit. An agent skill from zLanqing/codex-claude-academic-skills.

    4.7k GitHub starsUsed in 11 repos~5k tokens
    Research & ScienceAuto-check passed
  • Cantera Ignition Delay

    K-Dense-AI/scientific-agent-skills

    Runs Cantera constant-volume or constant-pressure ignition simulations and reports temperature-based ignition delay with mechanism provenance and checks.

    48k GitHub starsUsed in 1 repo~2.2k tokens
    Research & ScienceAuto-check passed
  • Weather

    trpc-group/trpc-agent-go

    Get current weather and forecasts via wttr.in or Open-Meteo.

    1.9k GitHub starsUsed in 8 repos~591 tokens
    Research & ScienceAuto-check passed
  • Pymol Visualization

    ChatMol/ChatMol

    Generate publication-quality molecular visualization images using PyMOL.

    373 GitHub stars~1.2k tokensUpdated 6 mo ago
    Research & ScienceAuto-check passed
  • Review

    Muuuun/luxas

    Write domain-authentic review articles that synthesize rather than stack.

    1.2k GitHub stars~2.1k tokensUpdated 1 mo ago
    Research & ScienceAuto-check passed

More from Cai-aa/CAE-Agent-Hub

All 57 skills in this repo
  • Ansys Structural Workbench

    Cai-aa/CAE-Agent-Hub

    Operate or inspect live ANSYS Workbench Mechanical structural simulations through the configured MCP, including model setup, materials, connections, loads, mesh, solve, convergence, validation, and…

    1k GitHub stars~2.2k tokensUpdated 10 days ago
    Auto-check passed
  • Cylinder O Grid

    Cai-aa/CAE-Agent-Hub

    Plan, create, adapt, and quality-audit coin-style five-block O-grid hexahedral meshes for cylindrical CAE models.

    1k GitHub stars~1.6k tokensUpdated 10 days ago
    Auto-check passed
  • Comsol Motor Nvh Evidence

    Cai-aa/CAE-Agent-Hub

    Evidence-first COMSOL Java API and batch workflow for permanent-magnet motor NVH.

    1k GitHub stars~1.3k tokensUpdated 10 days ago
    Auto-check passed
  • Aedt Evidence Electromagnetics

    Cai-aa/CAE-Agent-Hub

    Evidence-first Ansys Electronics Desktop and PyAEDT automation for Maxwell, HFSS, Q3D, Icepak, and related electromagnetic workflows.

    1k GitHub stars~591 tokensUpdated 10 days ago
    Auto-check passed
  • Evidence-first Ansys Mechanical structural automation through Workbench RunWB2 journals, Mechanical Scripting/ACT ExtAPI, or PyMechanical gRPC.

    1k GitHub stars~554 tokensUpdated 10 days ago
    Auto-check passed
  • Run Fluent Autoclave

    Cai-aa/CAE-Agent-Hub

    Run, diagnose, reproduce, and validate ANSYS Fluent CFD simulations of forced-convection autoclaves using Fluent MCP or PyFluent.

    1k GitHub stars~984 tokensUpdated 10 days ago
    Auto-check passed

Questions about Fenics Fem

What does Fenics Fem do?

A skill your agent uses to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and…. Fenics Fem is an agent skill from Cai-aa/CAE-Agent-Hub. Use this Skill to solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation, mesh generation with gmsh, Poisson/elasticity problems, boundary conditions, and paraview export.

When should I use Fenics Fem?

Fenics Fem fits situations like: solve PDEs with the finite element method using FEniCS/dolfinx: weak form formulation; mesh generation with gmsh; poisson/elasticity problems; boundary conditions.

How do I install Fenics Fem in Claude Code?

Run `npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a claude-code`. Or copy the skill folder (Skill/abaqus/reference/fenics-fem in Cai-aa/CAE-Agent-Hub) into .claude/skills/fenics-fem in your project. Claude Code loads it when a task matches its description.

How do I install Fenics Fem in Codex?

Run `npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a codex`. Or copy the skill folder (Skill/abaqus/reference/fenics-fem in Cai-aa/CAE-Agent-Hub) into .agents/skills/fenics-fem in your project. Codex loads it when a task matches its description.

Can I use Fenics Fem in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/fenics-fem, .gemini/skills/fenics-fem, .github/skills/fenics-fem and .opencode/skills/fenics-fem in your project.

What does Fenics Fem need to run?

Going by SKILL.md and its folder, Fenics Fem needs the command-line tools its instructions call (conda, python and docker). Our summary lists: Python 3; Docker.

Does Fenics Fem access the network?

SKILL.md names 4 domains. As links in the text: docs.fenicsproject.org, fenicsproject.org, gmsh.info and paraview.org. This is read from the text; nothing was executed.

Is Fenics Fem safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Fenics Fem use?

Fenics Fem is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Fenics Fem use?

About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Fenics Fem?

Skills that share tags, products or a category with Fenics Fem: Astropy (zLanqing/codex-claude-academic-skills, 4.7k stars), Pymatgen (zLanqing/codex-claude-academic-skills, 4.7k stars), Cantera Ignition Delay (K-Dense-AI/scientific-agent-skills, 48k stars) and Weather (trpc-group/trpc-agent-go, 1.9k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Fenics Fem?

Cai-aa (a GitHub user) maintains it in Cai-aa/CAE-Agent-Hub, which has 1,015 GitHub stars. The repository holds 57 skills in this directory. The repository was last updated on September 30, 2026.

Source: Cai-aa/CAE-Agent-Hub on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.