Note
Click here 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,
75 R_0=R_0,
76 rho_s=rho_glass,
77 E_s=80e9,
78 nu_s=0.20,
79 rho_f=rho_oil,
80 c_f=c_oil,
81 eta_f=eta_oil,
82 zeta_f=zeta_oil,
83 p_0=p_0,
84 wave_type=wave_type,
85 position=position,
86 inf_factor=60,
87 inf_type=None,
88 )
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.
98 print(f"{doinikov_viscous.R_0 = }")
99 print(f"{doinikov_viscous.delta = }")
100 print(f"{doinikov_viscous.inf_factor = }")
101 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\)
1
or'1'
:inf
is simply theinf_factor
Usually leaving it at None
is the best option.
116 doinikov_viscous.inf_type = 1
117 doinikov_viscous.inf_factor = 1e-4
118 print(f"{doinikov_viscous.inf_factor = }")
119 print(f"{doinikov_viscous.inf_type = }")
120 print(f"{doinikov_viscous.inf = }")
121 doinikov_viscous.inf_type = "radius"
122 doinikov_viscous.inf_factor = 60
123 print(f"{doinikov_viscous.inf_factor = }")
124 print(f"{doinikov_viscous.inf_type = }")
125 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.
138 if __name__ == "__main__":
139
140 doinikov_viscous.inf_type = None
141 plot = osaft.ARFPlot("inf_factor", np.arange(10, 200, 30))
142 plot.add_solutions(doinikov_viscous, multicore=True)
143 fig, ax = plot.plot_solutions(normalization="max", marker="o")
144
145 ax.set_xlabel("inf_factor")
146 ax.ticklabel_format(useOffset=False)
147 fig.tight_layout()
148 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 49.474 seconds)
Estimated memory usage: 9 MB