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/>.
28 Collection of lduMatrices solved together as a block system
31 Hrvoje Jasak, Wikki Ltd. All rights reserved
33 \*---------------------------------------------------------------------------*/
35 #include "coupledLduMatrix.H"
36 #include "processorLduInterfaceField.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(coupledLduMatrix, 1);
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 // Construct given size
49 Foam::coupledLduMatrix::coupledLduMatrix(const label size)
51 PtrList<lduMatrix>(size)
55 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
57 Foam::coupledLduMatrix::~coupledLduMatrix()
61 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
63 bool Foam::coupledLduMatrix::diagonal() const
65 const PtrList<lduMatrix>& matrices = *this;
69 forAll (matrices, matrixI)
71 diag = diag && matrices[matrixI].diagonal();
78 bool Foam::coupledLduMatrix::symmetric() const
80 const PtrList<lduMatrix>& matrices = *this;
84 forAll (matrices, matrixI)
87 (sym && matrices[matrixI].diagonal())
88 || (sym && matrices[matrixI].symmetric());
95 bool Foam::coupledLduMatrix::asymmetric() const
97 const PtrList<lduMatrix>& matrices = *this;
101 forAll (matrices, matrixI)
103 asym = (asym || matrices[matrixI].asymmetric());
110 void Foam::coupledLduMatrix::Amul
112 FieldField<Field, scalar>& result,
113 const FieldField<Field, scalar>& x,
114 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
115 const lduInterfaceFieldPtrsListList& interfaces,
119 const PtrList<lduMatrix>& matrices = *this;
121 // Reset product to zero
124 // Initialise the update of coupled interfaces
134 forAll (matrices, rowI)
136 matrices[rowI].AmulCore(result[rowI], x[rowI]);
139 // Update couple interfaces
140 updateMatrixInterfaces
151 void Foam::coupledLduMatrix::Tmul
153 FieldField<Field, scalar>& result,
154 const FieldField<Field, scalar>& x,
155 const PtrList<FieldField<Field, scalar> >& intCoeffs,
156 const lduInterfaceFieldPtrsListList& interfaces,
160 const PtrList<lduMatrix>& matrices = *this;
162 // Reset product to zero
165 // Initialise the update of coupled interfaces
175 forAll (matrices, rowI)
177 matrices[rowI].TmulCore(result[rowI], x[rowI]);
180 // Update couple interfaces
181 updateMatrixInterfaces
192 void Foam::coupledLduMatrix::initMatrixInterfaces
194 const PtrList<FieldField<Field, scalar> >& coupleCoeffs,
195 const lduInterfaceFieldPtrsListList& interfaces,
196 const FieldField<Field, scalar>& x,
197 FieldField<Field, scalar>& result,
198 const direction cmpt,
199 const bool switchToLhs
202 const PtrList<lduMatrix>& matrices = *this;
204 // Note. The comms design requires all non-processor interfaces
205 // to be updated first, followed by the update of processor
206 // interfaces. The reason is that non-processor coupled
207 // interfaces require a complex comms pattern involving more than
208 // pairwise communications.
209 // Under normal circumstances this is achieved naturally, since
210 // processor interfaces come last on the list and other coupled
211 // interfaces execute complex comms at init() level.
212 // For coupled matrices, the update loop needs to be split over
213 // all matrices by hand
214 // Bug fix: Zeljko Tukovic, 7/Apr/2015
216 // Init update all non-processor coupled interfaces
217 forAll (matrices, rowI)
221 Pstream::defaultCommsType() == Pstream::blocking
222 || Pstream::defaultCommsType() == Pstream::nonBlocking
225 forAll (interfaces[rowI], interfaceI)
227 if (interfaces[rowI].set(interfaceI))
231 !isA<processorLduInterfaceField>
233 interfaces[rowI][interfaceI]
237 interfaces[rowI][interfaceI].initInterfaceMatrixUpdate
242 coupleCoeffs[rowI][interfaceI],
244 static_cast<const Pstream::commsTypes>
246 Pstream::defaultCommsType()
254 else if (Pstream::defaultCommsType() == Pstream::scheduled)
256 // ERROR: Does not work with scheduled comms.
257 // To investigate. HJ, 11/Jun/2015
258 forAll (matrices, rowI)
260 const lduSchedule& patchSchedule =
261 matrices[rowI].patchSchedule();
263 // Loop over the "global" patches are on the list of
264 // interfaces but beyond the end of the schedule
265 // which only handles "normal" patches
268 label interfaceI = patchSchedule.size()/2;
269 interfaceI < interfaces.size();
273 if (interfaces[rowI].set(interfaceI))
277 !isA<processorLduInterfaceField>
279 interfaces[rowI][interfaceI]
283 interfaces[rowI][interfaceI].
284 initInterfaceMatrixUpdate
289 coupleCoeffs[rowI][interfaceI],
291 static_cast<const Pstream::commsTypes>
293 Pstream::defaultCommsType()
304 FatalErrorIn("void coupledLduMatrix::initMatrixInterfaces")
305 << "Unsuported communications type "
306 << Pstream::commsTypeNames[Pstream::defaultCommsType()]
311 // Init update for all processor interfaces
312 forAll (matrices, rowI)
316 Pstream::defaultCommsType() == Pstream::blocking
317 || Pstream::defaultCommsType() == Pstream::nonBlocking
320 forAll (interfaces[rowI], interfaceI)
322 if (interfaces[rowI].set(interfaceI))
326 isA<processorLduInterfaceField>
328 interfaces[rowI][interfaceI]
332 interfaces[rowI][interfaceI].initInterfaceMatrixUpdate
337 coupleCoeffs[rowI][interfaceI],
339 static_cast<const Pstream::commsTypes>
341 Pstream::defaultCommsType()
349 else if (Pstream::defaultCommsType() == Pstream::scheduled)
351 // ERROR: Does not work with scheduled comms.
352 // To investigate. HJ, 11/Jun/2015
353 forAll (matrices, rowI)
355 const lduSchedule& patchSchedule =
356 matrices[rowI].patchSchedule();
358 // Loop over the "global" patches are on the list of
359 // interfaces but beyond the end of the schedule
360 // which only handles "normal" patches
363 label interfaceI = patchSchedule.size()/2;
364 interfaceI < interfaces.size();
368 if (interfaces[rowI].set(interfaceI))
372 isA<processorLduInterfaceField>
374 interfaces[rowI][interfaceI]
378 interfaces[rowI][interfaceI].
379 initInterfaceMatrixUpdate
384 coupleCoeffs[rowI][interfaceI],
386 static_cast<const Pstream::commsTypes>
388 Pstream::defaultCommsType()
399 FatalErrorIn("void coupledLduMatrix::initMatrixInterfaces")
400 << "Unsuported communications type "
401 << Pstream::commsTypeNames[Pstream::defaultCommsType()]
408 void Foam::coupledLduMatrix::updateMatrixInterfaces
410 const PtrList<FieldField<Field, scalar> >& coupleCoeffs,
411 const lduInterfaceFieldPtrsListList& interfaces,
412 const FieldField<Field, scalar>& x,
413 FieldField<Field, scalar>& result,
414 const direction cmpt,
415 const bool switchToLhs
418 const PtrList<lduMatrix>& matrices = *this;
420 forAll (matrices, rowI)
422 matrices[rowI].updateMatrixInterfaces
435 // ************************************************************************* //