Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / primitives / BlockCoeff / BlockCoeff.C
blobd57c7b28136dfcce9f2b41b26a6c184830a9aa4f
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     Generic block coefficient type.  Used in BlockLduMatrix.  HJ, 2/Jan/2006
27 \*---------------------------------------------------------------------------*/
29 #include "demandDrivenData.H"
31 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
33 template<class Type>
34 typename Foam::BlockCoeff<Type>::scalarType&
35 Foam::BlockCoeff<Type>::toScalar()
37     if (!scalarCoeffPtr_)
38     {
39         // Debug check: demotion
40         if (linearCoeffPtr_ || squareCoeffPtr_)
41         {
42             FatalErrorIn
43             (
44                 "BlockCoeff<Type>::scalarType& "
45                 "BlockCoeff<Type>::toScalar()"
46             )   << "Detected demotion to scalar.  Probably an error"
47                 << abort(FatalError);
48         }
50         scalarCoeffPtr_ = new scalarType(pTraits<scalarType>::zero);
51     }
53     return *scalarCoeffPtr_;
57 template<class Type>
58 typename Foam::BlockCoeff<Type>::linearType&
59 Foam::BlockCoeff<Type>::toLinear()
61     if (!linearCoeffPtr_)
62     {
63         // Debug check: demotion
64         if (squareCoeffPtr_)
65         {
66             FatalErrorIn
67             (
68                 "BlockCoeff<Type>::linearType& "
69                 "BlockCoeff<Type>::toLinear()"
70             )   << "Detected demotion to linear.  Probably an error"
71                 << abort(FatalError);
72         }
74         linearCoeffPtr_ = new linearType(pTraits<linearType>::zero);
76         // If scalar is active, promote to linear
77         if (scalarCoeffPtr_)
78         {
79             *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits<linearType>::one;
80             deleteDemandDrivenData(scalarCoeffPtr_);
81         }
82     }
84     return *linearCoeffPtr_;
88 template<class Type>
89 typename Foam::BlockCoeff<Type>::squareType&
90 Foam::BlockCoeff<Type>::toSquare()
92     if (!squareCoeffPtr_)
93     {
94         squareCoeffPtr_ = new squareType(pTraits<squareType>::zero);
96         // If scalar is active, promote to square
97         if (scalarCoeffPtr_)
98         {
99             expandScalar(*squareCoeffPtr_, *scalarCoeffPtr_);
100             deleteDemandDrivenData(scalarCoeffPtr_);
101         }
103         // If linear is active, promote to square
104         if (linearCoeffPtr_)
105         {
106             expandLinear(*squareCoeffPtr_, *linearCoeffPtr_);
107             deleteDemandDrivenData(linearCoeffPtr_);
108         }
109     }
111     return *squareCoeffPtr_;
115 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
117 template<class Type>
118 Foam::BlockCoeff<Type>::BlockCoeff()
120     scalarCoeffPtr_(NULL),
121     linearCoeffPtr_(NULL),
122     squareCoeffPtr_(NULL)
126 template<class Type>
127 Foam::BlockCoeff<Type>::BlockCoeff(const BlockCoeff<Type>& f)
129     scalarCoeffPtr_(NULL),
130     linearCoeffPtr_(NULL),
131     squareCoeffPtr_(NULL)
133     if (f.scalarCoeffPtr_)
134     {
135         scalarCoeffPtr_ = new scalarType(*(f.scalarCoeffPtr_));
136     }
137     else if (f.linearCoeffPtr_)
138     {
139         linearCoeffPtr_ = new linearType(*(f.linearCoeffPtr_));
140     }
141     else if (f.squareCoeffPtr_)
142     {
143         squareCoeffPtr_ = new squareType(*(f.squareCoeffPtr_));
144     }
148 template<class Type>
149 Foam::BlockCoeff<Type>::BlockCoeff(Istream& is)
151     scalarCoeffPtr_(NULL),
152     linearCoeffPtr_(NULL),
153     squareCoeffPtr_(NULL)
155     // Read keyword and pick up allocated field
156     word key(is);
158     if
159     (
160         key
161      == blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED]
162     )
163     {
164     }
165     else if
166     (
167         key
168      == blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR]
169     )
170     {
171         scalarCoeffPtr_ = new scalarType(readScalar(is));
172     }
173     else if
174     (
175         key
176      == blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR]
177     )
178     {
179         linearCoeffPtr_ = new linearType(is);
180     }
181     else if
182     (
183         key
184      == blockCoeffBase::activeLevelNames_[blockCoeffBase::SQUARE]
185     )
186     {
187         squareCoeffPtr_ = new squareType(is);
188     }
189     else
190     {
191         FatalIOErrorIn
192         (
193             "BlockCoeff<Type>::BlockCoeff(Istream& is)",
194             is
195         )   << "invalid keyword while reading: " << key
196             << exit(FatalIOError);
197     }
201 template<class Type>
202 Foam::BlockCoeff<Type> Foam::BlockCoeff<Type>::clone() const
204     return BlockCoeff<Type>(*this);
208 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
210 template<class Type>
211 Foam::BlockCoeff<Type>::~BlockCoeff()
213     this->clear();
217 template<class Type>
218 inline void Foam::BlockCoeff<Type>::clear()
220     deleteDemandDrivenData(scalarCoeffPtr_);
221     deleteDemandDrivenData(linearCoeffPtr_);
222     deleteDemandDrivenData(squareCoeffPtr_);
226 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
228 template<class Type>
229 Foam::blockCoeffBase::activeLevel
230 Foam::BlockCoeff<Type>::activeType() const
232     if (scalarCoeffPtr_)
233     {
234         return blockCoeffBase::SCALAR;
235     }
236     else if (linearCoeffPtr_)
237     {
238         return blockCoeffBase::LINEAR;
239     }
240     else if (squareCoeffPtr_)
241     {
242         return blockCoeffBase::SQUARE;
243     }
244     else
245     {
246         return blockCoeffBase::UNALLOCATED;
247     }
251 template<class Type>
252 void Foam::BlockCoeff<Type>::checkActive() const
254     label nActive = 0;
256     if (scalarCoeffPtr_) nActive++;
257     if (linearCoeffPtr_) nActive++;
258     if (squareCoeffPtr_) nActive++;
260     if (nActive > 1)
261     {
262         FatalErrorIn("void Foam::BlockCoeff<Type>::checkActive() const")
263             << "Activation/deactivation error.  nActive = " << nActive
264             << abort(FatalError);
265     }
269 template<class Type>
270 const typename Foam::BlockCoeff<Type>::scalarType&
271 Foam::BlockCoeff<Type>::asScalar() const
273     if (!scalarCoeffPtr_)
274     {
275         FatalErrorIn
276         (
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);
283     }
285     return *scalarCoeffPtr_;
289 template<class Type>
290 const typename Foam::BlockCoeff<Type>::linearType&
291 Foam::BlockCoeff<Type>::asLinear() const
293     if (!linearCoeffPtr_)
294     {
295         FatalErrorIn
296         (
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);
303     }
305     return *linearCoeffPtr_;
309 template<class Type>
310 const typename Foam::BlockCoeff<Type>::squareType&
311 Foam::BlockCoeff<Type>::asSquare() const
313     if (!squareCoeffPtr_)
314     {
315         FatalErrorIn
316         (
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);
323     }
325     return *squareCoeffPtr_;
329 template<class Type>
330 typename Foam::BlockCoeff<Type>::scalarType&
331 Foam::BlockCoeff<Type>::asScalar()
333     if (linearCoeffPtr_ || squareCoeffPtr_)
334     {
335         FatalErrorIn
336         (
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);
343     }
345     if (!scalarCoeffPtr_)
346     {
347         return this->toScalar();
348     }
350     return *scalarCoeffPtr_;
354 template<class Type>
355 typename Foam::BlockCoeff<Type>::linearType&
356 Foam::BlockCoeff<Type>::asLinear()
358     if (squareCoeffPtr_)
359     {
360         FatalErrorIn
361         (
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);
368     }
370     if (!linearCoeffPtr_)
371     {
372         return this->toLinear();
373     }
375     return *linearCoeffPtr_;
379 template<class Type>
380 typename Foam::BlockCoeff<Type>::squareType&
381 Foam::BlockCoeff<Type>::asSquare()
383     if (!squareCoeffPtr_)
384     {
385         return this->toSquare();
386     }
388     return *squareCoeffPtr_;
392 template<class Type>
393 typename Foam::BlockCoeff<Type>::scalarType
394 Foam::BlockCoeff<Type>::component(const direction dir) const
396     if (scalarCoeffPtr_)
397     {
398         return *scalarCoeffPtr_;
399     }
400     else if (linearCoeffPtr_)
401     {
402         return linearCoeffPtr_->component(dir);
403     }
404     else if (squareCoeffPtr_)
405     {
406         return contractLinear
407         (
408             *squareCoeffPtr_
409         ).component(dir);
410     }
411     else
412     {
413         FatalErrorIn
414         (
415             "tmp<BlockCoeff<Type>::scalarType>"
416             "BlockCoeff<Type>::component(const direction dir) const"
417         )   << " not allocated."
418             << abort(FatalError);
419     }
421     // Dummy return to keep compiler happy
422     return *scalarCoeffPtr_;
426 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
428 template<class Type>
429 void Foam::BlockCoeff<Type>::operator=(const BlockCoeff<Type>& f)
431     if (this == &f)
432     {
433         FatalErrorIn("BlockCoeff<Type>::operator=(const BlockCoeff<Type>&)")
434             << "attempted assignment to self"
435             << abort(FatalError);
436     }
438     if (f.scalarCoeffPtr_)
439     {
440         this->toScalar() = *(f.scalarCoeffPtr_);
441     }
442     else if (f.linearCoeffPtr_)
443     {
444         this->toLinear() = *(f.linearCoeffPtr_);
445     }
446     else if (f.squareCoeffPtr_)
447     {
448         this->toSquare() = *(f.squareCoeffPtr_);
449     }
450     else
451     {
452         // Not allocated - do nothing
453     }
457 // * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
459 template<class Type>
460 Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff<Type>& f)
462     // Write active type
463     os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl;
465     if (f.scalarCoeffPtr_)
466     {
467         os << *(f.scalarCoeffPtr_);
468     }
469     else if (f.linearCoeffPtr_)
470     {
471         os << *(f.linearCoeffPtr_);
472     }
473     else if (f.squareCoeffPtr_)
474     {
475         os << *(f.squareCoeffPtr_);
476     }
478     return os;
482 // ************************************************************************* //