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 "lduMatrix.H"
00027 #include <OpenFOAM/diagonalSolver.H>
00028
00029
00030
00031 namespace Foam
00032 {
00033 defineRunTimeSelectionTable(lduMatrix::solver, symMatrix);
00034 defineRunTimeSelectionTable(lduMatrix::solver, asymMatrix);
00035 }
00036
00037
00038
00039
00040 Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
00041 (
00042 const word& fieldName,
00043 const lduMatrix& matrix,
00044 const FieldField<Field, scalar>& interfaceBouCoeffs,
00045 const FieldField<Field, scalar>& interfaceIntCoeffs,
00046 const lduInterfaceFieldPtrsList& interfaces,
00047 const dictionary& solverControls
00048 )
00049 {
00050 word name(solverControls.lookup("solver"));
00051
00052 if (matrix.diagonal())
00053 {
00054 return autoPtr<lduMatrix::solver>
00055 (
00056 new diagonalSolver
00057 (
00058 fieldName,
00059 matrix,
00060 interfaceBouCoeffs,
00061 interfaceIntCoeffs,
00062 interfaces,
00063 solverControls
00064 )
00065 );
00066 }
00067 else if (matrix.symmetric())
00068 {
00069 symMatrixConstructorTable::iterator constructorIter =
00070 symMatrixConstructorTablePtr_->find(name);
00071
00072 if (constructorIter == symMatrixConstructorTablePtr_->end())
00073 {
00074 FatalIOErrorIn
00075 (
00076 "lduMatrix::solver::New", solverControls
00077 ) << "Unknown symmetric matrix solver " << name << nl << nl
00078 << "Valid symmetric matrix solvers are :" << endl
00079 << symMatrixConstructorTablePtr_->sortedToc()
00080 << exit(FatalIOError);
00081 }
00082
00083 return autoPtr<lduMatrix::solver>
00084 (
00085 constructorIter()
00086 (
00087 fieldName,
00088 matrix,
00089 interfaceBouCoeffs,
00090 interfaceIntCoeffs,
00091 interfaces,
00092 solverControls
00093 )
00094 );
00095 }
00096 else if (matrix.asymmetric())
00097 {
00098 asymMatrixConstructorTable::iterator constructorIter =
00099 asymMatrixConstructorTablePtr_->find(name);
00100
00101 if (constructorIter == asymMatrixConstructorTablePtr_->end())
00102 {
00103 FatalIOErrorIn
00104 (
00105 "lduMatrix::solver::New", solverControls
00106 ) << "Unknown asymmetric matrix solver " << name << nl << nl
00107 << "Valid asymmetric matrix solvers are :" << endl
00108 << asymMatrixConstructorTablePtr_->sortedToc()
00109 << exit(FatalIOError);
00110 }
00111
00112 return autoPtr<lduMatrix::solver>
00113 (
00114 constructorIter()
00115 (
00116 fieldName,
00117 matrix,
00118 interfaceBouCoeffs,
00119 interfaceIntCoeffs,
00120 interfaces,
00121 solverControls
00122 )
00123 );
00124 }
00125 else
00126 {
00127 FatalIOErrorIn
00128 (
00129 "lduMatrix::solver::New", solverControls
00130 ) << "cannot solve incomplete matrix, "
00131 "no diagonal or off-diagonal coefficient"
00132 << exit(FatalIOError);
00133
00134 return autoPtr<lduMatrix::solver>(NULL);
00135 }
00136 }
00137
00138
00139
00140
00141 Foam::lduMatrix::solver::solver
00142 (
00143 const word& fieldName,
00144 const lduMatrix& matrix,
00145 const FieldField<Field, scalar>& interfaceBouCoeffs,
00146 const FieldField<Field, scalar>& interfaceIntCoeffs,
00147 const lduInterfaceFieldPtrsList& interfaces,
00148 const dictionary& solverControls
00149 )
00150 :
00151 fieldName_(fieldName),
00152 matrix_(matrix),
00153 interfaceBouCoeffs_(interfaceBouCoeffs),
00154 interfaceIntCoeffs_(interfaceIntCoeffs),
00155 interfaces_(interfaces),
00156 controlDict_(solverControls)
00157 {
00158 readControls();
00159 }
00160
00161
00162
00163
00164 void Foam::lduMatrix::solver::readControls()
00165 {
00166 maxIter_ = controlDict_.lookupOrDefault<label>("maxIter", 1000);
00167 tolerance_ = controlDict_.lookupOrDefault<scalar>("tolerance", 1e-6);
00168 relTol_ = controlDict_.lookupOrDefault<scalar>("relTol", 0);
00169 }
00170
00171
00172 void Foam::lduMatrix::solver::read(const dictionary& solverControls)
00173 {
00174 controlDict_ = solverControls;
00175 readControls();
00176 }
00177
00178
00179 Foam::scalar Foam::lduMatrix::solver::normFactor
00180 (
00181 const scalarField& psi,
00182 const scalarField& source,
00183 const scalarField& Apsi,
00184 scalarField& tmpField
00185 ) const
00186 {
00187
00188 matrix_.sumA(tmpField, interfaceBouCoeffs_, interfaces_);
00189 tmpField *= gAverage(psi);
00190
00191 return gSum(mag(Apsi - tmpField) + mag(source - tmpField)) + matrix_.small_;
00192
00193
00194
00195 }
00196
00197
00198