/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "MatrixBlock.H" // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // template inline void Foam::Matrix::doAlloc() { const label len = size(); if (len) { v_ = new Type[len]; } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline Foam::Matrix::Matrix() : mRows_(0), nCols_(0), v_(nullptr) {} template inline Foam::Matrix::Matrix(const labelPair& dims) : Matrix(dims.first(), dims.second()) {} template inline Foam::Matrix::Matrix(const labelPair& dims, const zero) : Matrix(dims.first(), dims.second(), Zero) {} template inline Foam::Matrix::Matrix(const labelPair& dims, const Type& val) : Matrix(dims.first(), dims.second(), val) {} template inline Foam::autoPtr> Foam::Matrix::clone() const { return autoPtr>::New(*this); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template inline const Foam::Matrix& Foam::Matrix::null() { return NullObjectRef>(); } template inline Foam::label Foam::Matrix::m() const noexcept { return mRows_; } template inline Foam::label Foam::Matrix::n() const noexcept { return nCols_; } template inline Foam::label Foam::Matrix::size() const { return mRows_ * nCols_; } template inline Foam::labelPair Foam::Matrix::sizes() const { return labelPair(mRows_, nCols_); } template inline bool Foam::Matrix::empty() const noexcept { return !mRows_ || !nCols_; } template inline void Foam::Matrix::checki(const label i) const { if (!mRows_ || !nCols_) { FatalErrorInFunction << "Attempt to access element from empty matrix" << abort(FatalError); } if (i < 0 || mRows_ <= i) { FatalErrorInFunction << "Index " << i << " out of range 0 ... " << mRows_-1 << abort(FatalError); } } template inline void Foam::Matrix::checkj(const label j) const { if (!mRows_ || !nCols_) { FatalErrorInFunction << "Attempt to access element from empty matrix" << abort(FatalError); } if (j < 0 || nCols_ <= j) { FatalErrorInFunction << "index " << j << " out of range 0 ... " << nCols_-1 << abort(FatalError); } } template inline void Foam::Matrix::checkSize() const { if (mRows_ < 0 || nCols_ < 0) { FatalErrorInFunction << "Incorrect size (" << mRows_ << ", " << nCols_ << ')' << nl << abort(FatalError); } // Could also check for odd sizes, like (0, N) and make (0,0) } template inline bool Foam::Matrix::uniform() const { const label len = size(); if (len == 0) { return false; } for (label idx = 1; idx < len; ++idx) { if (v_[0] != v_[idx]) { return false; } } return true; } template inline const Type* Foam::Matrix::cdata() const noexcept { return v_; } template inline Type* Foam::Matrix::data() noexcept { return v_; } template inline const Type* Foam::Matrix::rowData(const label irow) const { #ifdef FULLDEBUG checki(irow); #endif return (v_ + irow*nCols_); } template inline Type* Foam::Matrix::rowData(const label irow) { #ifdef FULLDEBUG checki(irow); #endif return (v_ + irow*nCols_); } template inline const Type& Foam::Matrix::at(const label idx) const { #ifdef FULLDEBUG if (idx < 0 || this->size() <= idx) { FatalErrorInFunction << "index " << idx << " out of range 0 ... " << this->size() << abort(FatalError); } #endif return *(v_ + idx); } template inline Type& Foam::Matrix::at(const label idx) { #ifdef FULLDEBUG if (idx < 0 || this->size() <= idx) { FatalErrorInFunction << "index " << idx << " out of range 0 ... " << this->size() << abort(FatalError); } #endif return *(v_ + idx); } template inline Foam::ConstMatrixBlock> Foam::Matrix::subColumn ( const label colIndex, const label rowIndex, label len ) const { if (len < 0) { len = mRows_ - rowIndex; } return ConstMatrixBlock ( *this, len, // rows 1, rowIndex, colIndex ); } template inline Foam::ConstMatrixBlock> Foam::Matrix::subRow ( const label rowIndex, const label colIndex, label len ) const { if (len < 0) { len = nCols_ - colIndex; } return ConstMatrixBlock ( *this, 1, len, // columns rowIndex, colIndex ); } template inline Foam::ConstMatrixBlock> Foam::Matrix::subMatrix ( const label rowIndex, const label colIndex, label szRows, label szCols ) const { if (szRows < 0) szRows = mRows_ - rowIndex; if (szCols < 0) szCols = nCols_ - colIndex; return ConstMatrixBlock ( *this, szRows, szCols, rowIndex, colIndex ); } template template inline Foam::ConstMatrixBlock> Foam::Matrix::block ( const label rowIndex, const label colIndex ) const { return ConstMatrixBlock ( *this, VectorSpace::mRows, VectorSpace::nCols, rowIndex, colIndex ); } template inline Foam::MatrixBlock> Foam::Matrix::subColumn ( const label colIndex, const label rowIndex, label len ) { if (len < 0) { len = mRows_ - rowIndex; } return MatrixBlock ( *this, len, // rows 1, rowIndex, colIndex ); } template inline Foam::MatrixBlock> Foam::Matrix::subRow ( const label rowIndex, const label colIndex, label len ) { if (len < 0) { len = nCols_ - colIndex; } return MatrixBlock ( *this, 1, len, // columns rowIndex, colIndex ); } template inline Foam::MatrixBlock> Foam::Matrix::subMatrix ( const label rowIndex, const label colIndex, label szRows, label szCols ) { if (szRows < 0) szRows = mRows_ - rowIndex; if (szCols < 0) szCols = nCols_ - colIndex; return MatrixBlock ( *this, szRows, szCols, rowIndex, colIndex ); } template template inline Foam::MatrixBlock> Foam::Matrix::block ( const label rowIndex, const label colIndex ) { return MatrixBlock ( *this, VectorSpace::mRows, VectorSpace::nCols, rowIndex, colIndex ); } template inline void Foam::Matrix::setSize(const label m, const label n) { resize(m, n); } template void Foam::Matrix::shallowResize(const label m, const label n) { mRows_ = m; nCols_ = n; } template inline Foam::tmp> Foam::Matrix::Amul ( const UList& x ) const { return this->AmulImpl(x); } template template inline Foam::tmp> Foam::Matrix::Amul ( const IndirectListBase& x ) const { return this->AmulImpl(x); } template inline Foam::tmp> Foam::Matrix::Tmul ( const UList& x ) const { return this->TmulImpl(x); } template template inline Foam::tmp> Foam::Matrix::Tmul ( const IndirectListBase& x ) const { return this->TmulImpl(x); } // * * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * // template inline typename Foam::Matrix::iterator Foam::Matrix::begin() { return v_; } template inline typename Foam::Matrix::iterator Foam::Matrix::end() { return v_ + (mRows_ * nCols_); } template inline typename Foam::Matrix::const_iterator Foam::Matrix::cbegin() const { return v_; } template inline typename Foam::Matrix::const_iterator Foam::Matrix::cend() const { return v_ + (mRows_ * nCols_); } template inline typename Foam::Matrix::const_iterator Foam::Matrix::begin() const { return v_; } template inline typename Foam::Matrix::const_iterator Foam::Matrix::end() const { return v_ + (mRows_ * nCols_); } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template inline const Type& Foam::Matrix::operator() ( const label irow, const label jcol ) const { #ifdef FULLDEBUG checki(irow); checkj(jcol); #endif return v_[irow*nCols_ + jcol]; } template inline Type& Foam::Matrix::operator() ( const label irow, const label jcol ) { #ifdef FULLDEBUG checki(irow); checkj(jcol); #endif return v_[irow*nCols_ + jcol]; } template inline const Type* Foam::Matrix::operator[](const label irow) const { #ifdef FULLDEBUG checki(irow); #endif return v_ + irow*nCols_; } template inline Type* Foam::Matrix::operator[](const label irow) { #ifdef FULLDEBUG checki(irow); #endif return v_ + irow*nCols_; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // //- Matrix-vector multiplication (A * x), where x is a column vector template inline tmp> operator* ( const Matrix& mat, const UList& x ) { return mat.Amul(x); } //- Matrix-vector multiplication (A * x), where x is a column vector template inline tmp> operator* ( const Matrix& mat, const IndirectListBase& x ) { return mat.Amul(x); } //- Vector-Matrix multiplication (x * A), where x is a row vector template inline tmp> operator* ( const UList& x, const Matrix& mat ) { return mat.Tmul(x); } //- Vector-Matrix multiplication (x * A), where x is a row vector template inline tmp> operator* ( const IndirectListBase& x, const Matrix& mat ) { return mat.Tmul(x); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // ************************************************************************* //