Week 6 - Data analysis
Aim: 1) Data Visualizer: The script should take column numbers as the input and plot the respective columns as separate images. Each file should be saved by the name of the column. The plot labels should be extracted from the file. If I request for a plot between column 1(crank angle) and column 8(volume), then label information should automatically be extracted and must appear as labels in the plots. This should not be done manually.
2) Compatibility check: Code should exit gracefully, if a non-compatible file is provided as input. It should say something like “File not recognized. Please provide a valid CONVERGE output file”.
3) Basic performance calculation: Calculate the area under P-V diagram. P is in column 2 and V is in column 8. Calculate the power output of this engine. Assume that RPM is 1500. The engine consumed 20 micro grams of fuel (per 1 stroke cycle). Calculate its fuel consumption.
Theory: Thermodynamic data collected from the simulation of a port fuel injected engine is extracted and analyzed from a data file using a Python program. This data file consists of 17 columns of different thermodynamic properties for which more than 8000 values have been recorded.
From the data file we can understand that it is a 4 stroke otto cycle. So we will apply the following formula to calculate the Work done, Power output and specific fuel consumption:
A = Area under P-V curve = Work done per cycle (MJ)
Power output = A.n.10^6 W
n = Number of cycles per second
n = N/2.60 for four stroke engines
n = N/60 for two stroke engines
N = rotations per min
SFC (Specific fuel consumption) = Fuel consumed in kg/hr/Power output in kW.
Python Code :
"""
Demonstrating file parsing in python
"""
import matplotlib. pyplot as plt
import numpy as np
from scipy. integrate import simps
file_name = input ('Enter converge file having .out Extension:')
#Compatibility check
try:
data = open(file_name,'r')
print ('\nData file is successfully opened.')
except FileNotFoundError:
print ('\nPlease enter a valid file name.\n')
# Checking if data is present in the converge file
i=0
for line in open(file_name):
if '#' not in line:
break
i = i+1
j = 0
for line in open(file_name):
j = j+1
if j>i:
break
if j==i:
print ('No data is present in the converge output file')
exit ()
#Data extraction
i=0
for line in open(file_name):
if i==2:
c = line. split () #Storing unit of variables in list c
i=0
break
if i==1:
b=line. split () #Storing names of variables in list b
i=i+1
if 'column' in line. split ():
a = line. split () #Storing column numbers of variables in list a
i=1
- remove("column”) #Removing column from list a
- remove ("#”) #Removing # from list a
a = np. array (a, dtype=np.int) #Converting data into integer
- remove ("#”) #Removing # from list b
c.remove ("#”) #Removing # from list c
num_col = len(a) #Number of columns/number of variables
#Getting the data
data_counter = 0 # Initializing the number of data points counter variable
data = np. arange (0, num_col)
for line in open(file_name):
if '#' not in line:
d = line. split () # Storing current data line as in d
d = np. array (d, dtype = np. float32) # Converting list data to float array
data = np. vstack ([data, d]) # Stacking the float array d in data matrix
data_counter = data_counter + 1
data = np. delete(data,0,0) # Deleting the first row used to initialize the array
#Data Visualizer
print('Type-')
for i in a:
print ('{} for {}’. format (i, b[i-1]))
print ('')
x = input ("Do you want a plot between any two variables? (y/n):")
while (x. lower () == 'y'):
cn1 = input ("Enter the clumn number of the variable along X-axis:")
cn2 = input ("Enter the clumn number of the variable along Y-axis:")
cn1 = int(cn1)
cn2 = int(cn2)
plt. figure ()
plt. plot (data [:, cn1-1], data[:,cn2-2])
plt. xlabel ('{} {}’. format(b[cn1-1], c[cn1-1]))
plt. ylabel ('{} {}’. format(b[cn2-2], c[cn2-2]))
plt. title ('{} {} vs {} {}’. format(b[cn2-1], c[cn2-1], b[cn1-1], c[cn1-1]))
z = "n"
z = input ("Do you want to save the plot? (y/n):")
if (z. lower () =='y'):
plt. savefig ("{}-{}.png”. format(b[cn2-1],b[cn1-1]))
plt. show ()
print('')
x = input("Do you want to plot any other two variables?(y/n)")
print('')
x = input("Do you want a single variable plot?(y/n):")
while(x.lower()=='y'):
cn = input("Enter column number of variable(Refer input map above):")
cn =int(cn)
plt.figure()
plt.plot(np.arange(0,data_counter),data[:,cn-1])
plt.xlabel('Data point number')
plt.ylabel('{} {}'.format(b[cn-1],c[cn-1]))
z = "n"
z = input("Do you want to save the plot? (y/n):")
if(z.lower()=='y'):
plt.savefig("{}.png".format(b[cn-1]))
plt.show()
print('')
x = input("Do you want any other single variable plot? (y/n):")
print('')
#Calculations
print('Performance of the engine')
#Work done
b1 = [i.lower() for i in b]
pressure_column = b1.index('pressure')
volume_column = b1.index('volume')
pressure = data[:,pressure_column]
volume = data[:,volume_column]
A = 0 #Area under P-V curve
A = simps(pressure,volume,even = 'first')*np.power(10,6) #Work per cycle(J)
#Power output
rpm = float(input('Enter the rpm of the engine at which data is collected'))
f = float(input('Enter the value of fuel consumed per cycle(in micrograms):'))
n = rpm/(2*60) # Number of cycle per second for four stroke engine
P = A*n #Power output(W) at speed N(rad/s)
#Specific fuel consumption
f = (f*n*3600)/np.power(10,9) #Fuel consumption (kg/hr)
sfc = (f*1000)/P #Specific fuel consumption(kg/hr.kW)
#Results
print('Area under the P-V curve(i.e the work done per cycle) = {} J'.format(A))
print('Power output at {} rpm = {} W'.format(rpm,P))
print('Specific fuel cosumption = {} Kg/kW.hr'.format(sfc))
Explanation of the code:
- Matplotlib, numpy and scipy.integrate libraries are imported.
- Compatibility check is done using try and except command. If non converge output is entered it will throw the error.
- Check is done using for loop to see whether data is present in the converge output file.
- Data extraction is done using line.split command. Unit of variables and names of variables are stored in variable c and b respectively.
- Column numbers of variables are stored in variable a.
- Column and # are removed from list a. Data is converted into integer using np.array command.
- Similarly # is removed from list b and c.
- Number of columns are defined.
- For getting the data provide an instruction to the user so that he/she can use the numbers as an input to designate the variables to be plotted.
- Ask users of plot between any two variables is required. If input is ‘y’ then ask for the numbers representing the variables to be plotted.
- Ask the user if the plot is to be saved or not.
- Then show the plot. Above steps run in a while loop until user gives an input ‘n’ to the question “ Do you want a plot between any two variables?(y/n):”
- Extract volume and pressure data from matrix ‘data’ and store in the ‘volume’ and ‘pressure’ respectively. Then, numerically integrate pressure and volume data using simps() function from scipy.integrate library. It is work done by the engine.
- Take the value of engine speed (in rpm) and fuel consumption(in microgram) from user. Calculate the power produced and specific fuel consumption using the derived formulas.
Results:




Conclusion: Area under P-V curve, power output and specific fuel consumption are calculated using formulas. The plot between different thermodynamic properties in engine data.out file is plotted.