ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / OpenFOAM / fields / Fields / Field / Field.C
blob8545c2aa9e3d85082938034eb8c6bbab82fc960e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "FieldMapper.H"
27 #include "FieldM.H"
28 #include "dictionary.H"
29 #include "contiguous.H"
31 // * * * * * * * * * * * * * * * Static Members  * * * * * * * * * * * * * * //
33 template<class Type>
34 const char* const Foam::Field<Type>::typeName("Field");
37 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
39 template<class Type>
40 Foam::Field<Type>::Field()
42     List<Type>()
46 template<class Type>
47 Foam::Field<Type>::Field(const label size)
49     List<Type>(size)
53 template<class Type>
54 Foam::Field<Type>::Field(const label size, const Type& t)
56     List<Type>(size, t)
60 template<class Type>
61 Foam::Field<Type>::Field
63     const UList<Type>& mapF,
64     const labelUList& mapAddressing
67     List<Type>(mapAddressing.size())
69     map(mapF, mapAddressing);
73 template<class Type>
74 Foam::Field<Type>::Field
76     const tmp<Field<Type> >& tmapF,
77     const labelUList& mapAddressing
80     List<Type>(mapAddressing.size())
82     map(tmapF, mapAddressing);
86 template<class Type>
87 Foam::Field<Type>::Field
89     const UList<Type>& mapF,
90     const labelListList& mapAddressing,
91     const scalarListList& mapWeights
94     List<Type>(mapAddressing.size())
96     map(mapF, mapAddressing, mapWeights);
100 template<class Type>
101 Foam::Field<Type>::Field
103     const tmp<Field<Type> >& tmapF,
104     const labelListList& mapAddressing,
105     const scalarListList& mapWeights
108     List<Type>(mapAddressing.size())
110     map(tmapF, mapAddressing, mapWeights);
114 template<class Type>
115 Foam::Field<Type>::Field
117     const UList<Type>& mapF,
118     const FieldMapper& mapper
121     List<Type>(mapper.size())
123     map(mapF, mapper);
127 template<class Type>
128 Foam::Field<Type>::Field
130     const tmp<Field<Type> >& tmapF,
131     const FieldMapper& mapper
134     List<Type>(mapper.size())
136     map(tmapF, mapper);
140 template<class Type>
141 Foam::Field<Type>::Field(const Field<Type>& f)
143     refCount(),
144     List<Type>(f)
148 template<class Type>
149 Foam::Field<Type>::Field(Field<Type>& f, bool reUse)
151     List<Type>(f, reUse)
155 template<class Type>
156 Foam::Field<Type>::Field(const Xfer<List<Type> >& f)
158     List<Type>(f)
162 template<class Type>
163 Foam::Field<Type>::Field(const Xfer<Field<Type> >& f)
165     List<Type>(f)
169 #ifdef __INTEL_COMPILER
170 template<class Type>
171 Foam::Field<Type>::Field(const typename Field<Type>::subField& sf)
173     List<Type>(sf)
175 #endif
178 template<class Type>
179 Foam::Field<Type>::Field(const UList<Type>& list)
181     List<Type>(list)
185 // Construct as copy of tmp<Field>
186 #ifdef ConstructFromTmp
187 template<class Type>
188 Foam::Field<Type>::Field(const tmp<Field<Type> >& tf)
190     List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
192     const_cast<Field<Type>&>(tf()).resetRefCount();
194 #endif
197 template<class Type>
198 Foam::Field<Type>::Field(Istream& is)
200     List<Type>(is)
204 template<class Type>
205 Foam::Field<Type>::Field
207     const word& keyword,
208     const dictionary& dict,
209     const label s
212     if (s)
213     {
214         ITstream& is = dict.lookup(keyword);
216         // Read first token
217         token firstToken(is);
219         if (firstToken.isWord())
220         {
221             if (firstToken.wordToken() == "uniform")
222             {
223                 this->setSize(s);
224                 operator=(pTraits<Type>(is));
225             }
226             else if (firstToken.wordToken() == "nonuniform")
227             {
228                 is >> static_cast<List<Type>&>(*this);
229                 if (this->size() != s)
230                 {
231                     FatalIOErrorIn
232                     (
233                         "Field<Type>::Field"
234                         "(const word& keyword, const dictionary&, const label)",
235                         dict
236                     )   << "size " << this->size()
237                         << " is not equal to the given value of " << s
238                         << exit(FatalIOError);
239                 }
240             }
241             else
242             {
243                 FatalIOErrorIn
244                 (
245                     "Field<Type>::Field"
246                     "(const word& keyword, const dictionary&, const label)",
247                     dict
248                 )   << "expected keyword 'uniform' or 'nonuniform', found "
249                     << firstToken.wordToken()
250                     << exit(FatalIOError);
251             }
252         }
253         else
254         {
255             if (is.version() == 2.0)
256             {
257                 IOWarningIn
258                 (
259                     "Field<Type>::Field"
260                     "(const word& keyword, const dictionary&, const label)",
261                     dict
262                 )   << "expected keyword 'uniform' or 'nonuniform', "
263                        "assuming deprecated Field format from "
264                        "Foam version 2.0." << endl;
266                 this->setSize(s);
268                 is.putBack(firstToken);
269                 operator=(pTraits<Type>(is));
270             }
271             else
272             {
273                 FatalIOErrorIn
274                 (
275                     "Field<Type>::Field"
276                     "(const word& keyword, const dictionary&, const label)",
277                     dict
278                 )   << "expected keyword 'uniform' or 'nonuniform', found "
279                     << firstToken.info()
280                     << exit(FatalIOError);
281             }
282         }
283     }
287 template<class Type>
288 Foam::tmp<Foam::Field<Type> > Foam::Field<Type>::clone() const
290     return tmp<Field<Type> >(new Field<Type>(*this));
294 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
296 template<class Type>
297 void Foam::Field<Type>::map
299     const UList<Type>& mapF,
300     const labelUList& mapAddressing
303     Field<Type>& f = *this;
305     if (f.size() != mapAddressing.size())
306     {
307         f.setSize(mapAddressing.size());
308     }
310     if (mapF.size() > 0)
311     {
312         forAll(f, i)
313         {
314             label mapI = mapAddressing[i];
316             if (mapI >= 0)
317             {
318                 f[i] = mapF[mapI];
319             }
320         }
321     }
325 template<class Type>
326 void Foam::Field<Type>::map
328     const tmp<Field<Type> >& tmapF,
329     const labelUList& mapAddressing
332     map(tmapF(), mapAddressing);
333     tmapF.clear();
337 template<class Type>
338 void Foam::Field<Type>::map
340     const UList<Type>& mapF,
341     const labelListList& mapAddressing,
342     const scalarListList& mapWeights
345     Field<Type>& f = *this;
347     if (f.size() != mapAddressing.size())
348     {
349         f.setSize(mapAddressing.size());
350     }
352     if (mapWeights.size() != mapAddressing.size())
353     {
354         FatalErrorIn
355         (
356             "void Field<Type>::map\n"
357             "(\n"
358             "    const UList<Type>& mapF,\n"
359             "    const labelListList& mapAddressing,\n"
360             "    const scalarListList& mapWeights\n"
361             ")"
362         ) << "Weights and addressing map have different sizes.  Weights size: "
363             << mapWeights.size() << " map size: " << mapAddressing.size()
364             << abort(FatalError);
365     }
367     forAll(f, i)
368     {
369         const labelList&  localAddrs   = mapAddressing[i];
370         const scalarList& localWeights = mapWeights[i];
372         f[i] = pTraits<Type>::zero;
374         forAll(localAddrs, j)
375         {
376             f[i] += localWeights[j]*mapF[localAddrs[j]];
377         }
378     }
382 template<class Type>
383 void Foam::Field<Type>::map
385     const tmp<Field<Type> >& tmapF,
386     const labelListList& mapAddressing,
387     const scalarListList& mapWeights
390     map(tmapF(), mapAddressing, mapWeights);
391     tmapF.clear();
395 template<class Type>
396 void Foam::Field<Type>::map
398     const UList<Type>& mapF,
399     const FieldMapper& mapper
402     if
403     (
404         mapper.direct()
405      && &mapper.directAddressing()
406      && mapper.directAddressing().size()
407     )
408     {
409         map(mapF, mapper.directAddressing());
410     }
411     else if (!mapper.direct() && mapper.addressing().size())
412     {
413         map(mapF, mapper.addressing(), mapper.weights());
414     }
418 template<class Type>
419 void Foam::Field<Type>::map
421     const tmp<Field<Type> >& tmapF,
422     const FieldMapper& mapper
425     map(tmapF(), mapper);
426     tmapF.clear();
430 template<class Type>
431 void Foam::Field<Type>::autoMap
433     const FieldMapper& mapper
436     if
437     (
438         (
439             mapper.direct()
440          && &mapper.directAddressing()
441          && mapper.directAddressing().size()
442         )
443      || (!mapper.direct() && mapper.addressing().size())
444     )
445     {
446         Field<Type> fCpy(*this);
447         map(fCpy, mapper);
448     }
449     else
450     {
451         this->setSize(mapper.size());
452     }
456 template<class Type>
457 void Foam::Field<Type>::rmap
459     const UList<Type>& mapF,
460     const labelUList& mapAddressing
463     Field<Type>& f = *this;
465     forAll(mapF, i)
466     {
467         label mapI = mapAddressing[i];
469         if (mapI >= 0)
470         {
471             f[mapI] = mapF[i];
472         }
473     }
477 template<class Type>
478 void Foam::Field<Type>::rmap
480     const tmp<Field<Type> >& tmapF,
481     const labelUList& mapAddressing
484     rmap(tmapF(), mapAddressing);
485     tmapF.clear();
489 template<class Type>
490 void Foam::Field<Type>::rmap
492     const UList<Type>& mapF,
493     const labelUList& mapAddressing,
494     const UList<scalar>& mapWeights
497     Field<Type>& f = *this;
499     f = pTraits<Type>::zero;
501     forAll(mapF, i)
502     {
503         f[mapAddressing[i]] += mapF[i]*mapWeights[i];
504     }
508 template<class Type>
509 void Foam::Field<Type>::rmap
511     const tmp<Field<Type> >& tmapF,
512     const labelUList& mapAddressing,
513     const UList<scalar>& mapWeights
516     rmap(tmapF(), mapAddressing, mapWeights);
517     tmapF.clear();
521 template<class Type>
522 void Foam::Field<Type>::negate()
524     TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
528 template<class Type>
529 Foam::tmp<Foam::Field<typename Foam::Field<Type>::cmptType> >
530 Foam::Field<Type>::component
532     const direction d
533 ) const
535     tmp<Field<cmptType> > Component(new Field<cmptType>(this->size()));
536     ::Foam::component(Component(), *this, d);
537     return Component;
541 template<class Type>
542 void Foam::Field<Type>::replace
544     const direction d,
545     const UList<cmptType>& sf
548     TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
549         cmptType, sf)
553 template<class Type>
554 void Foam::Field<Type>::replace
556     const direction d,
557     const tmp<Field<cmptType> >& tsf
560     replace(d, tsf());
561     tsf.clear();
565 template<class Type>
566 void Foam::Field<Type>::replace
568     const direction d,
569     const cmptType& c
572     TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
573         cmptType, c)
577 template<class Type>
578 Foam::tmp<Foam::Field<Type> > Foam::Field<Type>::T() const
580     tmp<Field<Type> > transpose(new Field<Type>(this->size()));
581     ::Foam::T(transpose(), *this);
582     return transpose;
586 template<class Type>
587 void Foam::Field<Type>::writeEntry(const word& keyword, Ostream& os) const
589     os.writeKeyword(keyword);
591     bool uniform = false;
593     if (this->size() && contiguous<Type>())
594     {
595         uniform = true;
597         forAll(*this, i)
598         {
599             if (this->operator[](i) != this->operator[](0))
600             {
601                 uniform = false;
602                 break;
603             }
604         }
605     }
607     if (uniform)
608     {
609         os << "uniform " << this->operator[](0) << token::END_STATEMENT;
610     }
611     else
612     {
613         os << "nonuniform ";
614         List<Type>::writeEntry(os);
615         os << token::END_STATEMENT;
616     }
618     os << endl;
622 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
624 template<class Type>
625 void Foam::Field<Type>::operator=(const Field<Type>& rhs)
627     if (this == &rhs)
628     {
629         FatalErrorIn("Field<Type>::operator=(const Field<Type>&)")
630             << "attempted assignment to self"
631             << abort(FatalError);
632     }
634     List<Type>::operator=(rhs);
638 template<class Type>
639 void Foam::Field<Type>::operator=(const SubField<Type>& rhs)
641     List<Type>::operator=(rhs);
645 template<class Type>
646 void Foam::Field<Type>::operator=(const UList<Type>& rhs)
648     List<Type>::operator=(rhs);
652 template<class Type>
653 void Foam::Field<Type>::operator=(const tmp<Field>& rhs)
655     if (this == &(rhs()))
656     {
657         FatalErrorIn("Field<Type>::operator=(const tmp<Field>&)")
658             << "attempted assignment to self"
659             << abort(FatalError);
660     }
662     // This is dodgy stuff, don't try it at home.
663     Field* fieldPtr = rhs.ptr();
664     List<Type>::transfer(*fieldPtr);
665     delete fieldPtr;
669 template<class Type>
670 void Foam::Field<Type>::operator=(const Type& t)
672     List<Type>::operator=(t);
676 template<class Type>
677 template<class Form, class Cmpt, int nCmpt>
678 void Foam::Field<Type>::operator=(const VectorSpace<Form,Cmpt,nCmpt>& vs)
680     typedef VectorSpace<Form,Cmpt,nCmpt> VSType;
681     TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
685 #define COMPUTED_ASSIGNMENT(TYPE, op)                                         \
686                                                                               \
687 template<class Type>                                                          \
688 void Foam::Field<Type>::operator op(const UList<TYPE>& f)                     \
689 {                                                                             \
690     TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f)                                 \
691 }                                                                             \
692                                                                               \
693 template<class Type>                                                          \
694 void Foam::Field<Type>::operator op(const tmp<Field<TYPE> >& tf)              \
695 {                                                                             \
696     operator op(tf());                                                        \
697     tf.clear();                                                               \
698 }                                                                             \
699                                                                               \
700 template<class Type>                                                          \
701 void Foam::Field<Type>::operator op(const TYPE& t)                            \
702 {                                                                             \
703     TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t)                                 \
706 COMPUTED_ASSIGNMENT(Type, +=)
707 COMPUTED_ASSIGNMENT(Type, -=)
708 COMPUTED_ASSIGNMENT(scalar, *=)
709 COMPUTED_ASSIGNMENT(scalar, /=)
711 #undef COMPUTED_ASSIGNMENT
714 // * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
716 template<class Type>
717 Foam::Ostream& Foam::operator<<(Ostream& os, const Field<Type>& f)
719     os  << static_cast<const List<Type>&>(f);
720     return os;
724 template<class Type>
725 Foam::Ostream& Foam::operator<<(Ostream& os, const tmp<Field<Type> >& tf)
727     os  << tf();
728     tf.clear();
729     return os;
733 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
735 #include "FieldFunctions.C"
737 // ************************************************************************* //