/*
Copyright (C) 2015 Philippe Miron
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "tecplotread.hpp"
tecplotread::tecplotread(string filename) :
validation_marker(0.0),
version(""),
byte_order(0),
file_type(0),
title("")
{
// open the file
file.open(filename.c_str(), ifstream::binary);
// validate opening of file
assert(file.good());
// Header section
// section i
char buffer[9];
file.read (buffer, 8);
buffer[8] = '\0';
version = string(buffer);
if (version != "#!TDV112")
cout << "Parser based on version #!TDV112, current version is: " << version << endl;
// section ii
readbin(byte_order);
// section iii
readbin(file_type);
title = ascii_to_string();
readbin(number_variables);
variable_names.resize(number_variables);
for (int i(0); izone_name = ascii_to_string();
readbin(z->parent_zone);
readbin(z->strand_id);
readbin(z->solution_time);
readbin(z->not_used);
readbin(z->zone_type);
readbin(z->data_packing);
readbin(z->var_location);
if (z->var_location == 1)
{
z->vars_location.resize(number_variables);
for (int i(0); ivars_location[i]);
}
// face neighbors
readbin(z->face_neighbors);
if (z->face_neighbors == 1)
{
readbin(z->number_face_neighbors);
if (z->number_face_neighbors != 0)
{
readbin(z->face_neighbors_mode);
if (z->zone_type >= 1 and z->zone_type <= 7 )
readbin(z->fe_face_neighbors);
}
}
// ordered zone
if (z->zone_type == 0)
{
readbin(z->imax);
readbin(z->jmax);
readbin(z->kmax);
if (z->jmax == 1 and z->kmax == 1) // 1D data
z->number_elements = (z->imax-1);
else if (z->kmax == 1) // 2D data
z->number_elements = (z->imax-1) * (z->jmax-1);
else
z->number_elements = (z->imax-1) * (z->jmax-1) * (z->kmax-1);
z->number_points = z->imax * z->jmax * z->kmax;
}
// finite element zone
if (z->zone_type >= 1 and z->zone_type <= 7)
{
readbin(z->number_points);
// only for FEPOLYGON or FEPOLYHEDRON
if (z->zone_type == 6 or z->zone_type == 7)
{
readbin(z->number_faces);
readbin(z->total_faces);
readbin(z->boundary_faces);
readbin(z->total_boundary_connections);
}
readbin(z->number_elements);
readbin(z->icell); // for future used, set to zero
readbin(z->jcell); // for future used, set to zero
readbin(z->kcell); // for future used, set to zero
}
// todo create an auxiliary structure
// add all the structures to a vector
readbin(validation_marker);
while (validation_marker == 1)
{
auxiliary* temp = new auxiliary;
temp->auxiliary_name = ascii_to_string();
readbin(temp->auxiliary_format); // only allow 0
temp->auxiliary_value = ascii_to_string();
z->auxiliaries.emplace_back(temp);
}
zones.emplace_back(z);
// read the next marker to check if
// there is more than one zone
readbin(validation_marker);
} // end of zone section
// section v
if (validation_marker == 399)
{
// read geometries
cout << "Geometry section not implemented. Stopping." << endl;
exit(-1);
}
// end of geometrie
////////////////////////
// end of header section
////////////////////////
// Data section
assert(validation_marker == 357.0);
for (size_t index(0); indexvariable_format.resize(number_variables);
for (int i(0); ivariable_format[i]);
readbin(zones[index]->has_passive_variables);
zones[index]->passive_variables.resize(number_variables, 0);
if (zones[index]->has_passive_variables)
{
for (int i(0); ipassive_variables[i]);
}
readbin(zones[index]->has_variable_sharing);
if (zones[index]->has_variable_sharing)
{
zones[index]->variable_sharing.resize(number_variables);
for (int i(0); ivariable_sharing[i]);
}
readbin(zones[index]->zone_share_connectivity); // if -1 no sharing
zones[index]->min_value.resize(number_variables);
zones[index]->max_value.resize(number_variables);
for (int i(0); imin_value[i]);
readbin(zones[index]->max_value[i]);
}
// read the data tables
zones[index]->variable_index.resize(4);
for (int i(0); ipassive_variables[i])
{
switch (zones[index]->variable_format[i])
{
case 1:
{
vector tempvalues;
read_zone_data(tempvalues, index, i);
zones[index]->data_float.emplace_back(tempvalues);
zones[index]->variable_index[0].emplace_back(i);
break;
}
case 2:
{
vector tempvalues;
read_zone_data(tempvalues, index, i);
zones[index]->data_double.emplace_back(tempvalues);
zones[index]->variable_index[1].emplace_back(i);
break;
}
case 3:
{
vector tempvalues;
read_zone_data(tempvalues, index, i);
zones[index]->data_longint.emplace_back(tempvalues);
zones[index]->variable_index[2].emplace_back(i);
break;
}
case 4:
{
vector tempvalues;
read_zone_data(tempvalues, index, i);
zones[index]->data_int.emplace_back(tempvalues);
zones[index]->variable_index[3].emplace_back(i);
break;
}
default:
{
cout << "type of data not supported: " << zones[index]->variable_format[i] << endl;
exit(-1);
break;
}
}
}
}
// TODO: complete this part
// I must say that I don't 100% understand
// this section ...
// specific to ordered zone
/*
if (zones[index]->zone_type == 0)
{
if (zones[index]->zone_share_connectivity == -1 and zones[index]->number_face_neighbors != 0)
{
// Face neighbor connections.
// N = (number of miscellaneous user defined
// face neighbor connections) * P
// (See note 5 below).
}
}
*/
// specific to fe zone
if (zones[index]->zone_type >= 1 and zones[index]->zone_type <= 7)
{
// not FEPOLYGON or FEPOLYHEDRON
if (zones[index]->zone_type != 6 or zones[index]->zone_type != 7)
{
int l(0);
if (zones[index]->zone_share_connectivity == -1)
{
// Set the number of node per element according
// to the zone type.
// 1=FELINESEG 2=FETRIANGLE 3=FEQUADRILATERAL
// 4=FETETRAHEDRON 5=FEBRICK
switch (zones[index]->zone_type)
{
case 1:
{
l = 2;
break;
}
case 2:
{
l = 3;
break;
}
case 3:
{
l = 4;
break;
}
case 4:
{
l = 4;
break;
}
case 5:
{
l = 8;
break;
}
default:
{
cout << "element type unknown << (" << zones[index]->zone_type << "), can't read connectivity." << endl;
exit(-1);
break;
}
}
read_zone_connectivity(zones[index]->zone_connectivity, index, l);
}
}
// TODO: other section to complete
// 6=FEPOLYGON 7=FEPOLYHEDRON
//else
//{
//}
}
}
};
// method to read a data type from a binary file
template
void tecplotread::readbin(T& obj) {
file.read(reinterpret_cast(addressof(obj)), sizeof(T));
}
template
void tecplotread::read_zone_data(vector& values, int zoneindex, int varindex)
{
// all variables located at nodes
if (zones[zoneindex]->var_location == 0)
{
values.resize(zones[zoneindex]->number_points);
}
else
{
// if not we have to look at the location of
// each particular variables
if (zones[zoneindex]->vars_location[varindex] == 0)
{
values.resize(zones[zoneindex]->number_points);
}
else
{
values.resize(zones[zoneindex]->number_elements);
}
}
for (size_t i(0); i
void tecplotread::read_zone_connectivity(vector& values, int zoneindex, int node_per_element)
{
// resize vector
values.resize(zones[zoneindex]->number_elements * node_per_element);
for (size_t i(0); izone_name << endl;
cout << "parent_zone: " << zones[i]->parent_zone << endl;
cout << "strand_id: " << zones[i]->strand_id << endl;
cout << "solution_time: " << zones[i]->solution_time << endl;
cout << "not_used: " << zones[i]->not_used << endl;
cout << "zone_type: " << zones[i]->zone_type << endl;
cout << "data_packing: " << zones[i]->data_packing << endl;
cout << "var_location: " << zones[i]->var_location << endl;
cout << "vars_location: " << zones[i]->vars_location << endl;
cout << "face_neighbors: " << zones[i]->face_neighbors << endl;
cout << "number_face_neighbors: " << zones[i]->number_face_neighbors << endl;
cout << "imax: " << zones[i]->imax << endl;
cout << "jmax: " << zones[i]->jmax << endl;
cout << "kmax: " << zones[i]->kmax << endl;
cout << "number_points: " << zones[i]->number_points << endl;
cout << "number_faces: " << zones[i]->number_faces << endl;
cout << "total_faces: " << zones[i]->total_faces << endl;
cout << "boundary_faces: " << zones[i]->boundary_faces << endl;
cout << "total_boundary_connections: " << zones[i]->total_boundary_connections << endl;
cout << "number_elements: " << zones[i]->number_elements << endl;
cout << "icell: " << zones[i]->icell << endl;
cout << "jcell: " << zones[i]->jcell << endl;
cout << "kcell: " << zones[i]->kcell << endl;
cout << "variable_format: " << zones[i]->variable_format << endl;
cout << "has_passive_variables: " << zones[i]->has_passive_variables << endl;
cout << "passive_variable: " << zones[i]->passive_variables << endl;
cout << "has_variable_sharing: " << zones[i]->has_variable_sharing << endl;
cout << "variable_sharing: " << zones[i]->variable_sharing << endl;
cout << "zone_share_connectivity: " << zones[i]->zone_share_connectivity << endl;
cout << "min_value: " << zones[i]->min_value << endl;
cout << "max_value: " << zones[i]->max_value << endl;
cout << "Size of the float vector: " << zones[i]->data_float.size() << endl;
for (size_t j(0); jdata_float.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[i]->variable_index[0][j]] << " " << zones[i]->data_float[j].size() << " values." << endl;
cout << "Size of the double vector: " << zones[i]->data_double.size() << endl;
for (size_t j(0); jdata_double.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[i]->variable_index[1][j]] << " " << zones[i]->data_double[j].size() << " values." << endl;
cout << "Size of the long int vector: " << zones[i]->data_longint.size() << endl;
for (size_t j(0); jdata_longint.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[i]->variable_index[2][j]] << " " << zones[i]->data_longint[j].size() << " values." << endl;
cout << "Size of the int vector: " << zones[i]->data_int.size() << endl;
for (size_t j(0); jdata_int.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[i]->variable_index[3][j]] << " " << zones[i]->data_int[j].size() << " values." << endl;
if (zones[i]->zone_share_connectivity == -1)
cout << "Size of connectivity: " << zones[i]->zone_connectivity.size() << endl;
cout << endl;
}
}
void tecplotread::zone_information(int zone_id)
{
// Validation
cout << "Information of zones: " << zone_id << endl;
cout << "version: " << version << endl;
cout << "byte_order: " << byte_order << endl;
cout << "file_type: " << file_type << endl;
cout << "title: " << title << endl;
cout << "number_variables: " << number_variables << endl;
cout << "variable_names: " << variable_names << endl;
// zone stats
cout << "zonename: " << zones[zone_id]->zone_name << endl;
cout << "parent_zone: " << zones[zone_id]->parent_zone << endl;
cout << "strand_id: " << zones[zone_id]->strand_id << endl;
cout << "solution_time: " << zones[zone_id]->solution_time << endl;
cout << "not_used: " << zones[zone_id]->not_used << endl;
cout << "zone_type: " << zones[zone_id]->zone_type << endl;
cout << "data_packing: " << zones[zone_id]->data_packing << endl;
cout << "var_location: " << zones[zone_id]->var_location << endl;
cout << "vars_location: " << zones[zone_id]->vars_location << endl;
cout << "face_neighbors: " << zones[zone_id]->face_neighbors << endl;
cout << "number_face_neighbors: " << zones[zone_id]->number_face_neighbors << endl;
cout << "imax: " << zones[zone_id]->imax << endl;
cout << "jmax: " << zones[zone_id]->jmax << endl;
cout << "kmax: " << zones[zone_id]->kmax << endl;
cout << "number_points: " << zones[zone_id]->number_points << endl;
cout << "number_faces: " << zones[zone_id]->number_faces << endl;
cout << "total_faces: " << zones[zone_id]->total_faces << endl;
cout << "boundary_faces: " << zones[zone_id]->boundary_faces << endl;
cout << "total_boundary_connections: " << zones[zone_id]->total_boundary_connections << endl;
cout << "number_elements: " << zones[zone_id]->number_elements << endl;
cout << "icell: " << zones[zone_id]->icell << endl;
cout << "jcell: " << zones[zone_id]->jcell << endl;
cout << "kcell: " << zones[zone_id]->kcell << endl;
cout << "variable_format: " << zones[zone_id]->variable_format << endl;
cout << "has_passive_variable: " << zones[zone_id]->has_passive_variables << endl;
cout << "passive_variable: " << zones[zone_id]->passive_variables << endl;
cout << "has_variable_sharing: " << zones[zone_id]->has_variable_sharing << endl;
cout << "variable_sharing: " << zones[zone_id]->variable_sharing << endl;
cout << "zone_share_connectivity: " << zones[zone_id]->zone_share_connectivity << endl;
cout << "min_value: " << zones[zone_id]->min_value << endl;
cout << "max_value: " << zones[zone_id]->max_value << endl;
cout << "Size of the float vector: " << zones[zone_id]->data_float.size() << endl;
for (size_t j(0); jdata_float.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[zone_id]->variable_index[0][j]] << " " << zones[zone_id]->data_float[j].size() << " values." << endl;
cout << "Size of the double vector: " << zones[zone_id]->data_double.size() << endl;
for (size_t j(0); jdata_double.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[zone_id]->variable_index[1][j]] << " " << zones[zone_id]->data_double[j].size() << " values." << endl;
cout << "Size of the long int vector: " << zones[zone_id]->data_longint.size() << endl;
for (size_t j(0); jdata_longint.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[zone_id]->variable_index[2][j]] << " " << zones[zone_id]->data_longint[j].size() << " values." << endl;
cout << "Size of the int vector: " << zones[zone_id]->data_int.size() << endl;
for (size_t j(0); jdata_int.size(); j++)
cout << "\t" << "[" << j << "]: " << variable_names[zones[zone_id]->variable_index[3][j]] << " " << zones[zone_id]->data_int[j].size() << " values." << endl;
if (zones[zone_id]->zone_share_connectivity == -1)
cout << "Size of connectivity: " << zones[zone_id]->zone_connectivity.size() << endl;
cout << endl;
}
tecplotread::~tecplotread()
{
// delete all the created zones
for (size_t i(0); i(&ascii), sizeof(ascii));
}
return value;
};
zone::zone() :
zone_name(""),
parent_zone(0),
strand_id(0),
solution_time(0.0),
not_used(0),
zone_type(0),
data_packing(0),
var_location(0),
face_neighbors(0),
number_face_neighbors(0),
face_neighbors_mode(0),
fe_face_neighbors(0),
imax(0),
jmax(0),
kmax(0),
number_points(0),
number_faces(0),
total_faces(0),
boundary_faces(0),
total_boundary_connections(0),
number_elements(0),
icell(0),
jcell(0),
kcell(0),
has_passive_variables(0),
has_variable_sharing(0),
zone_share_connectivity(0)
{};
int zone::getVariableFormat(int id) const {
assert(id >= 0 and id < int(variable_format.size()));
return variable_format[id];
};
vector zone::getVariableIndex(int id) const {
assert(id >= 0 and id < int(variable_index.size()));
return variable_index[id];
};
int zone::getVariableIndex(int type, int id) const {
assert(type >= 0 and type < int(variable_index.size()));
assert(id >= 0 and id < int(variable_index[type].size()));
return variable_index[type][id];
};
int zone::getPassiveVariables(int id) const {
assert(id >= 0 and id < int(passive_variables.size()));
return passive_variables[id];
};
int zone::getVariableSharing(int id) const {
assert(id >= 0 and id < int(variable_sharing.size()));
return variable_sharing[id];
};
double zone::getMinValue(int id) const {
assert(id >= 0 and id < int(min_value.size()));
return min_value[id];
};
double zone::getMaxValue(int id) const {
assert(id >= 0 and id < int(max_value.size()));
return max_value[id];
};
int zone::getVarsLocation(int id) const {
assert(id >= 0 and id < int(vars_location.size()));
return vars_location[id];
};
vector zone::getDataFloat(int id) const {
assert(id >= 0 and id < int(data_float.size()));
return data_float[id];
};
vector zone::getDataDouble(int id) const {
assert(id >= 0 and id < int(data_double.size()));
return data_double[id];
};
vector zone::getDataLongInt(int id) const {
assert(id >= 0 and id < int(data_longint.size()));
return data_longint[id];
};
vector zone::getDataInt(int id) const {
assert(id >= 0 and id < int(data_int.size()));
return data_int[id];
};
auxiliary::auxiliary() :
auxiliary_name(""),
auxiliary_format(-1),
auxiliary_value("")
{};