FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

MatrixIO.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "Matrix.H"
00027 #include <OpenFOAM/Istream.H>
00028 #include <OpenFOAM/Ostream.H>
00029 #include <OpenFOAM/token.H>
00030 #include <OpenFOAM/contiguous.H>
00031 
00032 // * * * * * * * * * * * * * * * Ostream Operator *  * * * * * * * * * * * * //
00033 
00034 template<class Form, class Type>
00035 Foam::Matrix<Form, Type>::Matrix(Istream& is)
00036 :
00037     n_(0),
00038     m_(0),
00039     v_(NULL)
00040 {
00041     operator>>(is, *this);
00042 }
00043 
00044 
00045 template<class Form, class Type>
00046 Foam::Istream& Foam::operator>>(Istream& is, Matrix<Form, Type>& M)
00047 {
00048     // Anull matrix
00049     M.clear();
00050 
00051     is.fatalCheck("operator>>(Istream&, Matrix<Form, Type>&)");
00052 
00053     token firstToken(is);
00054 
00055     is.fatalCheck("operator>>(Istream&, Matrix<Form, Type>&) : reading first token");
00056 
00057     if (firstToken.isLabel())
00058     {
00059         M.n_ = firstToken.labelToken();
00060         M.m_ = readLabel(is);
00061 
00062         label nm = M.n_*M.m_;
00063 
00064         // Read list contents depending on data format
00065         if (is.format() == IOstream::ASCII || !contiguous<Type>())
00066         {
00067             // Read beginning of contents
00068             char listDelimiter = is.readBeginList("Matrix");
00069 
00070             if (nm)
00071             {
00072                 M.allocate();
00073                 Type* v = M.v_[0];
00074 
00075                 if (listDelimiter == token::BEGIN_LIST)
00076                 {
00077                     label k = 0;
00078 
00079                     // loop over rows
00080                     for (register label i=0; i<M.n(); i++)
00081                     {
00082                         listDelimiter = is.readBeginList("MatrixRow");
00083 
00084                         for (register label j=0; j<M.m(); j++)
00085                         {
00086                             is >> v[k++];
00087 
00088                             is.fatalCheck
00089                             (
00090                                 "operator>>(Istream&, Matrix<Form, Type>&) : "
00091                                 "reading entry"
00092                             );
00093                         }
00094 
00095                         is.readEndList("MatrixRow");
00096                     }
00097                 }
00098                 else
00099                 {
00100                     Type element;
00101                     is >> element;
00102 
00103                     is.fatalCheck
00104                     (
00105                         "operator>>(Istream&, Matrix<Form, Type>&) : "
00106                         "reading the single entry"
00107                     );
00108 
00109                     for (register label i=0; i<nm; i++)
00110                     {
00111                         v[i] = element;
00112                     }
00113                 }
00114             }
00115 
00116             // Read end of contents
00117             is.readEndList("Matrix");
00118         }
00119         else
00120         {
00121             if (nm)
00122             {
00123                 M.allocate();
00124                 Type* v = M.v_[0];
00125 
00126                 is.read(reinterpret_cast<char*>(v), nm*sizeof(Type));
00127 
00128                 is.fatalCheck
00129                 (
00130                     "operator>>(Istream&, Matrix<Form, Type>&) : "
00131                     "reading the binary block"
00132                 );
00133             }
00134         }
00135     }
00136     else
00137     {
00138         FatalIOErrorIn("operator>>(Istream&, Matrix<Form, Type>&)", is)
00139             << "incorrect first token, expected <int>, found "
00140             << firstToken.info()
00141             << exit(FatalIOError);
00142     }
00143 
00144     return is;
00145 }
00146 
00147 
00148 template<class Form, class Type>
00149 Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<Form, Type>& M)
00150 {
00151     label nm = M.n_*M.m_;
00152 
00153     os  << M.n() << token::SPACE << M.m();
00154 
00155     // Write list contents depending on data format
00156     if (os.format() == IOstream::ASCII || !contiguous<Type>())
00157     {
00158         if (nm)
00159         {
00160             bool uniform = false;
00161 
00162             const Type* v = M.v_[0];
00163 
00164             if (nm > 1 && contiguous<Type>())
00165             {
00166                 uniform = true;
00167 
00168                 for (register label i=0; i< nm; i++)
00169                 {
00170                     if (v[i] != v[0])
00171                     {
00172                         uniform = false;
00173                         break;
00174                     }
00175                 }
00176             }
00177 
00178             if (uniform)
00179             {
00180                 // Write size of list and start contents delimiter
00181                 os  << token::BEGIN_BLOCK;
00182 
00183                 // Write list contents
00184                 os << v[0];
00185 
00186                 // Write end of contents delimiter
00187                 os << token::END_BLOCK;
00188             }
00189             else if (nm < 10 && contiguous<Type>())
00190             {
00191                 // Write size of list and start contents delimiter
00192                 os  << token::BEGIN_LIST;
00193 
00194                 label k = 0;
00195 
00196                 // loop over rows
00197                 for (register label i=0; i< M.n(); i++)
00198                 {
00199                     os  << token::BEGIN_LIST;
00200 
00201                     // Write row
00202                     for (register label j=0; j< M.m(); j++)
00203                     {
00204                         if (j > 0) os << token::SPACE;
00205                         os << v[k++];
00206                     }
00207 
00208                     os << token::END_LIST;
00209                 }
00210 
00211                 // Write end of contents delimiter
00212                 os << token::END_LIST;
00213             }
00214             else
00215             {
00216                 // Write size of list and start contents delimiter
00217                 os  << nl << token::BEGIN_LIST;
00218 
00219                 label k = 0;
00220 
00221                 // loop over rows
00222                 for (register label i=0; i< M.n(); i++)
00223                 {
00224                     os  << nl << token::BEGIN_LIST;
00225 
00226                     // Write row
00227                     for (register label j=0; j< M.m(); j++)
00228                     {
00229                         os << nl << v[k++];
00230                     }
00231 
00232                     os << nl << token::END_LIST;
00233                 }
00234 
00235                 // Write end of contents delimiter
00236                 os << nl << token::END_LIST << nl;
00237             }
00238         }
00239         else
00240         {
00241             os  << token::BEGIN_LIST << token::END_LIST << nl;
00242         }
00243     }
00244     else
00245     {
00246         if (nm)
00247         {
00248             os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(Type));
00249         }
00250     }
00251 
00252     // Check state of IOstream
00253     os.check("Ostream& operator<<(Ostream&, const Matrix&)");
00254 
00255     return os;
00256 }
00257 
00258 
00259 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines