FibreReader.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "FibreReader.hpp"
00030
00031 #include <sstream>
00032 #include "Exception.hpp"
00033
00034 template<unsigned DIM>
00035 FibreReader<DIM>::FibreReader(FileFinder& rFileFinder, FibreFileType fibreFileType)
00036 : mFileIsBinary(false)
00037 {
00038 if (fibreFileType == AXISYM)
00039 {
00040 mNumItemsPerLine = DIM;
00041 }
00042 else
00043 {
00044 mNumItemsPerLine = DIM*DIM;
00045 }
00046 mTokens.resize(mNumItemsPerLine);
00047
00048 mFilePath = rFileFinder.GetAbsolutePath();
00049 mDataFile.open(mFilePath.c_str());
00050 if (!mDataFile.is_open())
00051 {
00052 EXCEPTION("Failed to open fibre file " + rFileFinder.GetAbsolutePath());
00053 }
00054
00055
00056 ReadNumLinesOfDataFromFile();
00057 }
00058
00059 template<unsigned DIM>
00060 FibreReader<DIM>::~FibreReader()
00061 {
00062 mDataFile.close();
00063 }
00064
00065 template<unsigned DIM>
00066 void FibreReader<DIM>::GetAllAxi(std::vector< c_vector<double, DIM> >& direction)
00067 {
00068 assert(direction.empty());
00069 if (mNumItemsPerLine != DIM)
00070 {
00071 EXCEPTION("Use GetAllOrtho when reading orthotropic fibres");
00072 }
00073 for (unsigned i=0; i<mNumLinesOfData; i++)
00074 {
00075 c_vector<double, DIM> temp_vector;
00076 GetNextFibreVector(temp_vector, false);
00077 direction.push_back(temp_vector);
00078 }
00079 }
00080
00081 template<unsigned DIM>
00082 void FibreReader<DIM>::GetAllOrtho(std::vector< c_vector<double, DIM> >& first_direction,
00083 std::vector< c_vector<double, DIM> >& second_direction,
00084 std::vector< c_vector<double, DIM> >& third_direction)
00085 {
00086 assert(first_direction.empty());
00087 assert(second_direction.empty());
00088 assert(third_direction.empty());
00089 if (mNumItemsPerLine != DIM*DIM)
00090 {
00091 EXCEPTION("Use GetAllAxi when reading axisymmetric fibres");
00092 }
00093 for (unsigned i=0; i<mNumLinesOfData; i++)
00094 {
00095 c_matrix<double, DIM, DIM> temp_matrix;
00096 GetNextFibreSheetAndNormalMatrix(temp_matrix, true);
00097
00098
00099
00100 matrix_column<c_matrix<double, DIM, DIM> > col0(temp_matrix, 0);
00101 first_direction.push_back(col0);
00102 if (DIM>=2)
00103 {
00104 matrix_column<c_matrix<double, DIM, DIM> > col1(temp_matrix, 1);
00105 second_direction.push_back(col1);
00106 }
00107 if (DIM==3)
00108 {
00109 matrix_column<c_matrix<double, DIM, DIM> > col2(temp_matrix, 2);
00110 third_direction.push_back(col2);
00111 }
00112 }
00113
00114 }
00115 template<unsigned DIM>
00116 void FibreReader<DIM>::GetNextFibreSheetAndNormalMatrix(c_matrix<double,DIM,DIM>& rFibreMatrix,
00117 bool checkOrthogonality)
00118 {
00119 if (mNumItemsPerLine != DIM*DIM)
00120 {
00121 EXCEPTION("Use GetNextFibreVector when reading axisymmetric fibres");
00122 }
00123
00124 if (mFileIsBinary)
00125 {
00126
00127 mDataFile.read((char*)&(rFibreMatrix(0,0)), mNumItemsPerLine*sizeof(double));
00128 }
00129 else
00130 {
00131 unsigned num_entries = GetTokensAtNextLine();
00132 if(num_entries < mNumItemsPerLine)
00133 {
00134 EXCEPTION("A line is incomplete in " << mFilePath
00135 << " - each line should contain " << DIM*DIM << " entries");
00136 }
00137 for(unsigned i=0; i<DIM; i++)
00138 {
00139 for(unsigned j=0; j<DIM; j++)
00140 {
00141 rFibreMatrix(i,j) = mTokens[DIM*i + j];
00142 }
00143 }
00144
00145 }
00146
00147
00148
00149 rFibreMatrix = trans(rFibreMatrix);
00150
00151
00152 if(checkOrthogonality)
00153 {
00154 c_matrix<double,DIM,DIM> temp = prod(trans(rFibreMatrix),rFibreMatrix);
00155
00156 for(unsigned i=0; i<DIM; i++)
00157 {
00158 for(unsigned j=0; j<DIM; j++)
00159 {
00160 double val = (i==j ? 1.0 : 0.0);
00161
00162 if(fabs(temp(i,j)-val)>1e-4)
00163 {
00164 EXCEPTION("Read fibre-sheet matrix, " << rFibreMatrix << " from file "
00165 << " which is not orthogonal (tolerance 1e-4)");
00166 }
00167 }
00168 }
00169 }
00170
00171 }
00172
00173 template<unsigned DIM>
00174 void FibreReader<DIM>::GetNextFibreVector(c_vector<double,DIM>& rFibreVector,
00175 bool checkNormalised)
00176 {
00177 if (mNumItemsPerLine != DIM)
00178 {
00179 EXCEPTION("Use GetNextFibreSheetAndNormalMatrix when reading orthotropic fibres");
00180 }
00181
00182 if (mFileIsBinary)
00183 {
00184
00185 mDataFile.read((char*)&rFibreVector[0], mNumItemsPerLine*sizeof(double));
00186 }
00187 else
00188 {
00189 unsigned num_entries = GetTokensAtNextLine();
00190 if(num_entries < mNumItemsPerLine)
00191 {
00192 EXCEPTION("A line is incomplete in " << mFilePath
00193 << " - each line should contain " << DIM << " entries");
00194 }
00195 for(unsigned i=0; i<DIM; i++)
00196 {
00197 rFibreVector(i) = mTokens[i];
00198 }
00199 }
00200
00201
00202 if(checkNormalised && fabs(norm_2(rFibreVector)-1)>1e-4)
00203 {
00204 EXCEPTION("Read vector " << rFibreVector << " from file "
00205 << mFilePath << " which is not normalised (tolerance 1e-4)");
00206 }
00207 }
00208
00209
00210 template<unsigned DIM>
00211 unsigned FibreReader<DIM>::GetTokensAtNextLine()
00212 {
00213 assert(mTokens.size() == mNumItemsPerLine);
00214
00215 std::string line;
00216 bool blank_line;
00217
00218 do
00219 {
00220 getline(mDataFile, line);
00221
00222 if (line.empty() && mDataFile.eof())
00223 {
00224 mDataFile.close();
00225 std::string error = "End of file " + mFilePath + " reached. Either file contains less "
00226 + "definitions than defined in header, or one of the GetNext[..] methods "
00227 + "has been called too often";
00228 EXCEPTION(error);
00229 }
00230
00231
00232 line = line.substr(0, line.find('#'));
00233
00234 blank_line = (line.find_first_not_of(" \t",0) == std::string::npos);
00235 }
00236 while(blank_line);
00237
00238
00239 std::string::iterator iter = line.end();
00240 iter--;
00241 unsigned nchars2delete = 0;
00242 while(*iter == ' ' || *iter == '\t')
00243 {
00244 nchars2delete++;
00245 iter--;
00246 }
00247 line.erase(line.length()-nchars2delete);
00248
00249 std::stringstream line_stream(line);
00250
00251 unsigned index = 0;
00252 while (!line_stream.eof())
00253 {
00254 double item;
00255 line_stream >> item;
00256 if(index >= mNumItemsPerLine)
00257 {
00258 EXCEPTION("Too many entries in a line in " + mFilePath);
00259 }
00260 mTokens[index++] = item;
00261 }
00262
00263 return index;
00264 }
00265
00266
00267 template<unsigned DIM>
00268 void FibreReader<DIM>::ReadNumLinesOfDataFromFile()
00269 {
00270 std::string raw_line;
00271 bool blank_line = false;
00272 do
00273 {
00274 getline(mDataFile, raw_line);
00275
00276 raw_line = raw_line.substr(0, raw_line.find('#'));
00277
00278 blank_line = (raw_line.find_first_not_of(" \t",0) == std::string::npos);
00279 }
00280 while (blank_line);
00281
00282 std::stringstream header_line(raw_line);
00283
00284 header_line >> mNumLinesOfData;
00285
00286 std::string extras;
00287 header_line >> extras;
00288
00289 if (extras=="BIN")
00290 {
00291 mFileIsBinary = true;
00292 }
00293 else if (extras!="")
00294 {
00295 mDataFile.close();
00296 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");
00297 }
00298 }
00299
00300
00301
00302 template class FibreReader<1>;
00303 template class FibreReader<2>;
00304 template class FibreReader<3>;
00305
00306
00307
00308
00309