1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
5 \\ / A nd | 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 Vector-matrix multiplication operations for a block matrix
27 \*---------------------------------------------------------------------------*/
29 #include "BlockLduMatrix.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 Foam::tmp<Foam::Field<Type> >
35 Foam::BlockLduMatrix<Type>::decoupledH(const Field<Type>& x) const
37 typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
38 typedef typename TypeCoeffField::linearTypeField linearTypeField;
41 tmp<Field<Type> > tresult
43 new Field<Type>(lduAddr().size(), pTraits<Type>::zero)
45 Field<Type>& result = tresult();
47 const unallocLabelList& u = lduAddr().upperAddr();
48 const unallocLabelList& l = lduAddr().lowerAddr();
50 const TypeCoeffField& Upper = this->upper();
52 // Create multiplication function object
53 typename BlockCoeff<Type>::multiply mult;
55 // Lower multiplication
59 if (Upper.activeType() == blockCoeffBase::SCALAR)
61 const scalarTypeField& activeUpper = Upper.asScalar();
63 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
65 result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
68 else if (Upper.activeType() == blockCoeffBase::LINEAR)
70 const linearTypeField& activeUpper = Upper.asLinear();
72 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
74 result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
78 else // Asymmetric matrix
80 const TypeCoeffField& Lower = this->lower();
82 if (Lower.activeType() == blockCoeffBase::SCALAR)
84 const scalarTypeField& activeLower = Lower.asScalar();
86 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
88 result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
91 else if (Lower.activeType() == blockCoeffBase::LINEAR)
93 const linearTypeField& activeLower = Lower.asLinear();
95 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
97 result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
103 // Upper multiplication
105 if (Upper.activeType() == blockCoeffBase::SCALAR)
107 const scalarTypeField& activeUpper = Upper.asScalar();
109 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
111 result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
114 else if (Upper.activeType() == blockCoeffBase::LINEAR)
116 const linearTypeField& activeUpper = Upper.asLinear();
118 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
120 result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
129 Foam::tmp<Foam::Field<Type> >
130 Foam::BlockLduMatrix<Type>::decoupledFaceH(const Field<Type>& x) const
132 typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
133 typedef typename TypeCoeffField::linearTypeField linearTypeField;
135 const unallocLabelList& u = lduAddr().upperAddr();
136 const unallocLabelList& l = lduAddr().lowerAddr();
139 tmp<Field<Type> > tresult(new Field<Type>(u.size(), pTraits<Type>::zero));
140 Field<Type>& result = tresult();
142 const TypeCoeffField& Upper = this->upper();
144 // Create multiplication function object
145 typename BlockCoeff<Type>::multiply mult;
147 // Lower multiplication
151 if (Upper.activeType() == blockCoeffBase::SCALAR)
153 const scalarTypeField& activeUpper = Upper.asScalar();
155 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
157 // This can be optimised with a subtraction.
158 // Currently not done for clarity. HJ, 31/Oct/2007
160 mult(activeUpper[coeffI], x[u[coeffI]])
161 - mult(activeUpper[coeffI], x[l[coeffI]]);
164 else if (Upper.activeType() == blockCoeffBase::LINEAR)
166 const linearTypeField& activeUpper = Upper.asLinear();
168 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
170 // This can be optimised with a subtraction.
171 // Currently not done for clarity. HJ, 31/Oct/2007
173 mult(activeUpper[coeffI], x[u[coeffI]])
174 - mult(activeUpper[coeffI], x[l[coeffI]]);
178 else // Asymmetric matrix
180 const TypeCoeffField& Lower = this->lower();
182 if (Lower.activeType() == blockCoeffBase::SCALAR)
184 const scalarTypeField& activeUpper = Upper.asScalar();
185 const scalarTypeField& activeLower = Lower.asScalar();
187 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
190 mult(activeUpper[coeffI], x[u[coeffI]])
191 - mult(activeLower[coeffI], x[l[coeffI]]);
194 else if (Lower.activeType() == blockCoeffBase::LINEAR)
196 const linearTypeField& activeUpper = Upper.asLinear();
197 const linearTypeField& activeLower = Lower.asLinear();
199 for (register label coeffI = 0; coeffI < u.size(); coeffI++)
202 mult(activeUpper[coeffI], x[u[coeffI]])
203 - mult(activeLower[coeffI], x[l[coeffI]]);
212 // ************************************************************************* //