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

Matrix.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 <OpenFOAM/Matrix.H>
00027 
00028 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
00029 
00030 template<class Form, class Type>
00031 void Foam::Matrix<Form, Type>::allocate()
00032 {
00033     if (n_ && m_)
00034     {
00035         v_ = new Type*[n_];
00036         v_[0] = new Type[n_*m_];
00037 
00038         for (register label i=1; i<n_; i++)
00039         {
00040             v_[i] = v_[i-1] + m_;
00041         }
00042     }
00043 }
00044 
00045 
00046 // * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * //
00047 
00048 template<class Form, class Type>
00049 Foam::Matrix<Form, Type>::~Matrix()
00050 {
00051     if (v_)
00052     {
00053         delete[] (v_[0]);
00054         delete[] v_;
00055     }
00056 }
00057 
00058 
00059 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00060 
00061 template<class Form, class Type>
00062 Foam::Matrix<Form, Type>::Matrix(const label n, const label m)
00063 :
00064     n_(n),
00065     m_(m),
00066     v_(NULL)
00067 {
00068     if (n_ < 0 || m_ < 0)
00069     {
00070         FatalErrorIn("Matrix<Form, Type>::Matrix(const label n, const label m)")
00071             << "bad n, m " << n_ << ", " << m_
00072             << abort(FatalError);
00073     }
00074 
00075     allocate();
00076 }
00077 
00078 
00079 template<class Form, class Type>
00080 Foam::Matrix<Form, Type>::Matrix(const label n, const label m, const Type& a)
00081 :
00082     n_(n),
00083     m_(m),
00084     v_(NULL)
00085 {
00086     if (n_ < 0 || m_ < 0)
00087     {
00088         FatalErrorIn
00089         (
00090             "Matrix<Form, Type>::Matrix(const label n, const label m, const T&)"
00091         )   << "bad n, m " << n_ << ", " << m_
00092             << abort(FatalError);
00093     }
00094 
00095     allocate();
00096 
00097     if (v_)
00098     {
00099         Type* v = v_[0];
00100 
00101         label nm = n_*m_;
00102 
00103         for (register label i=0; i<nm; i++)
00104         {
00105             v[i] = a;
00106         }
00107     }
00108 }
00109 
00110 
00111 template<class Form, class Type>
00112 Foam::Matrix<Form, Type>::Matrix(const Matrix<Form, Type>& a)
00113 :
00114     n_(a.n_),
00115     m_(a.m_),
00116     v_(NULL)
00117 {
00118     if (a.v_)
00119     {
00120         allocate();
00121         Type* v = v_[0];
00122         const Type* av = a.v_[0];
00123 
00124         label nm = n_*m_;
00125         for (register label i=0; i<nm; i++)
00126         {
00127             v[i] = av[i];
00128         }
00129     }
00130 }
00131 
00132 
00133 template<class Form, class Type>
00134 void Foam::Matrix<Form, Type>::clear()
00135 {
00136     if (v_)
00137     {
00138         delete[] (v_[0]);
00139         delete[] v_;
00140     }
00141     n_ = 0;
00142     m_ = 0;
00143     v_ = NULL;
00144 }
00145 
00146 
00147 template<class Form, class Type>
00148 void Foam::Matrix<Form, Type>::transfer(Matrix<Form, Type>& a)
00149 {
00150     clear();
00151 
00152     n_ = a.n_;
00153     a.n_ = 0;
00154 
00155     m_ = a.m_;
00156     a.m_ = 0;
00157 
00158     v_ = a.v_;
00159     a.v_ = NULL;
00160 }
00161 
00162 
00163 template<class Form, class Type>
00164 Form Foam::Matrix<Form, Type>::T() const
00165 {
00166     const Matrix<Form, Type>& A = *this;
00167     Form At(m(), n());
00168 
00169     for (register label i=0; i<n(); i++)
00170     {
00171         for (register label j=0; j<m(); j++)
00172         {
00173             At[j][i] = A[i][j];
00174         }
00175     }
00176 
00177     return At;
00178 }
00179 
00180 
00181 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00182 
00183 template<class Form, class Type>
00184 void Foam::Matrix<Form, Type>::operator=(const Type& t)
00185 {
00186     if (v_)
00187     {
00188         Type* v = v_[0];
00189 
00190         label nm = n_*m_;
00191         for (register label i=0; i<nm; i++)
00192         {
00193             v[i] = t;
00194         }
00195     }
00196 }
00197 
00198 
00199 // Assignment operator. Takes linear time.
00200 template<class Form, class Type>
00201 void Foam::Matrix<Form, Type>::operator=(const Matrix<Form, Type>& a)
00202 {
00203     if (this == &a)
00204     {
00205         FatalErrorIn("Matrix<Form, Type>::operator=(const Matrix<Form, Type>&)")
00206             << "attempted assignment to self"
00207             << abort(FatalError);
00208     }
00209 
00210     if (n_ != a.n_ || m_ != a.m_)
00211     {
00212         clear();
00213         n_ = a.n_;
00214         m_ = a.m_;
00215         allocate();
00216     }
00217 
00218     if (v_)
00219     {
00220         Type* v = v_[0];
00221         const Type* av = a.v_[0];
00222 
00223         label nm = n_*m_;
00224         for (register label i=0; i<nm; i++)
00225         {
00226             v[i] = av[i];
00227         }
00228     }
00229 }
00230 
00231 
00232 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
00233 
00234 template<class Form, class Type>
00235 const Type& Foam::max(const Matrix<Form, Type>& a)
00236 {
00237     label nm = a.n()*a.m();
00238 
00239     if (nm)
00240     {
00241         label curMaxI = 0;
00242         const Type* v = a[0];
00243 
00244         for (register label i=1; i<nm; i++)
00245         {
00246             if (v[i] > v[curMaxI])
00247             {
00248                 curMaxI = i;
00249             }
00250         }
00251 
00252         return v[curMaxI];
00253     }
00254     else
00255     {
00256         FatalErrorIn("max(const Matrix<Form, Type>&)")
00257             << "matrix is empty"
00258             << abort(FatalError);
00259 
00260         // Return in error to keep compiler happy
00261         return a[0][0];
00262     }
00263 }
00264 
00265 
00266 template<class Form, class Type>
00267 const Type& Foam::min(const Matrix<Form, Type>& a)
00268 {
00269     label nm = a.n()*a.m();
00270 
00271     if (nm)
00272     {
00273         label curMinI = 0;
00274         const Type* v = a[0];
00275 
00276         for (register label i=1; i<nm; i++)
00277         {
00278             if (v[i] < v[curMinI])
00279             {
00280                 curMinI = i;
00281             }
00282         }
00283 
00284         return v[curMinI];
00285     }
00286     else
00287     {
00288         FatalErrorIn("min(const Matrix<Form, Type>&)")
00289             << "matrix is empty"
00290             << abort(FatalError);
00291 
00292         // Return in error to keep compiler happy
00293         return a[0][0];
00294     }
00295 }
00296 
00297 
00298 // * * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * //
00299 
00300 template<class Form, class Type>
00301 Form Foam::operator-(const Matrix<Form, Type>& a)
00302 {
00303     Form na(a.n(), a.m());
00304 
00305     if (a.n() && a.m())
00306     {
00307         Type* nav = na[0];
00308         const Type* av = a[0];
00309 
00310         label nm = a.n()*a.m();
00311         for (register label i=0; i<nm; i++)
00312         {
00313             nav[i] = -av[i];
00314         }
00315     }
00316 
00317     return na;
00318 }
00319 
00320 
00321 template<class Form, class Type>
00322 Form Foam::operator+(const Matrix<Form, Type>& a, const Matrix<Form, Type>& b)
00323 {
00324     if (a.n() != b.n())
00325     {
00326         FatalErrorIn
00327         (
00328             "Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
00329         )   << "attempted add matrices with different number of rows: "
00330             << a.n() << ", " << b.n()
00331             << abort(FatalError);
00332     }
00333 
00334     if (a.m() != b.m())
00335     {
00336         FatalErrorIn
00337         (
00338             "Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
00339         )   << "attempted add matrices with different number of columns: "
00340             << a.m() << ", " << b.m()
00341             << abort(FatalError);
00342     }
00343 
00344     Form ab(a.n(), a.m());
00345 
00346     Type* abv = ab[0];
00347     const Type* av = a[0];
00348     const Type* bv = b[0];
00349 
00350     label nm = a.n()*a.m();
00351     for (register label i=0; i<nm; i++)
00352     {
00353         abv[i] = av[i] + bv[i];
00354     }
00355 
00356     return ab;
00357 }
00358 
00359 
00360 template<class Form, class Type>
00361 Form Foam::operator-(const Matrix<Form, Type>& a, const Matrix<Form, Type>& b)
00362 {
00363     if (a.n() != b.n())
00364     {
00365         FatalErrorIn
00366         (
00367             "Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
00368         )   << "attempted add matrices with different number of rows: "
00369             << a.n() << ", " << b.n()
00370             << abort(FatalError);
00371     }
00372 
00373     if (a.m() != b.m())
00374     {
00375         FatalErrorIn
00376         (
00377             "Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
00378         )   << "attempted add matrices with different number of columns: "
00379             << a.m() << ", " << b.m()
00380             << abort(FatalError);
00381     }
00382 
00383     Form ab(a.n(), a.m());
00384 
00385     Type* abv = ab[0];
00386     const Type* av = a[0];
00387     const Type* bv = b[0];
00388 
00389     label nm = a.n()*a.m();
00390     for (register label i=0; i<nm; i++)
00391     {
00392         abv[i] = av[i] - bv[i];
00393     }
00394 
00395     return ab;
00396 }
00397 
00398 
00399 template<class Form, class Type>
00400 Form Foam::operator*(const scalar s, const Matrix<Form, Type>& a)
00401 {
00402     Form sa(a.n(), a.m());
00403 
00404     if (a.n() && a.m())
00405     {
00406         Type* sav = sa[0];
00407         const Type* av = a[0];
00408 
00409         label nm = a.n()*a.m();
00410         for (register label i=0; i<nm; i++)
00411         {
00412             sav[i] = s*av[i];
00413         }
00414     }
00415 
00416     return sa;
00417 }
00418 
00419 
00420 // * * * * * * * * * * * * * * * *  IOStream operators * * * * * * * * * * * //
00421 
00422 #include <OpenFOAM/MatrixIO.C>
00423 
00424 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines