For importing velocity transfer function, I would use numpy.loadtxt()
, as it returns an array that you can easily manipulate, slice, or multiply with other numpy arrays. I’m not familiar with Pandas, so it may also be capable of handling this task as well.
To apply velocity transfer functions onto results:
#%% First, compute potentials and get the results into a manageable numpy array
micPosition = np.array([[xmic1, ymic1, zmic1],
[xmic2, ymic2, zmic2],
[..., ..., ...]]).T
nMic = np.shape(micPosition)[1]
# to store projected pressure
pressure = np.zeros([nFreq, nMic, nSurf], dtype=complex) # store results
# pretty sure you can regroup this with the previous loops
for f in range(nFreq): # looping through frequencies
for s in range(nSurf): # looping through surfaces
spaceU = bempp.api.function_space(grid, "DP", 0, segments=[surface[s]]])
pressure[f, :, s] = np.reshape(
helmholtz_potential.double_layer(spaceP, micPosition, -k[f]) *
p_mesh[f, s] - 1j * omega[f] * rho *
helmholtz_potential.single_layer(spaceU, micPosition, -k[f]) *
u_mesh[f, s], nMic)
#%% Apply velocity to results (complex valued)
pressure_p = np.copy(pressure) # to keep initial results from changing
# velocity of first surface
pressure_p[:, :, 0] *= your_velocity_function # 1D (velocity) array might need to be tiled or repeated
# into a 2D array
# ...do the same for all surfaces
# sum the total contribution from all faces -> output array of shape (nFreq, nMic)
pressure_s = np.sum(pressure_p, axis=2)
However, this example assumes that each radiating surface has only one uniform velocity defined across its boundary: treating it as an infinitely rigid piston with no modal behavior.
In your case, where you want to apply independent velocities to each node, this approach won’t work. Instead of using a single velocity for an entire surface, you’ll need to apply velocity independently at each degree of freedom (DOF). In that case, you can replace the previous “coeff_surface” argument to allow for independent velocities at each DOF. It would be tricky to explain fully here. But depending on your mesh/application, you can define a function_space
that already incorporates your Abaqus nodes as DOFs, which will allow you to apply the velocities directly in coeff_surface
– as long as your grid indexing corresponds to the DOF indexing.
This whole thing can be a bit difficult to understand, but I hope it helps!