39 #include "TrianglesMeshReader.hpp" 42 static const char* NODES_FILE_EXTENSION =
".node";
43 static const char* ELEMENTS_FILE_EXTENSION =
".ele";
44 static const char* FACES_FILE_EXTENSION =
".face";
45 static const char* EDGES_FILE_EXTENSION =
".edge";
46 static const char* NCL_FILE_EXTENSION =
".ncl";
47 static const char* CABLE_FILE_EXTENSION =
".cable";
53 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
55 unsigned orderOfElements,
56 unsigned orderOfBoundaryElements,
57 bool readContainingElementForBoundaryElements)
58 : mFilesBaseName(pathBaseName),
68 mCableElementsRead(0),
70 mBoundaryFacesRead(0),
72 mNumNodeAttributes(0),
73 mNumElementAttributes(0),
74 mNumFaceAttributes(0),
75 mNumCableElementAttributes(0),
76 mOrderOfElements(orderOfElements),
77 mOrderOfBoundaryElements(orderOfBoundaryElements),
79 mReadContainingElementOfBoundaryElement(readContainingElementForBoundaryElements),
80 mFilesAreBinary(false),
81 mMeshIsHexahedral(false),
82 mNodeFileReadBuffer(nullptr),
83 mElementFileReadBuffer(nullptr),
84 mFaceFileReadBuffer(nullptr),
85 mNodePermutationDefined(false)
88 assert(orderOfElements==1 || orderOfElements==2);
91 EXCEPTION(
"Boundary element file should not have containing element info if it is quadratic");
99 assert(SPACE_DIM==ELEMENT_DIM);
109 assert(SPACE_DIM==ELEMENT_DIM);
119 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
127 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
133 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
139 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
145 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
151 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
157 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
163 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
169 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
186 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
189 std::vector<double> ret_coords(SPACE_DIM);
198 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
205 std::vector<double> element_attributes;
219 for (std::vector<unsigned>::iterator node_it = element_data.
NodeIndices.begin();
231 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
238 std::vector<double> cable_element_attributes;
264 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
268 std::vector<unsigned> ret_indices;
271 if (ELEMENT_DIM == 1)
279 assert(ELEMENT_DIM != 0);
284 std::vector<double> face_attributes;
290 if (face_attributes.size() > 0)
318 for (std::vector<unsigned>::iterator node_it = ret_indices.begin();
319 node_it != ret_indices.end();
332 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
337 EXCEPTION(
"Random access is only implemented in mesh readers for binary mesh files.");
341 EXCEPTION(
"Node does not exist - not enough nodes.");
367 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
372 EXCEPTION(
"Random access is only implemented in mesh readers for binary mesh files.");
376 EXCEPTION(
"Element " << index <<
" does not exist - not enough elements (only " <<
mNumElements <<
").");
396 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
401 EXCEPTION(
"Random access is only implemented in mesh readers for binary mesh files.");
405 EXCEPTION(
"Face does not exist - not enough faces.");
429 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
434 EXCEPTION(
"NCL file functionality is only implemented in mesh readers for binary mesh files.");
439 EXCEPTION(
"No NCL file available for this mesh.");
443 EXCEPTION(
"Connectivity list does not exist - not enough nodes.");
465 std::vector<unsigned> containing_element_indices;
468 std::vector<double> dummy;
475 while ( containing_element_indices[num_containing_elements-1] == UINT_MAX )
477 num_containing_elements--;
480 containing_element_indices.resize(num_containing_elements);
482 return containing_element_indices;
485 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
495 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
500 mNodesFile.open(file_name.c_str(), std::ios::binary);
503 EXCEPTION(
"Could not open data file: " + file_name);
507 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
511 std::string file_name;
512 if (ELEMENT_DIM == SPACE_DIM)
518 if (ELEMENT_DIM == 1)
522 else if (ELEMENT_DIM == 2)
528 EXCEPTION(
"Can't have a zero-dimensional mesh in a one-dimensional space");
535 EXCEPTION(
"Could not open data file: " + file_name);
539 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
543 std::string file_name;
544 if (ELEMENT_DIM == 3)
548 else if (ELEMENT_DIM == 2)
558 mFacesFile.open(file_name.c_str(), std::ios::binary);
561 EXCEPTION(
"Could not open data file: " + file_name);
565 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
569 mNclFile.open(file_name.c_str(), std::ios::binary);
574 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
586 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
592 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
600 std::stringstream node_header_line(buffer);
603 if (SPACE_DIM != dimension)
605 EXCEPTION(
"SPACE_DIM != dimension read from file ");
610 node_header_line >> extras;
627 std::stringstream node_first_line(buffer);
628 unsigned first_index;
629 node_first_line >> first_index;
630 assert(first_index == 0 || first_index == 1);
643 std::stringstream element_header_line(buffer);
645 unsigned extra_attributes = 0;
647 if (ELEMENT_DIM == SPACE_DIM)
654 std::string element_extras;
655 element_header_line >> element_extras;
656 if (element_extras ==
"BIN")
661 else if (element_extras ==
"HEX")
664 if (ELEMENT_DIM == 2)
669 if (ELEMENT_DIM == 3)
677 assert (element_extras ==
"");
686 <<
"expected number, " <<
mNodesPerElement <<
" (which is calculated given " 687 <<
"the order of elements chosen, " <<
mOrderOfElements <<
" (1=linear, 2=quadratics)");
698 if (ELEMENT_DIM == 1 || ELEMENT_DIM == 2)
704 std::string element_extras;
705 element_header_line >> element_extras;
706 if (element_extras ==
"BIN")
727 if (ELEMENT_DIM == 1)
735 std::stringstream face_header_line(buffer);
738 assert(mNumFaceAttributes==0 || mNumFaceAttributes==1);
745 std::string face_extras;
746 face_header_line >> face_extras;
748 if (mNumFaceAttributes==1)
750 unsigned num_boundary_faces = 0;
751 bool end_of_file=
false;
757 num_boundary_faces++;
803 std::stringstream ncl_header_line(buffer);
804 unsigned num_nodes_in_file;
809 EXCEPTION(
"NCL file does not contain the correct number of nodes for mesh");
822 std::stringstream cable_header_line(buffer);
823 unsigned num_nodes_per_cable_element;
825 assert(num_nodes_per_cable_element == 2u);
830 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
840 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
847 getline(rFileStream, rRawLine,
'\n');
848 if (rFileStream.eof())
851 EXCEPTION(
"File contains incomplete data: unexpected end of file.");
855 rRawLine = rRawLine.substr(0, rRawLine.find(
'#',0));
857 line_is_blank = (rRawLine.find_first_not_of(
" \t",0) == std::string::npos);
859 while (line_is_blank);
862 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
863 template<
class T_DATA>
865 std::vector<T_DATA>& rDataPacket,
const unsigned& rNumAttributes, std::vector<double>& rAttributes)
869 if (!rDataPacket.empty())
871 rFileStream.read((
char*)&rDataPacket[0], rDataPacket.size()*
sizeof(T_DATA));
873 if (rNumAttributes > 0)
875 for (
unsigned i = 0; i < rNumAttributes; i++)
878 rFileStream.read((
char*) &attribute,
sizeof(
double));
879 rAttributes.push_back(attribute);
887 std::stringstream buffer_stream(buffer);
890 buffer_stream >> item_index;
895 if (item_index != expectedItemNumber)
900 expectedItemNumber--;
902 EXCEPTION(
"Data for item " << expectedItemNumber <<
" missing");
905 for (
unsigned i=0; i<rDataPacket.size(); i++)
907 buffer_stream >> rDataPacket[i];
910 if (rNumAttributes > 0)
912 for (
unsigned i = 0; i < rNumAttributes; i++)
915 buffer_stream >> attribute;
916 if (buffer_stream.fail())
918 EXCEPTION(
"Error in reading attribute index " << i <<
" (out of " << rNumAttributes <<
") in one of the files in " <<
mFilesBaseName);
920 rAttributes.push_back(attribute);
926 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
932 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
935 assert(ELEMENT_DIM == 1);
942 std::vector<unsigned> node_indices(2);
943 std::vector<double> dummy_attribute;
946 std::vector<unsigned> node_count(
mNumNodes);
947 for (
unsigned element_index=0; element_index<
mNumElements;element_index++)
956 node_count[node_indices[0]]++;
957 node_count[node_indices[1]]++;
961 for (
unsigned node_index=0; node_index<
mNumNodes;node_index++)
963 if (node_count[node_index] == 1u)
977 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
982 for (
unsigned i=0; i<rNodeIndices.size(); i++)
989 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
995 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1001 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1013 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1019 EXCEPTION(
"Permuted read can only be used with binary files since it requires random access to the node file.");
1031 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1040 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
unsigned mNumNodeAttributes
ElementData GetNextCableElementData()
std::vector< unsigned > mPermutationVector
unsigned GetNumFaceAttributes() const
unsigned GetNumNodes() const
bool mReadContainingElementOfBoundaryElement
std::ifstream mCableElementsFile
std::streampos mElementFileDataStart
std::streampos mFaceFileDataStart
unsigned ContainingElement
void GetNextLineFromStream(std::ifstream &rFileStream, std::string &rRawLine)
unsigned mNumElementAttributes
char * mFaceFileReadBuffer
#define EXCEPTION(message)
TrianglesMeshReader(std::string pathBaseName, unsigned orderOfElements=1, unsigned orderOfBoundaryElements=1, bool readContainingElementsForBoundaryElements=false)
std::vector< unsigned > GetContainingElementIndices(unsigned index)
unsigned GetNumElementAttributes() const
unsigned GetNumCableElementAttributes() const
unsigned GetNumCableElements() const
unsigned mNodesPerElement
unsigned GetNumElements() const
std::streamoff mElementItemWidth
std::vector< unsigned > NodeIndices
bool IsFileFormatBinary()
ElementData GetNextElementData()
unsigned mNumFaceAttributes
std::vector< double > mNodeAttributes
std::string mFilesBaseName
void SetNodePermutation(std::vector< unsigned > &rPermutationVector)
std::streampos mNodeFileDataStart
void SetReadBufferSize(unsigned bufferSize)
unsigned mCableElementsRead
char * mNodeFileReadBuffer
std::streamoff mFaceItemWidth
unsigned mOrderOfBoundaryElements
unsigned mMaxNodeBdyMarker
std::streampos mNclFileDataStart
std::streamoff mNodeItemWidth
unsigned mBoundaryFacesRead
std::vector< double > GetNextNode()
std::ifstream mElementsFile
void EnsureIndexingFromZero(std::vector< unsigned > &rNodeIndices)
char * mElementFileReadBuffer
void OpenCableElementsFile()
unsigned mOrderOfElements
bool HasNodePermutation()
ElementData GetFaceData(unsigned index)
unsigned GetNumFaces() const
ElementData GetNextFaceData()
const std::vector< unsigned > & rGetNodePermutation()
unsigned mNumElementNodes
bool mNodePermutationDefined
std::vector< unsigned > mInversePermutationVector
std::streamoff mNclItemWidth
unsigned mNumCableElements
unsigned mNodesPerBoundaryElement
std::string GetMeshFileBaseName()
unsigned mNumCableElementAttributes
std::vector< double > GetNodeAttributes()
void GetNextItemFromStream(std::ifstream &rFileStream, unsigned expectedItemNumber, std::vector< T_DATA > &rDataPacket, const unsigned &rNumAttributes, std::vector< double > &rAttributes)
std::vector< double > GetNode(unsigned index)
ElementData GetElementData(unsigned index)
std::vector< unsigned > mOneDimBoundary
unsigned mMaxContainingElements