Project 1 - Parsing NASA thermodynamic data
The program is designed such that it will take 2 inputs -
- Element name to display plots for that specific element.
- Temperature value which would be used further in the program to evaluate specific heat, enthalpy and entropy values for all elements at either low temperature range or high temperature range based on the value input and store plots for them in seperate folders within a master folder.
%Matlab code for File Parsing Assignment
clear all
close all
clc
%Reading the data file
file = fopen('THERMO.dat','r')
%used fgetl 5 times to eliminate the first 5 lines from the file to get to
%the numbers directly.
fgetl(file);
fgetl(file);
fgetl(file);
fgetl(file);
fgetl(file);
%Taking out the element name from the 6th line which would be used further
%in the code.
element_line = fgetl(file);
element(1,1:6) = element_line(1:6);
%Created a loop to store all the lines into a variable as presented in the
%data file.
for i = 1:211
value = fgetl(file);
temp_val(i,:) = value;
end
%%
%Created a counter variable to create columns
ct =1;
row =1;
%Started with an I loop which would run 211 times as the no of rows
%containing the values of temperature variables
for i=1:211
%Since the values are within 15 characters we can create a range from
%1-15
a=1;
b=15;
%Since there are unwanted details in every 4th row so here I am
%checking if the Ith row is divisible by 4 that means we do not need
%any data from the 4th row and we can skip it
if rem(i,4) == 0
continue
end
%Starting a nested loop to extract values from every column of every
%row.
for j=1:5
%J loop is for no of columns.
if ct == 15
%Once counter reaches 15 we want to change the change the row
%and start the column from beginning. so increminting and
%initializing values
row=row+1;
ct =1;
continue
end
%We only have 14 variables so if the counter reaches 15 the loop
%will terminate
temp = temp_val(i,a:b);
%Creating a variable that will store the value in string format
conv(row,ct) = str2double(temp);
%Converting the string back to float/double format
a = a+15;
b = b+15;
%Increasing the variable a and b by 15 to get the next range of
%data set which has a character input of 15
ct = ct+1;
%Increasing counter by 1 to store every value in different column
end
end
%Since we have got all the data from the file we would now close it
fclose(file);
%%
%Here we would extract the element name from the data.
%The 1st element has already been extracted in the beginning of the code.
%So K is initialized as 2 to fill the 2nd row of the array.
k=2;
for i =1:length(temp_val)
%The loop is running for the no of rows in the file.
%Name of the element is in every 4th row so we are checking if i has
%reached the 4th row we will extract the element name.
%column size is given for 6 character length as the element name is not
%bigger than that.
if rem(i,4) == 0
element(k,1:6) = temp_val(i,1:6);
k = k+1;
end
end
%%
%Converting character array to string array.
%Character array had 53 rows and 6 columns which had unnecessary space and
%would not let compare with input string so converted into a single column
%string array
for i=1:53
fin_elem(i,1) = cellstr(element(i,1:6));
end
%%
%Taking Inputs from the user for Element
%Taking a variable compare to eliminate any issues with upper/lower case
%string
compare = 0;
while compare ~= 1
%Running a while loop till the user gives a valid input which is
%present in the data
inp = inputdlg('Please enter the Element you want to get details for');
%Running an I loop to compare the input element name with existing data
for i=1:53
compare = strcmpi(fin_elem(i),inp);
%Once we get a valid input and matched with our data loop will be
%terminated to avoid any further time waste
if compare == 1
%Once the element is matched we will extract its location too for
%temperature range comparison
element_no = i;
break
end
end
%If input data does not match with existing data an error message will pop
%up
if compare ~= 1
warndlg('Please enter valid name for element present in the data file');
end
end
%%
%Taking input for temperature at which Specific heat, enthalpy and entropy
%would be calculated.
%Creating a check variable which would check if the input value is within
%range or not
check =0;
while check~=1
%While loop will run until a correct input is given
input = inputdlg('Please enter the Temperature value at which properties needs to be calculated');
input1 = str2double(input);
%Since local temperature is different for many elements using if and
%elseif command to check in which range does the element falls and
%if the input temperature value is within the range of that specific
%element
if (element_no>=1 && element_no<=28 && element_no~= 20)
if (input1>=200 && input1<=3500)
x = linspace(200,3500,100);
%X is the temperature variable which is storing values of
%temperature for the given range which would be used for plotting
check = 1;
break;
end
%After every check break command is used to avoid complete iteration
%and save time and also limit the values in temperature variable - X to
%avoid any extra lines in plots.
elseif element_no == 20
if (input1>=300 && input1<=3000)
%Creating and storing temperature range based on specific element
%data in X and will use further to plot graphs
x = linspace(300,3000,100);
check = 1;
break;
end
elseif element_no == 29 || element_no == 31
if (input1>=300 && input1<=4000)
x = linspace(300,4000,100);
check = 1;
break;
end
elseif element_no>=32 && element_no<=41 || element_no == 45 || element_no == 46 || element_no == 52
if (input1>=200 && input1<=6000)
x = linspace(200,6000,100);
check = 1;
break;
end
elseif element_no>=42 && element_no<=44 || element_no>=47 && element_no<=51 || element_no == 53 || element_no == 30
if (input1>=300 && input1<=5000)
x = linspace(300,5000,100);
check = 1;
break;
end
end
if check ~= 1
%If the user inputs a value outside the range pop-up will be shown
warndlg('Please enter valid number within range');
end
end
%%
%Calculating Enthalpy, Entropy and Specific Heat with the help of a
%function called thermod
%Since the formula would be calculated based on the input temperature
%value. We can now check the lower and middle range.
%Based on the entered temperature value range of variables would be sent to
%the function for calculation of properties.
low = 0;
%Here taken a variable low which would check if the given input falls under
%low temperature range or high temperature range which would be used
%further
if (element_no>=1 && element_no<=28 && element_no~= 20 || element_no>=32 && element_no<=41 || element_no == 45 || element_no == 46 || element_no == 52)
if input1>=200 && input1<=1000
%Here we check if the input value falls in the lower temeperature
%range or higher temperature range. Accordingly 7 variables would
%be sent to the function thermod
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,1:7));
low = 1;
else
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,8:14));
end
elseif (element_no == 20 || element_no>= 29 && element_no<=31 || element_no>=47 && element_no<=51 || element_no == 53)
if input1>=300 && input1<=1000
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,1:7));
low = 1;
else
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,8:14));
end
elseif element_no == 42
if input1>=300 && input1<=1382
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,1:7));
low = 1;
else
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,8:14));
end
elseif element_no == 43
if input1>=300 && input1<=1368
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,1:7));
low = 1;
else
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,8:14));
end
elseif element_no == 44
if input1>=300 && input1<=1478
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,1:7));
low = 1;
else
[cp(element_no,:),h(element_no,:),s(element_no,:)] = thermod(x,conv(:,8:14));
end
end
%%
%In the above processes Parameters for only the input element would be
%calculated. In this section we are creating a new variable which will
%collect the temperature values which would be unique for every element
%local range
variable(1,:) = linspace(200,3500,100);
variable(2,:) = linspace(300,3000,100);
variable(3,:) = linspace(300,4000,100);
variable(4,:) = linspace(200,6000,100);
variable(5,:) = linspace(300,5000,100);
%Here we will check if the input temperature is in the low temperature
%range or higher temperature range. Accordingly the parameters would be
%calculated with the help of the function we creater earlier.
if low == 1
for i=1:53
if i == element_no
%Since we are already creating a folder for the asked element
%we would be skipping the process from here
continue;
else
%Here based on the range of temperature we are adding rows
if (input1>=200 && input1<=3500)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(1,:),conv(i,1:7));
elseif (input1>=300 && input1<=3000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(2,:),conv(i,1:7));
elseif (input1>=300 && input1<=4000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(3,:),conv(i,1:7));
elseif (input1>=200 && input1<=6000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(4,:),conv(i,1:7));
elseif (input1>=300 && input1<=5000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(5,:),conv(i,1:7));
end
end
end
else
%this loop will work for high temperature
for i=1:53
if i == element_no
continue;
else
if (input1>=200 && input1<=3500)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(1,:),conv(i,8:14));
elseif (input1>=300 && input1<=3000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(2,:),conv(i,8:14));
elseif (input1>=300 && input1<=4000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(3,:),conv(i,8:14));
elseif (input1>=200 && input1<=6000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(4,:),conv(i,8:14));
elseif (input1>=300 && input1<=5000)
[cp(i,:),h(i,:),s(i,:)] = thermod(variable(5,:),conv(i,8:14));
end
end
end
end
%%
%Here we would display the plots for element requested by the user
%Figure 1 represents Specific Heat, 2nd Enthalpy and 3rd Entropy
figure(1)
%Plotting graph individually
plot(x,cp(element_no,:))
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Specific Heat');
title([fin_elem(element_no),' Plot for Temperature vs Specific Heat'])
figure(2)
plot(x,h(element_no,:))
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Enthalpy');
title([fin_elem(element_no),' Plot for Temperature vs Enthalpy'])
figure(3)
plot(x,s(element_no,:))
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Entropy');
title([fin_elem(element_no),' Plot for Temperature vs Entropy']);
%%
%Here we will calculate the molecular weight for the element input by the
%user
mweight=0;
for i= 1:6
%Since there are maximum of 6 columns in elements we are running the
%loop 6 times and checking if the element input is matching to some
%specfic character then molecular weight of that character would be
%added.
if(element(element_no,i) == 'C')
mweight= mweight+12.011;
elseif(element(element_no,i) == 'O')
mweight = mweight+15.9994;
elseif(element(element_no,i) == 'H')
mweight = mweight+1.0080;
elseif(element(element_no,i) == 'N')
mweight = mweight+14.0067;
elseif(element(element_no,i) == 'S')
mweight= mweight+32.065;
%For Argon ar the molecular weight has been divided into 2 and
%given half to each a and r
elseif(element(element_no,i) == 'A')
mweight = mweight+19.974;
elseif(element(element_no,i) == 'R')
mweight = mweight+19.974;
%In some cases there are blank spaces as well as opening and
%closing brackets which contribute nothing to molecular weight so
%adding 0 for it.
elseif(element(element_no,i) == '(' || element(element_no,i) == ')' || element(element_no,i) == ' ')
mweight= mweight+0;
else
%In some cases there are numbers along with string so extracting
%that number and converting it to double.
conversion = str2double(element(element_no,i));
if(element(element_no,i-1) == 'C')
%Here conversionn-1 is used since the value of character is already
%added once we want remaining values of that character. Expample
%CH4 value of c and h has already been added so we need value of H
%for more 3 times only
mweight= mweight+((conversion-1)*12.011);
elseif(element(element_no,i-1) == 'O')
mweight= mweight+((conversion-1)*15.9994);
elseif(element(element_no,i-1) == 'H')
mweight= mweight+((conversion-1)*1.0080);
elseif(element(element_no,i-1) == 'N')
mweight= mweight+((conversion-1)*14.0067);
elseif(element(element_no,i-1) == 'S')
mweight= mweight+((conversion-1)*32.065);
elseif(element(element_no,i-1) == 'A')
mweight= mweight+((conversion-1)*19.974);
elseif(element(element_no,i-1) == 'R')
mweight= mweight+((conversion-1)*19.974);
end
end
end
%Printing the value of Molecular weight in command window
fprintf('Molecular Weight of %s',fin_elem{element_no})
fprintf(' is %f Kg/mol',mweight)
%%
%Creating a destination folder File_Parsing_Assignment where all the
%subfolders and plots would be save later.
dest_dir = 'E:\Skill Lync\Matlab Programs\file_parsing_assignment';
mkdir(dest_dir);
%Entering the master folder to create subfolders individually for every
%element
%Within the main folder we need to create a total of 53 subfolders unique
% %for every element.
for i=1:53
cd(dest_dir)
%After every loop the main folder would be opened so a subfolder is
%creater in the main folder and not within a subfolder.
sub = element(i,:);
%Creating folder with the name of the element.
folder = sprintf('%s',sub);
mkdir(folder);
cd(folder)
%Entering the subfolder to save all plots.
%Turning off the visibility of the plots so it runs in the background.
f = figure('visible','off');
%Plotting graph individually
%Based on local temperature range of temperature is different for
%different elements.
if (i>=1 && i<=28 && i~=20)
plot(variable(1,:),cp(i,:));
elseif (i==20)
plot(variable(2,:),cp(i,:));
elseif (i>=29 && i<=31)
plot(variable(3,:),cp(i,:));
elseif (i>=32 && i<=41 || i==45 || i==46 || i==52)
plot(variable(4,:),cp(i,:));
elseif (i==30 || i>=42 && i<=44 || i>=47 && i<=51 || i==53)
plot(variable(5,:),cp(i,:));
end
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Specific Heat');
title([fin_elem(element_no),' Plot for Temperature vs Specific Heat'])
%Saving plots in form of pictures in required subfolder
saveas (gcf, 'specific_heat','png')
f = figure('visible','off');
if (i>=1 && i<=28 && i~=20)
plot(variable(1,:),h(i,:));
elseif (i==20)
plot(variable(2,:),h(i,:));
elseif (i>=29 && i<=31)
plot(variable(3,:),h(i,:));
elseif (i>=32 && i<=41 || i==45 || i==46 || i==52)
plot(variable(4,:),h(i,:));
elseif (i==30 || i>=42 && i<=44 || i>=47 && i<=51 || i==53)
plot(variable(5,:),h(i,:));
end
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Enthalpy');
title([fin_elem(i),' Plot for Temperature vs Enthalpy'])
saveas (gcf, 'enthalpy', 'png')
f = figure('visible','off');
if (i>=1 && i<=28 && i~=20)
plot(variable(1,:),s(i,:));
elseif (i==20)
plot(variable(2,:),s(i,:));
elseif (i>=29 && i<=31)
plot(variable(3,:),s(i,:));
elseif (i>=32 && i<=41 || i==45 || i==46 || i==52)
plot(variable(4,:),s(i,:));
elseif (i==30 || i>=42 && i<=44 || i>=47 && i<=51 || i==53)
plot(variable(5,:),s(i,:));
end
grid on
xlim([0 6500]);
xlabel('Temperature');
ylabel('Entropy');
title([fin_elem(element_no),' Plot for Temperature vs Entropy']);
saveas (gcf,'entropy', 'png')
end
%Function for File Parsing Assignment
function [cp,h,s] = thermod(x,y)
r = 8.3145; %J/mol.K
cp = r.*(y(1,1)+(y(1,2).*x)+(y(1,3).*x.^2)+(y(1,4).*x.^3)+(y(1,5).*x.^4));
h = r.*x.*(y(1,1)+(y(1,2).*(x./2))+(y(1,3).*((x.^2)./3))+(y(1,4).*((x.^3)./4))+(y(1,5).*((x.^4)./5))+y(1,6)./x);
s = r.*((y(1,1)*(log(x)))+(y(1,2).*x)+(y(1,3).*((x.^2)./2))+(y(1,4).*((x.^3)./3))+(y(1,5).*((x.^4)./4))+y(1,7));
%In the function we basically recieve the values of local temperature range
%and variable values and provide specific heat, enthalpy and entropy as
%output
end