-
Notifications
You must be signed in to change notification settings - Fork 2
Payam/acoustic noise spectrum #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
pdpdhp
wants to merge
10
commits into
master
Choose a base branch
from
payam/acoustic_noise_spectrum
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
47735bf
acoustic_scripts
pdpdhp bc12823
acoustic_scripts
pdpdhp 689006c
readme_usage
pdpdhp c83ba57
confidence_bounds
pdpdhp 372632e
typo
pdpdhp 333f5f3
comments_byChai
pdpdhp c52cdd9
unsteady_loads_confidence_bounds
pdpdhp 7f0a434
typo
pdpdhp 1134844
changes_according_to_new_release
pdpdhp b1a5ebd
effective_normalization_acc_wopwop
pdpdhp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
23,996 changes: 23,996 additions & 0 deletions
23,996
examples/acoustics/1bc78977-5127-4c1f-91b1-db5723415424_total_forces_v2.csv
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Usage: | ||
|
||
Use the acoustic.py to calculate and plot the noise spectrums, OASPL, and averaged noise spectrum for observers: | ||
|
||
python acoustic.py -i example1_aeroacoustics_v3.csv -o my_simulation | ||
|
||
Use the acoustic.py with -n to specify a particular observer to calculate and plot the noise spectrum and OASPL. | ||
|
||
python acoustic.py -i example1_aeroacoustics_v3.csv -n <observer_id> -o my_simulation | ||
|
||
------------------------------------------------------------------------------------------------------------------- | ||
|
||
Use the unsteadyLoads.py to calculate and plot unsteady aerodynamic loads starting from a physical step for example 3000 and get a report on forces: | ||
|
||
option 1 with caseId: | ||
|
||
python unsteadyLoads.py -caseId <xxxxxxx> -start <starting_physical_step> -o my_simulation | ||
|
||
option 2 with <caseId>_total_forces_v2.csv file and a json input including reference values: | ||
|
||
python unsteadyLoads.py -i <caseId>_total_forces_v2.csv -s 3000 -r reference_flow360.json -o my_simulation | ||
|
||
option 3 with <caseId>_total_forces_v2.csv file and without a json input for reference values: | ||
|
||
python unsteadyLoads.py -i <caseId>_total_forces_v2.csv -s 3000 -o my_simulation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
|
||
import os | ||
import argparse | ||
|
||
import numpy as np | ||
import pandas as pd | ||
from matplotlib import pyplot as plt | ||
import matplotlib.ticker as ticker | ||
|
||
def read_acoustic_file(a_csv): | ||
pressure_data = pd.read_csv(a_csv,skipinitialspace=True) | ||
times = pressure_data['time'] | ||
steps = pressure_data['physical_step'] | ||
p = pressure_data.iloc[:,2:-1] | ||
return [np.array(times),np.array(steps),np.array(p)] | ||
|
||
def filter_zero_data(time,steps,pressure,observerId): | ||
# dictionary of acoustic data for filtering | ||
acoustic_data_indices = {} | ||
acoustic_data = {} | ||
# number of observers and their length | ||
num_observers = pressure.shape[-1] | ||
length_observers = pressure.shape[0] | ||
# default when observerId is not given | ||
observerId_start = 0 | ||
observerId_end = num_observers | ||
# list of indices of first and last non-zero elements for observers | ||
first_elements = [] | ||
last_elements = [] | ||
# all input as data | ||
data = np.column_stack((steps,time,pressure)) | ||
|
||
# when observerId is given | ||
if observerId is not None: | ||
# when id is within range | ||
if observerId >= 0 and observerId <= num_observers-1: | ||
observerId_start = observerId | ||
observerId_end = observerId+1 | ||
num_observers = 1 | ||
# when id is not within range | ||
else: | ||
print("Observer Id doesn't exist") | ||
exit() | ||
|
||
# loop over observers to find where they are not zero | ||
for i in range(observerId_start,observerId_end,1): | ||
p_observer = data[:,i+2] | ||
acoustic_data_indices[i] = np.where(p_observer!=0)[0] | ||
|
||
# lists of indices of elements at the beginning or/and ending where they are not zero | ||
for i in range(observerId_start,observerId_end,1): | ||
if len(acoustic_data_indices[i]) != 0: | ||
first_elements.append(acoustic_data_indices[i][0]) | ||
last_elements.append(acoustic_data_indices[i][-1]) | ||
# when all data for an observer are zero | ||
else: | ||
first_elements.append(0) | ||
last_elements.append(length_observers) | ||
|
||
# max index where still there is a zero element for all observers | ||
start_index = max(first_elements) | ||
# min index where still there is a zero element for all observers | ||
end_index = min(last_elements)+1 | ||
|
||
# physical time and step where all observers all non zero | ||
acoustic_data['time'] = time[start_index:end_index] | ||
acoustic_data['physical_step'] = steps[start_index:end_index] | ||
|
||
# non-zero acoustic data for all observers with the same physical time | ||
for i in range(observerId_start,observerId_end,1): | ||
p_observer = data[:,i+2] | ||
acoustic_data[i] = p_observer[start_index:end_index] | ||
return [observerId_start,observerId_end,num_observers,acoustic_data] | ||
|
||
# based on signal amplitude | ||
def cal_decibel_amplitude(p): | ||
p_ref = 2e-5 | ||
return 20 * np.log10(p/p_ref) | ||
|
||
# based on signal power | ||
def cal_decibel_power(p): | ||
p_ref = 2e-5 | ||
return 10 * np.log10(p / p_ref**2) | ||
#end | ||
|
||
def plot_response(name,freq,resp,key): | ||
fig, ax = plt.subplots() | ||
# optional axis limit | ||
# ax.axis([100, 18000, 0, 70]) | ||
plt.plot(freq,resp,'crimson',linewidth=0.8,marker='o',markersize=0.8) | ||
plt.xscale('log') | ||
for axis in [ax.xaxis, ax.yaxis]: | ||
formatter = ticker.ScalarFormatter() | ||
formatter.set_scientific(False) | ||
axis.set_major_formatter(formatter) | ||
ax.yaxis.set_minor_formatter(formatter) | ||
ax.xaxis.set_minor_formatter(formatter) | ||
|
||
# optional log minor ticker | ||
ax.xaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs=(0.2, 0.4, 0.6, 0.8), numticks=5)) | ||
|
||
plot_title = f'Noise Spectrum - Observer {key}' if key != 'avg' else f'Noise Spectrum - Averaged' | ||
plt.title(plot_title, fontsize=10) | ||
plt.xlabel('Frequency [Hz]', fontsize=10) | ||
plt.ylabel('SPL [dB]', fontsize=10) | ||
plt.grid(which='major') | ||
plt.grid(which='minor', ls='--',color='k',linewidth=0.5) | ||
ax.tick_params(axis='x',which='major',labelsize=8,pad=10) | ||
ax.tick_params(axis='y',which='major',labelsize=8) | ||
ax.tick_params(axis='both',which='minor',labelsize=5) | ||
|
||
# figure resolution | ||
plt.rcParams['figure.dpi'] = 500 | ||
plt.rcParams['savefig.dpi'] = 500 | ||
plt.savefig(f'{name}_narrow-band_spectra_{key}.png', bbox_inches='tight') | ||
plt.close() | ||
|
||
def get_spectrum(a_sound,rho,a_csv,o_name,obsrId): | ||
# reads acoustic csv file | ||
tt,stp,pdata = read_acoustic_file(a_csv) | ||
# filters zeros from acoustic data | ||
startId,endId,num_observers,acoustic_data = filter_zero_data(tt,stp,pdata,obsrId) | ||
|
||
# output file basename | ||
out_file = os.path.splitext(os.path.basename(o_name))[0] | ||
# output oaspl file in dat format | ||
oaspl_file = os.path.join(os.curdir,out_file+'_OASPL'+'.dat') | ||
print(f"variables=i,{'oaspl_'+out_file}",file=open(oaspl_file, 'w')) | ||
|
||
# initialized avg spectrum | ||
avg_response = 0 | ||
# loop over observers | ||
for i in range(startId,endId,1): | ||
# get physical time from acoustic data | ||
tt = acoustic_data['time'] | ||
# get acoustic pressures for an observer | ||
pp = acoustic_data[i] | ||
# convert to dimensional pressure | ||
pp = pp * rho * (a_sound**2) | ||
# get the mean pressure for the observer | ||
p0 = np.mean(pp) | ||
# get the RMS for the pressure fluctuations | ||
p_rms = np.sqrt(np.mean((pp - p0)**2)) | ||
# get the overall sound pressure based on pressure fluctuations | ||
spl = cal_decibel_amplitude(p_rms) | ||
# print oaspl | ||
print('Observer {} | OASPL: {:.5f} dB'.format(i,spl)) | ||
# print oaspl in the file | ||
print("{}, {:.5f}".format(i,spl),file=open(oaspl_file, 'a')) | ||
|
||
# get the mean time step size for pressure fluctuations | ||
mean_step_size = (tt[1:] - tt[:-1]).mean() | ||
# define the windowing function | ||
window = np.hanning(len(pp)) | ||
# windowing checks | ||
# window /= window.mean() | ||
# window = np.ones(len(pp)) #no window | ||
|
||
# sums for normalization purpose - equation 19 and 20 | ||
s1 = sum(window) | ||
s2 = sum(window**2) | ||
# sampling frequency - section 7 | ||
fs = 1/(mean_step_size/a_sound) | ||
# effective noise bandwidth - equation 22 | ||
enbw = 2 * fs * (s2 / s1**(5/2)) | ||
# define the signal | ||
h =(pp - p0)*window | ||
# fft over the signal | ||
X = np.fft.fft(h) | ||
# get number of samples | ||
N = len(X) | ||
n_oneside = N//2 | ||
# find the dimensional frequencies from the fft | ||
freq = np.fft.fftfreq(N,d=mean_step_size/a_sound) | ||
freq_oneside = freq[:n_oneside] | ||
|
||
# power spectrum - equation 23 | ||
psX = (2 * np.abs(X[:n_oneside])**2) / s1**2 | ||
# power spectrum density - equation 24 | ||
psdX = psX / enbw | ||
# linear spectrum density - equation 25 | ||
lsdX = np.sqrt(psdX) | ||
# linear spectrum - equation 26 | ||
lsX = np.sqrt(psX) | ||
|
||
# calculate the sound pressure level | ||
# response = cal_decibel_amplitude(lsX) | ||
response = cal_decibel_power(psdX) | ||
|
||
# collect the spectrum for averaging between observers | ||
avg_response += np.abs(response) | ||
|
||
# plot the response | ||
plot_response(out_file,freq_oneside,response,i) | ||
|
||
# averaging the spectrum across all observers - which is useful in some cases | ||
avg_response = avg_response/num_observers | ||
# plot the average spectrum | ||
plot_response(out_file,freq_oneside,avg_response,'avg') | ||
#end | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-i','--input',help='Specify the input aeroacoustic CSV file. For example: <caseId>_aeroacoustics_v3.csv',type=str,required=True) | ||
parser.add_argument('-n','--observerId',help='Observer Id number for acoustic pos-processing.',type=int,required=False) | ||
parser.add_argument('-o','--output',help='Specify the output file name for calculated OASPL.',type=str,required=True) | ||
args = parser.parse_args() | ||
scriptDir = os.getcwd() | ||
|
||
# speed of sound and density in SI for dimensional values | ||
a_speed = 340.3 | ||
density = 1.225 | ||
|
||
# getUnsteadyAerodynamicLoads(args.caseId) | ||
get_spectrum(a_speed,density,args.input,args.output,args.observerId) | ||
#end | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are going to be a few changes in the release version of aeroacoustics, physical_time will be renamed to time. Will let you know when the final release version is ready for testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Looking forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File will be renamed to total_acoustics_v3.csv for release-23.2.3.0