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 {
00037 if (fibreFileType == AXISYM)
00038 {
00039 mNumItemsPerLine = DIM;
00040 }
00041 else
00042 {
00043 mNumItemsPerLine = DIM*DIM;
00044 }
00045 mTokens.resize(mNumItemsPerLine);
00046
00047 mFilePath = rFileFinder.GetAbsolutePath();
00048 mDataFile.open(mFilePath.c_str());
00049 if (!mDataFile.is_open())
00050 {
00051 EXCEPTION("Failed to open fibre file " + rFileFinder.GetAbsolutePath());
00052 }
00053
00054
00055 ReadNumLinesOfDataFromFile();
00056 }
00057
00058 template<unsigned DIM>
00059 FibreReader<DIM>::~FibreReader()
00060 {
00061 mDataFile.close();
00062 }
00063
00064 template<unsigned DIM>
00065 void FibreReader<DIM>::GetAllAxi(std::vector< c_vector<double, DIM> >& direction)
00066 {
00067 assert(direction.empty());
00068 if (mNumItemsPerLine != DIM)
00069 {
00070 EXCEPTION("Use GetAllOrtho when reading orthotropic fibres");
00071 }
00072 for (unsigned i=0; i<mNumLinesOfData; i++)
00073 {
00074 c_vector<double, DIM> temp_vector;
00075 GetNextFibreVector(temp_vector, false);
00076 direction.push_back(temp_vector);
00077 }
00078 }
00079
00080 template<unsigned DIM>
00081 void FibreReader<DIM>::GetAllOrtho(std::vector< c_vector<double, DIM> >& first_direction,
00082 std::vector< c_vector<double, DIM> >& second_direction,
00083 std::vector< c_vector<double, DIM> >& third_direction)
00084 {
00085 assert(first_direction.empty());
00086 assert(second_direction.empty());
00087 assert(third_direction.empty());
00088 if (mNumItemsPerLine != DIM*DIM)
00089 {
00090 EXCEPTION("Use GetAllAxi when reading axisymmetric fibres");
00091 }
00092 for (unsigned i=0; i<mNumLinesOfData; i++)
00093 {
00094 c_matrix<double, DIM, DIM> temp_matrix;
00095 GetNextFibreSheetAndNormalMatrix(temp_matrix, false);
00096 matrix_row<c_matrix<double, DIM, DIM> > row0(temp_matrix, 0);
00097 first_direction.push_back(row0);
00098 if (DIM>=2)
00099 {
00100 matrix_row<c_matrix<double, DIM, DIM> > row1(temp_matrix, 1);
00101 second_direction.push_back(row1);
00102 }
00103 if (DIM==3)
00104 {
00105 matrix_row<c_matrix<double, DIM, DIM> > row2(temp_matrix, 2);
00106 third_direction.push_back(row2);
00107 }
00108 }
00109
00110 }
00111 template<unsigned DIM>
00112 void FibreReader<DIM>::GetNextFibreSheetAndNormalMatrix(c_matrix<double,DIM,DIM>& rFibreMatrix,
00113 bool checkOrthogonality)
00114 {
00115 if (mNumItemsPerLine != DIM*DIM)
00116 {
00117 EXCEPTION("Use GetNextFibreVector when reading axisymmetric fibres");
00118 }
00119
00120 unsigned num_entries = GetTokensAtNextLine();
00121 if(num_entries < mNumItemsPerLine)
00122 {
00123 std::stringstream string_stream;
00124 string_stream << "A line is incomplete in " << mFilePath
00125 << " - each line should contain " << DIM*DIM << " entries";
00126 EXCEPTION(string_stream.str());
00127 }
00128
00129 for(unsigned i=0; i<DIM; i++)
00130 {
00131 for(unsigned j=0; j<DIM; j++)
00132 {
00133 rFibreMatrix(j,i) = mTokens[DIM*i + j];
00134 }
00135 }
00136
00137 if(checkOrthogonality)
00138 {
00139 c_matrix<double,DIM,DIM> temp = prod(trans(rFibreMatrix),rFibreMatrix);
00140
00141 for(unsigned i=0; i<DIM; i++)
00142 {
00143 for(unsigned j=0; j<DIM; j++)
00144 {
00145 double val = (i==j ? 1.0 : 0.0);
00146
00147 if(fabs(temp(i,j)-val)>1e-4)
00148 {
00149 std::stringstream string_stream;
00150 string_stream << "Read fibre-sheet matrix, " << rFibreMatrix << " from file "
00151 << " which is not orthogonal (tolerance 1e-4)";
00152 EXCEPTION(string_stream.str());
00153 }
00154 }
00155 }
00156 }
00157
00158 }
00159
00160 template<unsigned DIM>
00161 void FibreReader<DIM>::GetNextFibreVector(c_vector<double,DIM>& rFibreVector,
00162 bool checkNormalised)
00163 {
00164 if (mNumItemsPerLine != DIM)
00165 {
00166 EXCEPTION("Use GetNextFibreSheetAndNormalMatrix when reading orthotropic fibres");
00167 }
00168
00169 unsigned num_entries = GetTokensAtNextLine();
00170 if(num_entries < mNumItemsPerLine)
00171 {
00172 std::stringstream string_stream;
00173 string_stream << "A line is incomplete in " << mFilePath
00174 << " - each line should contain " << DIM << " entries";
00175 EXCEPTION(string_stream.str());
00176 }
00177
00178 for(unsigned i=0; i<DIM; i++)
00179 {
00180 rFibreVector(i) = mTokens[i];
00181 }
00182
00183 if(checkNormalised && fabs(norm_2(rFibreVector)-1)>1e-4)
00184 {
00185 std::stringstream string_stream;
00186 string_stream << "Read vector " << rFibreVector << " from file "
00187 << mFilePath << " which is not normalised (tolerance 1e-4)";
00188 EXCEPTION(string_stream.str());
00189 }
00190 }
00191
00192
00193 template<unsigned DIM>
00194 unsigned FibreReader<DIM>::GetTokensAtNextLine()
00195 {
00196 assert(mTokens.size() == mNumItemsPerLine);
00197
00198 std::string line;
00199 bool blank_line;
00200
00201 do
00202 {
00203 getline(mDataFile, line);
00204
00205 if (line.empty() && mDataFile.eof())
00206 {
00207 mDataFile.close();
00208 std::string error = "End of file " + mFilePath + " reached. Either file contains less "
00209 + "definitions than defined in header, or one of the GetNext[..] methods "
00210 + "has been called too often";
00211 EXCEPTION(error);
00212 }
00213
00214
00215 line = line.substr(0, line.find('#'));
00216
00217 blank_line = (line.find_first_not_of(" \t",0) == std::string::npos);
00218 }
00219 while(blank_line);
00220
00221
00222 std::string::iterator iter = line.end();
00223 iter--;
00224 unsigned nchars2delete = 0;
00225 while(*iter == ' ')
00226 {
00227 nchars2delete++;
00228 iter--;
00229 }
00230 line.erase(line.length()-nchars2delete);
00231
00232 std::stringstream line_stream(line);
00233
00234 unsigned index = 0;
00235 while (!line_stream.eof())
00236 {
00237 double item;
00238 line_stream >> item;
00239 if(index >= mNumItemsPerLine)
00240 {
00241 EXCEPTION("Too many entries in a line in " + mFilePath);
00242 }
00243 mTokens[index++] = item;
00244 }
00245
00246 return index;
00247 }
00248
00249
00250 template<unsigned DIM>
00251 void FibreReader<DIM>::ReadNumLinesOfDataFromFile()
00252 {
00253 if (GetTokensAtNextLine() != 1)
00254 {
00255 mDataFile.close();
00256 EXCEPTION("First (non comment) line of the fibre orientation file should contain the number of lines of data in the file (and nothing else)");
00257 }
00258
00259 mNumLinesOfData = (unsigned) mTokens[0];
00260 }
00261
00262
00263
00264 template class FibreReader<1>;
00265 template class FibreReader<2>;
00266 template class FibreReader<3>;
00267
00268
00269
00270
00271