Noisy Duck¶
A python tool for computing eigenmode decompositions of duct flows.
- Free software: BSD license
- Documentation: https://noisyduck.readthedocs.io.
Features¶
- Annular duct mode decomposition
Credits¶
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
Noisy Duck¶
A python tool for computing eigenmode decompositions of duct flows.
- Free software: BSD license
- Documentation: https://noisyduck.readthedocs.io.
Features¶
- Annular duct mode decomposition
Credits¶
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
Installation¶
Stable release¶
To install Noisy Duck, run this command in your terminal:
$ pip install noisyduck
This is the preferred method to install Noisy Duck, as it will always install the most recent stable release.
If you don’t have pip installed, this Python installation guide can guide you through the process.
From sources¶
The sources for Noisy Duck can be downloaded from the Github repo.
You can either clone the public repository:
$ git clone git://github.com/nwukie/noisyduck
Or download the tarball:
$ curl -OL https://github.com/nwukie/noisyduck/tarball/master
Once you have a copy of the source, you can install it with:
$ python setup.py install
Usage¶
To use Noisy Duck in a project:
import noisyduck
Example: Annular Cylindrical Duct¶
Numerical eigenvalue/eigenvector decomposition:
import noisyduck as nd
eigenvalues, eigenvectors = nd.annulus.numerical.decomposition(omega,m,r,rho,u,v,w,p,gam,filter='acoustic')
Analytical eigenvalue/eigenvector decomposition:
import noisyduck as nd
eigenvalues, eigenvectors = nd.annulus.analytical.decomposition(omega,m,mach,ri,ro,n)
See cylindrical_annulus_uniform_flow.py
.
Cylindrical Annuluar Duct¶
Analytical¶
This module provides a functionality for computing the eigenvalue/eigenvector decomposition of a uniform axial flow in an annular cylindrical duct. The decomposition is based on an analytical solution of the convected wave equation for pressure, yielding the acoustic part of the eigen decomposition. The eigenvectors from this decomposition correspond specifically to the acoustic pressure disturbance.
The analysis here follows that of Moinier and Giles, “Eigenmode Analysis for Turbomachinery Applications”, Journal of Propulsion and Power, Vol. 21, No. 6, 2005.
For a uniform axial mean, linear pressure perturbations satisfy the convected wave equation
where \(M\) is the Mach number of the axial mean flow and \(r\) has been normalized by the outer duct radius. Boundary conditions for a hard-walled duct imply zero radial velocity, which is imposed using the condition
Conducting a normal mode analysis of the governing equation involves assuming a solution with a form
This leads to a Bessel equation
where \(\mu^2 = (\omega + M k)^2 - k^2\). The solution to the Bessel equation is
where \(J_m\) and \(Y_m\) are Bessel functions. Applying boundary conditions to the general solution gives a set of two equations
which has nontrivial solutions as long as the determinant is zero. Solving for the zeros of the determinant give \(\mu\), at which point the quadratic equation above can be solved for the axial wavenumbers \(k\).
eigenvalues, eigenvectors =
noisyduck.annulus.analytical.decomposition(omega,m,mach,r,n)
-
noisyduck.annulus.analytical.
compute_eigenvalues
(omega, mach, zeros)[source]¶ This procedure compute the analytical eigenvalues for the convected wave equation. A uniform set of nodes is created to search for sign changes in the value for the eigensystem. When a sign change is detected, it is known that a zero is close. The eigensystem is then passed to a bisection routine to find the location of the zero. The location corresponds to the eigenvalue for the system.
Parameters: - omega (float) – temporal wavenumber.
- m (int) – circumferential wavenumber.
- mach (float) – Mach number.
- ri (float) – inner radius of a circular annulus.
- ro (float) – outer radius of a circular annulus.
- n (int) – number of eigenvalues to compute.
Returns: An array of the first ‘n’ eigenvalues for the system.
-
noisyduck.annulus.analytical.
compute_eigenvector
(r, sigma, m, zero)[source]¶ Return the eigenvector for the system.
Parameters: - r (np.array(float)) – array of radial locations.
- sigma (float) – ratio of inner to outer radius, ri/ro.
- m (int) – circumferential wavenumber.
- zero (float) – a zero of the determinant of the convected wave equation
Returns: the eigenvector associated with the input ‘m’ and ‘zero’, evaluated at radial locations defined by the input array ‘r’. Length of the return array is len(r).
-
noisyduck.annulus.analytical.
compute_zeros
(m, mach, ri, ro, n)[source]¶ This procedure compute the zeros of the determinant for the convected wave equation.
A uniform set of nodes is created to search for sign changes in the value of the function. When a sign change is detected, it is known that a zero is close. The function is then passed to a bisection routine to find the location of the zero.
Parameters: - m (int) – circumferential wavenumber.
- mach (float) – Mach number
- ri (float) – inner radius of a circular annulus.
- ro (float) – outer radius of a circular annulus.
- n (int) – number of eigenvalues to compute.
Returns: An array of the first ‘n’ eigenvalues for the system.
-
noisyduck.annulus.analytical.
decomposition
(omega, m, mach, r, n)[source]¶ This procedure computes the analytical eigen-decomposition of the convected wave equation. The eigenvectors returned correspond specifically with acoustic pressure perturbations.
Inner and outer radii are computed using min(r) and max(r), so it is important that these end-points are included in the incoming array of radial locations.
Parameters: - omega (float) – temporal wave number.
- m (int) – circumferential wave number.
- mach (float) – Mach number.
- r (float) – array of radius stations, including rmin and rmax.
- n (int) – number of eigenvalues/eigenvectors to compute.
Returns: a tuple containing an array of eigenvalues, and an array of eigenvectors evaluated at radial locations.
Return type: (eigenvalues, eigenvectors)
-
noisyduck.annulus.analytical.
eigensystem
(b, m, ri, ro)[source]¶ Computes the function associated with the eigensystem of the convected wave equation. The location of the zeros for this function correspond to the eigenvalues for the convected wave equation.
The solution to the Bessel equation with boundary conditions applied yields a system of two linear equations. .. math:
A x = \begin{bmatrix} J'_m(\mu \lambda) & Y'_m(\mu \lambda) \\ J'_m(\mu) & Y'_m(\mu) \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \end{bmatrix} = 0
This procedure evaluates the function .. math:
det(A) = f(b) = J_m(b*ri)*Y_m(b*ro) - J_m(b*ro)*Y_m(b*ri)
So, this procedure can be passed to another routine such as numpy to find zeros.
Parameters: - b (float) – coordinate.
- m (int) – circumferential wave number.
- ri (float) – inner radius of a circular annulus.
- ro (float) – outer radius of a circular annulus.
Numerical¶
This module provides a functionality for computing the numerical eigenvalue/eigenvector decomposition of a uniform axial flow in an annular cylindrical duct. The decomposition is based on a normal mode analysis of the three-dimensional linearized Euler equations, which yields an eigensystem that is discretized and solved numerically.
eigenvalues, eigenvectors_l, eigenvectors_r =
noisyduck.annulus.numerical.decomposition(omega,
m,
r,
rho,
vr,
vt,
vz,
p,
gam,
filter='acoustic')
-
noisyduck.annulus.numerical.
construct_numerical_eigensystem_general
(omega, m, r, rho, vr, vt, vz, p, gam, perturb_omega=True)[source]¶ Constructs the numerical representation of the eigenvalue problem associated with the three-dimensional linearized euler equations subjected to a normal mode analysis.
NOTE: If perturb_omega=True, a small imaginary part is added to the temporal frequency to facilitate determining the propagation direction of eigenmodes based on the sign of the imaginary part of their eigenvalue. That is: \(\omega = \omega - 10^{-5}\omega j\). See Moinier and Giles[2].
- [1] Kousen, K. A., “Eigenmodes of Ducted Flows With Radially-Dependent
- Axial and Swirl Velocity Components”, NASA/CR 1999-208881, March 1999.
- [2] Moinier, P., and Giles, M. B., “Eigenmode Analysis for Turbomachinery
- Applications”, Journal of Propulsion and Power, Vol. 21, No. 6, November-December 2005.
Parameters: - omega (float) – temporal frequency.
- m (int) – circumferential wavenumber.
- r (float) – array of equally-spaced radius locations for the discretization, including end points.
- rho (float) – mean density.
- vr (float) – mean radial velocity.
- vt (float) – mean tangential velocity.
- vz (float) – mean axial velocity.
- p (float) – mean pressure.
- gam (float) – ratio of specific heats.
- perturb_omega (bool) – If true, small imaginary part is added to the temporal frequency. Can help in determining direction of propagation.
Returns: - left-hand side of generalized eigenvalue problem, right-hand
side of generalized eigenvalue problem.
Return type: (M, N)
-
noisyduck.annulus.numerical.
construct_numerical_eigensystem_radial_equilibrium
(omega, m, r, rho, vr, vt, vz, p, gam, perturb_omega=True)[source]¶ Constructs the numerical representation of the eigenvalue problem associated with the three-dimensional linearized euler equations under the assumption of radial equilibrium subjected to a normal mode analysis.
NOTE: If perturb_omega=True, a small imaginary part is added to the temporal frequency to facilitate determining the propagation direction of eigenmodes based on the sign of the imaginary part of their eigenvalue. That is: \(\omega = \omega - 10^{-5}\omega j\). See Moinier and Giles[2].
The equation set used for this decomposition is consistent with that presented by Sharma et. al[1]. Even for radial equilibrium flows, this equation set is missing a dvt_dr term in the tangential velocity equation and also a drho_dr term in the radial velocity equation.
References: [1] Sharma, A., Richards, S. K., Wood, T. H., Shieh, C., “Numerical
Prediction of Exhaust Fan-Tone Noise from High-Bypass Aircraft Engines”, AIAA Journal, Vol. 47, No. 12, December 2009.- [2] Moinier, P., and Giles, M. B., “Eigenmode Analysis for Turbomachinery
- Applications”, Journal of Propulsion and Power, Vol. 21, No. 6, November-December 2005.
- [3] Kousen, K. A., “Eigenmodes of Ducted Flows With Radially-Dependent
- Axial and Swirl Velocity Components”, NASA/CR 1999-208881, March 1999.
Parameters: - omega (float) – temporal frequency.
- m (int) – circumferential wavenumber.
- r (float) – array of equally-spaced radius locations for the discretization, including end points.
- rho (float) – mean density.
- vr (float) – mean radial velocity.
- vt (float) – mean tangential velocity.
- vz (float) – mean axial velocity.
- p (float) – mean pressure.
- gam (float) – ratio of specific heats.
Returns: - left-hand side of generalized eigenvalue problem, right-hand
side of generalized eigenvalue problem.
Return type: (M, N)
-
noisyduck.annulus.numerical.
decomposition
(omega, m, r, rho, vr, vt, vz, p, gam, filter='None', alpha=1e-05, equation='general', perturb_omega=True)[source]¶ Compute the numerical eigen-decomposition of the three-dimensional linearized Euler equations for a cylindrical annulus.
Parameters: - omega (float) – temporal frequency.
- m (int) – circumferential wavenumber.
- r (float) – array of equally-spaced radius locations for the discretization, including end points.
- rho (float) – mean density.
- vr (float) – mean radial velocity.
- vt (float) – mean tangential velocity.
- vz (float) – mean axial velocity.
- p (float) – mean pressure.
- gam (float) – ratio of specific heats.
- filter (string, optional) – Optional filter for eigenmodes. values = [‘None’, ‘acoustic’]
- alpha (float, optional) – Criteria governing filtering acoustic modes.
- equation (string, optional) – Select from of governing equation for the decomposition. values = [‘general’, ‘radial equilibrium’]
- perturb_omega (bool) – If true, small imaginary part is added to the temporal frequency. Can help in determining direction of propagation.
Returns: a tuple containing an array of eigenvalues, an array of left eigenvectors evaluated at radial locations, an array of right eigenvectors evaluated at radial locations.
Return type: (eigenvalues, left_eigenvectors, right_eigenvectors)
Note
The eigenvectors being returned include each field \([\rho,v_r,v_t,v_z,p]\). The primitive variables can be extracted into their own eigenvectors by copying out those entries from the returned eigenvectors as:
res = len(r) rho_eigenvectors = eigenvectors[0*res:1*res,:] vr_eigenvectors = eigenvectors[1*res:2*res,:] vt_eigenvectors = eigenvectors[2*res:3*res,:] vz_eigenvectors = eigenvectors[3*res:4*res,:] p_eigenvectors = eigenvectors[4*res:5*res,:]
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/nwukie/noisyduck/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” and “help wanted” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “enhancement” and “help wanted” is open to whoever wants to implement it.
Write Documentation¶
Noisy Duck could always use more documentation, whether as part of the official Noisy Duck docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/nwukie/noisyduck/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up noisyduck for local development.
Fork the noisyduck repo on GitHub.
Clone your fork locally:
$ git clone git@github.com:your_name_here/noisyduck.git
Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:
$ mkvirtualenv noisyduck $ cd noisyduck/ $ python setup.py develop
Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:
$ flake8 noisyduck tests $ python setup.py test or py.test $ tox
To get flake8 and tox, just pip install them into your virtualenv.
Commit your changes and push your branch to GitHub:
$ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 2.6, 2.7, 3.3, 3.4 and 3.5, and for PyPy. Check https://travis-ci.org/nwukie/noisyduck/pull_requests and make sure that the tests pass for all supported Python versions.
Credits¶
Development Lead¶
- Nathan Wukie <nathan.wukie@gmail.com>
Contributors¶
None yet. Why not be the first?