Material Parameter Determination
The main use of the infinitelayer classes is the design and simulation of acoustic treatment. Before this can be done the correct parameters of the desired materials are required.
Symbol 
Constructor argument 
Description 

rho_bulk 
Density of absorber matrix and fluid 

flow_res 
static air flow resistivity 

porosity 
volume porosity 

tortuosity 
tortuosity 

length_visc 
viscous characteristic length 

length_therm 
thermal characteristic length 

limp or rigid model 
limp 
switch 
For this purpose a large and expensive set of test requirements is necessary. The first three parameters are usually directly measured parameters but the last three are derived by inverse methods, e.g. by parameter fitting of test to simulation results. One option is described in [Ata2005] and is based on reducing a cost function that is the sum of squared differences of the measured and simulated surface impedance .
(1)
where was determined from impedance tube tests in [Ata2005]. However, even more variables can be derived by Atallas method, but one should keep in mind that the sensitity to errors is getting larger the more parameters are derived form the minimisation of the costfunction.
The SciPy package provides many methods for curve fitting and minimisation. Thus, pyva in combination with the capabilities of scipy is an ideal toolset for this task.
Atalla Test Case
The following inputs are required:
# Numerics
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import dual_annealing
# pyva packages
import pyva.properties.materialClasses as matC
import pyva.models as mds
import pyva.systems.infiniteLayers as iL
Three parameters are derived by direct test methods:
Symbol 
Fibrous1 
Unit 

89.6 

21235 

0.94 
The remaining parameters and must be determined by minimizing (1) So we define the given parameters with:
# Fibrous 1
flow_res = 21235.
porosity = 0.94
rho_bulk = 89.6
Further important test parameters are the thickness of the specimen and the environmental conditions:
h = 23.37e3
T = 22.6+273.15
P0 = 1.002
These conditions are applied by using the air()
method:
air_test = matC.Fluid.air(T,P0)
The first step is to create a function that gives an EquivalentFluid with these three parameters as input:
def fibre_fit(tor,Lam_visc,Lam_term):
return matC.EquivalentFluid(flow_res, porosity , tor, rho_bulk, \
Lam_visc, Lam_term,\
rho0 = air_test.rho0, \
c0 = air_test.c0,\
dynamic_viscosity = air_test.dynamic_viscosity,\
Cp = air_test.Cp, heat_conductivity=air_test.heat_conductivity, \
limp = limp )
in a second step, this function is used to create TMmodel of the setup:
def layer_fit(tor,Lam_visc,Lam_term):
return mds.TMmodel((iL.FluidLayer(h,fibre_fit(tor,Lam_visc,Lam_term)),))
and third, to create the surface impedance of this:
def impedance_fit(f,tor,Lam_visc,Lam_term):
return layer_fit(tor,Lam_visc,Lam_term).impedance(2*np.pi*f,0.).ydata.flatten()
For the cost function the test data is required that the author has tried to derive graphically from the original paper. It is imported by
# Import test data
f_test,Zs_re,Zs_im = np.loadtxt ('.//data//'+test_str[test1]+'.csv',
unpack = True,
usecols = (0,1,2), skiprows = 1,
delimiter = ',')
# create absolute values
Zs = (Zs_re+1j*Zs_im)*z0
According to [Ata2005] only values above 500 Hz are considered due to low precision below this limit.
# index for frequency range selection
i_freq = f_test >= f_min
We are now prepared to create the cost function:
def cost_function(x):
return np.sum(np.abs(impedance_fit(f_test[i_freq],x[0],x[1],x[2])Zs[i_freq])**2)
Lower and upper bound are required and chosen according to [Ata2005]:
# set bounds
lw = [1.,1.e6,1.e6] # lower bounds
up = [4.,4.e4,4.e4] # upper bounds
bounds=list(zip(lw, up))
The dual_annealing method from the scipy.optimize package does the final job for us:
res = dual_annealing(cost_function, bounds = bounds)
With the following result:
>>> res
fun: 10445.463547490406
message: ['Maximum number of iteration reached']
nfev: 6285
nhev: 0
nit: 1000
njev: 71
status: 0
success: True
x: array([1.00000000e+00, 3.48187655e05, 1.51283590e04])
By using the impedance_fit function with this parameters we get the result in terms of the surface impedance
z_surf = impedance_fit(freq, *res.x)
In figure Surface impedance of fibrous material. Pyva and [Ata2005] Results. the result of such a setup is shown and compared to the results received with parameters from [Ata2005]. We see that the author did not perfectly succeed in picking the data from the paper copy. However, the general option to receive the parameters from impedance tests without expensive commercial software and using pyva, python and some powerful toolboxes is demonstrated.
Further materials from [Ata2005] can be tested with the full example in Material Parameter Determination. If you interested in applying the method on your test data, feel free to contact the author at author@alexanderpeiffer.de. Test impedance data with additional parameters derived by other methods are very welcome.