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 #include <OpenFOAM/Matrix.H>
00027
00028
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
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
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
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
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
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
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
00293 return a[0][0];
00294 }
00295 }
00296
00297
00298
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
00421
00422 #include <OpenFOAM/MatrixIO.C>
00423
00424