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>::GetNextFibreSheetAndNormalMatrix(c_matrix<double,DIM,DIM>& rFibreMatrix,
00066 bool checkOrthogonality)
00067 {
00068 if (mNumItemsPerLine != DIM*DIM)
00069 {
00070 EXCEPTION("Use GetNextFibreVector when reading axisymmetric fibres.");
00071 }
00072
00073 unsigned num_entries = GetTokensAtNextLine();
00074 if(num_entries < mNumItemsPerLine)
00075 {
00076 std::stringstream string_stream;
00077 string_stream << "A line is incomplete in " << mFilePath
00078 << " - each line should contain " << DIM*DIM << " entries";
00079 EXCEPTION(string_stream.str());
00080 }
00081
00082 for(unsigned i=0; i<DIM; i++)
00083 {
00084 for(unsigned j=0; j<DIM; j++)
00085 {
00086 rFibreMatrix(j,i) = mTokens[DIM*i + j];
00087 }
00088 }
00089
00090 if(checkOrthogonality)
00091 {
00092 c_matrix<double,DIM,DIM> temp = prod(trans(rFibreMatrix),rFibreMatrix);
00093
00094 for(unsigned i=0; i<DIM; i++)
00095 {
00096 for(unsigned j=0; j<DIM; j++)
00097 {
00098 double val = (i==j ? 1.0 : 0.0);
00099
00100 if(fabs(temp(i,j)-val)>1e-4)
00101 {
00102 std::stringstream string_stream;
00103 string_stream << "Read fibre-sheet matrix, " << rFibreMatrix << " from file "
00104 << " which is not orthogonal (tolerance 1e-4)";
00105 EXCEPTION(string_stream.str());
00106 }
00107 }
00108 }
00109 }
00110
00111 }
00112
00113 template<unsigned DIM>
00114 void FibreReader<DIM>::GetNextFibreVector(c_vector<double,DIM>& rFibreVector,
00115 bool checkNormalised)
00116 {
00117 if (mNumItemsPerLine != DIM)
00118 {
00119 EXCEPTION("Use GetNextFibreSheetAndNormalMatrix when reading orthotropic fibres.");
00120 }
00121
00122 unsigned num_entries = GetTokensAtNextLine();
00123 if(num_entries < mNumItemsPerLine)
00124 {
00125 std::stringstream string_stream;
00126 string_stream << "A line is incomplete in " << mFilePath
00127 << " - each line should contain " << DIM << " entries";
00128 EXCEPTION(string_stream.str());
00129 }
00130
00131 for(unsigned i=0; i<DIM; i++)
00132 {
00133 rFibreVector(i) = mTokens[i];
00134 }
00135
00136 if(checkNormalised && fabs(norm_2(rFibreVector)-1)>1e-4)
00137 {
00138 std::stringstream string_stream;
00139 string_stream << "Read vector " << rFibreVector << " from file "
00140 << mFilePath << " which is not normalised (tolerance 1e-4)";
00141 EXCEPTION(string_stream.str());
00142 }
00143 }
00144
00145
00146 template<unsigned DIM>
00147 unsigned FibreReader<DIM>::GetTokensAtNextLine()
00148 {
00149 assert(mTokens.size() == mNumItemsPerLine);
00150
00151 std::string line;
00152 bool blank_line;
00153
00154 do
00155 {
00156 getline(mDataFile, line);
00157
00158 if (line.empty() && mDataFile.eof())
00159 {
00160 mDataFile.close();
00161 std::string error = "End of file " + mFilePath + " reached. Either file contains less "
00162 + "definitions than defined in header, or one of the GetNext[..] methods "
00163 + "has been called too often";
00164 EXCEPTION(error);
00165 }
00166
00167
00168 line = line.substr(0, line.find('#'));
00169
00170 blank_line = (line.find_first_not_of(" \t",0) == std::string::npos);
00171 }
00172 while(blank_line);
00173
00174
00175 std::string::iterator iter = line.end();
00176 iter--;
00177 unsigned nchars2delete = 0;
00178 while(*iter == ' ')
00179 {
00180 nchars2delete++;
00181 iter--;
00182 }
00183 line.erase(line.length()-nchars2delete);
00184
00185 std::stringstream line_stream(line);
00186
00187 unsigned index = 0;
00188 while (!line_stream.eof())
00189 {
00190 double item;
00191 line_stream >> item;
00192 if(index >= mNumItemsPerLine)
00193 {
00194 EXCEPTION("Too many entries in a line in " + mFilePath);
00195 }
00196 mTokens[index++] = item;
00197 }
00198
00199 return index;
00200 }
00201
00202
00203 template<unsigned DIM>
00204 void FibreReader<DIM>::ReadNumLinesOfDataFromFile()
00205 {
00206 if (GetTokensAtNextLine() != 1)
00207 {
00208 mDataFile.close();
00209 EXCEPTION("First (non comment) line of the fibre orientation file should contain the number of lines of data in the file (and nothing else)");
00210 }
00211
00212 mNumLinesOfData = (unsigned) mTokens[0];
00213 }
00214
00215
00216
00217 template class FibreReader<1>;
00218 template class FibreReader<2>;
00219 template class FibreReader<3>;
00220
00221
00222
00223
00224