36 #include "FibreReader.hpp"
41 template<
unsigned DIM>
43 : mFileIsBinary(false),
46 if (fibreFileType == AXISYM)
67 template<
unsigned DIM>
73 template<
unsigned DIM>
76 assert(direction.empty());
77 if (mNumItemsPerLine != DIM)
79 EXCEPTION(
"Use GetAllOrtho when reading orthotropic fibres");
81 direction.reserve(mNumLinesOfData);
82 for (
unsigned i=0; i<mNumLinesOfData; i++)
84 c_vector<double, DIM> temp_vector;
85 GetFibreVector(i, temp_vector,
false);
86 direction.push_back(temp_vector);
90 template<
unsigned DIM>
92 std::vector< c_vector<double, DIM> >& second_direction,
93 std::vector< c_vector<double, DIM> >& third_direction)
95 assert(first_direction.empty());
96 assert(second_direction.empty());
97 assert(third_direction.empty());
98 if (mNumItemsPerLine != DIM*DIM)
100 EXCEPTION(
"Use GetAllAxi when reading axisymmetric fibres");
102 for (
unsigned i=0; i<mNumLinesOfData; i++)
104 c_matrix<double, DIM, DIM> temp_matrix;
105 GetFibreSheetAndNormalMatrix(i, temp_matrix,
true);
109 matrix_column<c_matrix<double, DIM, DIM> > col0(temp_matrix, 0);
110 first_direction.push_back(col0);
113 matrix_column<c_matrix<double, DIM, DIM> > col1(temp_matrix, 1);
114 second_direction.push_back(col1);
118 matrix_column<c_matrix<double, DIM, DIM> > col2(temp_matrix, 2);
119 third_direction.push_back(col2);
124 template<
unsigned DIM>
126 c_matrix<double,DIM,DIM>& rFibreMatrix,
127 bool checkOrthogonality)
129 if (mNumItemsPerLine != DIM*DIM)
131 EXCEPTION(
"Use GetFibreVector when reading axisymmetric fibres");
133 if (fibreIndex < mNextIndex)
135 EXCEPTION(
"Fibre reads must be monotonically increasing; " << fibreIndex
136 <<
" is before expected next index " << mNextIndex);
142 mDataFile.seekg((fibreIndex-mNextIndex)*mNumItemsPerLine*
sizeof(
double), std::ios::cur);
144 mDataFile.read((
char*)&(rFibreMatrix(0,0)), mNumItemsPerLine*
sizeof(
double));
145 mNextIndex = fibreIndex+1;
149 unsigned num_entries = 0u;
150 while (fibreIndex >= mNextIndex)
152 num_entries = GetTokensAtNextLine();
155 if (num_entries < mNumItemsPerLine)
157 EXCEPTION(
"A line is incomplete in " << mFilePath
158 <<
" - each line should contain " << DIM*DIM <<
" entries");
160 for (
unsigned i=0; i<DIM; i++)
162 for (
unsigned j=0; j<DIM; j++)
164 rFibreMatrix(i,j) = mTokens[DIM*i + j];
170 rFibreMatrix = trans(rFibreMatrix);
172 if (checkOrthogonality)
175 c_matrix<double,DIM,DIM> temp;
176 temp = prod(trans(rFibreMatrix), rFibreMatrix);
179 for (
unsigned i=0; i<DIM; i++)
181 for (
unsigned j=0; j<DIM; j++)
183 double val = (i==j ? 1.0 : 0.0);
185 if (fabs(temp(i,j)-val) > 1e-4)
187 EXCEPTION(
"Read fibre-sheet matrix, " << rFibreMatrix <<
" from file "
188 <<
" which is not orthogonal (tolerance 1e-4)");
195 template<
unsigned DIM>
197 c_vector<double,DIM>& rFibreVector,
198 bool checkNormalised)
200 if (mNumItemsPerLine != DIM)
202 EXCEPTION(
"Use GetFibreSheetAndNormalMatrix when reading orthotropic fibres");
204 if (fibreIndex < mNextIndex)
206 EXCEPTION(
"Fibre reads must be monotonically increasing; " << fibreIndex
207 <<
" is before expected next index " << mNextIndex);
213 mDataFile.seekg((fibreIndex-mNextIndex)*mNumItemsPerLine*
sizeof(
double), std::ios::cur);
215 mDataFile.read((
char*)&rFibreVector[0], mNumItemsPerLine*
sizeof(
double));
216 mNextIndex = fibreIndex+1;
220 unsigned num_entries = 0u;
221 while (fibreIndex >= mNextIndex)
223 num_entries = GetTokensAtNextLine();
226 if (num_entries < mNumItemsPerLine)
228 EXCEPTION(
"A line is incomplete in " << mFilePath
229 <<
" - each line should contain " << DIM <<
" entries");
231 for (
unsigned i=0; i<DIM; i++)
233 rFibreVector(i) = mTokens[i];
238 if (checkNormalised && fabs(norm_2(rFibreVector)-1)>1e-4)
240 EXCEPTION(
"Read vector " << rFibreVector <<
" from file "
241 << mFilePath <<
" which is not normalised (tolerance 1e-4)");
245 template<
unsigned DIM>
248 assert(mTokens.size() == mNumItemsPerLine);
255 getline(mDataFile, line);
257 if (line.empty() && mDataFile.eof())
260 std::string error =
"End of file " + mFilePath +
" reached. Either file contains fewer "
261 +
"definitions than defined in header, or one of the GetNext[..] methods "
262 +
"has been called too often";
267 line = line.substr(0, line.find(
'#'));
269 blank_line = (line.find_first_not_of(
" \t",0) == std::string::npos);
274 std::string::iterator iter = line.end();
276 unsigned nchars2delete = 0;
277 while (*iter ==
' ' || *iter ==
'\t')
282 line.erase(line.length()-nchars2delete);
284 std::stringstream line_stream(line);
287 while (!line_stream.eof())
291 if (index >= mNumItemsPerLine)
293 EXCEPTION(
"Too many entries in a line in " + mFilePath);
295 mTokens[index++] = item;
301 template<
unsigned DIM>
304 std::string raw_line;
305 bool blank_line =
false;
308 getline(mDataFile, raw_line);
310 raw_line = raw_line.substr(0, raw_line.find(
'#'));
312 blank_line = (raw_line.find_first_not_of(
" \t",0) == std::string::npos);
316 std::stringstream header_line(raw_line);
318 header_line >> mNumLinesOfData;
321 header_line >> extras;
325 mFileIsBinary =
true;
330 EXCEPTION(
"First (non comment) line of the fibre orientation file should contain the number of lines of data in the file (and possibly a BIN tag) at most");
FibreReader(const FileFinder &rFileFinder, FibreFileType fibreFileType)
std::string GetAbsolutePath() const
#define EXCEPTION(message)
void ReadNumLinesOfDataFromFile()
unsigned GetTokensAtNextLine()
std::vector< double > mTokens
unsigned mNumItemsPerLine
void GetFibreVector(unsigned fibreIndex, c_vector< double, DIM > &rFibreVector, bool checkNormalised=true)
void GetAllAxi(std::vector< c_vector< double, DIM > > &direction)
void GetAllOrtho(std::vector< c_vector< double, DIM > > &first_direction, std::vector< c_vector< double, DIM > > &second_direction, std::vector< c_vector< double, DIM > > &third_direction)
void GetFibreSheetAndNormalMatrix(unsigned fibreIndex, c_matrix< double, DIM, DIM > &rFibreMatrix, bool checkOrthogonality=true)