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

lduMatrix.H

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 Class
00025     Foam::lduMatrix
00026 
00027 Description
00028     lduMatrix is a general matrix class in which the coefficients are
00029     stored as three arrays, one for the upper triangle, one for the
00030     lower triangle and a third for the diagonal.
00031 
00032     Addressing arrays must be supplied for the upper and lower triangles.
00033 
00034     It might be better if this class were organised as a hierachy starting
00035     from an empty matrix, then deriving diagonal, symmetric and asymmetric
00036     matrices.
00037 
00038 SourceFiles
00039     lduMatrixATmul.C
00040     lduMatrix.C
00041     lduMatrixTemplates.C
00042     lduMatrixOperations.C
00043     lduMatrixSolver.C
00044     lduMatrixPreconditioner.C
00045     lduMatrixTests.C
00046     lduMatrixUpdateMatrixInterfaces.C
00047 
00048 \*---------------------------------------------------------------------------*/
00049 
00050 #ifndef lduMatrix_H
00051 #define lduMatrix_H
00052 
00053 #include <OpenFOAM/lduMesh.H>
00054 #include <OpenFOAM/primitiveFieldsFwd.H>
00055 #include <OpenFOAM/FieldField.H>
00056 #include <OpenFOAM/lduInterfaceFieldPtrsList.H>
00057 #include <OpenFOAM/typeInfo.H>
00058 #include <OpenFOAM/autoPtr.H>
00059 #include <OpenFOAM/runTimeSelectionTables.H>
00060 
00061 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00062 
00063 namespace Foam
00064 {
00065 
00066 // Forward declaration of friend functions and operators
00067 
00068 class lduMatrix;
00069 Ostream& operator<<(Ostream&, const lduMatrix&);
00070 
00071 
00072 /*---------------------------------------------------------------------------*\
00073                            Class lduMatrix Declaration
00074 \*---------------------------------------------------------------------------*/
00075 
00076 class lduMatrix
00077 {
00078     // private data
00079 
00080         //- LDU mesh reference
00081         const lduMesh& lduMesh_;
00082 
00083         //- Coefficients (not including interfaces)
00084         scalarField *lowerPtr_, *diagPtr_, *upperPtr_;
00085 
00086 
00087 public:
00088 
00089     //- Class returned by the solver, containing performance statistics
00090     class solverPerformance
00091     {
00092         word   solverName_;
00093         word   fieldName_;
00094         scalar initialResidual_;
00095         scalar finalResidual_;
00096         label  noIterations_;
00097         bool   converged_;
00098         bool   singular_;
00099 
00100 
00101     public:
00102 
00103         // Constructors
00104 
00105             solverPerformance()
00106             :
00107                 initialResidual_(0),
00108                 finalResidual_(0),
00109                 noIterations_(0),
00110                 converged_(false),
00111                 singular_(false)
00112             {}
00113 
00114 
00115             solverPerformance
00116             (
00117                 const word&  solverName,
00118                 const word&  fieldName,
00119                 const scalar iRes = 0,
00120                 const scalar fRes = 0,
00121                 const label  nIter = 0,
00122                 const bool   converged = false,
00123                 const bool   singular = false
00124             )
00125             :
00126                 solverName_(solverName),
00127                 fieldName_(fieldName),
00128                 initialResidual_(iRes),
00129                 finalResidual_(fRes),
00130                 noIterations_(nIter),
00131                 converged_(converged),
00132                 singular_(singular)
00133             {}
00134 
00135 
00136         // Member functions
00137 
00138             //- Return solver name
00139             const word& solverName() const
00140             {
00141                 return solverName_;
00142             }
00143 
00144             //- Return initial residual
00145             scalar initialResidual() const
00146             {
00147                 return initialResidual_;
00148             }
00149 
00150             //- Return initial residual
00151             scalar& initialResidual()
00152             {
00153                 return initialResidual_;
00154             }
00155 
00156 
00157             //- Return final residual
00158             scalar finalResidual() const
00159             {
00160                 return finalResidual_;
00161             }
00162 
00163             //- Return final residual
00164             scalar& finalResidual()
00165             {
00166                 return finalResidual_;
00167             }
00168 
00169 
00170             //- Return number of iterations
00171             label nIterations() const
00172             {
00173                 return noIterations_;
00174             }
00175 
00176             //- Return number of iterations
00177             label& nIterations()
00178             {
00179                 return noIterations_;
00180             }
00181 
00182 
00183             //- Has the solver converged?
00184             bool converged() const
00185             {
00186                 return converged_;
00187             }
00188 
00189             //- Is the matrix singular?
00190             bool singular() const
00191             {
00192                 return singular_;
00193             }
00194 
00195             //- Convergence test
00196             bool checkConvergence
00197             (
00198                 const scalar tolerance,
00199                 const scalar relTolerance
00200             );
00201 
00202             //- Singularity test
00203             bool checkSingularity(const scalar residual);
00204 
00205             //- Print summary of solver performance
00206             void print() const;
00207     };
00208 
00209 
00210     //- Abstract base-class for lduMatrix solvers
00211     class solver
00212     {
00213     protected:
00214 
00215         // Protected data
00216 
00217             word fieldName_;
00218             const lduMatrix& matrix_;
00219             const FieldField<Field, scalar>& interfaceBouCoeffs_;
00220             const FieldField<Field, scalar>& interfaceIntCoeffs_;
00221             lduInterfaceFieldPtrsList interfaces_;
00222 
00223             //- dictionary of controls
00224             dictionary controlDict_;
00225 
00226             //- Maximum number of iterations in the solver
00227             label maxIter_;
00228 
00229             //- Final convergence tolerance
00230             scalar tolerance_;
00231 
00232             //- Convergence tolerance relative to the initial
00233             scalar relTol_;
00234 
00235 
00236         // Protected Member Functions
00237 
00238             //- Read the control parameters from the controlDict_
00239             virtual void readControls();
00240 
00241 
00242     public:
00243 
00244         //- Runtime type information
00245         virtual const word& type() const = 0;
00246 
00247 
00248         // Declare run-time constructor selection tables
00249 
00250             declareRunTimeSelectionTable
00251             (
00252                 autoPtr,
00253                 solver,
00254                 symMatrix,
00255                 (
00256                     const word& fieldName,
00257                     const lduMatrix& matrix,
00258                     const FieldField<Field, scalar>& interfaceBouCoeffs,
00259                     const FieldField<Field, scalar>& interfaceIntCoeffs,
00260                     const lduInterfaceFieldPtrsList& interfaces,
00261                     const dictionary& solverControls
00262                 ),
00263                 (
00264                     fieldName,
00265                     matrix,
00266                     interfaceBouCoeffs,
00267                     interfaceIntCoeffs,
00268                     interfaces,
00269                     solverControls
00270                 )
00271             );
00272 
00273             declareRunTimeSelectionTable
00274             (
00275                 autoPtr,
00276                 solver,
00277                 asymMatrix,
00278                 (
00279                     const word& fieldName,
00280                     const lduMatrix& matrix,
00281                     const FieldField<Field, scalar>& interfaceBouCoeffs,
00282                     const FieldField<Field, scalar>& interfaceIntCoeffs,
00283                     const lduInterfaceFieldPtrsList& interfaces,
00284                     const dictionary& solverControls
00285                 ),
00286                 (
00287                     fieldName,
00288                     matrix,
00289                     interfaceBouCoeffs,
00290                     interfaceIntCoeffs,
00291                     interfaces,
00292                     solverControls
00293                 )
00294             );
00295 
00296 
00297         // Constructors
00298 
00299             solver
00300             (
00301                 const word& fieldName,
00302                 const lduMatrix& matrix,
00303                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00304                 const FieldField<Field, scalar>& interfaceIntCoeffs,
00305                 const lduInterfaceFieldPtrsList& interfaces,
00306                 const dictionary& solverControls
00307             );
00308 
00309         // Selectors
00310 
00311             //- Return a new solver
00312             static autoPtr<solver> New
00313             (
00314                 const word& fieldName,
00315                 const lduMatrix& matrix,
00316                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00317                 const FieldField<Field, scalar>& interfaceIntCoeffs,
00318                 const lduInterfaceFieldPtrsList& interfaces,
00319                 const dictionary& solverControls
00320             );
00321 
00322 
00323 
00324         // Destructor
00325 
00326             virtual ~solver()
00327             {}
00328 
00329 
00330         // Member functions
00331 
00332             // Access
00333 
00334                 const word& fieldName() const
00335                 {
00336                     return fieldName_;
00337                 }
00338 
00339                 const lduMatrix& matrix() const
00340                 {
00341                     return matrix_;
00342                 }
00343 
00344                  const FieldField<Field, scalar>& interfaceBouCoeffs() const
00345                  {
00346                      return interfaceBouCoeffs_;
00347                  }
00348 
00349                  const FieldField<Field, scalar>& interfaceIntCoeffs() const
00350                  {
00351                      return interfaceIntCoeffs_;
00352                  }
00353 
00354                  const lduInterfaceFieldPtrsList& interfaces() const
00355                  {
00356                      return interfaces_;
00357                  }
00358 
00359 
00360             //- Read and reset the solver parameters from the given stream
00361             virtual void read(const dictionary&);
00362 
00363             virtual solverPerformance solve
00364             (
00365                 scalarField& psi,
00366                 const scalarField& source,
00367                 const direction cmpt=0
00368             ) const = 0;
00369 
00370             //- Return the matrix norm used to normalise the residual for the
00371             //  stopping criterion
00372             scalar normFactor
00373             (
00374                 const scalarField& psi,
00375                 const scalarField& source,
00376                 const scalarField& Apsi,
00377                 scalarField& tmpField
00378             ) const;
00379     };
00380 
00381 
00382     //- Abstract base-class for lduMatrix smoothers
00383     class smoother
00384     {
00385     protected:
00386 
00387         // Protected data
00388 
00389             word fieldName_;
00390             const lduMatrix& matrix_;
00391             const FieldField<Field, scalar>& interfaceBouCoeffs_;
00392             const FieldField<Field, scalar>& interfaceIntCoeffs_;
00393             const lduInterfaceFieldPtrsList& interfaces_;
00394 
00395 
00396     public:
00397 
00398         //- Find the smoother name (directly or from a sub-dictionary)
00399         static word getName(const dictionary&);
00400 
00401         //- Runtime type information
00402         virtual const word& type() const = 0;
00403 
00404 
00405         // Declare run-time constructor selection tables
00406 
00407             declareRunTimeSelectionTable
00408             (
00409                 autoPtr,
00410                 smoother,
00411                 symMatrix,
00412                 (
00413                     const word& fieldName,
00414                     const lduMatrix& matrix,
00415                     const FieldField<Field, scalar>& interfaceBouCoeffs,
00416                     const FieldField<Field, scalar>& interfaceIntCoeffs,
00417                     const lduInterfaceFieldPtrsList& interfaces
00418                 ),
00419                 (
00420                     fieldName,
00421                     matrix,
00422                     interfaceBouCoeffs,
00423                     interfaceIntCoeffs,
00424                     interfaces
00425                 )
00426             );
00427 
00428             declareRunTimeSelectionTable
00429             (
00430                 autoPtr,
00431                 smoother,
00432                 asymMatrix,
00433                 (
00434                     const word& fieldName,
00435                     const lduMatrix& matrix,
00436                     const FieldField<Field, scalar>& interfaceBouCoeffs,
00437                     const FieldField<Field, scalar>& interfaceIntCoeffs,
00438                     const lduInterfaceFieldPtrsList& interfaces
00439                 ),
00440                 (
00441                     fieldName,
00442                     matrix,
00443                     interfaceBouCoeffs,
00444                     interfaceIntCoeffs,
00445                     interfaces
00446                 )
00447             );
00448 
00449 
00450         // Constructors
00451 
00452             smoother
00453             (
00454                 const word& fieldName,
00455                 const lduMatrix& matrix,
00456                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00457                 const FieldField<Field, scalar>& interfaceIntCoeffs,
00458                 const lduInterfaceFieldPtrsList& interfaces
00459             );
00460 
00461 
00462         // Selectors
00463 
00464             //- Return a new smoother
00465             static autoPtr<smoother> New
00466             (
00467                 const word& fieldName,
00468                 const lduMatrix& matrix,
00469                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00470                 const FieldField<Field, scalar>& interfaceIntCoeffs,
00471                 const lduInterfaceFieldPtrsList& interfaces,
00472                 const dictionary& solverControls
00473             );
00474 
00475 
00476         // Destructor
00477 
00478             virtual ~smoother()
00479             {}
00480 
00481 
00482         // Member functions
00483 
00484             // Access
00485 
00486                 const word& fieldName() const
00487                 {
00488                     return fieldName_;
00489                 }
00490 
00491                 const lduMatrix& matrix() const
00492                 {
00493                     return matrix_;
00494                 }
00495 
00496                  const FieldField<Field, scalar>& interfaceBouCoeffs() const
00497                  {
00498                      return interfaceBouCoeffs_;
00499                  }
00500 
00501                  const FieldField<Field, scalar>& interfaceIntCoeffs() const
00502                  {
00503                      return interfaceIntCoeffs_;
00504                  }
00505 
00506                  const lduInterfaceFieldPtrsList& interfaces() const
00507                  {
00508                      return interfaces_;
00509                  }
00510 
00511 
00512             //- Smooth the solution for a given number of sweeps
00513             virtual void smooth
00514             (
00515                 scalarField& psi,
00516                 const scalarField& source,
00517                 const direction cmpt,
00518                 const label nSweeps
00519             ) const = 0;
00520     };
00521 
00522 
00523     //- Abstract base-class for lduMatrix preconditioners
00524     class preconditioner
00525     {
00526     protected:
00527 
00528         // Protected data
00529 
00530             //- Reference to the base-solver this preconditioner is used with
00531             const solver& solver_;
00532 
00533 
00534     public:
00535 
00536         //- Find the preconditioner name (directly or from a sub-dictionary)
00537         static word getName(const dictionary&);
00538 
00539         //- Runtime type information
00540         virtual const word& type() const = 0;
00541 
00542 
00543         // Declare run-time constructor selection tables
00544 
00545             declareRunTimeSelectionTable
00546             (
00547                 autoPtr,
00548                 preconditioner,
00549                 symMatrix,
00550                 (
00551                     const solver& sol,
00552                     const dictionary& solverControls
00553                 ),
00554                 (sol, solverControls)
00555             );
00556 
00557             declareRunTimeSelectionTable
00558             (
00559                 autoPtr,
00560                 preconditioner,
00561                 asymMatrix,
00562                 (
00563                     const solver& sol,
00564                     const dictionary& solverControls
00565                 ),
00566                 (sol, solverControls)
00567             );
00568 
00569 
00570         // Constructors
00571 
00572             preconditioner
00573             (
00574                 const solver& sol
00575             )
00576             :
00577                 solver_(sol)
00578             {}
00579 
00580 
00581         // Selectors
00582 
00583             //- Return a new preconditioner
00584             static autoPtr<preconditioner> New
00585             (
00586                 const solver& sol,
00587                 const dictionary& solverControls
00588             );
00589 
00590 
00591         // Destructor
00592 
00593             virtual ~preconditioner()
00594             {}
00595 
00596 
00597         // Member functions
00598 
00599             //- Read and reset the preconditioner parameters
00600             //  from the given stream
00601             virtual void read(const dictionary&)
00602             {}
00603 
00604             //- Return wA the preconditioned form of residual rA
00605             virtual void precondition
00606             (
00607                 scalarField& wA,
00608                 const scalarField& rA,
00609                 const direction cmpt=0
00610             ) const = 0;
00611 
00612             //- Return wT the transpose-matrix preconditioned form of
00613             //  residual rT.
00614             //  This is only required for preconditioning asymmetric matrices.
00615             virtual void preconditionT
00616             (
00617                 scalarField& wT,
00618                 const scalarField& rT,
00619                 const direction cmpt=0
00620             ) const
00621             {
00622                 notImplemented
00623                 (
00624                     type() +"::preconditionT"
00625                     "(scalarField& wT, const scalarField& rT, "
00626                     "const direction cmpt)"
00627                 );
00628             }
00629     };
00630 
00631 
00632     // Static data
00633 
00634         // Declare name of the class and its debug switch
00635         ClassName("lduMatrix");
00636 
00637         //- Large scalar for the use in solvers
00638         static const scalar great_;
00639 
00640         //- Small scalar for the use in solvers
00641         static const scalar small_;
00642 
00643 
00644     // Constructors
00645 
00646         //- Construct given an LDU addressed mesh.
00647         //  The coefficients are initially empty for subsequent setting.
00648         lduMatrix(const lduMesh&);
00649 
00650         //- Construct as copy
00651         lduMatrix(const lduMatrix&);
00652 
00653         //- Construct as copy or re-use as specified.
00654         lduMatrix(lduMatrix&, bool reUse);
00655 
00656         //- Construct given an LDU addressed mesh and an Istream
00657         //  from which the coefficients are read
00658         lduMatrix(const lduMesh&, Istream&);
00659 
00660 
00661     // Destructor
00662 
00663         ~lduMatrix();
00664 
00665 
00666     // Member functions
00667 
00668         // Access to addressing
00669 
00670             //- Return the LDU mesh from which the addressing is obtained
00671             const lduMesh& mesh() const
00672             {
00673                 return lduMesh_;
00674             }
00675 
00676             //- Return the LDU addressing
00677             const lduAddressing& lduAddr() const
00678             {
00679                 return lduMesh_.lduAddr();
00680             }
00681 
00682             //- Return the patch evaluation schedule
00683             const lduSchedule& patchSchedule() const
00684             {
00685                 return lduAddr().patchSchedule();
00686             }
00687 
00688 
00689         // Access to coefficients
00690 
00691             scalarField& lower();
00692             scalarField& diag();
00693             scalarField& upper();
00694 
00695             const scalarField& lower() const;
00696             const scalarField& diag() const;
00697             const scalarField& upper() const;
00698 
00699             bool hasDiag() const
00700             {
00701                 return (diagPtr_);
00702             }
00703 
00704             bool hasUpper() const
00705             {
00706                 return (upperPtr_);
00707             }
00708 
00709             bool hasLower() const
00710             {
00711                 return (lowerPtr_);
00712             }
00713 
00714             bool diagonal() const
00715             {
00716                 return (diagPtr_ && !lowerPtr_ && !upperPtr_);
00717             }
00718 
00719             bool symmetric() const
00720             {
00721                 return (diagPtr_ && (!lowerPtr_ && upperPtr_));
00722             }
00723 
00724             bool asymmetric() const
00725             {
00726                 return (diagPtr_ && lowerPtr_ && upperPtr_);
00727             }
00728 
00729 
00730         // operations
00731 
00732             void sumDiag();
00733             void negSumDiag();
00734 
00735             void sumMagOffDiag(scalarField& sumOff) const;
00736 
00737             //- Matrix multiplication with updated interfaces.
00738             void Amul
00739             (
00740                 scalarField&,
00741                 const tmp<scalarField>&,
00742                 const FieldField<Field, scalar>&,
00743                 const lduInterfaceFieldPtrsList&,
00744                 const direction cmpt
00745             ) const;
00746 
00747             //- Matrix transpose multiplication with updated interfaces.
00748             void Tmul
00749             (
00750                 scalarField&,
00751                 const tmp<scalarField>&,
00752                 const FieldField<Field, scalar>&,
00753                 const lduInterfaceFieldPtrsList&,
00754                 const direction cmpt
00755             ) const;
00756 
00757 
00758             //- Sum the coefficients on each row of the matrix
00759             void sumA
00760             (
00761                 scalarField&,
00762                 const FieldField<Field, scalar>&,
00763                 const lduInterfaceFieldPtrsList&
00764             ) const;
00765 
00766 
00767             void residual
00768             (
00769                 scalarField& rA,
00770                 const scalarField& psi,
00771                 const scalarField& source,
00772                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00773                 const lduInterfaceFieldPtrsList& interfaces,
00774                 const direction cmpt
00775             ) const;
00776 
00777             tmp<scalarField> residual
00778             (
00779                 const scalarField& psi,
00780                 const scalarField& source,
00781                 const FieldField<Field, scalar>& interfaceBouCoeffs,
00782                 const lduInterfaceFieldPtrsList& interfaces,
00783                 const direction cmpt
00784             ) const;
00785 
00786 
00787             //- Initialise the update of interfaced interfaces
00788             //  for matrix operations
00789             void initMatrixInterfaces
00790             (
00791                 const FieldField<Field, scalar>& interfaceCoeffs,
00792                 const lduInterfaceFieldPtrsList& interfaces,
00793                 const scalarField& psiif,
00794                 scalarField& result,
00795                 const direction cmpt
00796             ) const;
00797 
00798             //- Update interfaced interfaces for matrix operations
00799             void updateMatrixInterfaces
00800             (
00801                 const FieldField<Field, scalar>& interfaceCoeffs,
00802                 const lduInterfaceFieldPtrsList& interfaces,
00803                 const scalarField& psiif,
00804                 scalarField& result,
00805                 const direction cmpt
00806             ) const;
00807 
00808 
00809             template<class Type>
00810             tmp<Field<Type> > H(const Field<Type>&) const;
00811 
00812             template<class Type>
00813             tmp<Field<Type> > H(const tmp<Field<Type> >&) const;
00814 
00815             tmp<scalarField> H1() const;
00816 
00817             template<class Type>
00818             tmp<Field<Type> > faceH(const Field<Type>&) const;
00819 
00820             template<class Type>
00821             tmp<Field<Type> > faceH(const tmp<Field<Type> >&) const;
00822 
00823 
00824     // Member operators
00825 
00826         void operator=(const lduMatrix&);
00827 
00828         void negate();
00829 
00830         void operator+=(const lduMatrix&);
00831         void operator-=(const lduMatrix&);
00832 
00833         void operator*=(const scalarField&);
00834         void operator*=(scalar);
00835 
00836 
00837     // Ostream operator
00838 
00839         friend Ostream& operator<<(Ostream&, const lduMatrix&);
00840 };
00841 
00842 
00843 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00844 
00845 } // End namespace Foam
00846 
00847 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00848 
00849 #ifdef NoRepository
00850 #   include <OpenFOAM/lduMatrixTemplates.C>
00851 #endif
00852 
00853 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00854 
00855 #endif
00856 
00857 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines