Go to the documentation of this file.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/GaussSeidelSmoother.H>
00027
00028
00029
00030 namespace Foam
00031 {
00032 defineTypeNameAndDebug(GaussSeidelSmoother, 0);
00033
00034 lduMatrix::smoother::addsymMatrixConstructorToTable<GaussSeidelSmoother>
00035 addGaussSeidelSmootherSymMatrixConstructorToTable_;
00036
00037 lduMatrix::smoother::addasymMatrixConstructorToTable<GaussSeidelSmoother>
00038 addGaussSeidelSmootherAsymMatrixConstructorToTable_;
00039 }
00040
00041
00042
00043
00044 Foam::GaussSeidelSmoother::GaussSeidelSmoother
00045 (
00046 const word& fieldName,
00047 const lduMatrix& matrix,
00048 const FieldField<Field, scalar>& interfaceBouCoeffs,
00049 const FieldField<Field, scalar>& interfaceIntCoeffs,
00050 const lduInterfaceFieldPtrsList& interfaces
00051 )
00052 :
00053 lduMatrix::smoother
00054 (
00055 fieldName,
00056 matrix,
00057 interfaceBouCoeffs,
00058 interfaceIntCoeffs,
00059 interfaces
00060 )
00061 {}
00062
00063
00064
00065
00066 void Foam::GaussSeidelSmoother::smooth
00067 (
00068 const word& fieldName_,
00069 scalarField& psi,
00070 const lduMatrix& matrix_,
00071 const scalarField& source,
00072 const FieldField<Field, scalar>& interfaceBouCoeffs_,
00073 const lduInterfaceFieldPtrsList& interfaces_,
00074 const direction cmpt,
00075 const label nSweeps
00076 )
00077 {
00078 register scalar* __restrict__ psiPtr = psi.begin();
00079
00080 register const label nCells = psi.size();
00081
00082 scalarField bPrime(nCells);
00083 register scalar* __restrict__ bPrimePtr = bPrime.begin();
00084
00085 register const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
00086 register const scalar* const __restrict__ upperPtr =
00087 matrix_.upper().begin();
00088 register const scalar* const __restrict__ lowerPtr =
00089 matrix_.lower().begin();
00090
00091 register const label* const __restrict__ uPtr =
00092 matrix_.lduAddr().upperAddr().begin();
00093
00094 register const label* const __restrict__ ownStartPtr =
00095 matrix_.lduAddr().ownerStartAddr().begin();
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 FieldField<Field, scalar> mBouCoeffs(interfaceBouCoeffs_.size());
00111
00112 forAll(mBouCoeffs, patchi)
00113 {
00114 if (interfaces_.set(patchi))
00115 {
00116 mBouCoeffs.set(patchi, -interfaceBouCoeffs_[patchi]);
00117 }
00118 }
00119
00120 for (label sweep=0; sweep<nSweeps; sweep++)
00121 {
00122 bPrime = source;
00123
00124 matrix_.initMatrixInterfaces
00125 (
00126 mBouCoeffs,
00127 interfaces_,
00128 psi,
00129 bPrime,
00130 cmpt
00131 );
00132
00133 matrix_.updateMatrixInterfaces
00134 (
00135 mBouCoeffs,
00136 interfaces_,
00137 psi,
00138 bPrime,
00139 cmpt
00140 );
00141
00142 register scalar curPsi;
00143 register label fStart;
00144 register label fEnd = ownStartPtr[0];
00145
00146 for (register label cellI=0; cellI<nCells; cellI++)
00147 {
00148
00149 fStart = fEnd;
00150 fEnd = ownStartPtr[cellI + 1];
00151
00152
00153 curPsi = bPrimePtr[cellI];
00154
00155
00156 for (register label curFace=fStart; curFace<fEnd; curFace++)
00157 {
00158 curPsi -= upperPtr[curFace]*psiPtr[uPtr[curFace]];
00159 }
00160
00161
00162 curPsi /= diagPtr[cellI];
00163
00164
00165 for (register label curFace=fStart; curFace<fEnd; curFace++)
00166 {
00167 bPrimePtr[uPtr[curFace]] -= lowerPtr[curFace]*curPsi;
00168 }
00169
00170 psiPtr[cellI] = curPsi;
00171 }
00172 }
00173 }
00174
00175
00176 void Foam::GaussSeidelSmoother::smooth
00177 (
00178 scalarField& psi,
00179 const scalarField& source,
00180 const direction cmpt,
00181 const label nSweeps
00182 ) const
00183 {
00184 smooth
00185 (
00186 fieldName_,
00187 psi,
00188 matrix_,
00189 source,
00190 interfaceBouCoeffs_,
00191 interfaces_,
00192 cmpt,
00193 nSweeps
00194 );
00195 }
00196
00197
00198