Note
Click here to download the full example code
Frontiers: Copper Particle in Viscous Oil#
This example corresponds to section 3.3 in our publication. In this example we study the acoustic radiation force (ARF) on a copper particle suspended in a viscous oil. We compare the theory by Doinikov (rigid, 1994) and the theory by Settnes & Bruus (2012).
As always we start off by importing the necessary Python modules. For our example we are going to need the osaft library, and the packages NumPy and Matplotlib.
18 import numpy as np
19 from matplotlib import pyplot as plt
20 from matplotlib.patches import Circle
21
22 import osaft
The next step is to define the properties for our example, these include the material properties, the properties of the acoustic field and the radius. We always assume SI-units.
The wave type is set using the osaft.WaveType
enum. Currently, there are
two options:
osaft.WaveType.STANDING
and osaft.WaveType.TRAVELLING
for a plane
standing wave and a plane travelling wave, respectively.
34 # --------
35 # Geometry
36 # --------
37 # Radius
38 R_0 = 5e-6 # [m]
39
40 # --------------------
41 # Properties of Copper
42 # --------------------
43 # Speed of sound
44 rho_cu = 8_930 # [m/s]
45 # Density
46 c_cu = 5_100 # [kg/m^3]
47
48 # -------------------
49 # Properties of Oil
50 # -------------------
51 # Speed of sound
52 c_oil = 1_445 # [m/s]
53 # Density
54 rho_oil = 922.6 # [kg/m^3]
55 # Viscosity
56 eta_oil = 0.03 # [Pa s]
57 zeta_oil = 0 # [Pa s]
58
59 # --------------------------------
60 # Properties of the Acoustic Field
61 # --------------------------------
62 # Frequency
63 f = 5e5 # [Hz]
64 # Pressure
65 p_0 = 1e5 # [Pa]
66 # Wave type
67 wave_type = osaft.WaveType.STANDING
68 # Position of the particle in the field
69 position = np.pi / 4 # [rad]
70
71 # Once all properties are defined we can initialize the solution classes.
72 # In this example, we use the classes ``osaft.doinikov1994rigid.ARF()``, and
73 # ``osaft.settnes2012.ARF()``.
74
75 doinikov = osaft.doinikov1994rigid.ARF(
76 f=f,
77 R_0=R_0,
78 rho_s=rho_cu,
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 long_wavelength=True,
87 )
88
89 settnes = osaft.settnes2012.ARF(
90 f=f,
91 R_0=R_0,
92 rho_s=rho_cu,
93 c_s=c_cu,
94 rho_f=rho_oil,
95 c_f=c_oil,
96 eta_f=eta_oil,
97 p_0=p_0,
98 wave_type=wave_type,
99 position=position,
100 )
Next, we want to compare the boundary layer thickness and the particle radius for the given parameter. Both quantities are properties of our solution classes and can easily be evaluated, and we can compute the ratio.
106 print(f"{settnes.delta / settnes.R_0 = :.2f}")
settnes.delta / settnes.R_0 = 0.91
With the model from Doinikov it is also possible to compute the scattering
field. To plot the scattering field we need to initialize a
osaft.FluidScatteringPlot()
instance.
The class takes the model as an argument and the radius range r_max
that
is plotted. For more options see the documentation.
The method plot()
will then generate the plot.
As always with Matplotlib, we need to call plt.show()
to display the
plot.
plot()
returns two Matplotlib objects, a Figure
and an Axes
object.
These can be used to further manipulate the plot and to save it.
121 # Scattering plot small viscosity
122 scattering_plot = osaft.FluidScatteringPlot(doinikov, r_max=5 * doinikov.R_0)
123 fig, ax = scattering_plot.plot_velocity(inst=False, incident=False)
124
125 # Adding a circle to illustrate the boundary layer thickness
126 circle = Circle(
127 (0, 0),
128 doinikov.R_0 + doinikov.delta,
129 fill=False,
130 edgecolor="white",
131 linestyle="--",
132 )
133 ax.add_artist(circle)
134 plt.show()
Finally, we want to compare the ARF in the different models. To plot the
ARF we need to initialize an osaft.ARFPlot()
instance. With the method
add_solutions()
we can add our models to the plotter.
With set_abscissa()
we define the variable that we want to
plot the ARF against. Here we select the fluid viscosity eta_f.
Finally, osaft.ARFPlot.plot_solutions()
will generate the plot. Again,
we call plt.show()
to display the plot.
145 # sphinx_gallery_thumbnail_number = -1
146
147 # Initializing plotting class
148 arf_plot = osaft.ARFPlot()
149
150 # Add solutions to be plotted
151 arf_plot.add_solutions(settnes, doinikov)
152
153 # Define independent plotting variable (in this case the fluid viscosity)
154 arf_plot.set_abscissa(np.linspace(1e-5, 0.1, 300), "eta_f")
155 fig, ax = arf_plot.plot_solutions()
156
157 # Setting the axis labels
158 ax.set_xlabel(r"$\eta \, \mathrm{[Pa s]}$")
159
160 plt.show()
/home/docs/checkouts/readthedocs.org/user_builds/osaft/checkouts/stable/osaft/plotting/datacontainers/arf_datacontainer.py:56: AssumptionWarning: Theory might not be valid anymore!
self._arf = self._compute_arf_single_process(attr_name, values)
Note
It is only possible to plot the ARF against
properties that wrap an underlying PassiveVariable
, i.e. an input
parameter of the model.
You can get a list of all input variables using the method
input_variables()
.
170 print(f"{doinikov.input_variables() = }")
171 print(f"{settnes.input_variables() = }")
doinikov.input_variables() = ['long_wavelength', 'fastened_sphere', 'rho_s', 'position', 'p_0', 'wave_type', 'rho_f', 'c_f', 'eta_f', 'zeta_f', 'R_0', 'f', 'N_max', 'small_boundary_layer', 'large_boundary_layer', 'background_streaming']
settnes.input_variables() = ['position', 'p_0', 'wave_type', 'rho_s', 'c_s', 'rho_f', 'c_f', 'eta_f', 'R_0', 'f']
Total running time of the script: ( 0 minutes 5.270 seconds)
Estimated memory usage: 9 MB