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()
example frontiers cu in oil

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()
example frontiers cu in oil
/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

Gallery generated by Sphinx-Gallery