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 Generic block coefficient type. Used in BlockLduMatrix. HJ, 2/Jan/2006
27 \*---------------------------------------------------------------------------*/
29 #include "demandDrivenData.H"
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 typename Foam::BlockCoeff<Type>::scalarType&
35 Foam::BlockCoeff<Type>::toScalar()
39 // Debug check: demotion
40 if (linearCoeffPtr_ || squareCoeffPtr_)
44 "BlockCoeff<Type>::scalarType& "
45 "BlockCoeff<Type>::toScalar()"
46 ) << "Detected demotion to scalar. Probably an error"
50 scalarCoeffPtr_ = new scalarType(pTraits<scalarType>::zero);
53 return *scalarCoeffPtr_;
58 typename Foam::BlockCoeff<Type>::linearType&
59 Foam::BlockCoeff<Type>::toLinear()
63 // Debug check: demotion
68 "BlockCoeff<Type>::linearType& "
69 "BlockCoeff<Type>::toLinear()"
70 ) << "Detected demotion to linear. Probably an error"
74 linearCoeffPtr_ = new linearType(pTraits<linearType>::zero);
76 // If scalar is active, promote to linear
79 *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits<linearType>::one;
80 deleteDemandDrivenData(scalarCoeffPtr_);
84 return *linearCoeffPtr_;
89 typename Foam::BlockCoeff<Type>::squareType&
90 Foam::BlockCoeff<Type>::toSquare()
94 squareCoeffPtr_ = new squareType(pTraits<squareType>::zero);
96 // If scalar is active, promote to square
99 expandScalar(*squareCoeffPtr_, *scalarCoeffPtr_);
100 deleteDemandDrivenData(scalarCoeffPtr_);
103 // If linear is active, promote to square
106 expandLinear(*squareCoeffPtr_, *linearCoeffPtr_);
107 deleteDemandDrivenData(linearCoeffPtr_);
111 return *squareCoeffPtr_;
115 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
118 Foam::BlockCoeff<Type>::BlockCoeff()
120 scalarCoeffPtr_(NULL),
121 linearCoeffPtr_(NULL),
122 squareCoeffPtr_(NULL)
127 Foam::BlockCoeff<Type>::BlockCoeff(const BlockCoeff<Type>& f)
129 scalarCoeffPtr_(NULL),
130 linearCoeffPtr_(NULL),
131 squareCoeffPtr_(NULL)
133 if (f.scalarCoeffPtr_)
135 scalarCoeffPtr_ = new scalarType(*(f.scalarCoeffPtr_));
137 else if (f.linearCoeffPtr_)
139 linearCoeffPtr_ = new linearType(*(f.linearCoeffPtr_));
141 else if (f.squareCoeffPtr_)
143 squareCoeffPtr_ = new squareType(*(f.squareCoeffPtr_));
149 Foam::BlockCoeff<Type>::BlockCoeff(Istream& is)
151 scalarCoeffPtr_(NULL),
152 linearCoeffPtr_(NULL),
153 squareCoeffPtr_(NULL)
155 // Read keyword and pick up allocated field
161 == blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED]
168 == blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR]
171 scalarCoeffPtr_ = new scalarType(readScalar(is));
176 == blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR]
179 linearCoeffPtr_ = new linearType(is);
184 == blockCoeffBase::activeLevelNames_[blockCoeffBase::SQUARE]
187 squareCoeffPtr_ = new squareType(is);
193 "BlockCoeff<Type>::BlockCoeff(Istream& is)",
195 ) << "invalid keyword while reading: " << key
196 << exit(FatalIOError);
202 Foam::BlockCoeff<Type> Foam::BlockCoeff<Type>::clone() const
204 return BlockCoeff<Type>(*this);
208 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
211 Foam::BlockCoeff<Type>::~BlockCoeff()
218 inline void Foam::BlockCoeff<Type>::clear()
220 deleteDemandDrivenData(scalarCoeffPtr_);
221 deleteDemandDrivenData(linearCoeffPtr_);
222 deleteDemandDrivenData(squareCoeffPtr_);
226 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
229 Foam::blockCoeffBase::activeLevel
230 Foam::BlockCoeff<Type>::activeType() const
234 return blockCoeffBase::SCALAR;
236 else if (linearCoeffPtr_)
238 return blockCoeffBase::LINEAR;
240 else if (squareCoeffPtr_)
242 return blockCoeffBase::SQUARE;
246 return blockCoeffBase::UNALLOCATED;
252 void Foam::BlockCoeff<Type>::checkActive() const
256 if (scalarCoeffPtr_) nActive++;
257 if (linearCoeffPtr_) nActive++;
258 if (squareCoeffPtr_) nActive++;
262 FatalErrorIn("void Foam::BlockCoeff<Type>::checkActive() const")
263 << "Activation/deactivation error. nActive = " << nActive
264 << abort(FatalError);
270 const typename Foam::BlockCoeff<Type>::scalarType&
271 Foam::BlockCoeff<Type>::asScalar() const
273 if (!scalarCoeffPtr_)
277 "BlockCoeff<Type>::scalarType& "
278 "BlockCoeff<Type>::asScalar()"
279 ) << "Requested scalar but active type is: "
280 << blockCoeffBase::activeLevelNames_[this->activeType()]
281 << ". This is not allowed."
282 << abort(FatalError);
285 return *scalarCoeffPtr_;
290 const typename Foam::BlockCoeff<Type>::linearType&
291 Foam::BlockCoeff<Type>::asLinear() const
293 if (!linearCoeffPtr_)
297 "BlockCoeff<Type>::linearType& "
298 "BlockCoeff<Type>::asLinear()"
299 ) << "Requested linear but active type is: "
300 << blockCoeffBase::activeLevelNames_[this->activeType()]
301 << ". This is not allowed."
302 << abort(FatalError);
305 return *linearCoeffPtr_;
310 const typename Foam::BlockCoeff<Type>::squareType&
311 Foam::BlockCoeff<Type>::asSquare() const
313 if (!squareCoeffPtr_)
317 "BlockCoeff<Type>::squareType& "
318 "BlockCoeff<Type>::asSquare()"
319 ) << "Requested square but active type is: "
320 << blockCoeffBase::activeLevelNames_[this->activeType()]
321 << ". This is not allowed."
322 << abort(FatalError);
325 return *squareCoeffPtr_;
330 typename Foam::BlockCoeff<Type>::scalarType&
331 Foam::BlockCoeff<Type>::asScalar()
333 if (linearCoeffPtr_ || squareCoeffPtr_)
337 "BlockCoeff<Type>::scalarType& "
338 "BlockCoeff<Type>::asScalar()"
339 ) << "Requested scalar but active type is: "
340 << blockCoeffBase::activeLevelNames_[this->activeType()]
341 << ". This is not allowed."
342 << abort(FatalError);
345 if (!scalarCoeffPtr_)
347 return this->toScalar();
350 return *scalarCoeffPtr_;
355 typename Foam::BlockCoeff<Type>::linearType&
356 Foam::BlockCoeff<Type>::asLinear()
362 "BlockCoeff<Type>::linearType& "
363 "BlockCoeff<Type>::asLinear()"
364 ) << "Requested linear but active type is: "
365 << blockCoeffBase::activeLevelNames_[this->activeType()]
366 << ". This is not allowed."
367 << abort(FatalError);
370 if (!linearCoeffPtr_)
372 return this->toLinear();
375 return *linearCoeffPtr_;
380 typename Foam::BlockCoeff<Type>::squareType&
381 Foam::BlockCoeff<Type>::asSquare()
383 if (!squareCoeffPtr_)
385 return this->toSquare();
388 return *squareCoeffPtr_;
393 typename Foam::BlockCoeff<Type>::scalarType
394 Foam::BlockCoeff<Type>::component(const direction dir) const
398 return *scalarCoeffPtr_;
400 else if (linearCoeffPtr_)
402 return linearCoeffPtr_->component(dir);
404 else if (squareCoeffPtr_)
406 return contractLinear
415 "tmp<BlockCoeff<Type>::scalarType>"
416 "BlockCoeff<Type>::component(const direction dir) const"
417 ) << " not allocated."
418 << abort(FatalError);
421 // Dummy return to keep compiler happy
422 return *scalarCoeffPtr_;
426 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
429 void Foam::BlockCoeff<Type>::operator=(const BlockCoeff<Type>& f)
433 FatalErrorIn("BlockCoeff<Type>::operator=(const BlockCoeff<Type>&)")
434 << "attempted assignment to self"
435 << abort(FatalError);
438 if (f.scalarCoeffPtr_)
440 this->toScalar() = *(f.scalarCoeffPtr_);
442 else if (f.linearCoeffPtr_)
444 this->toLinear() = *(f.linearCoeffPtr_);
446 else if (f.squareCoeffPtr_)
448 this->toSquare() = *(f.squareCoeffPtr_);
452 // Not allocated - do nothing
457 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
460 Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff<Type>& f)
463 os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl;
465 if (f.scalarCoeffPtr_)
467 os << *(f.scalarCoeffPtr_);
469 else if (f.linearCoeffPtr_)
471 os << *(f.linearCoeffPtr_);
473 else if (f.squareCoeffPtr_)
475 os << *(f.squareCoeffPtr_);
482 // ************************************************************************* //