This is a function from a program I am working on for my internship, which involves research in computational science. I have some text files with reference data in a directory data/
with name e.g. AR00.1 that look like this:
90.000 73.629
120.00 98.338
150.00 123.00
180.00 147.64
210.00 172.28
...
The function works, with output as expected. I am fairly new to C++ and programming in general (had a little less than a year of C before I started with C++.) Am I doing things efficiently (i.e. loading all of the data into memory at once and calling it when needed) or is there a better way to access this data? The part that seems messiest to me is the nested vectors, though I can't think of another way to do them as I've no formal education in data structures.
In any case, here is a minimum example of the function with an arbitrary main function to show my usage. Thank you for taking the time to read and review this!
//includes go here
struct reference_data
{
double temperature,
volume_l_mol,
volume_m3,
compressibility;
};
using namespace std;
vector<vector<vector<reference_data>>> read_reference_data(vector<string> species, vector<string> pressure_strings);
int main()
{
vector<string> species = {"AR","CH4","CO2","H2","HE","KR","N2","NE","XE"};
vector<string> pressures = {"00.1", "001", "005", "010", "020", "030"};
vector<vector<vector<reference_data>>> NIST_data = read_reference_data(species,pressures);
cout << NIST_data[0][0][0].temperature //90 for above data example
return 0;
}
vector<vector<vector<reference_data>>> read_reference_data(vector<string> species, vector<string> pressure_strings)
{
vector<double> pressure_floats = {00.1, 001, 005, 010, 020, 030};
// ALL->SPECIES->PRES->STATE POINTS
vector<vector<vector<reference_data>>> NIST_data;
for(unsigned long species_ind = 0;species_ind<species.size();species_ind++)
{
//SPECIES->PRES->STATE POINTS
vector<vector<reference_data>> this_species;
string a_line;
for(auto pressure_ind= 0; pressure_ind < pressure_strings.size(); pressure_ind++)
{
string file_name = "data/";
file_name += species[species_ind];
file_name += pressure_strings[pressure_ind];
ifstream input(file_name);
if(input.is_open())
{
//PRES->STATE POINTS
vector<reference_data> this_pressure;
while (getline(input, a_line))
{
vector<string> this_line;
istringstream iss(a_line);
//copy the numbers of interest from the line into the vector this_line (thanks Doug / SO !)
copy(
istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(this_line)
);
if(this_line.size())
{
//STATE_POINT (we made it!)
reference_data this_point;
this_point.temperature = atof(this_line[0].c_str());
this_point.volume_l_mol = atof(this_line[1].c_str());
double liters = this_point.volume_l_mol*MOLES;
this_point.volume_m3 = liters / 1000.0;
this_point.compressibility = get_compressibility(this_point.temperature,
pressure_floats[pressure_ind],
this_point.volume_m3);
this_pressure.push_back(this_point);//add current temperature to the pressure it corresponds to
}
else
{
cerr << "Data line in read_reference_data() is empty--check your input file"
<< endl;
}
}
this_species.push_back(this_pressure);//add current pressure to species it corresponds to
}
else
{
cerr << "Error in opening file " << file_name
<< " in read_reference_data()" << endl;
}
input.close();
}
NIST_data.push_back(this_species);//add current species to all data
}
return NIST_data;
}