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

LUscalarMatrix.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 "LUscalarMatrix.H"
00027 #include <OpenFOAM/lduMatrix.H>
00028 #include "procLduMatrix.H"
00029 #include "procLduInterface.H"
00030 
00031 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00032 
00033 Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& matrix)
00034 :
00035     scalarSquareMatrix(matrix),
00036     pivotIndices_(n())
00037 {
00038     LUDecompose(*this, pivotIndices_);
00039 }
00040 
00041 
00042 Foam::LUscalarMatrix::LUscalarMatrix
00043 (
00044     const lduMatrix& ldum,
00045     const FieldField<Field, scalar>& interfaceCoeffs,
00046     const lduInterfaceFieldPtrsList& interfaces
00047 )
00048 {
00049     if (Pstream::parRun())
00050     {
00051         PtrList<procLduMatrix> lduMatrices(Pstream::nProcs());
00052 
00053         label lduMatrixi = 0;
00054 
00055         lduMatrices.set
00056         (
00057             lduMatrixi++,
00058             new procLduMatrix
00059             (
00060                 ldum,
00061                 interfaceCoeffs,
00062                 interfaces
00063             )
00064         );
00065 
00066         if (Pstream::master())
00067         {
00068             for
00069             (
00070                 int slave=Pstream::firstSlave();
00071                 slave<=Pstream::lastSlave();
00072                 slave++
00073             )
00074             {
00075                 lduMatrices.set
00076                 (
00077                     lduMatrixi++,
00078                     new procLduMatrix(IPstream(Pstream::scheduled, slave)())
00079                 );
00080             }
00081         }
00082         else
00083         {
00084             OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
00085             procLduMatrix cldum
00086             (
00087                 ldum,
00088                 interfaceCoeffs,
00089                 interfaces
00090             );
00091             toMaster<< cldum;
00092 
00093         }
00094 
00095         if (Pstream::master())
00096         {
00097             label nCells = 0;
00098             forAll(lduMatrices, i)
00099             {
00100                 nCells += lduMatrices[i].size();
00101             }
00102 
00103             scalarSquareMatrix m(nCells, nCells, 0.0);
00104             transfer(m);
00105             convert(lduMatrices);
00106         }
00107     }
00108     else
00109     {
00110         label nCells = ldum.lduAddr().size();
00111         scalarSquareMatrix m(nCells, nCells, 0.0);
00112         transfer(m);
00113         convert(ldum, interfaceCoeffs, interfaces);
00114     }
00115 
00116     if (Pstream::master())
00117     {
00118         pivotIndices_.setSize(n());
00119         LUDecompose(*this, pivotIndices_);
00120     }
00121 }
00122 
00123 
00124 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00125 
00126 void Foam::LUscalarMatrix::convert
00127 (
00128     const lduMatrix& ldum,
00129     const FieldField<Field, scalar>& interfaceCoeffs,
00130     const lduInterfaceFieldPtrsList& interfaces
00131 )
00132 {
00133     const label* __restrict__ uPtr = ldum.lduAddr().upperAddr().begin();
00134     const label* __restrict__ lPtr = ldum.lduAddr().lowerAddr().begin();
00135 
00136     const scalar* __restrict__ diagPtr = ldum.diag().begin();
00137     const scalar* __restrict__ upperPtr = ldum.upper().begin();
00138     const scalar* __restrict__ lowerPtr = ldum.lower().begin();
00139 
00140     register const label nCells = ldum.diag().size();
00141     register const label nFaces = ldum.upper().size();
00142 
00143     for (register label cell=0; cell<nCells; cell++)
00144     {
00145         operator[](cell)[cell] = diagPtr[cell];
00146     }
00147 
00148     for (register label face=0; face<nFaces; face++)
00149     {
00150         label uCell = uPtr[face];
00151         label lCell = lPtr[face];
00152 
00153         operator[](uCell)[lCell] = lowerPtr[face];
00154         operator[](lCell)[uCell] = upperPtr[face];
00155     }
00156 
00157     forAll(interfaces, inti)
00158     {
00159         if (interfaces.set(inti))
00160         {
00161             const lduInterface& interface = interfaces[inti].interface();
00162 
00163             const label* __restrict__ ulPtr = interface.faceCells().begin();
00164             const scalar* __restrict__ upperLowerPtr =
00165                 interfaceCoeffs[inti].begin();
00166 
00167             register label inFaces = interface.faceCells().size()/2;
00168 
00169             for (register label face=0; face<inFaces; face++)
00170             {
00171                 label uCell = ulPtr[face];
00172                 label lCell = ulPtr[face + inFaces];
00173 
00174                 operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
00175                 operator[](lCell)[uCell] -= upperLowerPtr[face];
00176             }
00177         }
00178     }
00179 
00180     //printDiagonalDominance();
00181 }
00182 
00183 
00184 void Foam::LUscalarMatrix::convert
00185 (
00186     const PtrList<procLduMatrix>& lduMatrices
00187 )
00188 {
00189     procOffsets_.setSize(lduMatrices.size() + 1);
00190     procOffsets_[0] = 0;
00191 
00192     forAll(lduMatrices, ldumi)
00193     {
00194         procOffsets_[ldumi+1] = procOffsets_[ldumi] + lduMatrices[ldumi].size();
00195     }
00196 
00197     forAll(lduMatrices, ldumi)
00198     {
00199         const procLduMatrix& lduMatrixi = lduMatrices[ldumi];
00200         label offset = procOffsets_[ldumi];
00201 
00202         const label* __restrict__ uPtr = lduMatrixi.upperAddr_.begin();
00203         const label* __restrict__ lPtr = lduMatrixi.lowerAddr_.begin();
00204 
00205         const scalar* __restrict__ diagPtr = lduMatrixi.diag_.begin();
00206         const scalar* __restrict__ upperPtr = lduMatrixi.upper_.begin();
00207         const scalar* __restrict__ lowerPtr = lduMatrixi.lower_.begin();
00208 
00209         register const label nCells = lduMatrixi.size();
00210         register const label nFaces = lduMatrixi.upper_.size();
00211 
00212         for (register label cell=0; cell<nCells; cell++)
00213         {
00214             label globalCell = cell + offset;
00215             operator[](globalCell)[globalCell] = diagPtr[cell];
00216         }
00217 
00218         for (register label face=0; face<nFaces; face++)
00219         {
00220             label uCell = uPtr[face] + offset;
00221             label lCell = lPtr[face] + offset;
00222 
00223             operator[](uCell)[lCell] = lowerPtr[face];
00224             operator[](lCell)[uCell] = upperPtr[face];
00225         }
00226 
00227         const PtrList<procLduInterface>& interfaces =
00228             lduMatrixi.interfaces_;
00229 
00230         forAll(interfaces, inti)
00231         {
00232             const procLduInterface& interface = interfaces[inti];
00233 
00234             if (interface.myProcNo_ == interface.neighbProcNo_)
00235             {
00236                 const label* __restrict__ ulPtr = interface.faceCells_.begin();
00237 
00238                 const scalar* __restrict__ upperLowerPtr =
00239                     interface.coeffs_.begin();
00240 
00241                 register label inFaces = interface.faceCells_.size()/2;
00242 
00243                 for (register label face=0; face<inFaces; face++)
00244                 {
00245                     label uCell = ulPtr[face] + offset;
00246                     label lCell = ulPtr[face + inFaces] + offset;
00247 
00248                     operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
00249                     operator[](lCell)[uCell] -= upperLowerPtr[face];
00250                 }
00251             }
00252             else if (interface.myProcNo_ < interface.neighbProcNo_)
00253             {
00254                 const PtrList<procLduInterface>& neiInterfaces =
00255                     lduMatrices[interface.neighbProcNo_].interfaces_;
00256 
00257                 label neiInterfacei = -1;
00258 
00259                 forAll(neiInterfaces, ninti)
00260                 {
00261                     if
00262                     (
00263                         neiInterfaces[ninti].neighbProcNo_
00264                      == interface.myProcNo_
00265                     )
00266                     {
00267                         neiInterfacei = ninti;
00268                         break;
00269                     }
00270                 }
00271 
00272                 if (neiInterfacei == -1)
00273                 {
00274                     FatalErrorIn("LUscalarMatrix::convert") << exit(FatalError);
00275                 }
00276 
00277                 const procLduInterface& neiInterface =
00278                     neiInterfaces[neiInterfacei];
00279 
00280                 const label* __restrict__ uPtr = interface.faceCells_.begin();
00281                 const label* __restrict__ lPtr = neiInterface.faceCells_.begin();
00282 
00283                 const scalar* __restrict__ upperPtr = interface.coeffs_.begin();
00284                 const scalar* __restrict__ lowerPtr = neiInterface.coeffs_.begin();
00285 
00286                 register label inFaces = interface.faceCells_.size();
00287                 label neiOffset = procOffsets_[interface.neighbProcNo_];
00288 
00289                 for (register label face=0; face<inFaces; face++)
00290                 {
00291                     label uCell = uPtr[face] + offset;
00292                     label lCell = lPtr[face] + neiOffset;
00293 
00294                     operator[](uCell)[lCell] -= lowerPtr[face];
00295                     operator[](lCell)[uCell] -= upperPtr[face];
00296                 }
00297             }
00298         }
00299     }
00300 
00301     //printDiagonalDominance();
00302 }
00303 
00304 
00305 void Foam::LUscalarMatrix::printDiagonalDominance() const
00306 {
00307     for (label i=0; i<n(); i++)
00308     {
00309         scalar sum = 0.0;
00310         for (label j=0; j<n(); j++)
00311         {
00312             if (i != j)
00313             {
00314                 sum += operator[](i)[j];
00315             }
00316         }
00317         Info<< mag(sum)/mag(operator[](i)[i]) << endl;
00318     }
00319 }
00320 
00321 
00322 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines