Note
Go to the end to download the full example code
Doinikov 2021 Viscous - Convergence Study
In this example we use the model doinikov2021viscous. For the
computation of the ARF the acoustic field is integrated from the surface of
the particle to infinity. “Infinity” here means a point far away from the
particle where the acoustic field is no longer influenced by its presence. Our
quadrature method scipy.integrate.quad
offers the option to integrate to infinity for converging functions.
However, for the given integral this does not work reliably. We therefore
choose the distance far away from the particle ourselves. In this example it is
shown how.
In this example we study a glass sphere viscous fluid.
20 import numpy as np
21 from matplotlib import pyplot as plt
22
23 import osaft
24
25 # --------
26 # Geometry
27 # --------
28 # Radius
29 R_0 = 1e-6 # [m]
30
31 # --------------------
32 # Properties of Glass
33 # --------------------
34 # Speed of sound
35 c_1_glass = 4_521 # [m/s]
36 c_2_glass = 2_226 # [m/s]
37 # Density
38 rho_glass = 2_240 # [kg/m^3]
39
40 # -----------------
41 # Properties of Oil
42 # -----------------
43 # Speed of sound
44 c_oil = 1_400 # [m/s]
45 # Density
46 rho_oil = 900 # [kg/m^3]
47 # Viscosity
48 eta_oil = 0.04 # [Pa s]
49 zeta_oil = 0 # [Pa s]
50
51 # --------------------------------
52 # Properties of the Acoustic Field
53 # --------------------------------
54 # Frequency
55 f = 5e5 # [Hz]
56 # Pressure
57 p_0 = 1e5 # [Pa]
58 # Wave type
59 wave_type = osaft.WaveType.STANDING
60 # Position of the particle in the field
61 position = np.pi / 4 # [rad]
Here, we are given the primary and the secondary wave speed of
glass only. The model doinikov2021viscous, however, takes the Young’s
modulus and the Poisson’s ratio as input parameters. We therefore have to
convert the properties. The ElasticSolid class offers such conversion
methods.
70 E_s = osaft.ElasticSolid.E_from_wave_speed(c_1_glass, c_2_glass, rho_glass)
71 nu_s = osaft.ElasticSolid.nu_from_wave_speed(c_1_glass, c_2_glass)
72
73 doinikov_viscous = osaft.doinikov2021viscous.ARF(
74 f=f, R_0=R_0,
75 rho_s=rho_glass, E_s=80e9, nu_s=0.20,
76 rho_f=rho_oil, c_f=c_oil,
77 eta_f=eta_oil, zeta_f=zeta_oil,
78 p_0=p_0, wave_type=wave_type,
79 position=position,
80 inf_factor=60, inf_type=None,
81 )
We could now straightaway compute the ARF with the model. And for most cases this will work just fine. However, if you need to be extra sure that the integral has been solved accurately you might want to make a conversion study for the value of “infinity”. By default, this value is set to \(60\max{(R_0,\delta)}\). That is, it is set to 60 times the boundary layer thickness or the radius, whichever is greater.
91 print(f'{doinikov_viscous.R_0 = }')
92 print(f'{doinikov_viscous.delta = }')
93 print(f'{doinikov_viscous.inf_factor = }')
94 print(f'{doinikov_viscous.inf = }')
doinikov_viscous.R_0 = 1e-06
doinikov_viscous.delta = 5.319230405352436e-06
doinikov_viscous.inf_factor = 60
doinikov_viscous.inf = 0.00031915382432114614
The value of inf can also be set manually using the two parameters
inf_factor and inf_type. inf_factor is the prefactor for
inf_type and should be a numerical value. For inf_type there are 4
options:
None: \(\text{inf_factor}\cdot\max{(R_0,\delta)}\)
'delta': the boundary layer thickness \(\delta\)
'radius': the radius \(\delta\)
1or'1':infis simply theinf_factor
Usually leaving it at None is the best option.
109 doinikov_viscous.inf_type = 1
110 doinikov_viscous.inf_factor = 1e-4
111 print(f'{doinikov_viscous.inf_factor = }')
112 print(f'{doinikov_viscous.inf_type = }')
113 print(f'{doinikov_viscous.inf = }')
114 doinikov_viscous.inf_type = 'radius'
115 doinikov_viscous.inf_factor = 60
116 print(f'{doinikov_viscous.inf_factor = }')
117 print(f'{doinikov_viscous.inf_type = }')
118 print(f'{doinikov_viscous.inf = }')
doinikov_viscous.inf_factor = 0.0001
doinikov_viscous.inf_type = 1
doinikov_viscous.inf = 0.0001
doinikov_viscous.inf_factor = 60
doinikov_viscous.inf_type = 'radius'
doinikov_viscous.inf = 5.9999999999999995e-05
Often it is not apriori clear what value should be chosen. Therefore,
a convergence study can be performed. The plotting functionality of OSAFT
can be very handy for this since we can plot the ARF against the
inf_factor.
In order for multiprocessing to work you need to run your code inside the
if __name__ == '__main__': clause as shown below.
Check the multiprocessing example.
131 if __name__ == '__main__':
132
133 doinikov_viscous.inf_type = None
134 plot = osaft.ARFPlot('inf_factor', np.arange(10, 200, 30))
135 plot.add_solutions(doinikov_viscous, multicore=True)
136 fig, ax = plot.plot_solutions(normalization='max', marker='o')
137
138 ax.set_xlabel('inf_factor')
139 ax.ticklabel_format(useOffset=False)
140 fig.tight_layout()
141 plt.show()

We see that already for a value of inf_factor of 40 the ARF stops
changing significantly. In fact, going from inf_factor = 40 to
inf_factor = 200 will change the value of the ARF less than 0.001%.
This will be sufficiently accurate for most cases. Note that this also means
for the given example the default settings would give a very accurate
estimate of the ARF.
Total running time of the script: ( 2 minutes 47.250 seconds)
Estimated memory usage: 9 MB