1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "LUscalarMatrix.H"
27 #include "lduMatrix.H"
28 #include "procLduMatrix.H"
29 #include "procLduInterface.H"
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& matrix)
35 scalarSquareMatrix(matrix),
38 LUDecompose(*this, pivotIndices_);
42 Foam::LUscalarMatrix::LUscalarMatrix
44 const lduMatrix& ldum,
45 const FieldField<Field, scalar>& interfaceCoeffs,
46 const lduInterfaceFieldPtrsList& interfaces
49 if (Pstream::parRun())
51 PtrList<procLduMatrix> lduMatrices(Pstream::nProcs());
66 if (Pstream::master())
70 int slave=Pstream::firstSlave();
71 slave<=Pstream::lastSlave();
78 new procLduMatrix(IPstream(Pstream::scheduled, slave)())
84 OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
95 if (Pstream::master())
98 forAll(lduMatrices, i)
100 nCells += lduMatrices[i].size();
103 scalarSquareMatrix m(nCells, 0.0);
105 convert(lduMatrices);
110 label nCells = ldum.lduAddr().size();
111 scalarSquareMatrix m(nCells, 0.0);
113 convert(ldum, interfaceCoeffs, interfaces);
116 if (Pstream::master())
118 pivotIndices_.setSize(n());
119 LUDecompose(*this, pivotIndices_);
124 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
126 void Foam::LUscalarMatrix::convert
128 const lduMatrix& ldum,
129 const FieldField<Field, scalar>& interfaceCoeffs,
130 const lduInterfaceFieldPtrsList& interfaces
133 const label* __restrict__ uPtr = ldum.lduAddr().upperAddr().begin();
134 const label* __restrict__ lPtr = ldum.lduAddr().lowerAddr().begin();
136 const scalar* __restrict__ diagPtr = ldum.diag().begin();
137 const scalar* __restrict__ upperPtr = ldum.upper().begin();
138 const scalar* __restrict__ lowerPtr = ldum.lower().begin();
140 register const label nCells = ldum.diag().size();
141 register const label nFaces = ldum.upper().size();
143 for (register label cell=0; cell<nCells; cell++)
145 operator[](cell)[cell] = diagPtr[cell];
148 for (register label face=0; face<nFaces; face++)
150 label uCell = uPtr[face];
151 label lCell = lPtr[face];
153 operator[](uCell)[lCell] = lowerPtr[face];
154 operator[](lCell)[uCell] = upperPtr[face];
157 forAll(interfaces, inti)
159 if (interfaces.set(inti))
161 const lduInterface& interface = interfaces[inti].coupledInterface();
163 const label* __restrict__ ulPtr = interface.faceCells().begin();
164 const scalar* __restrict__ upperLowerPtr =
165 interfaceCoeffs[inti].begin();
167 register label inFaces = interface.faceCells().size()/2;
169 for (register label face=0; face<inFaces; face++)
171 label uCell = ulPtr[face];
172 label lCell = ulPtr[face + inFaces];
174 operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
175 operator[](lCell)[uCell] -= upperLowerPtr[face];
180 //printDiagonalDominance();
184 void Foam::LUscalarMatrix::convert
186 const PtrList<procLduMatrix>& lduMatrices
189 procOffsets_.setSize(lduMatrices.size() + 1);
192 forAll(lduMatrices, ldumi)
194 procOffsets_[ldumi+1] = procOffsets_[ldumi] + lduMatrices[ldumi].size();
197 forAll(lduMatrices, ldumi)
199 const procLduMatrix& lduMatrixi = lduMatrices[ldumi];
200 label offset = procOffsets_[ldumi];
202 const label* __restrict__ uPtr = lduMatrixi.upperAddr_.begin();
203 const label* __restrict__ lPtr = lduMatrixi.lowerAddr_.begin();
205 const scalar* __restrict__ diagPtr = lduMatrixi.diag_.begin();
206 const scalar* __restrict__ upperPtr = lduMatrixi.upper_.begin();
207 const scalar* __restrict__ lowerPtr = lduMatrixi.lower_.begin();
209 register const label nCells = lduMatrixi.size();
210 register const label nFaces = lduMatrixi.upper_.size();
212 for (register label cell=0; cell<nCells; cell++)
214 label globalCell = cell + offset;
215 operator[](globalCell)[globalCell] = diagPtr[cell];
218 for (register label face=0; face<nFaces; face++)
220 label uCell = uPtr[face] + offset;
221 label lCell = lPtr[face] + offset;
223 operator[](uCell)[lCell] = lowerPtr[face];
224 operator[](lCell)[uCell] = upperPtr[face];
227 const PtrList<procLduInterface>& interfaces =
228 lduMatrixi.interfaces_;
230 forAll(interfaces, inti)
232 const procLduInterface& interface = interfaces[inti];
234 if (interface.myProcNo_ == interface.neighbProcNo_)
236 const label* __restrict__ ulPtr = interface.faceCells_.begin();
238 const scalar* __restrict__ upperLowerPtr =
239 interface.coeffs_.begin();
241 register label inFaces = interface.faceCells_.size()/2;
243 for (register label face=0; face<inFaces; face++)
245 label uCell = ulPtr[face] + offset;
246 label lCell = ulPtr[face + inFaces] + offset;
248 operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
249 operator[](lCell)[uCell] -= upperLowerPtr[face];
252 else if (interface.myProcNo_ < interface.neighbProcNo_)
254 const PtrList<procLduInterface>& neiInterfaces =
255 lduMatrices[interface.neighbProcNo_].interfaces_;
257 label neiInterfacei = -1;
259 forAll(neiInterfaces, ninti)
263 neiInterfaces[ninti].neighbProcNo_
264 == interface.myProcNo_
267 neiInterfacei = ninti;
272 if (neiInterfacei == -1)
274 FatalErrorIn("LUscalarMatrix::convert") << exit(FatalError);
277 const procLduInterface& neiInterface =
278 neiInterfaces[neiInterfacei];
280 const label* __restrict__ uPtr = interface.faceCells_.begin();
281 const label* __restrict__ lPtr = neiInterface.faceCells_.begin();
283 const scalar* __restrict__ upperPtr = interface.coeffs_.begin();
284 const scalar* __restrict__ lowerPtr = neiInterface.coeffs_.begin();
286 register label inFaces = interface.faceCells_.size();
287 label neiOffset = procOffsets_[interface.neighbProcNo_];
289 for (register label face=0; face<inFaces; face++)
291 label uCell = uPtr[face] + offset;
292 label lCell = lPtr[face] + neiOffset;
294 operator[](uCell)[lCell] -= lowerPtr[face];
295 operator[](lCell)[uCell] -= upperPtr[face];
301 //printDiagonalDominance();
305 void Foam::LUscalarMatrix::printDiagonalDominance() const
307 for (label i=0; i<n(); i++)
310 for (label j=0; j<n(); j++)
314 sum += operator[](i)[j];
317 Info<< mag(sum)/mag(operator[](i)[i]) << endl;
322 // ************************************************************************* //