Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / matrices / blockLduMatrix / BlockLduMatrix / BlockConstraint / BlockConstraintTools.C
blob6cf8835ee377847361e896915d933a8cfa33050e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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 Description
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.
30 Author
31     Hrvoje Jasak, Wikki Ltd.  All rights reserved.
33 \*---------------------------------------------------------------------------*/
35 #include "error.H"
37 #include "BlockConstraint.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 namespace Foam
44 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
46 template<class Type>
47 void BlockConstraint<Type>::setMatrix
49     const BlockLduMatrix<Type>& matrix,
50     const TypeField& x,
51     const TypeField& b
54     if (matrixCoeffsSet_)
55     {
56         FatalErrorIn
57         (
58             "void BlockConstraint<Type>::setMatrix\n"
59             "(\n"
60             "    const BlockLduMatrix<Type>& matrix,\n"
61             "    const TypeField& x,\n"
62             "    const TypeField& b\n"
63             ")"
64         )   << "matrix coefficients already set"
65             << abort(FatalError);
66     }
68     matrixCoeffsSet_ = true;
70     if (matrix.thereIsDiag())
71     {
72         diagCoeff_ = matrix.diag().getCoeff(rowID_);
73     }
75     b_ = b[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)
95     {
96         losortAddr[laI] = losort[startFaceNbr + laI];
97     }
99     if (matrix.thereIsUpper())
100     {
101         // Get the upper coefficients
103         const TypeCoeffField& matrixUpper = matrix.upper();
105         // owner side
106         upperCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
107         TypeCoeffField& uOwn = *upperCoeffsOwnerPtr_;
109         matrixUpper.getSubset(uOwn, startFaceOwn, ownSize);
111         // neighbour side
112         upperCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
113         TypeCoeffField& uNbr = *upperCoeffsNeighbourPtr_;
115         matrixUpper.getSubset(uNbr, losortAddr);
116     }
118     if (matrix.thereIsLower())
119     {
120         // Get the lower coefficients
122         const TypeCoeffField& matrixLower = matrix.lower();
124         // owner side
125         lowerCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
126         TypeCoeffField& lOwn = *lowerCoeffsOwnerPtr_;
128         matrixLower.getSubset(lOwn, startFaceOwn, ownSize);
130         // neighbour side
131         lowerCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
132         TypeCoeffField& lNbr = *lowerCoeffsNeighbourPtr_;
134         matrixLower.getSubset(lNbr, losortAddr);
135     }
139 template<class Type>
140 void BlockConstraint<Type>::eliminateEquation
142     BlockLduMatrix<Type>& matrix,
143     TypeField& b
144 ) const
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)
166     {
167         losortAddr[laI] = losort[startFaceNbr + laI];
168     }
170     typename BlockCoeff<Type>::multiply mult;
172     // My index = rowID_
173     if (matrix.symmetric())
174     {
175         TypeField bOwn;
176         TypeField bNbr;
178         TypeCoeffField& upperLower = matrix.upper();
179         upperLower.zeroOutSubset(startFaceOwn, ownSize);
180         upperLower.zeroOutSubset(losortAddr);
182         bOwn = upperCoeffsOwner()*value_;
183         bNbr = upperCoeffsNeighbour()*value_;
185         // owner side
187         forAll (bOwn, soI)
188         {
189             // add contribution to b of the neighbour (I am the owner)
190             b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
191         }
193         // neighbour side
195         forAll (bNbr, snI)
196         {
197             // add contribution to b of owner (I am the neighbour)
198             b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
199         }
200     }
201     else if (matrix.asymmetric())
202     {
203         // Do upper
204         TypeCoeffField& matrixUpper = matrix.upper();
206         matrixUpper.zeroOutSubset(startFaceOwn, ownSize);
207         TypeField bOwn = lowerCoeffsOwner()*value_;
209         // Do lower
210         TypeCoeffField& matrixLower = matrix.lower();
212         matrixLower.zeroOutSubset(losortAddr);
213         TypeField bNbr = upperCoeffsNeighbour()*value_;
215         // owner side
217         forAll (bOwn, soI)
218         {
219             // add contribution to b of the neighbour (I am the owner)
220             b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
221         }
223         // neighbour side
225         forAll (bNbr, snI)
226         {
227             // add contribution to b of owner (I am the neighbour)
228             b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
229         }
230     }
234 template<class Type>
235 void BlockConstraint<Type>::setSourceDiag
237     BlockLduMatrix<Type>& matrix,
238     Field<Type>& x,
239     Field<Type>& b
240 ) const
242     const Type& fc = fixedComponents();
244     typename BlockCoeff<Type>::multiply mult;
246     if (mag(fc) > SMALL)
247     {
248         b[rowID()] =
249             cmptMultiply
250             (
251                 fc,
252                 mult(matrix.diag().getCoeff(rowID()), value())
253             );
255         // set the solution to the right value as well
256         x[rowID()] = cmptMultiply(fc, value());
257     }
261 template<class Type>
262 void BlockConstraint<Type>::reconstructMatrix
264     BlockLduMatrix<Type>& matrix
265 ) const
267     if (!matrixCoeffsSet_)
268     {
269         FatalErrorIn
270         (
271             "void BlockConstraint<Type>::reconstructMatrix("
272             "BlockLduMatrix<Type>& matrix)"
273         )   << "matrix coefficients not set"
274             << abort(FatalError);
275     }
277     if (matrix.thereIsDiag())
278     {
279         matrix.diag().setCoeff(rowID_, diagCoeff_);
280     }
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)
300     {
301         losortAddr[laI] = losort[startFaceNbr + laI];
302     }
304     if (matrix.thereIsUpper())
305     {
306         // Get the upper coefficients
308         TypeCoeffField& matrixUpper = matrix.upper();
310         // owner side
311         const TypeCoeffField& uOwn = upperCoeffsOwner();
313         matrixUpper.setSubset(uOwn, startFaceOwn, ownSize);
315         // neighbour side
316         const TypeCoeffField& uNbr = upperCoeffsNeighbour();
318         matrixUpper.setSubset(uNbr, losortAddr);
319     }
321     if (matrix.thereIsLower())
322     {
323         // Get the lower coefficients
325         TypeCoeffField& matrixLower = matrix.lower();
327         // owner side
328         const TypeCoeffField& lOwn = lowerCoeffsOwner();
330         matrixLower.setSubset(lOwn, startFaceOwn, ownSize);
332         // neighbour side
333         const TypeCoeffField& lNbr = lowerCoeffsNeighbour();
335         matrixLower.setSubset(lNbr, losortAddr);
336     }
340 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
342 } // End namespace Foam
344 // ************************************************************************* //