/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2016-2023 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 . Class Foam::fvMatrix Description A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise. SourceFiles fvMatrix.C fvMatrixSolve.C fvScalarMatrix.C \*---------------------------------------------------------------------------*/ #ifndef Foam_fvMatrix_H #define Foam_fvMatrix_H #include "volFields.H" #include "surfaceFields.H" #include "lduMatrix.H" #include "tmp.H" #include "autoPtr.H" #include "dimensionedTypes.H" #include "className.H" #include "lduPrimitiveMeshAssembly.H" #include "lduMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // Forward Declarations template class fvMatrix; template class UIndirectList; template Ostream& operator<<(Ostream&, const fvMatrix&); template tmp> operator& ( const fvMatrix&, const DimensionedField& ); template tmp> operator& ( const fvMatrix&, const tmp>& ); template tmp> operator& ( const fvMatrix&, const tmp>& ); template tmp> operator& ( const tmp>&, const DimensionedField& ); template tmp> operator& ( const tmp>&, const tmp>& ); template tmp> operator& ( const tmp>&, const tmp>& ); /*---------------------------------------------------------------------------*\ Class fvMatrix Declaration \*---------------------------------------------------------------------------*/ template class fvMatrix : public refCount, public lduMatrix { public: // Public Types //- The geometric field type for psi typedef GeometricField psiFieldType; //- Field type for face flux (for non-orthogonal correction) typedef GeometricField faceFluxFieldType; /// //- The internal field type for the psi field /// typedef DimensionedField Internal; private: // Private Data //- Const reference to field // Converted into a non-const reference at the point of solution. const psiFieldType& psi_; //- Originating fvMatrices when assembling matrices. Empty if not used. PtrList> subMatrices_; //- Is the fvMatrix using implicit formulation bool useImplicit_; //- Name of the lduAssembly word lduAssemblyName_; //- Number of fvMatrices added to this label nMatrix_; //- Dimension set dimensionSet dimensions_; //- Source term Field source_; //- Boundary scalar field containing pseudo-matrix coeffs //- for internal cells FieldField internalCoeffs_; //- Boundary scalar field containing pseudo-matrix coeffs //- for boundary cells FieldField boundaryCoeffs_; //- Face flux field for non-orthogonal correction mutable std::unique_ptr faceFluxCorrectionPtr_; protected: //- Declare friendship with the fvSolver class friend class fvSolver; // Protected Member Functions //- Add patch contribution to internal field template void addToInternalField ( const labelUList& addr, const Field& pf, Field& intf ) const; template void addToInternalField ( const labelUList& addr, const tmp>& tpf, Field& intf ) const; //- Subtract patch contribution from internal field template void subtractFromInternalField ( const labelUList& addr, const Field& pf, Field& intf ) const; template void subtractFromInternalField ( const labelUList& addr, const tmp>& tpf, Field& intf ) const; // Implicit helper functions //- Name the implicit assembly addressing // \return true if assembly is used bool checkImplicit(const label fieldi = 0); // Matrix completion functionality void addBoundaryDiag ( scalarField& diag, const direction cmpt ) const; void addCmptAvBoundaryDiag(scalarField& diag) const; void addBoundarySource ( Field& source, const bool couples=true ) const; // Matrix manipulation functionality //- Set solution in given cells to the specified values template class ListType> void setValuesFromList ( const labelUList& cellLabels, const ListType& values ); public: //- Solver class returned by the solver function //- used for systems in which it is useful to cache the solver for reuse. // E.g. if the solver is potentially expensive to construct (AMG) and can // be used several times (PISO) class fvSolver { fvMatrix& fvMat_; autoPtr solver_; public: // Constructors fvSolver(fvMatrix& fvMat, autoPtr&& sol) : fvMat_(fvMat), solver_(std::move(sol)) {} // Member Functions //- Solve returning the solution statistics. // Solver controls read from dictionary SolverPerformance solve(const dictionary& solverControls); //- Solve returning the solution statistics. // Solver controls read from fvSolution SolverPerformance solve(); }; // Runtime information ClassName("fvMatrix"); // Constructors //- Construct given a field to solve for fvMatrix ( const GeometricField& psi, const dimensionSet& ds ); //- Copy construct fvMatrix(const fvMatrix&); //- Copy/move construct from tmp> fvMatrix(const tmp>&); //- Deprecated(2022-05) - construct with dimensionSet instead // \deprecated(2022-05) - construct with dimensionSet instead FOAM_DEPRECATED_FOR(2022-05, "Construct with dimensionSet") fvMatrix ( const GeometricField& psi, Istream& is ) : fvMatrix(psi, dimensionSet(is)) {} //- Construct and return a clone tmp> clone() const { return tmp>::New(*this); } //- Destructor virtual ~fvMatrix(); // Member Functions // Access // Coupling label nMatrices() const { return (nMatrix_ == 0 ? 1 : nMatrix_); } const fvMatrix& matrix(const label i) const { return (nMatrix_ == 0 ? *this : subMatrices_[i]); } fvMatrix& matrix(const label i) { return (nMatrix_ == 0 ? *this : subMatrices_[i]); } label globalPatchID ( const label fieldi, const label patchi ) const { if (!lduMeshPtr()) { return patchi; } else { return lduMeshPtr()->patchMap()[fieldi][patchi]; } } //- Transfer lower, upper, diag and source to this fvMatrix void transferFvMatrixCoeffs(); //- Create or update ldu assembly void createOrUpdateLduPrimitiveAssembly(); //- Access to lduPrimitiveMeshAssembly lduPrimitiveMeshAssembly* lduMeshPtr(); //- Const Access to lduPrimitiveMeshAssembly const lduPrimitiveMeshAssembly* lduMeshPtr() const; //- Manipulate matrix void manipulateMatrix(direction cmp); //- Manipulate boundary/internal coeffs for coupling void setBounAndInterCoeffs(); //- Set interfaces void setInterfaces ( lduInterfaceFieldPtrsList&, PtrDynList& newInterfaces ); //- Add internal and boundary contribution to local patches void mapContributions ( label fieldi, const FieldField& fluxContrib, FieldField& contrib, bool internal ) const; //- Return optional lduAdressing const lduPrimitiveMeshAssembly& lduMeshAssembly() { return *lduMeshPtr(); } //- Return psi const GeometricField& psi ( const label i = 0 ) const { return ( (i == 0 && nMatrix_ == 0) ? psi_ : matrix(i).psi() ); } GeometricField& psi ( const label i = 0 ) { return ( (i == 0 && nMatrix_ == 0) ? const_cast < GeometricField& >(psi_) : const_cast < GeometricField& > ( matrix(i).psi() ) ); } //- Clear multiple fvMatrices void clear() { subMatrices_.clear(); nMatrix_ = 0; } const dimensionSet& dimensions() const noexcept { return dimensions_; } Field& source() noexcept { return source_; } const Field& source() const noexcept { return source_; } //- fvBoundary scalar field containing pseudo-matrix coeffs //- for internal cells const FieldField& internalCoeffs() const noexcept { return internalCoeffs_; } //- fvBoundary scalar field containing pseudo-matrix coeffs //- for internal cells FieldField& internalCoeffs() noexcept { return internalCoeffs_; } //- fvBoundary scalar field containing pseudo-matrix coeffs //- for boundary cells const FieldField& boundaryCoeffs() const noexcept { return boundaryCoeffs_; } //- fvBoundary scalar field containing pseudo-matrix coeffs //- for boundary cells FieldField& boundaryCoeffs() noexcept { return boundaryCoeffs_; } //- Declare return type of the faceFluxCorrectionPtr() function typedef std::unique_ptr faceFluxFieldPtrType; //- Return pointer to face-flux non-orthogonal correction field faceFluxFieldPtrType& faceFluxCorrectionPtr() { return faceFluxCorrectionPtr_; } //- Set pointer to face-flux non-orthogonal correction field void faceFluxCorrectionPtr(faceFluxFieldType* flux) { faceFluxCorrectionPtr_.reset(flux); } //- True if face-flux non-orthogonal correction field exists bool hasFaceFluxCorrection() const noexcept { return bool(faceFluxCorrectionPtr_); } // Operations //- Set solution in given cells to the specified value //- and eliminate the corresponding equations from the matrix. void setValues ( const labelUList& cellLabels, const Type& value ); //- Set solution in given cells to the specified values //- and eliminate the corresponding equations from the matrix. void setValues ( const labelUList& cellLabels, const UList& values ); //- Set solution in given cells to the specified values //- and eliminate the corresponding equations from the matrix. void setValues ( const labelUList& cellLabels, const UIndirectList& values ); //- Set reference level for solution void setReference ( const label celli, const Type& value, const bool forceReference = false ); //- Set reference level for solution void setReferences ( const labelUList& cellLabels, const Type& value, const bool forceReference = false ); //- Set reference level for solution void setReferences ( const labelUList& cellLabels, const UList& values, const bool forceReference = false ); //- Set reference level for a component of the solution //- on a given patch face void setComponentReference ( const label patchi, const label facei, const direction cmpt, const scalar value ); //- Add fvMatrix void addFvMatrix(fvMatrix& matrix); //- Relax matrix (for steady-state solution). // alpha = 1 : diagonally equal // alpha < 1 : diagonally dominant // alpha = 0 : do nothing // Note: Requires positive diagonal. void relax(const scalar alpha); //- Relax matrix (for steady-state solution). // alpha is read from controlDict void relax(); //- Manipulate based on a boundary field void boundaryManipulate ( typename GeometricField:: Boundary& values ); //- Construct and return the solver // Use the given solver controls autoPtr solver(const dictionary&); //- Construct and return the solver // Solver controls read from fvSolution autoPtr solver(); //- Solve segregated or coupled returning the solution statistics. // Use the given solver controls SolverPerformance solveSegregatedOrCoupled(const dictionary&); //- Solve segregated or coupled returning the solution statistics. // Solver controls read from fvSolution SolverPerformance solveSegregatedOrCoupled(); //- Solve segregated returning the solution statistics. // Use the given solver controls SolverPerformance solveSegregated(const dictionary&); //- Solve coupled returning the solution statistics. // Use the given solver controls SolverPerformance solveCoupled(const dictionary&); //- Solve returning the solution statistics. // Use the given solver controls SolverPerformance solve(const dictionary&); //- Solve returning the solution statistics. // Uses \p name solver controls from fvSolution SolverPerformance solve(const word& name); //- Solve returning the solution statistics. // Solver controls read from fvSolution SolverPerformance solve(); //- Return the matrix residual tmp> residual() const; //- Return the matrix scalar diagonal tmp D() const; //- Return the matrix Type diagonal tmp> DD() const; //- Return the central coefficient tmp A() const; //- Return the H operation source tmp> H() const; //- Return H(1) tmp H1() const; //- Return the face-flux field from the matrix tmp> flux() const; //- Return the solver dictionary (from fvSolution) for \p name const dictionary& solverDict(const word& name) const; //- Return the solver dictionary for psi, //- taking into account finalIteration const dictionary& solverDict() const; // Member Operators void operator=(const fvMatrix&); void operator=(const tmp>&); //- Inplace negate void negate(); void operator+=(const fvMatrix&); void operator+=(const tmp>&); void operator-=(const fvMatrix&); void operator-=(const tmp>&); void operator+=(const DimensionedField&); void operator+=(const tmp>&); void operator+= ( const tmp>& ); void operator-=(const DimensionedField&); void operator-=(const tmp>&); void operator-= ( const tmp>& ); void operator+=(const dimensioned&); void operator-=(const dimensioned&); void operator+=(Foam::zero) {} void operator-=(Foam::zero) {} void operator*=(const volScalarField::Internal&); void operator*=(const tmp&); void operator*=(const tmp&); void operator*=(const dimensioned&); // Friend Operators friend tmp> operator& ( const fvMatrix&, const DimensionedField& ); friend tmp> operator& ( const fvMatrix&, const tmp>& ); friend tmp> operator& ( const tmp>&, const DimensionedField& ); friend tmp> operator& ( const tmp>&, const tmp>& ); // Ostream Operator friend Ostream& operator<< ( Ostream&, const fvMatrix& ); }; // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // template void checkMethod ( const fvMatrix&, const fvMatrix&, const char* ); template void checkMethod ( const fvMatrix&, const DimensionedField&, const char* ); template void checkMethod ( const fvMatrix&, const dimensioned&, const char* ); //- Solve returning the solution statistics given convergence tolerance // Use the given solver controls template SolverPerformance solve ( fvMatrix&, const dictionary& solverControls ); //- Solve returning the solution statistics given convergence tolerance, //- deleting temporary matrix after solution. // Use the given solver controls template SolverPerformance solve ( const tmp>&, const dictionary& solverControls ); //- Solve returning the solution statistics given convergence tolerance // Uses \p name solver controls from fvSolution template SolverPerformance solve(fvMatrix&, const word& name); //- Solve returning the solution statistics given convergence tolerance, //- deleting temporary matrix after solution. // Uses \p name solver controls from fvSolution template SolverPerformance solve(const tmp>&, const word& name); //- Solve returning the solution statistics given convergence tolerance // Uses solver controls from fvSolution template SolverPerformance solve(fvMatrix&); //- Solve returning the solution statistics given convergence tolerance, //- deleting temporary matrix after solution. // Uses solver controls from fvSolution template SolverPerformance solve(const tmp>&); //- Return the correction form of the given matrix //- by subtracting the matrix multiplied by the current field template tmp> correction(const fvMatrix&); //- Return the correction form of the given temporary matrix //- by subtracting the matrix multiplied by the current field template tmp> correction(const tmp>&); // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // template tmp> operator== ( const fvMatrix&, const fvMatrix& ); template tmp> operator== ( const tmp>&, const fvMatrix& ); template tmp> operator== ( const fvMatrix&, const tmp>& ); template tmp> operator== ( const tmp>&, const tmp>& ); template tmp> operator== ( const fvMatrix&, const DimensionedField& ); template tmp> operator== ( const fvMatrix&, const tmp>& ); template tmp> operator== ( const fvMatrix&, const tmp>& ); template tmp> operator== ( const tmp>&, const DimensionedField& ); template tmp> operator== ( const tmp>&, const tmp>& ); template tmp> operator== ( const tmp>&, const tmp>& ); template tmp> operator== ( const fvMatrix&, const dimensioned& ); template tmp> operator== ( const tmp>&, const dimensioned& ); template tmp> operator== ( const fvMatrix&, const Foam::zero ); template tmp> operator== ( const tmp>&, const Foam::zero ); //- Unary negation template tmp> operator- ( const fvMatrix& ); //- Unary negation template tmp> operator- ( const tmp>& ); template tmp> operator+ ( const fvMatrix&, const fvMatrix& ); template tmp> operator+ ( const tmp>&, const fvMatrix& ); template tmp> operator+ ( const fvMatrix&, const tmp>& ); template tmp> operator+ ( const tmp>&, const tmp>& ); template tmp> operator+ ( const fvMatrix&, const DimensionedField& ); template tmp> operator+ ( const fvMatrix&, const tmp>& ); template tmp> operator+ ( const fvMatrix&, const tmp>& ); template tmp> operator+ ( const tmp>&, const DimensionedField& ); template tmp> operator+ ( const tmp>&, const tmp>& ); template tmp> operator+ ( const tmp>&, const tmp>& ); template tmp> operator+ ( const DimensionedField&, const fvMatrix& ); template tmp> operator+ ( const tmp>&, const fvMatrix& ); template tmp> operator+ ( const tmp>&, const fvMatrix& ); template tmp> operator+ ( const DimensionedField&, const tmp>& ); template tmp> operator+ ( const tmp>&, const tmp>& ); template tmp> operator+ ( const tmp>&, const tmp>& ); template tmp> operator+ ( const fvMatrix&, const dimensioned& ); template tmp> operator+ ( const tmp>&, const dimensioned& ); template tmp> operator+ ( const dimensioned&, const fvMatrix& ); template tmp> operator+ ( const dimensioned&, const tmp>& ); template tmp> operator- ( const fvMatrix&, const fvMatrix& ); template tmp> operator- ( const tmp>&, const fvMatrix& ); template tmp> operator- ( const fvMatrix&, const tmp>& ); template tmp> operator- ( const tmp>&, const tmp>& ); template tmp> operator- ( const fvMatrix&, const DimensionedField& ); template tmp> operator- ( const fvMatrix&, const tmp>& ); template tmp> operator- ( const fvMatrix&, const tmp>& ); template tmp> operator- ( const tmp>&, const DimensionedField& ); template tmp> operator- ( const tmp>&, const tmp>& ); template tmp> operator- ( const tmp>&, const tmp>& ); template tmp> operator- ( const DimensionedField&, const fvMatrix& ); template tmp> operator- ( const tmp>&, const fvMatrix& ); template tmp> operator- ( const tmp>&, const fvMatrix& ); template tmp> operator- ( const DimensionedField&, const tmp>& ); template tmp> operator- ( const tmp>&, const tmp>& ); template tmp> operator- ( const tmp>&, const tmp>& ); template tmp> operator- ( const fvMatrix&, const dimensioned& ); template tmp> operator- ( const tmp>&, const dimensioned& ); template tmp> operator- ( const dimensioned&, const fvMatrix& ); template tmp> operator- ( const dimensioned&, const tmp>& ); template tmp> operator* ( const volScalarField::Internal&, const fvMatrix& ); template tmp> operator* ( const tmp&, const fvMatrix& ); template tmp> operator* ( const tmp&, const fvMatrix& ); template tmp> operator* ( const volScalarField::Internal&, const tmp>& ); template tmp> operator* ( const tmp&, const tmp>& ); template tmp> operator* ( const tmp&, const tmp>& ); template tmp> operator* ( const dimensioned&, const fvMatrix& ); template tmp> operator* ( const dimensioned&, const tmp>& ); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository #include "fvMatrix.C" #endif // Specialisation for scalars #include "fvScalarMatrix.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* //