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 "LUscalarMatrix.H"
00027 #include <OpenFOAM/lduMatrix.H>
00028 #include "procLduMatrix.H"
00029 #include "procLduInterface.H"
00030
00031
00032
00033 Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& matrix)
00034 :
00035 scalarSquareMatrix(matrix),
00036 pivotIndices_(n())
00037 {
00038 LUDecompose(*this, pivotIndices_);
00039 }
00040
00041
00042 Foam::LUscalarMatrix::LUscalarMatrix
00043 (
00044 const lduMatrix& ldum,
00045 const FieldField<Field, scalar>& interfaceCoeffs,
00046 const lduInterfaceFieldPtrsList& interfaces
00047 )
00048 {
00049 if (Pstream::parRun())
00050 {
00051 PtrList<procLduMatrix> lduMatrices(Pstream::nProcs());
00052
00053 label lduMatrixi = 0;
00054
00055 lduMatrices.set
00056 (
00057 lduMatrixi++,
00058 new procLduMatrix
00059 (
00060 ldum,
00061 interfaceCoeffs,
00062 interfaces
00063 )
00064 );
00065
00066 if (Pstream::master())
00067 {
00068 for
00069 (
00070 int slave=Pstream::firstSlave();
00071 slave<=Pstream::lastSlave();
00072 slave++
00073 )
00074 {
00075 lduMatrices.set
00076 (
00077 lduMatrixi++,
00078 new procLduMatrix(IPstream(Pstream::scheduled, slave)())
00079 );
00080 }
00081 }
00082 else
00083 {
00084 OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
00085 procLduMatrix cldum
00086 (
00087 ldum,
00088 interfaceCoeffs,
00089 interfaces
00090 );
00091 toMaster<< cldum;
00092
00093 }
00094
00095 if (Pstream::master())
00096 {
00097 label nCells = 0;
00098 forAll(lduMatrices, i)
00099 {
00100 nCells += lduMatrices[i].size();
00101 }
00102
00103 scalarSquareMatrix m(nCells, nCells, 0.0);
00104 transfer(m);
00105 convert(lduMatrices);
00106 }
00107 }
00108 else
00109 {
00110 label nCells = ldum.lduAddr().size();
00111 scalarSquareMatrix m(nCells, nCells, 0.0);
00112 transfer(m);
00113 convert(ldum, interfaceCoeffs, interfaces);
00114 }
00115
00116 if (Pstream::master())
00117 {
00118 pivotIndices_.setSize(n());
00119 LUDecompose(*this, pivotIndices_);
00120 }
00121 }
00122
00123
00124
00125
00126 void Foam::LUscalarMatrix::convert
00127 (
00128 const lduMatrix& ldum,
00129 const FieldField<Field, scalar>& interfaceCoeffs,
00130 const lduInterfaceFieldPtrsList& interfaces
00131 )
00132 {
00133 const label* __restrict__ uPtr = ldum.lduAddr().upperAddr().begin();
00134 const label* __restrict__ lPtr = ldum.lduAddr().lowerAddr().begin();
00135
00136 const scalar* __restrict__ diagPtr = ldum.diag().begin();
00137 const scalar* __restrict__ upperPtr = ldum.upper().begin();
00138 const scalar* __restrict__ lowerPtr = ldum.lower().begin();
00139
00140 register const label nCells = ldum.diag().size();
00141 register const label nFaces = ldum.upper().size();
00142
00143 for (register label cell=0; cell<nCells; cell++)
00144 {
00145 operator[](cell)[cell] = diagPtr[cell];
00146 }
00147
00148 for (register label face=0; face<nFaces; face++)
00149 {
00150 label uCell = uPtr[face];
00151 label lCell = lPtr[face];
00152
00153 operator[](uCell)[lCell] = lowerPtr[face];
00154 operator[](lCell)[uCell] = upperPtr[face];
00155 }
00156
00157 forAll(interfaces, inti)
00158 {
00159 if (interfaces.set(inti))
00160 {
00161 const lduInterface& interface = interfaces[inti].interface();
00162
00163 const label* __restrict__ ulPtr = interface.faceCells().begin();
00164 const scalar* __restrict__ upperLowerPtr =
00165 interfaceCoeffs[inti].begin();
00166
00167 register label inFaces = interface.faceCells().size()/2;
00168
00169 for (register label face=0; face<inFaces; face++)
00170 {
00171 label uCell = ulPtr[face];
00172 label lCell = ulPtr[face + inFaces];
00173
00174 operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
00175 operator[](lCell)[uCell] -= upperLowerPtr[face];
00176 }
00177 }
00178 }
00179
00180
00181 }
00182
00183
00184 void Foam::LUscalarMatrix::convert
00185 (
00186 const PtrList<procLduMatrix>& lduMatrices
00187 )
00188 {
00189 procOffsets_.setSize(lduMatrices.size() + 1);
00190 procOffsets_[0] = 0;
00191
00192 forAll(lduMatrices, ldumi)
00193 {
00194 procOffsets_[ldumi+1] = procOffsets_[ldumi] + lduMatrices[ldumi].size();
00195 }
00196
00197 forAll(lduMatrices, ldumi)
00198 {
00199 const procLduMatrix& lduMatrixi = lduMatrices[ldumi];
00200 label offset = procOffsets_[ldumi];
00201
00202 const label* __restrict__ uPtr = lduMatrixi.upperAddr_.begin();
00203 const label* __restrict__ lPtr = lduMatrixi.lowerAddr_.begin();
00204
00205 const scalar* __restrict__ diagPtr = lduMatrixi.diag_.begin();
00206 const scalar* __restrict__ upperPtr = lduMatrixi.upper_.begin();
00207 const scalar* __restrict__ lowerPtr = lduMatrixi.lower_.begin();
00208
00209 register const label nCells = lduMatrixi.size();
00210 register const label nFaces = lduMatrixi.upper_.size();
00211
00212 for (register label cell=0; cell<nCells; cell++)
00213 {
00214 label globalCell = cell + offset;
00215 operator[](globalCell)[globalCell] = diagPtr[cell];
00216 }
00217
00218 for (register label face=0; face<nFaces; face++)
00219 {
00220 label uCell = uPtr[face] + offset;
00221 label lCell = lPtr[face] + offset;
00222
00223 operator[](uCell)[lCell] = lowerPtr[face];
00224 operator[](lCell)[uCell] = upperPtr[face];
00225 }
00226
00227 const PtrList<procLduInterface>& interfaces =
00228 lduMatrixi.interfaces_;
00229
00230 forAll(interfaces, inti)
00231 {
00232 const procLduInterface& interface = interfaces[inti];
00233
00234 if (interface.myProcNo_ == interface.neighbProcNo_)
00235 {
00236 const label* __restrict__ ulPtr = interface.faceCells_.begin();
00237
00238 const scalar* __restrict__ upperLowerPtr =
00239 interface.coeffs_.begin();
00240
00241 register label inFaces = interface.faceCells_.size()/2;
00242
00243 for (register label face=0; face<inFaces; face++)
00244 {
00245 label uCell = ulPtr[face] + offset;
00246 label lCell = ulPtr[face + inFaces] + offset;
00247
00248 operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
00249 operator[](lCell)[uCell] -= upperLowerPtr[face];
00250 }
00251 }
00252 else if (interface.myProcNo_ < interface.neighbProcNo_)
00253 {
00254 const PtrList<procLduInterface>& neiInterfaces =
00255 lduMatrices[interface.neighbProcNo_].interfaces_;
00256
00257 label neiInterfacei = -1;
00258
00259 forAll(neiInterfaces, ninti)
00260 {
00261 if
00262 (
00263 neiInterfaces[ninti].neighbProcNo_
00264 == interface.myProcNo_
00265 )
00266 {
00267 neiInterfacei = ninti;
00268 break;
00269 }
00270 }
00271
00272 if (neiInterfacei == -1)
00273 {
00274 FatalErrorIn("LUscalarMatrix::convert") << exit(FatalError);
00275 }
00276
00277 const procLduInterface& neiInterface =
00278 neiInterfaces[neiInterfacei];
00279
00280 const label* __restrict__ uPtr = interface.faceCells_.begin();
00281 const label* __restrict__ lPtr = neiInterface.faceCells_.begin();
00282
00283 const scalar* __restrict__ upperPtr = interface.coeffs_.begin();
00284 const scalar* __restrict__ lowerPtr = neiInterface.coeffs_.begin();
00285
00286 register label inFaces = interface.faceCells_.size();
00287 label neiOffset = procOffsets_[interface.neighbProcNo_];
00288
00289 for (register label face=0; face<inFaces; face++)
00290 {
00291 label uCell = uPtr[face] + offset;
00292 label lCell = lPtr[face] + neiOffset;
00293
00294 operator[](uCell)[lCell] -= lowerPtr[face];
00295 operator[](lCell)[uCell] -= upperPtr[face];
00296 }
00297 }
00298 }
00299 }
00300
00301
00302 }
00303
00304
00305 void Foam::LUscalarMatrix::printDiagonalDominance() const
00306 {
00307 for (label i=0; i<n(); i++)
00308 {
00309 scalar sum = 0.0;
00310 for (label j=0; j<n(); j++)
00311 {
00312 if (i != j)
00313 {
00314 sum += operator[](i)[j];
00315 }
00316 }
00317 Info<< mag(sum)/mag(operator[](i)[i]) << endl;
00318 }
00319 }
00320
00321
00322