Astropy
zLanqing/codex-claude-academic-skills
Comprehensive Python library for astronomy and astrophysics.
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…
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ 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-srcUse ~/.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/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .claude/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-femType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .agents/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .agents/skills/fenics-fem && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .agents/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .cursor/skills/fenics-fem && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .cursor/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Cai-aa/CAE-Agent-Hub.git --path Skill/abaqus/reference/fenics-fem--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .gemini/skills/fenics-fem && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .gemini/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-femInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .github/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .github/skills/fenics-fem && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .github/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Cai-aa/CAE-Agent-Hub --skill fenics-fem -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Cai-aa/CAE-Agent-Hub fenics-fem --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Cai-aa/CAE-Agent-Hub.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/Skill/abaqus/reference/fenics-fem .opencode/skills/fenics-fem && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "fenics-fem" agent skill from https://github.com/Cai-aa/CAE-Agent-Hub/tree/main/Skill/abaqus/reference/fenics-fem into .opencode/skills/fenics-fem/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "fenics-fem", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
fenics-femA 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.
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.
3 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 194ef49. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
condapythondockerFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
docs.fenicsproject.orgfenicsproject.orggmsh.infoparaview.orgFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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.
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.
The full file from Cai-aa/CAE-Agent-Hub at commit 194ef49, republished under its MIT licence (© Cai-aa). 455 words, ~4,839 tokens.
.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.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.
Use this Skill when you need to:
Do not use this Skill when:
solve_bvpThe 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
| Space | dolfinx name | Use 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) |
For Lagrange P1 elements on a quasi-uniform mesh of size h:
# 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"""
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"""
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()"""
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")"""
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.")"""
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.")| Error | Cause | Fix |
|---|---|---|
PETSc error: KSP diverged | Ill-conditioned system or wrong BC | Check BCs; try LU solver: "ksp_type": "preonly", "pc_type": "lu" |
dolfinx.fem.functionspace not found | Old API (dolfinx < 0.6) | Use FunctionSpace(domain, ("CG", 1)) for older versions |
gmsh: no surfaces found | Forgot synchronize() after OCC operations | Call gmsh.model.occ.synchronize() before meshing |
| Negative Jacobian warning | Poor mesh quality | Call gmsh.model.mesh.optimize("Netgen") |
MixedElement import error | Changed API in dolfinx 0.7+ | Use basix.ufl.mixed_element or BlockedElement |
| XDMF file not readable in ParaView | H5 file missing | Both .xdmf and .h5 files must be in the same directory |
| Slow solve for large meshes | Dense direct solver | Switch to iterative solver with HYPRE preconditioner |
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}")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.")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.")| Version | Date | Change |
|---|---|---|
| 1.0.0 | 2026-03-17 | Initial 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
SKILL.md and 2 other files in Skill/abaqus/reference/fenics-fem of Cai-aa/CAE-Agent-Hub.
Open the folder on GitHubat commit 194ef49
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Fenics Fem this skillCai-aa/CAE-Agent-Hub | 1k | — | ~4.8k | Automated safety check: Pass | MIT | |
| AstropyzLanqing/codex-claude-academic-skills | 4.7k | 13 repos | ~2.9k | Automated safety check: Pass | BSD-3-Clause | |
| PymatgenzLanqing/codex-claude-academic-skills | 4.7k | 11 repos | ~5k | Automated safety check: Pass | MIT | |
| Cantera Ignition DelayK-Dense-AI/scientific-agent-skills | 48k | 1 repos | ~2.2k | Automated safety check: Pass | MIT | |
| Weathertrpc-group/trpc-agent-go | 1.9k | 8 repos | ~591 | Automated safety check: Pass | Apache-2.0 | |
| Pymol VisualizationChatMol/ChatMol | 373 | — | ~1.2k | Automated safety check: Pass | MIT |
zLanqing/codex-claude-academic-skills
Comprehensive Python library for astronomy and astrophysics.
zLanqing/codex-claude-academic-skills
Materials science toolkit. An agent skill from zLanqing/codex-claude-academic-skills.
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.
trpc-group/trpc-agent-go
Get current weather and forecasts via wttr.in or Open-Meteo.
ChatMol/ChatMol
Generate publication-quality molecular visualization images using PyMOL.
Muuuun/luxas
Write domain-authentic review articles that synthesize rather than stack.
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…
Cai-aa/CAE-Agent-Hub
Plan, create, adapt, and quality-audit coin-style five-block O-grid hexahedral meshes for cylindrical CAE models.
Cai-aa/CAE-Agent-Hub
Evidence-first COMSOL Java API and batch workflow for permanent-magnet motor NVH.
Cai-aa/CAE-Agent-Hub
Evidence-first Ansys Electronics Desktop and PyAEDT automation for Maxwell, HFSS, Q3D, Icepak, and related electromagnetic workflows.
Cai-aa/CAE-Agent-Hub
Evidence-first Ansys Mechanical structural automation through Workbench RunWB2 journals, Mechanical Scripting/ACT ExtAPI, or PyMechanical gRPC.
Cai-aa/CAE-Agent-Hub
Run, diagnose, reproduce, and validate ANSYS Fluent CFD simulations of forced-convection autoclaves using Fluent MCP or PyFluent.
Categories
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.