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/GAMGSolver.H>
00027
00028
00029
00030 namespace Foam
00031 {
00032 defineTypeNameAndDebug(GAMGSolver, 0);
00033
00034 lduMatrix::solver::addsymMatrixConstructorToTable<GAMGSolver>
00035 addGAMGSolverMatrixConstructorToTable_;
00036
00037 lduMatrix::solver::addasymMatrixConstructorToTable<GAMGSolver>
00038 addGAMGAsymSolverMatrixConstructorToTable_;
00039 }
00040
00041
00042
00043
00044 Foam::GAMGSolver::GAMGSolver
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 const dictionary& solverControls
00052 )
00053 :
00054 lduMatrix::solver
00055 (
00056 fieldName,
00057 matrix,
00058 interfaceBouCoeffs,
00059 interfaceIntCoeffs,
00060 interfaces,
00061 solverControls
00062 ),
00063
00064
00065
00066 cacheAgglomeration_(false),
00067 nPreSweeps_(0),
00068 nPostSweeps_(2),
00069 nFinestSweeps_(2),
00070 scaleCorrection_(matrix.symmetric()),
00071 directSolveCoarsest_(false),
00072 agglomeration_(GAMGAgglomeration::New(matrix_, controlDict_)),
00073
00074 matrixLevels_(agglomeration_.size()),
00075 interfaceLevels_(agglomeration_.size()),
00076 interfaceLevelsBouCoeffs_(agglomeration_.size()),
00077 interfaceLevelsIntCoeffs_(agglomeration_.size())
00078 {
00079 readControls();
00080
00081 forAll(agglomeration_, fineLevelIndex)
00082 {
00083 agglomerateMatrix(fineLevelIndex);
00084 }
00085
00086 if (matrixLevels_.size())
00087 {
00088 const label coarsestLevel = matrixLevels_.size() - 1;
00089
00090 if (directSolveCoarsest_)
00091 {
00092 coarsestLUMatrixPtr_.set
00093 (
00094 new LUscalarMatrix
00095 (
00096 matrixLevels_[coarsestLevel],
00097 interfaceLevelsBouCoeffs_[coarsestLevel],
00098 interfaceLevels_[coarsestLevel]
00099 )
00100 );
00101 }
00102 }
00103 else
00104 {
00105 FatalErrorIn
00106 (
00107 "GAMGSolver::GAMGSolver"
00108 "("
00109 "const word& fieldName,"
00110 "const lduMatrix& matrix,"
00111 "const FieldField<Field, scalar>& interfaceBouCoeffs,"
00112 "const FieldField<Field, scalar>& interfaceIntCoeffs,"
00113 "const lduInterfaceFieldPtrsList& interfaces,"
00114 "const dictionary& solverControls"
00115 ")"
00116 ) << "No coarse levels created, either matrix too small for GAMG"
00117 " or nCellsInCoarsestLevel too large.\n"
00118 " Either choose another solver of reduce "
00119 "nCellsInCoarsestLevel."
00120 << exit(FatalError);
00121 }
00122 }
00123
00124
00125
00126
00127 Foam::GAMGSolver::~GAMGSolver()
00128 {
00129
00130 forAll (interfaceLevels_, leveli)
00131 {
00132 lduInterfaceFieldPtrsList& curLevel = interfaceLevels_[leveli];
00133
00134 forAll (curLevel, i)
00135 {
00136 if (curLevel.set(i))
00137 {
00138 delete curLevel(i);
00139 }
00140 }
00141 }
00142
00143 if (!cacheAgglomeration_)
00144 {
00145 delete &agglomeration_;
00146 }
00147 }
00148
00149
00150
00151
00152 void Foam::GAMGSolver::readControls()
00153 {
00154 lduMatrix::solver::readControls();
00155
00156
00157 controlDict_.readIfPresent("cacheAgglomeration", cacheAgglomeration_);
00158 controlDict_.readIfPresent("nPreSweeps", nPreSweeps_);
00159 controlDict_.readIfPresent("nPostSweeps", nPostSweeps_);
00160 controlDict_.readIfPresent("nFinestSweeps", nFinestSweeps_);
00161 controlDict_.readIfPresent("scaleCorrection", scaleCorrection_);
00162 controlDict_.readIfPresent("directSolveCoarsest", directSolveCoarsest_);
00163 }
00164
00165
00166 const Foam::lduMatrix& Foam::GAMGSolver::matrixLevel(const label i) const
00167 {
00168 if (i == 0)
00169 {
00170 return matrix_;
00171 }
00172 else
00173 {
00174 return matrixLevels_[i - 1];
00175 }
00176 }
00177
00178
00179 const Foam::lduInterfaceFieldPtrsList& Foam::GAMGSolver::interfaceLevel
00180 (
00181 const label i
00182 ) const
00183 {
00184 if (i == 0)
00185 {
00186 return interfaces_;
00187 }
00188 else
00189 {
00190 return interfaceLevels_[i - 1];
00191 }
00192 }
00193
00194
00195 const Foam::FieldField<Foam::Field, Foam::scalar>&
00196 Foam::GAMGSolver::interfaceBouCoeffsLevel
00197 (
00198 const label i
00199 ) const
00200 {
00201 if (i == 0)
00202 {
00203 return interfaceBouCoeffs_;
00204 }
00205 else
00206 {
00207 return interfaceLevelsBouCoeffs_[i - 1];
00208 }
00209 }
00210
00211
00212 const Foam::FieldField<Foam::Field, Foam::scalar>&
00213 Foam::GAMGSolver::interfaceIntCoeffsLevel
00214 (
00215 const label i
00216 ) const
00217 {
00218 if (i == 0)
00219 {
00220 return interfaceIntCoeffs_;
00221 }
00222 else
00223 {
00224 return interfaceLevelsIntCoeffs_[i - 1];
00225 }
00226 }
00227
00228
00229