FEM-Helmholtz

This section explains how Numav can perform acoustic simulations based on the Helmholtz equation.

Quick start

Here is a complete example of a simulation code:

using Numav

# Create the simulation object
s = create_simulation(
    numerical_method = Fem,
    equation = Helmholtz,
    element_shape = Tetrahedron,
    element_order = Linear
)

# Set simulated frequencies
set_frequency!(s, max=200) # (Hz)

# Load mesh
load_mesh!(s, "path/to/mesh_file.bdf")

# Define material (frequency-dependent)
rho(f) = 1.20
c(f) = 343
add_volume_material!(s, physical_group=1, density=rho, speed_of_sound=c)

# Add a surface impedance boundary condition
Z(f) = 1f + 2im
add_surface_material!(s, physical_group=4, specific_acoustic_impedance=Z)

# Add a monopole volume velocity source at a point
Q(f) = 10/f
add_sound_source!(s, coordinates=[1.0, 1.5, 2.0], volume_velocity=Q)

# Add a particle velocity source on a surface
U(f) = 15/f
add_sound_source!(s, physical_group=2, particle_velocity=U)

# Add pressure sources (to point or surface)
P(f) = 2f
add_sound_source!(s, coordinates=[2.0, 2.5, 1.0], pressure=P)
add_sound_source!(s, physical_group=3, pressure=P)

# Set output file and run
set_result_export_path!(s, "result.h5")
run!(s)

For more details, look at the Functions section.

Functions

Numav.create_simulationFunction

Creates and returns an instance of the Simulation type.

Keyword argumentsTypeSupported optionsDescription
numerical_methodNumav.OptionFemNumerical method used.
equationNumav.OptionHelmholtzDifferential equation to be solved.
element_shapeNumav.OptionTetrahedronGeometrical shape of elements.
element_orderNumav.OptionLinear, QuadraticPolynomial order of the finite elements.

Examples

s = create_simulation(
    numerical_method = Fem,
    equation = Helmholtz,
    element_shape = Tetrahedron,
    element_order = Linear
)
source
Numav.set_frequency!Function

Sets the frequecies to perform the simulations with two mutually exclusive ways to use it:

  • automatic mode: pass max (and optionally min, length, sampling_density and step) and Numav will automatically determine the frequency vector;
  • manual mode: pass vector directly, giving full control over which frequencies are evaluated.
Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
Keyword arguments
maxRealUpper frequency limit (Hz). Required unless steps is provided. Mutually exclusive with steps.
minRealLower bound of the frequency range (Hz). Only usable together with max. Defaults to 0 if omitted.
lengthIntegerNumber of frequency steps to compute within the min/max range. Only usable together with max. Defaults to 4096 if omitted.
sampling_densityNumav.OptionSampling strategy to use within the range. Only usable together with max. Defaults to Quadratic if omitted.
stepRealDifference in Hertz between each frequency step, supposing equally spaced steps. Only usable together with max. Cannot be used together with length and sampling_density.
vectorVector{Real}List of frequencies in Hertz to solve at. Cannot be used together with max, min, length, sampling_density and step.

sampling_density options

ModeDescription
Quadratic (default)Frequency discretization density grows quadratically with frequency. It tends to follow the modal density of rooms, being the recommended option for good accuracy and computation time balance.
ConstantFrequency steps are evenly spaced (uniform spacing). Suitable for broadband analyses where equal resolution at all frequencies is desired.

Examples

Solve up to a maximum frequency, letting Numav automatically pick the steps from 0 Hz:

set_frequency!(s, max=200) # solve from 0 Hz to 200 Hz

Solve within an explicit range, by adding min:

set_frequency!(s, min=20, max=200) # solve from 20 Hz to 200 Hz

Control the number of frequency steps with length (defaults to 4096 when not specified):

set_frequency!(s, max=200, length=500) # evaluate at 500 frequency points

A higher step count gives finer frequency resolution at the cost of longer computation time.

Control how steps are distributed with sampling_density (defaults to Quadratic when not specified):

set_frequency!(s, max=200, sampling_density=Constant)

Manually specify the exact frequencies with vector, for example to match measurement points or concentrate resolution around a resonance:

set_frequency!(s, vector=[10, 40, 60, 100]) # Solve only at these frequencies
Tip

Use get_frequency_vector to visually check the defined frequency vector.

source
Numav.load_mesh!Function

Loads the mesh file. It defines the geometry of the domain and must contain the physical groups that are referenced when assigning boundary conditions. To generate meshes, a good open-source option is Gmsh.

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
path_to_meshStringPath to the mesh file (.bdf).

Examples

load_mesh!(s, "some_mesh_file.bdf")
Warning

Currently, only meshes in the small field BDF format are supported.

Warning

The coordinates in the mesh file must be given in meters.

source
Numav.add_volume_material!Function

Assigns acoustic material properties to a volumetric region of the mesh, identified by its physical group tag.

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
Keyword arguments
physical_groupInteger, Vector{Integer}Physical group ID (or vector of IDs) from the mesh.
densityfrequency-dependent physical quantityDensity in kg/m³.
speed_of_soundfrequency-dependent physical quantitySpeed of sound in m/s.

Examples

rho(f) = 1.20 # air density in kg/m³
c(f) = 343 # speed of sound in m/s
add_volume_material!(s, physical_group=1, density=rho, speed_of_sound=c)

Physical quantities can by complex to model sound absorption:

rho(f) = 1.20 + 0.001*f
c(f) = 340 + 0.1*sqrt(f)
add_volume_material!(s, physical_group=1, density=rho, speed_of_sound=c)

Multiple physical groups can be assigned at once:

add_volume_material!(s, physical_group=[4,6], density=1.2, speed_of_sound=343)
source
Numav.add_surface_material!Function

Assigns a specific acoustic impedance boundary condition to a surface in the mesh. This is used to model absorbers, reflecting surfaces or other boundary treatments.

The specific acoustic impedance is the ratio of complex amplitude of acoustic pressure to complex amplitude of normal particle velocity (in Pa·s/m).

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
Keyword arguments
physical_groupInteger, Vector{Integer}Physical group ID of the boundary surface.
specific_acoustic_impedancefrequency-dependent physical quantityspecific surface acoustic impedance (Pa·s/m).

Examples

Z(f) = 1f + 2im
add_surface_material!(s, physical_group=4, specific_acoustic_impedance=Z)

Multiple physical groups can be assigned at once:

add_surface_material!(s, physical_group=[3,1], specific_acoustic_impedance=1.0)
source
Numav.add_sound_source!Function

Adds sound sources either at a specific point in space (via coordinates) or over a surface region (via physical_group). Three excitation types are supported: volume_velocity, particle velocity, and pressure.

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
Keyword arguments
coordinatesVector{Real}, Vector{Vector{Real}}[x, y, z] location of a point source in m.
physical_groupInteger, Vector{Integer}Physical group ID of a surface or volume region.
volume_velocityfrequency-dependent physical quantityVolume velocity in m³/s.
particle_velocityfrequency-dependent physical quantityNormal particle velocity in m/s.
pressurefrequency-dependent physical quantityAcoustic pressure in Pa.

Examples

Volume velocity source (monopole):

Q(f) = 10/f # Volume velocity in m³/s as a function of frequency
add_sound_source!(s, coordinates=[1.0, 1.5, 2.0], volume_velocity=Q)

Suitable for modeling punctual omnidirectional sources.

Particle velocity source (vibrating surface):

U(f) = 15/f # Particle velocity in m/s
add_sound_source!(s, physical_group=2, particle_velocity=U)

Prescribes the normal component of particle velocity on all surfaces of a physical group. Useful for modeling vibrating panels or pistons.

Pressure source:

P(f) = 2f # Pressure in Pa as a function of frequency

# At a point in space
add_sound_source!(s, coordinates=[2.0, 2.5, 1.0], pressure=P)

# On a mesh surface
add_sound_source!(s, physical_group=3, pressure=P)

Prescribes acoustic pressure, either at a point or on a surface.

Multiple points or physical groups can be assigned at once:

p1 = [1.0, 3.0, 2.0]
p2 = [3.0, 1.0, 1.0]
add_sound_source!(s, coordinates=[p1,p2], volume_velocity=0.01)
add_sound_source!(s, physical_group=[3,5,9,2], particle_velocity=0.01)
Note

Each call to add_sound_source! should specify either coordinates or physical_group (not both), and exactly one excitation type keyword.

source
Numav.set_result_export_path!Function

Specifies the file path where simulation results will be written when calling run!.

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.
file_pathStringResult file path (.h5).

Examples

set_result_export_path!(s, "result.h5")
source
Numav.run!Function

Assembles and solves the system of equations for all frequencies in the defined range while writing the results to the specified export path during the solution.

Positional argumentsTypeDescription
simulationSimulationThe simulation instance.

Examples

run!(s)

Output format

Results are exported as files in the HDF5 format (.h5). It contains all the results and passed inputs to setup the simulation. To read the results, it is recommended to use HDF5.jl or HDFView.

Tip

With HDF5.jl, you can post-process results in Julia like:

using HDF5
r = h5open("result.h5", "r")
# inspect contents
source
Numav.plot_pressure_fieldFunction

Plots a 3D graph of the pressure field for all space and frequncies.

Positional argumentsTypeDescription
file_pathStringResult file path (.h5).
Keyword arguments
dbBoolControls if the plot uses the decibel scale. Defaults to false.
colormapSymbolColors used for the scale. Available options here. Defaults to :rainbow1.

Examples

plot_pressure_field("result.h5")
Warning

This function is not accurate for second order elements. The graph shown does not account for the non-vertex nodes.

source