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/>.
25 A storage mechanism which allows setting of the fixed value and
26 consequently recovering the equation for a single row of the matrix as
27 well as b. The equation is taken out of the matrix using a
28 variant of compact matrix storage mechanism.
31 Hrvoje Jasak, Wikki Ltd. All rights reserved.
33 \*---------------------------------------------------------------------------*/
37 #include "BlockConstraint.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 void BlockConstraint<Type>::setMatrix
49 const BlockLduMatrix<Type>& matrix,
58 "void BlockConstraint<Type>::setMatrix\n"
60 " const BlockLduMatrix<Type>& matrix,\n"
61 " const TypeField& x,\n"
62 " const TypeField& b\n"
64 ) << "matrix coefficients already set"
68 matrixCoeffsSet_ = true;
70 if (matrix.thereIsDiag())
72 diagCoeff_ = matrix.diag().getCoeff(rowID_);
77 const label startFaceOwn =
78 matrix.lduAddr().ownerStartAddr()[rowID_];
79 const label endFaceOwn =
80 matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
81 const label ownSize = endFaceOwn - startFaceOwn;
83 const label startFaceNbr =
84 matrix.lduAddr().losortStartAddr()[rowID_];
85 const label endFaceNbr =
86 matrix.lduAddr().losortStartAddr()[rowID_ + 1];
87 const label nbrSize = endFaceNbr - startFaceNbr;
89 const unallocLabelList& losort = matrix.lduAddr().losortAddr();
91 // Create losort addressing
92 labelList losortAddr(nbrSize);
94 forAll (losortAddr, laI)
96 losortAddr[laI] = losort[startFaceNbr + laI];
99 if (matrix.thereIsUpper())
101 // Get the upper coefficients
103 const TypeCoeffField& matrixUpper = matrix.upper();
106 upperCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
107 TypeCoeffField& uOwn = *upperCoeffsOwnerPtr_;
109 matrixUpper.getSubset(uOwn, startFaceOwn, ownSize);
112 upperCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
113 TypeCoeffField& uNbr = *upperCoeffsNeighbourPtr_;
115 matrixUpper.getSubset(uNbr, losortAddr);
118 if (matrix.thereIsLower())
120 // Get the lower coefficients
122 const TypeCoeffField& matrixLower = matrix.lower();
125 lowerCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
126 TypeCoeffField& lOwn = *lowerCoeffsOwnerPtr_;
128 matrixLower.getSubset(lOwn, startFaceOwn, ownSize);
131 lowerCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
132 TypeCoeffField& lNbr = *lowerCoeffsNeighbourPtr_;
134 matrixLower.getSubset(lNbr, losortAddr);
140 void BlockConstraint<Type>::eliminateEquation
142 BlockLduMatrix<Type>& matrix,
146 const label startFaceOwn =
147 matrix.lduAddr().ownerStartAddr()[rowID_];
148 const label endFaceOwn =
149 matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
150 const label ownSize = endFaceOwn - startFaceOwn;
152 const label startFaceNbr =
153 matrix.lduAddr().losortStartAddr()[rowID_];
154 const label endFaceNbr =
155 matrix.lduAddr().losortStartAddr()[rowID_ + 1];
156 const label nbrSize = endFaceNbr - startFaceNbr;
158 const unallocLabelList& owner = matrix.lduAddr().lowerAddr();
159 const unallocLabelList& neighbour = matrix.lduAddr().upperAddr();
160 const unallocLabelList& losort = matrix.lduAddr().losortAddr();
162 // Create losort addressing
163 labelList losortAddr(nbrSize);
165 forAll (losortAddr, laI)
167 losortAddr[laI] = losort[startFaceNbr + laI];
170 typename BlockCoeff<Type>::multiply mult;
173 if (matrix.symmetric())
178 TypeCoeffField& upperLower = matrix.upper();
179 upperLower.zeroOutSubset(startFaceOwn, ownSize);
180 upperLower.zeroOutSubset(losortAddr);
182 bOwn = upperCoeffsOwner()*value_;
183 bNbr = upperCoeffsNeighbour()*value_;
189 // add contribution to b of the neighbour (I am the owner)
190 b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
197 // add contribution to b of owner (I am the neighbour)
198 b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
201 else if (matrix.asymmetric())
204 TypeCoeffField& matrixUpper = matrix.upper();
206 matrixUpper.zeroOutSubset(startFaceOwn, ownSize);
207 TypeField bOwn = lowerCoeffsOwner()*value_;
210 TypeCoeffField& matrixLower = matrix.lower();
212 matrixLower.zeroOutSubset(losortAddr);
213 TypeField bNbr = upperCoeffsNeighbour()*value_;
219 // add contribution to b of the neighbour (I am the owner)
220 b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
227 // add contribution to b of owner (I am the neighbour)
228 b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
235 void BlockConstraint<Type>::setSourceDiag
237 BlockLduMatrix<Type>& matrix,
242 const Type& fc = fixedComponents();
244 typename BlockCoeff<Type>::multiply mult;
252 mult(matrix.diag().getCoeff(rowID()), value())
255 // set the solution to the right value as well
256 x[rowID()] = cmptMultiply(fc, value());
262 void BlockConstraint<Type>::reconstructMatrix
264 BlockLduMatrix<Type>& matrix
267 if (!matrixCoeffsSet_)
271 "void BlockConstraint<Type>::reconstructMatrix("
272 "BlockLduMatrix<Type>& matrix)"
273 ) << "matrix coefficients not set"
274 << abort(FatalError);
277 if (matrix.thereIsDiag())
279 matrix.diag().setCoeff(rowID_, diagCoeff_);
282 const label startFaceOwn =
283 matrix.lduAddr().ownerStartAddr()[rowID_];
284 const label endFaceOwn =
285 matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
286 const label ownSize = endFaceOwn - startFaceOwn;
288 const label startFaceNbr =
289 matrix.lduAddr().losortStartAddr()[rowID_];
290 const label endFaceNbr =
291 matrix.lduAddr().losortStartAddr()[rowID_ + 1];
292 const label nbrSize = endFaceNbr - startFaceNbr;
294 const unallocLabelList& losort = matrix.lduAddr().losortAddr();
296 // Create losort addressing
297 labelList losortAddr(nbrSize);
299 forAll (losortAddr, laI)
301 losortAddr[laI] = losort[startFaceNbr + laI];
304 if (matrix.thereIsUpper())
306 // Get the upper coefficients
308 TypeCoeffField& matrixUpper = matrix.upper();
311 const TypeCoeffField& uOwn = upperCoeffsOwner();
313 matrixUpper.setSubset(uOwn, startFaceOwn, ownSize);
316 const TypeCoeffField& uNbr = upperCoeffsNeighbour();
318 matrixUpper.setSubset(uNbr, losortAddr);
321 if (matrix.thereIsLower())
323 // Get the lower coefficients
325 TypeCoeffField& matrixLower = matrix.lower();
328 const TypeCoeffField& lOwn = lowerCoeffsOwner();
330 matrixLower.setSubset(lOwn, startFaceOwn, ownSize);
333 const TypeCoeffField& lNbr = lowerCoeffsNeighbour();
335 matrixLower.setSubset(lNbr, losortAddr);
340 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
342 } // End namespace Foam
344 // ************************************************************************* //