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];
171 rFibreMatrix = trans(rFibreMatrix);
173 if (checkOrthogonality)
176 c_matrix<double,DIM,DIM> temp;
177 temp = prod(trans(rFibreMatrix), rFibreMatrix);
180 for (
unsigned i=0; i<DIM; i++)
182 for (
unsigned j=0; j<DIM; j++)
184 double val = (i==j ? 1.0 : 0.0);
186 if (fabs(temp(i,j)-val) > 1e-4)
188 EXCEPTION(
"Read fibre-sheet matrix, " << rFibreMatrix <<
" from file "
189 <<
" which is not orthogonal (tolerance 1e-4)");
196 template<
unsigned DIM>
198 c_vector<double,DIM>& rFibreVector,
199 bool checkNormalised)
201 if (mNumItemsPerLine != DIM)
203 EXCEPTION(
"Use GetFibreSheetAndNormalMatrix when reading orthotropic fibres");
205 if (fibreIndex < mNextIndex)
207 EXCEPTION(
"Fibre reads must be monotonically increasing; " << fibreIndex
208 <<
" is before expected next index " << mNextIndex);
214 mDataFile.seekg((fibreIndex-mNextIndex)*mNumItemsPerLine*
sizeof(
double), std::ios::cur);
216 mDataFile.read((
char*)&rFibreVector[0], mNumItemsPerLine*
sizeof(
double));
217 mNextIndex = fibreIndex+1;
221 unsigned num_entries = 0u;
222 while (fibreIndex >= mNextIndex)
224 num_entries = GetTokensAtNextLine();
227 if (num_entries < mNumItemsPerLine)
229 EXCEPTION(
"A line is incomplete in " << mFilePath
230 <<
" - each line should contain " << DIM <<
" entries");
232 for (
unsigned i=0; i<DIM; i++)
234 rFibreVector(i) = mTokens[i];
239 if (checkNormalised && fabs(norm_2(rFibreVector)-1)>1e-4)
241 EXCEPTION(
"Read vector " << rFibreVector <<
" from file "
242 << mFilePath <<
" which is not normalised (tolerance 1e-4)");
247 template<
unsigned DIM>
250 assert(mTokens.size() == mNumItemsPerLine);
257 getline(mDataFile, line);
259 if (line.empty() && mDataFile.eof())
262 std::string error =
"End of file " + mFilePath +
" reached. Either file contains fewer "
263 +
"definitions than defined in header, or one of the GetNext[..] methods "
264 +
"has been called too often";
269 line = line.substr(0, line.find(
'#'));
271 blank_line = (line.find_first_not_of(
" \t",0) == std::string::npos);
276 std::string::iterator iter = line.end();
278 unsigned nchars2delete = 0;
279 while(*iter ==
' ' || *iter ==
'\t')
284 line.erase(line.length()-nchars2delete);
286 std::stringstream line_stream(line);
289 while (!line_stream.eof())
293 if(index >= mNumItemsPerLine)
295 EXCEPTION(
"Too many entries in a line in " + mFilePath);
297 mTokens[index++] = item;
304 template<
unsigned DIM>
307 std::string raw_line;
308 bool blank_line =
false;
311 getline(mDataFile, raw_line);
313 raw_line = raw_line.substr(0, raw_line.find(
'#'));
315 blank_line = (raw_line.find_first_not_of(
" \t",0) == std::string::npos);
319 std::stringstream header_line(raw_line);
321 header_line >> mNumLinesOfData;
324 header_line >> extras;
328 mFileIsBinary =
true;
333 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)