1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 \*---------------------------------------------------------------------------*/
27 #include "demandDrivenData.H"
28 #include "expandTensorField.H"
30 // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
34 Foam::DecoupledCoeffField<Type>::typeName("DecoupledCoeffField");
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
41 inline void Foam::DecoupledCoeffField<Type>::checkSize
46 if (f.size() != this->size())
50 "void DecoupledCoeffField<Type>::checkSize("
51 "const Field<Type2>& f) const"
52 ) << "Incorrect field size: " << f.size()
53 << " local size: " << size()
60 typename Foam::DecoupledCoeffField<Type>::scalarTypeField&
61 Foam::DecoupledCoeffField<Type>::toScalar()
65 // Debug check: demotion
70 "DecoupledCoeffField<Type>::scalarTypeField& "
71 "DecoupledCoeffField<Type>::toScalar()"
72 ) << "Detected demotion to scalar. Probably an error"
77 new scalarTypeField(size(), pTraits<scalarType>::zero);
80 return *scalarCoeffPtr_;
85 typename Foam::DecoupledCoeffField<Type>::linearTypeField&
86 Foam::DecoupledCoeffField<Type>::toLinear()
91 new linearTypeField(size(), pTraits<linearType>::zero);
93 // If scalar is active, promote to linear
96 *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits<linearType>::one;
97 deleteDemandDrivenData(scalarCoeffPtr_);
101 return *linearCoeffPtr_;
105 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
108 Foam::DecoupledCoeffField<Type>::DecoupledCoeffField(const label size)
110 scalarCoeffPtr_(NULL),
111 linearCoeffPtr_(NULL),
117 Foam::DecoupledCoeffField<Type>::DecoupledCoeffField
119 const DecoupledCoeffField<Type>& f
123 scalarCoeffPtr_(NULL),
124 linearCoeffPtr_(NULL),
127 if (f.scalarCoeffPtr_)
129 scalarCoeffPtr_ = new scalarTypeField(*(f.scalarCoeffPtr_));
131 else if (f.linearCoeffPtr_)
133 linearCoeffPtr_ = new linearTypeField(*(f.linearCoeffPtr_));
139 Foam::DecoupledCoeffField<Type>::DecoupledCoeffField(Istream& is)
141 scalarCoeffPtr_(NULL),
142 linearCoeffPtr_(NULL),
145 // Read keyword and pick up allocated field
151 == blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED]
154 size_ = readLabel(is);
159 == blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR]
162 scalarCoeffPtr_ = new scalarTypeField(is);
163 size_ = scalarCoeffPtr_->size();
168 == blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR]
171 linearCoeffPtr_ = new linearTypeField(is);
172 size_ = linearCoeffPtr_->size();
178 "DecoupledCoeffField<Type>::DecoupledCoeffField(Istream& is)",
180 ) << "invalid keyword while reading: " << key
181 << exit(FatalIOError);
187 Foam::tmp<Foam::DecoupledCoeffField<Type> >
188 Foam::DecoupledCoeffField<Type>::clone() const
190 return tmp<DecoupledCoeffField<Type> >
192 new DecoupledCoeffField<Type>(*this)
197 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
200 Foam::DecoupledCoeffField<Type>::~DecoupledCoeffField()
207 void Foam::DecoupledCoeffField<Type>::clear()
209 deleteDemandDrivenData(scalarCoeffPtr_);
210 deleteDemandDrivenData(linearCoeffPtr_);
214 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217 inline Foam::label Foam::DecoupledCoeffField<Type>::size() const
224 void Foam::DecoupledCoeffField<Type>::negate()
228 scalarCoeffPtr_->negate();
230 else if (linearCoeffPtr_)
232 linearCoeffPtr_->negate();
238 Foam::tmp<Foam::DecoupledCoeffField<Type> >
239 Foam::DecoupledCoeffField<Type>::transpose() const
241 tmp<DecoupledCoeffField<Type> > tt
243 new DecoupledCoeffField<Type>(this->size())
245 DecoupledCoeffField<Type>& t = tt();
249 t.toScalar() = *scalarCoeffPtr_;
251 else if (linearCoeffPtr_)
253 t.toLinear() = *linearCoeffPtr_;
257 // Not allocated - do nothing
266 Foam::blockCoeffBase::activeLevel
267 Foam::DecoupledCoeffField<Type>::activeType() const
271 return blockCoeffBase::SCALAR;
273 else if (linearCoeffPtr_)
275 return blockCoeffBase::LINEAR;
279 return blockCoeffBase::UNALLOCATED;
285 void Foam::DecoupledCoeffField<Type>::checkActive() const
289 if (scalarCoeffPtr_) nActive++;
290 if (linearCoeffPtr_) nActive++;
296 "void Foam::DecoupledCoeffField<Type>::checkActive() const"
297 ) << "Activation/deactivation error. nActive = " << nActive
298 << abort(FatalError);
304 const typename Foam::DecoupledCoeffField<Type>::scalarTypeField&
305 Foam::DecoupledCoeffField<Type>::asScalar() const
307 if (!scalarCoeffPtr_)
311 "DecoupledCoeffField<Type>::scalarTypeField& "
312 "DecoupledCoeffField<Type>::asScalar()"
313 ) << "Requested scalar but active type is: "
314 << blockCoeffBase::activeLevelNames_[this->activeType()]
315 << ". This is not allowed."
316 << abort(FatalError);
319 return *scalarCoeffPtr_;
324 const typename Foam::DecoupledCoeffField<Type>::linearTypeField&
325 Foam::DecoupledCoeffField<Type>::asLinear() const
327 if (!linearCoeffPtr_)
331 "DecoupledCoeffField<Type>::linearTypeField& "
332 "DecoupledCoeffField<Type>::asLinear()"
333 ) << "Requested linear but active type is: "
334 << blockCoeffBase::activeLevelNames_[this->activeType()]
335 << ". This is not allowed."
336 << abort(FatalError);
339 return *linearCoeffPtr_;
344 typename Foam::DecoupledCoeffField<Type>::scalarTypeField&
345 Foam::DecoupledCoeffField<Type>::asScalar()
351 "DecoupledCoeffField<Type>::scalarTypeField& "
352 "DecoupledCoeffField<Type>::asScalar()"
353 ) << "Requested scalar but active type is: "
354 << blockCoeffBase::activeLevelNames_[this->activeType()]
355 << ". This is not allowed."
356 << abort(FatalError);
359 if (!scalarCoeffPtr_)
361 return this->toScalar();
364 return *scalarCoeffPtr_;
369 typename Foam::DecoupledCoeffField<Type>::linearTypeField&
370 Foam::DecoupledCoeffField<Type>::asLinear()
372 if (!linearCoeffPtr_)
374 return this->toLinear();
377 return *linearCoeffPtr_;
382 Foam::tmp<typename Foam::DecoupledCoeffField<Type>::scalarTypeField>
383 Foam::DecoupledCoeffField<Type>::component(const direction dir) const
387 return *scalarCoeffPtr_;
389 else if (linearCoeffPtr_)
391 return linearCoeffPtr_->component(dir);
397 "tmp<DecoupledCoeffField<Type>::scalarTypeField>"
398 "DecoupledCoeffField<Type>::component(const direction dir) const"
399 ) << "Field not allocated."
400 << abort(FatalError);
403 // Dummy return to keep compiler happy
404 return *scalarCoeffPtr_;
409 Foam::BlockCoeff<Type>
410 Foam::DecoupledCoeffField<Type>::getCoeff(const label index) const
412 BlockCoeff<Type> result;
416 result.asScalar() = (*scalarCoeffPtr_)[index];
418 else if (linearCoeffPtr_)
420 result.asLinear() = (*linearCoeffPtr_)[index];
428 void Foam::DecoupledCoeffField<Type>::setCoeff
431 const BlockCoeff<Type>& coeff
434 BlockCoeff<Type> result;
436 if (coeff.activeType() == blockCoeffBase::SCALAR)
438 (*scalarCoeffPtr_)[index] = result.asScalar();
440 else if (coeff.activeType() == blockCoeffBase::LINEAR)
442 (*linearCoeffPtr_)[index] = result.asLinear();
448 void Foam::DecoupledCoeffField<Type>::getSubset
450 DecoupledCoeffField<Type>& f,
456 if (f.size() != size)
460 "template<class Type>\n"
461 "void Foam::DecoupledCoeffField<Type>::getSubset\n"
463 " DecoupledCoeffField<Type>& f,\n"
464 " const label start,\n"
465 " const label size\n"
467 ) << "Incompatible sizes: " << f.size() << " and " << size
468 << abort(FatalError);
473 scalarTypeField& ff = f.asScalar();
475 const scalarTypeField& localF = (*scalarCoeffPtr_);
479 ff[ffI] = localF[start + ffI];
482 else if (linearCoeffPtr_)
484 linearTypeField& ff = f.asLinear();
486 const linearTypeField& localF = (*linearCoeffPtr_);
490 ff[ffI] = localF[start + ffI];
497 void Foam::DecoupledCoeffField<Type>::getSubset
499 DecoupledCoeffField<Type>& f,
500 const labelList& addr
504 if (f.size() != addr.size())
508 "template<class Type>\n"
509 "void Foam::DecoupledCoeffField<Type>::getSubset\n"
511 " DecoupledCoeffField<Type>& f,\n"
512 " const labelList addr\n"
514 ) << "Incompatible sizes: " << f.size() << " and " << addr.size()
515 << abort(FatalError);
520 scalarTypeField& ff = f.asScalar();
522 const scalarTypeField& localF = (*scalarCoeffPtr_);
526 ff[ffI] = localF[addr[ffI]];
529 else if (linearCoeffPtr_)
531 linearTypeField& ff = f.asLinear();
533 const linearTypeField& localF = (*linearCoeffPtr_);
537 ff[ffI] = localF[addr[ffI]];
544 void Foam::DecoupledCoeffField<Type>::setSubset
546 const DecoupledCoeffField<Type>& f,
552 if (f.size() != size)
556 "template<class Type>\n"
557 "void Foam::DecoupledCoeffField<Type>::setSubset\n"
559 " const DecoupledCoeffField<Type>& f,\n"
560 " const label start,\n"
561 " const label size\n"
563 ) << "Incompatible sizes: " << f.size() << " and " << size
564 << abort(FatalError);
567 if (f.activeType() == blockCoeffBase::SCALAR)
569 const scalarTypeField& ff = f.asScalar();
571 scalarTypeField& localF = this->asScalar();
575 localF[start + ffI] = ff[ffI];
578 else if (f.activeType() == blockCoeffBase::LINEAR)
580 const linearTypeField& ff = f.asLinear();
582 linearTypeField& localF = this->asLinear();
586 localF[start + ffI] = ff[ffI];
593 void Foam::DecoupledCoeffField<Type>::setSubset
595 const DecoupledCoeffField<Type>& f,
596 const labelList& addr
600 if (f.size() != addr.size())
604 "template<class Type>\n"
605 "void Foam::DecoupledCoeffField<Type>::setSubset\n"
607 " const DecoupledCoeffField<Type>& f,\n"
608 " const labelList addr\n"
610 ) << "Incompatible sizes: " << f.size() << " and " << addr.size()
611 << abort(FatalError);
614 if (f.activeType() == blockCoeffBase::SCALAR)
616 const scalarTypeField& ff = f.asScalar();
618 scalarTypeField& localF = this->asScalar();
622 localF[addr[ffI]] = ff[ffI];
625 else if (f.activeType() == blockCoeffBase::LINEAR)
627 const linearTypeField& ff = f.asLinear();
629 linearTypeField& localF = this->asLinear();
633 localF[addr[ffI]] = ff[ffI];
640 void Foam::DecoupledCoeffField<Type>::zeroOutSubset
648 scalarTypeField& localF = this->asScalar();
650 for (label ffI = 0; ffI < size; ffI++)
652 localF[start + ffI] = pTraits<scalarType>::zero;
655 else if (linearCoeffPtr_)
657 linearTypeField& localF = this->asLinear();
659 for (label ffI = 0; ffI < size; ffI++)
661 localF[start + ffI] = pTraits<linearType>::zero;
668 void Foam::DecoupledCoeffField<Type>::zeroOutSubset
670 const labelList& addr
675 scalarTypeField& localF = this->asScalar();
679 localF[addr[ffI]] = pTraits<scalarType>::zero;
682 else if (linearCoeffPtr_)
684 linearTypeField& localF = this->asLinear();
688 localF[addr[ffI]] = pTraits<linearType>::zero;
695 void Foam::DecoupledCoeffField<Type>::addSubset
697 const DecoupledCoeffField<Type>& f,
698 const labelList& addr
702 if (f.size() != addr.size())
706 "template<class Type>\n"
707 "void Foam::DecoupledCoeffField<Type>::addSubset\n"
709 " const DecoupledCoeffField<Type>& f,\n"
710 " const labelList addr\n"
712 ) << "Incompatible sizes: " << f.size() << " and " << addr.size()
713 << abort(FatalError);
718 f.activeType() == blockCoeffBase::LINEAR
719 || this->activeType() == blockCoeffBase::LINEAR
722 const linearTypeField& ff = f.asLinear();
724 linearTypeField& localF = this->asLinear();
728 localF[addr[ffI]] += ff[ffI];
733 f.activeType() == blockCoeffBase::SCALAR
734 && this->activeType() == blockCoeffBase::SCALAR
737 const scalarTypeField& ff = f.asScalar();
739 scalarTypeField& localF = this->asScalar();
743 localF[addr[ffI]] += ff[ffI];
750 "template<class Type>\n"
751 "void Foam::DecoupledCoeffField<Type>::addSubset\n"
753 " const DecoupledCoeffField<Type>& f,\n"
754 " const labelList addr\n"
756 ) << "Incompatible combination of types"
757 << abort(FatalError);
762 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
765 void Foam::DecoupledCoeffField<Type>::operator=
767 const DecoupledCoeffField<Type>& f
774 "DecoupledCoeffField<Type>::operator=("
775 "const DecoupledCoeffField<Type>&)"
776 ) << "attempted assignment to self"
777 << abort(FatalError);
781 if (f.size() != this->size())
785 "DecoupledCoeffField<Type>::operator=("
786 "const DecoupledCoeffField<Type>&)"
787 ) << "Incorrect field size: " << f.size()
788 << " local size: " << size()
789 << abort(FatalError);
792 if (f.scalarCoeffPtr_)
794 this->toScalar() = *(f.scalarCoeffPtr_);
796 else if (f.linearCoeffPtr_)
798 this->toLinear() = *(f.linearCoeffPtr_);
802 // Not allocated - do nothing
808 void Foam::DecoupledCoeffField<Type>::operator=
810 const tmp<DecoupledCoeffField>& tf
817 "DecoupledCoeffField<Type>::operator=("
818 "const tmp<DecoupledCoeffField>&)"
819 ) << "attempted assignment to self"
820 << abort(FatalError);
828 #define COMPUTED_BASE_ASSIGNMENT(op) \
830 template<class Type> \
831 void Foam::DecoupledCoeffField<Type>::operator op \
833 const DecoupledCoeffField<Type>& f \
836 if (f.size() != this->size()) \
840 "void DecoupledCoeffField<tensor>::operator " \
841 "op(const DecoupledCoeffField<tensor>& f)" \
842 ) << "Incorrect field size: " << f.size() \
843 << " local size: " << size() \
844 << abort(FatalError); \
848 if (f.scalarCoeffPtr_) \
850 this->toScalar() op *(f.scalarCoeffPtr_); \
852 else if (f.linearCoeffPtr_) \
854 this->toLinear() op *(f.linearCoeffPtr_); \
861 template<class Type> \
862 void Foam::DecoupledCoeffField<Type>::operator op \
864 const tmp<DecoupledCoeffField<Type> >& tf \
872 #define COMPUTED_ARG_ASSIGNMENT(op) \
874 template<class Type> \
875 void Foam::DecoupledCoeffField<Type>::operator op(const scalarTypeField& f) \
879 const blockCoeffBase::activeLevel al = this->activeType(); \
881 if (al == blockCoeffBase::UNALLOCATED || al == blockCoeffBase::SCALAR) \
883 this->toScalar() op f; \
885 else if (al == blockCoeffBase::LINEAR) \
887 this->toLinear() op f*pTraits<linearType>::one; \
894 template<class Type> \
895 void Foam::DecoupledCoeffField<Type>::operator op \
897 const tmp<scalarTypeField>& tf \
905 template<class Type> \
906 void Foam::DecoupledCoeffField<Type>::operator op(const linearTypeField& f) \
910 const blockCoeffBase::activeLevel al = this->activeType(); \
914 al == blockCoeffBase::UNALLOCATED \
915 || al == blockCoeffBase::SCALAR \
916 || al == blockCoeffBase::LINEAR \
919 this->toLinear() op f; \
926 template<class Type> \
927 void Foam::DecoupledCoeffField<Type>::operator op \
929 const tmp<linearTypeField>& tf \
937 #define COMPUTED_BASE_OPERATOR(TYPE, op) \
939 template<class Type> \
940 void Foam::DecoupledCoeffField<Type>::operator op(const TYPE& t) \
942 if (scalarCoeffPtr_) \
944 *(scalarCoeffPtr_) op t; \
946 else if (linearCoeffPtr_) \
948 *(linearCoeffPtr_) op t; \
955 template<class Type> \
956 void Foam::DecoupledCoeffField<Type>::operator op(const UList<TYPE>& tf) \
960 if (scalarCoeffPtr_) \
962 *(scalarCoeffPtr_) op tf; \
964 else if (linearCoeffPtr_) \
966 *(linearCoeffPtr_) op tf; \
973 template<class Type> \
974 void Foam::DecoupledCoeffField<Type>::operator op \
976 const tmp<Field<TYPE> >& tf \
984 #define COMPUTED_ASSIGNMENT(op) \
985 COMPUTED_BASE_ASSIGNMENT(op) \
986 COMPUTED_ARG_ASSIGNMENT(op)
988 // Remaining operator=
989 COMPUTED_ARG_ASSIGNMENT(=)
991 COMPUTED_ASSIGNMENT(+=)
992 COMPUTED_ASSIGNMENT(-=)
994 COMPUTED_BASE_OPERATOR(scalar, *=)
995 COMPUTED_BASE_OPERATOR(scalar, /=)
997 #undef COMPUTED_BASE_OPERATOR
998 #undef COMPUTED_BASE_ASSIGNMENT
999 #undef COMPUTED_ARG_ASSIGNMENT
1000 #undef COMPUTED_ASSIGNMENT
1003 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
1005 template<class Type>
1006 Foam::Ostream& Foam::operator<<(Ostream& os, const DecoupledCoeffField<Type>& f)
1008 // Write active type
1009 os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl;
1011 if (f.activeType() == blockCoeffBase::SCALAR)
1015 else if (f.activeType() == blockCoeffBase::LINEAR)
1021 // Not allocated: write size
1029 template<class Type>
1030 Foam::Ostream& Foam::operator<<
1033 const tmp<DecoupledCoeffField<Type> >& tf
1042 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1044 # include "DecoupledCoeffFieldFunctions.C"
1047 // ************************************************************************* //