Skip to content

[FEATURE] add pytta.fem, finite elements for the Helmholtz equation - #122

Open
aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-fem
Open

aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-fem

Conversation

@aguirreSL

Copy link
Copy Markdown

Adds pytta.fem, a finite element solver for the Helmholtz equation in air with linear tetrahedra, the counterpart of the fluid FEM application of the ITA-Toolbox:

(K - k² M + jk Σ β_s M_s) p = jωρ Σ N_s u_s

with K and M the stiffness and mass matrices of the fluid, M_s the mass matrix of a boundary surface of normalized admittance β_s = ρc / Z_s, and N_s u_s the load of a surface vibrating with normal velocity u_s into the fluid, for exp(jωt).

  1. box_mesh(Lx, Ly, Lz, nx, ny, nz): a tetrahedral mesh of a box, six tetrahedra per hexahedron, with the boundary triangles of each side.
  2. assemble(nodes, tets) and surface_mass(nodes, triangles): the sparse matrices.
  3. modes(nodes, tets, num, c): eigenfrequencies and mode shapes of the rigid-walled cavity.
  4. harmonic(nodes, tets, freq, velocity, admittance, faces, c, rho): the pressure at the nodes with vibrating and absorbing surfaces.

The formulation is the standard one (Ihlenburg, Finite Element Analysis of Acoustic Scattering, 1998; Zienkiewicz, Taylor and Zhu, The Finite Element Method). The ITA FluidFEM application belongs to a part of the ITA-Toolbox whose license is "all rights reserved", so nothing was taken from it. Other meshes can be passed as node and tetrahedron arrays, e.g. from a mesh generator.

The tests in tests/test_fem.py compare with analytic fields and print the measured differences:

  1. The first ten modes of a 1 × 0.8 × 0.6 m box lie above the exact ones, as a conforming FEM must, and the largest error falls from 3.22 % to 0.86 % when the elements halve, a ratio of 3.7 for the expected 4 of linear elements.
  2. In a tube driven by a piston, the pressure is ρcu e^(-jkx) with an anechoic end (9.8e-4) and -jρcu cos(k(L - x)) / sin(kL) with a rigid end (1.3e-3).

Checked with Python 3.12, numpy 1.26 and scipy 1.17. The 7 failures of development (3 in test_h5io.py, 4 in test_pyttasave.py) are the same with and without this change.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant