Challenge

Project 1 - Parsing NASA thermodynamic data

1) Aim

Write a code to

1.Extract the 14 coefficients and calculates the enthalpy, entropy and specific heats for all the species in the data file. The formulae are shown below.

Here R is the universal gas constant, T is the temperature

The first 7 coefficients are high-temperature coefficients and the second 7 coefficients are low-temperature coefficients.

2. Calculate the molecular weight of each species and display same in the command window

3. Plot the Cp, Enthalpy, and Entropy for the local temperature range specified for each species.

4. Save the plots as images with appropriate names and dump them in separate folders for each species with a suitable name through codes.

2) Theory

1) Data Parsing

Parsing is defined as "the analysis of input to organize the data according to the rule of grammar." It can be defined in many ways. However, the gist word remains the same: parsing means to find the underlying structure of the data we are given. Fundamentally, parsing is necessary because different entities need the data to be in different forms. Parsing allows transforming data in a way that can be understood by specific software.

2) Syntaxes used:

fopen('filename.format','r')- Open the file with the specified name and read the data within it

fgetl(filename)- returns the next line of the specified file, removing the newline characters. By default it reads the first line inscribed in a file of a particular format.

strsplit-Split string or character vector at specified delimiter. By taking a particular entity as a reference a split can be made

strfind- Used for searching a particular string with a string array

str2num- Used to convert a string into a number

cd-Change current folder

mkdir-This MATLAB function creates the folder and folderName

savefig- Saves a figure to a specified format

3) Thermodynamic properties

The given data file contains thermodynamic properties such as Specific heat (Cp), Enthalpy (H) and Entropy(S). They have also documented the coefficients that are required to evaluate these polynomials for 1000+ species.

Specific heat (Cp) -Specific heat capacity is the amount of heat energy required to raise the temperature of a substance per unit mass. In a way it is also called as sensible heating ( does not induce a phase change). Cp means at constant pressure

Enthalpy (H)-The sum of the internal energy of the system plus the product of the pressure of the gas in the system and its volume.

Entropy (S)- It is the measure of a system's thermal energy per unit temperature that is unavailable for doing useful work.

R-Universal gas constant

Units

Specific heat (Cp)-Joules per kilogram and Kelvin [J kg-1 K-1]

Enthalpy (H)- Joules or KiloJoules ( J or Kj

Entropy (S)- joules per kelvin (J⋅K−1)

Dependence of the above-mentioned properties with respect to temperature:

3) Explanation of code used

f1=fopen('THERMO.dat','r')

fopen command is used the open the thermo data file and r represents the read format

%fgetl(fileID) returns the next line of the specified file
% by default it takes first line
     get=fgetl(f1);
     

% first line of data files features three global temperature temperature
% and is split
 temp=fgetl(f1);
 temp_sp=strsplit(temp);

The second line of the data file represents global temperature values which has to be read. To read the required line two fgetl commands are used and upon reading the second line the data which is in form of the string and is stored in a variable called as temp. The temp variable is then split using string split command and stored in variable called as temp_sp.

% command to convert string in cell array to number
 global_low_temp=str2num(temp_sp{2});
 global_mid_temp=str2num(temp_sp{3});
 global_high_temp=str2num(temp_sp{4}); % creating an array of temperature extractted
 Temp=linspace(global_low_temp,global_high_temp,1000);

The temp_sp variable contains three global temperatures that constitute a cell. Each of these is converted into number format by str2num and the lower, middle and high temperatures are stored in separate variables named as global_low_temperature,global_mid_temperature, and global_high_temperature. An array containing 1000 temperature values spread between global_low_temperature and global_high_temperature is created with linspace command.

% skipping intial comments in data file
 for i = 1:3
      get=fgetl(f1);
      
  end

The data file contains comments which is skipped by using fgetl command within a for loop for a loop counter variable called as i which skips from line after global temperatures value till the next required line.

for j=1:53
      tline=fgetl(f1);
 %splitting the cell array
     A=strsplit(tline,' ');
 % reading name of species
     species=A{1};
     low_temp=str2num(A{end-3});
     mid_temp=str2num(A{end-2});
     high_temp=str2num(A{end-1});
  % initiating a search on next line
     tline_1=fgetl(f1);
  % there exists a string E in each line which is used as base for string
  %split string search to find higher coefficient
 % a1 to a7 are  higher temperature coefficients
     a_s=strfind(tline_1,'E');
     a_s_1=tline_1(1:a_s(1)+3);
     a_s_1=str2num(a_s_1);
     a_s_2=tline_1(a_s(1)+4:a_s(2)+3);
     a_s_2=str2num(a_s_2);
     a_s_3=tline_1(a_s(2)+4:a_s(3)+3);
     a_s_3=str2num(a_s_3);
     a_s_4=tline_1(a_s(3)+4:a_s(4)+3);
     a_s_4=str2num(a_s_4);
     a_s_5=tline_1(a_s(4)+4:a_s(5)+3);
     a_s_5=str2num(a_s_5);
      
     tline_2=fgetl(f1);
     b_s=strfind(tline_2,'E');
     a_s_6=tline_2(1:b_s(1)+3);
     a_s_6=str2num(a_s_6);
     a_s_7=tline_2(b_s(1)+4:b_s(2)+3);
     a_s_7=str2num(a_s_7);
  %a8 to a14 are  higher temperature coefficients
     a_s_8=tline_2(b_s(2)+4:b_s(3)+3);
     a_s_8=str2num(a_s_8);
     a_s_9=tline_2(b_s(3)+4:b_s(4)+3);
     a_s_9=str2num(a_s_9);
     a_s_10=tline_2(b_s(4)+4:b_s(5)+3);
     a_s_10=str2num(a_s_10);
  
     tline_3=fgetl(f1);
     c_s=strfind(tline_3,'E');
     a_s_11=tline_3(1:c_s(1)+3);
     a_s_11=str2num(a_s_11);
     a_s_12=tline_3(c_s(1)+4:c_s(2)+3);
     a_s_12=str2num(a_s_12);
     a_s_13=tline_3(c_s(2)+4:c_s(3)+3);
     a_s_13=str2num(a_s_13);
     a_s_14=tline_3(c_s(3)+4:c_s(4)+3);
     a_s_14=str2num(a_s_14);

a for loop is started to retrieve essential data about species from next 53 lines. A loop counter variable j is assigned from the previous required line for next 53 line.For each value of i a line is read with getline command that is stored in a variable called as tline. For each iteration the cell is split using strsplit and stored in a variable defined as A. The data file is in such a way that for each of these 53 iteration the species name is at first from left.

For each of the species, there is a low temperature, high temperature and mid-value of temperature which is positioned at end of each line. Three variables namely low_temp,mid_temp, and high_temp are defined and its position is found with required command A{end-3}, A{end-2} and A{end-1} converted to numbers and stored in the respective variables. A search is initiated on next line for 53 iterations ie line after one which contains species names and stored in tline_1. A string search on same line is done to locate 'E'. Strfind of E is done on tline_1 and the position of it is stored in a variable called a_s. The required value of the coefficient is accessed 'tline_1(1:a_s(1)+3' ( the point of location of E and taking it as 1 till a_s(1)+3 is stored ) in a variable called as a_s_1. The string is then converted to a number and stored in a_s_1. The same is done to evaluate coefficients up to a5. Between two lines that contain species name, there are 3 lines that contain data about the thermodynamic coefficient. tline_1 represents line after one that contains species name. Similar to above a string search for 'E' is done on next two lines and there by evaluating the coefficients. These two variables are used : t_line2 and t_line3 and the input argument of fgetl is used. The position of 'E' is found by strfind and stored in variables b_s and c_s. As done earlier the required coefficients are found with 'E' as base and converted to number format.a6 to a10 is evaluated from 2nd line and a11 to a14 is found from 3 after the line that contains species name.

for x = 1:length(Temp)
         if(Temp<=global_mid_temp)
            S=R*Temp(a_s_8.*log(Temp)+(a_s_9*Temp)+((a_s_10*(Temp).^2)/2)+((a_s_11*(Temp).^3)/3)+((a_s_12*(Temp).^4)/4)+a_s_14);
         else
            S=R*(a_s_1.*log(Temp)+(a_s_2*Temp)+((a_s_3*(Temp).^2)/2)+((a_s_4*(Temp).^3)/3)+((a_s_5*(Temp).^4)/4)+a_s_7); 
         end
     end
         
     for y = 1:length(Temp)
          if (Temp<=global_mid_temp)
            H=R.*Temp.*(a_s_8+((a_s_9*Temp)./2)+((a_s_10*(Temp).^2)./3)+((a_s_11*(Temp).^3)./4)+((a_s_12*(Temp).^4)./5)+(a_s_13)./Temp);
        
          else
            H=R.*Temp.*(a_s_1+((a_s_2*Temp)./2)+((a_s_3*(Temp).^2)./2)+((a_s_4*(Temp).^3)./3)+((a_s_5*(Temp).^4)./4)+(a_s_6)./Temp); 
          end
     end
     
     for z= 1:length(Temp)
         if(Temp<=global_mid_temp)
            cp=R*(a_s_8+(a_s_9*Temp)+(a_s_10*(Temp).^2)+(a_s_11*(Temp).^3)+(a_s_12*(Temp).^4));
         else
            cp=R*(a_s_1+(a_s_2*Temp)+(a_s_3*(Temp).^2)+(a_s_4*(Temp).^3)+(a_s_5*(Temp).^4)); 
         end
     end

Three for loops are initiated each having loop index variable x,y,z to find S,H, and Cp. The loop index variables scan through 'Temp' which a variable defined earlier that contains 1000 values of temperature between low_global_temp and high global temp. A comparison statement is initiated with an if and else loop with for loop such that if loop works if the Temp is less than global_mid_temp and else works if the temperature is otherwise. By doing so all required coefficients are evaluated.All this happens for each species as the loop iterates between 1 to 53

% plotting Cp Vs T, S Vs T & H Vs T
 % Creating file separately and saving
   cd('C:\Users\Skill__Lync\Documents\MATLAB\Dataparsing_Final_Project')
   % creating a species directory
   mkdir(species);
   
   cd(species);
 
 figure(1)
 plot(Temp,cp,'linewidth',3,'color','r')
 xlabel('Temperature in K')
 ylabel('Specific heat in KJ')
 title(sprintf('Specific heat Vs Temperature range of %s',species));
 grid on
 saveas(figure(1),'Specific heat.jpg')
 figure(2)
 plot(Temp,S,'linewidth',3,'color','b')
 xlabel('Temperature in K')
 ylabel('Entropy in KJ/mol-K')
 title(sprintf('Entropy Vs Temperature range of %s',species));
 grid on
 saveas(figure(2),'Entropy.jpg')   
 figure(3)
 plot(Temp,H,'linewidth',3,'color','b')
 xlabel('Temperature in K')
 ylabel('Enthalpy in KJ/mol')
 title(sprintf('Enthalpy Vs Temperature range of %s',species));
 grid on
 saveas(figure(3),'Enthalpy.jpg')    

The code is written in such a way that a separate folder is created for each species to save the plots of entropy, enthalpy, and specific heat. But as the loop iterates the plot for a successive species must not be saved in the previous folder. The figures are plotted figure 1 for cp vs temperature, figure 2 for entropy vs temperature and figure 3 for enthalpy vs temperature. After each set of figure-plot command saves command is done as cp.jpg,entropt.jpg and enthalpy.jpg to save all three plots for each species in its respective folder as defined previously.

 molecular_weight = molecular_mass(species);
 
 
  end   
 
function Mol = molecular_mass(species_name)
 


%Defining atomic names of species and their respective atomic weights
Atoms = ['H','C', 'N', 'O','A'];
Atomic_weight = [1,12,14,16,40];
Mol=0;

for i = 1:length(species_name) % loop scans through length of species
for j = 1:length(Atoms) %nested for loop scans through length of atomiv names
if strcmp(species_name(i),Atoms(j)) % two strings are compared
Mol= Mol+ Atomic_weight(j);
position = j;
end
end
n = str2num(species_name(i)); % checks whether a species contain more than one element or atom and increment is done
if(n>1)
Mol= Mol +Atomic_weight(position)*(n-1);
end
end


% end
  sprintf('Molecular weight of %s:%f u',species_name,Mol)
 end

The molecular weight which has to be found called by creating a separate user-defined function and the loop is closed.

1) An array called as atoms is defined

2) Another array called as atomic weight which has atomic weights of H,C,N,O,A is defined

3) A variable called as mol is defined and assigned a value of 0

4) A for loop is started that scans across species name

5) A nested for loop is created which scans across the string array that is defined as atom

6) An if condition is created used to compare species_name and the string atoms

7) strcmp command is used to find molecular weight upon the comparison.

8)If both strings are found to be same,the molecular weight is assigned

9)string is converted to number and assigned to a variable called n

10) if loop searches whether the species contain more than a string 'like H2O','CO2' if found n>1

11) The Mol(variable for total molecular mass) is found by multiplying atomic weight with position and n-1.

12) The loops are closed and sprint f command is used to display is species and its corresponding mass

4) Output

Plots for O2,CO2 and N2

Error encountered

There was a recurring error in nested for loops used to find molecular mass which was due to a variable. It was showing in such a way that even when position variable was assigned for mass where not calculated properly

Complete code : code for finding coefficient

clear all
close all
clc
% Input is value of R which is universal gas constant
R=8.314;
% Program to read the given thermodynamic data file
% fopen coomand opens the file and is stored in a varible called f1
f1=fopen('THERMO.dat','r');
%fgetl(fileID) returns the next line of the specified file
% by default it takes first line
     get=fgetl(f1);
     

% first line of data files features three global temperature temperature
% and is split
 temp=fgetl(f1);
 temp_sp=strsplit(temp);
 % command to convert string in cell array to number
 global_low_temp=str2num(temp_sp{2});
 global_mid_temp=str2num(temp_sp{3});
 global_high_temp=str2num(temp_sp{4}); % creating an array of temperature extractted
 Temp=linspace(global_low_temp,global_high_temp,1000);
 % skipping intial comments in data file
 for i = 1:3
      get=fgetl(f1);
      
  end
  for j=1:53
      tline=fgetl(f1);
 %splitting the cell array
     A=strsplit(tline,' ');
 % reading name of species
     species=A{1};
     low_temp=str2num(A{end-3});
     mid_temp=str2num(A{end-2});
     high_temp=str2num(A{end-1});
  % initiating a search on next line
     tline_1=fgetl(f1);
  % there exists a string E in each line which is used as base for string
  %split string search to find higher coefficient
 % a1 to a7 are  higher temperature coefficients
     a_s=strfind(tline_1,'E');
     a_s_1=tline_1(1:a_s(1)+3);
     a_s_1=str2num(a_s_1);
     a_s_2=tline_1(a_s(1)+4:a_s(2)+3);
     a_s_2=str2num(a_s_2);
     a_s_3=tline_1(a_s(2)+4:a_s(3)+3);
     a_s_3=str2num(a_s_3);
     a_s_4=tline_1(a_s(3)+4:a_s(4)+3);
     a_s_4=str2num(a_s_4);
     a_s_5=tline_1(a_s(4)+4:a_s(5)+3);
     a_s_5=str2num(a_s_5);
      
     tline_2=fgetl(f1);
     b_s=strfind(tline_2,'E');
     a_s_6=tline_2(1:b_s(1)+3);
     a_s_6=str2num(a_s_6);
     a_s_7=tline_2(b_s(1)+4:b_s(2)+3);
     a_s_7=str2num(a_s_7);
  %a8 to a14 are  higher temperature coefficients
     a_s_8=tline_2(b_s(2)+4:b_s(3)+3);
     a_s_8=str2num(a_s_8);
     a_s_9=tline_2(b_s(3)+4:b_s(4)+3);
     a_s_9=str2num(a_s_9);
     a_s_10=tline_2(b_s(4)+4:b_s(5)+3);
     a_s_10=str2num(a_s_10);
  
     tline_3=fgetl(f1);
     c_s=strfind(tline_3,'E');
     a_s_11=tline_3(1:c_s(1)+3);
     a_s_11=str2num(a_s_11);
     a_s_12=tline_3(c_s(1)+4:c_s(2)+3);
     a_s_12=str2num(a_s_12);
     a_s_13=tline_3(c_s(2)+4:c_s(3)+3);
     a_s_13=str2num(a_s_13);
     a_s_14=tline_3(c_s(3)+4:c_s(4)+3);
     a_s_14=str2num(a_s_14);
       
     for x = 1:length(Temp)
         if(Temp<=global_mid_temp)
            S=R*Temp(a_s_8.*log(Temp)+(a_s_9*Temp)+((a_s_10*(Temp).^2)/2)+((a_s_11*(Temp).^3)/3)+((a_s_12*(Temp).^4)/4)+a_s_14);
         else
            S=R*(a_s_1.*log(Temp)+(a_s_2*Temp)+((a_s_3*(Temp).^2)/2)+((a_s_4*(Temp).^3)/3)+((a_s_5*(Temp).^4)/4)+a_s_7); 
         end
     end
         
     for y = 1:length(Temp)
          if (Temp<=global_mid_temp)
            H=R.*Temp.*(a_s_8+((a_s_9*Temp)./2)+((a_s_10*(Temp).^2)./3)+((a_s_11*(Temp).^3)./4)+((a_s_12*(Temp).^4)./5)+(a_s_13)./Temp);
        
          else
            H=R.*Temp.*(a_s_1+((a_s_2*Temp)./2)+((a_s_3*(Temp).^2)./2)+((a_s_4*(Temp).^3)./3)+((a_s_5*(Temp).^4)./4)+(a_s_6)./Temp); 
          end
     end
     
     for z= 1:length(Temp)
         if(Temp<=global_mid_temp)
            cp=R*(a_s_8+(a_s_9*Temp)+(a_s_10*(Temp).^2)+(a_s_11*(Temp).^3)+(a_s_12*(Temp).^4));
         else
            cp=R*(a_s_1+(a_s_2*Temp)+(a_s_3*(Temp).^2)+(a_s_4*(Temp).^3)+(a_s_5*(Temp).^4)); 
         end
     end
     
 % plotting Cp Vs T, S Vs T & H Vs T
 % Creating file separately and saving
   cd('C:\Users\Skill__Lync\Documents\MATLAB\Dataparsing_Final_Project')
   % creating a species directory
   mkdir(species);
   
   cd(species);
 
 figure(1)
 plot(Temp,cp,'linewidth',3,'color','r')
 xlabel('Temperature in K')
 ylabel('Specific heat in KJ')
 title(sprintf('Specific heat Vs Temperature range of %s',species));
 grid on
 saveas(figure(1),'Specific heat.jpg')
 figure(2)
 plot(Temp,S,'linewidth',3,'color','b')
 xlabel('Temperature in K')
 ylabel('Entropy in KJ/mol-K')
 title(sprintf('Entropy Vs Temperature range of %s',species));
 grid on
 saveas(figure(2),'Entropy.jpg')   
 figure(3)
 plot(Temp,H,'linewidth',3,'color','b')
 xlabel('Temperature in K')
 ylabel('Enthalpy in KJ/mol')
 title(sprintf('Enthalpy Vs Temperature range of %s',species));
 grid on
 saveas(figure(3),'Enthalpy.jpg')      
 
 molecular_weight = molecular_mass(species);
 
 
  end   
 
 
 
         
         
         
         
         
 

User defined function for calculating molecular mass of species:

function Mol = molecular_mass(species_name)
 


%Defining atomic names of species and their respective atomic weights
Atoms = ['H','C', 'N', 'O','A'];
Atomic_weight = [1,12,14,16,40];
Mol=0;

for i = 1:length(species_name) % loop scans through length of species
for j = 1:length(Atoms) %nested for loop scans through length of atomiv names
if strcmp(species_name(i),Atoms(j)) % two strings are compared
Mol= Mol+ Atomic_weight(j);
position = j;
end
end
n = str2num(species_name(i)); % checks whether a species contain more than one element or atom and increment is done
if(n>1)
Mol= Mol +Atomic_weight(position)*(n-1);
end
end


% end
  sprintf('Molecular weight of %s:%f u',species_name,Mol)
 end

References

1) https://www.sciencedirect.com/topics/computer-science/data-parsing

2) Mathworks for syntax definition creating folders and change directory, different string commands

3) http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html

4) http://www.ece.northwestern.edu/local-apps/matlabhelp/techdoc/ref/mkdir.html

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.