1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
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
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"
28 #include "dictionary.H"
29 #include "contiguous.H"
31 // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
34 const char* const Foam::Field<Type>::typeName("Field");
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 Foam::Field<Type>::Field()
47 Foam::Field<Type>::Field(const label size)
54 Foam::Field<Type>::Field(const label size, const Type& t)
61 Foam::Field<Type>::Field
63 const UList<Type>& mapF,
64 const labelUList& mapAddressing
67 List<Type>(mapAddressing.size())
69 map(mapF, mapAddressing);
74 Foam::Field<Type>::Field
76 const tmp<Field<Type> >& tmapF,
77 const labelUList& mapAddressing
80 List<Type>(mapAddressing.size())
82 map(tmapF, mapAddressing);
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);
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);
115 Foam::Field<Type>::Field
117 const UList<Type>& mapF,
118 const FieldMapper& mapper
121 List<Type>(mapper.size())
128 Foam::Field<Type>::Field
130 const tmp<Field<Type> >& tmapF,
131 const FieldMapper& mapper
134 List<Type>(mapper.size())
141 Foam::Field<Type>::Field(const Field<Type>& f)
149 Foam::Field<Type>::Field(Field<Type>& f, bool reUse)
156 Foam::Field<Type>::Field(const Xfer<List<Type> >& f)
163 Foam::Field<Type>::Field(const Xfer<Field<Type> >& f)
169 #ifdef __INTEL_COMPILER
171 Foam::Field<Type>::Field(const typename Field<Type>::subField& sf)
179 Foam::Field<Type>::Field(const UList<Type>& list)
185 // Construct as copy of tmp<Field>
186 #ifdef ConstructFromTmp
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();
198 Foam::Field<Type>::Field(Istream& is)
205 Foam::Field<Type>::Field
208 const dictionary& dict,
214 ITstream& is = dict.lookup(keyword);
217 token firstToken(is);
219 if (firstToken.isWord())
221 if (firstToken.wordToken() == "uniform")
224 operator=(pTraits<Type>(is));
226 else if (firstToken.wordToken() == "nonuniform")
228 is >> static_cast<List<Type>&>(*this);
229 if (this->size() != s)
234 "(const word& keyword, const dictionary&, const label)",
236 ) << "size " << this->size()
237 << " is not equal to the given value of " << s
238 << exit(FatalIOError);
246 "(const word& keyword, const dictionary&, const label)",
248 ) << "expected keyword 'uniform' or 'nonuniform', found "
249 << firstToken.wordToken()
250 << exit(FatalIOError);
255 if (is.version() == 2.0)
260 "(const word& keyword, const dictionary&, const label)",
262 ) << "expected keyword 'uniform' or 'nonuniform', "
263 "assuming deprecated Field format from "
264 "Foam version 2.0." << endl;
268 is.putBack(firstToken);
269 operator=(pTraits<Type>(is));
276 "(const word& keyword, const dictionary&, const label)",
278 ) << "expected keyword 'uniform' or 'nonuniform', found "
280 << exit(FatalIOError);
288 Foam::tmp<Foam::Field<Type> > Foam::Field<Type>::clone() const
290 return tmp<Field<Type> >(new Field<Type>(*this));
294 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
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())
307 f.setSize(mapAddressing.size());
314 label mapI = mapAddressing[i];
326 void Foam::Field<Type>::map
328 const tmp<Field<Type> >& tmapF,
329 const labelUList& mapAddressing
332 map(tmapF(), mapAddressing);
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())
349 f.setSize(mapAddressing.size());
352 if (mapWeights.size() != mapAddressing.size())
356 "void Field<Type>::map\n"
358 " const UList<Type>& mapF,\n"
359 " const labelListList& mapAddressing,\n"
360 " const scalarListList& mapWeights\n"
362 ) << "Weights and addressing map have different sizes. Weights size: "
363 << mapWeights.size() << " map size: " << mapAddressing.size()
364 << abort(FatalError);
369 const labelList& localAddrs = mapAddressing[i];
370 const scalarList& localWeights = mapWeights[i];
372 f[i] = pTraits<Type>::zero;
374 forAll(localAddrs, j)
376 f[i] += localWeights[j]*mapF[localAddrs[j]];
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);
396 void Foam::Field<Type>::map
398 const UList<Type>& mapF,
399 const FieldMapper& mapper
405 && &mapper.directAddressing()
406 && mapper.directAddressing().size()
409 map(mapF, mapper.directAddressing());
411 else if (!mapper.direct() && mapper.addressing().size())
413 map(mapF, mapper.addressing(), mapper.weights());
419 void Foam::Field<Type>::map
421 const tmp<Field<Type> >& tmapF,
422 const FieldMapper& mapper
425 map(tmapF(), mapper);
431 void Foam::Field<Type>::autoMap
433 const FieldMapper& mapper
440 && &mapper.directAddressing()
441 && mapper.directAddressing().size()
443 || (!mapper.direct() && mapper.addressing().size())
446 Field<Type> fCpy(*this);
451 this->setSize(mapper.size());
457 void Foam::Field<Type>::rmap
459 const UList<Type>& mapF,
460 const labelUList& mapAddressing
463 Field<Type>& f = *this;
467 label mapI = mapAddressing[i];
478 void Foam::Field<Type>::rmap
480 const tmp<Field<Type> >& tmapF,
481 const labelUList& mapAddressing
484 rmap(tmapF(), mapAddressing);
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;
503 f[mapAddressing[i]] += mapF[i]*mapWeights[i];
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);
522 void Foam::Field<Type>::negate()
524 TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
529 Foam::tmp<Foam::Field<typename Foam::Field<Type>::cmptType> >
530 Foam::Field<Type>::component
535 tmp<Field<cmptType> > Component(new Field<cmptType>(this->size()));
536 ::Foam::component(Component(), *this, d);
542 void Foam::Field<Type>::replace
545 const UList<cmptType>& sf
548 TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
554 void Foam::Field<Type>::replace
557 const tmp<Field<cmptType> >& tsf
566 void Foam::Field<Type>::replace
572 TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
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);
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>())
599 if (this->operator[](i) != this->operator[](0))
609 os << "uniform " << this->operator[](0) << token::END_STATEMENT;
614 List<Type>::writeEntry(os);
615 os << token::END_STATEMENT;
622 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
625 void Foam::Field<Type>::operator=(const Field<Type>& rhs)
629 FatalErrorIn("Field<Type>::operator=(const Field<Type>&)")
630 << "attempted assignment to self"
631 << abort(FatalError);
634 List<Type>::operator=(rhs);
639 void Foam::Field<Type>::operator=(const SubField<Type>& rhs)
641 List<Type>::operator=(rhs);
646 void Foam::Field<Type>::operator=(const UList<Type>& rhs)
648 List<Type>::operator=(rhs);
653 void Foam::Field<Type>::operator=(const tmp<Field>& rhs)
655 if (this == &(rhs()))
657 FatalErrorIn("Field<Type>::operator=(const tmp<Field>&)")
658 << "attempted assignment to self"
659 << abort(FatalError);
662 // This is dodgy stuff, don't try it at home.
663 Field* fieldPtr = rhs.ptr();
664 List<Type>::transfer(*fieldPtr);
670 void Foam::Field<Type>::operator=(const Type& t)
672 List<Type>::operator=(t);
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) \
687 template<class Type> \
688 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
690 TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
693 template<class Type> \
694 void Foam::Field<Type>::operator op(const tmp<Field<TYPE> >& tf) \
700 template<class Type> \
701 void Foam::Field<Type>::operator op(const TYPE& t) \
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 * * * * * * * * * * * * * //
717 Foam::Ostream& Foam::operator<<(Ostream& os, const Field<Type>& f)
719 os << static_cast<const List<Type>&>(f);
725 Foam::Ostream& Foam::operator<<(Ostream& os, const tmp<Field<Type> >& tf)
733 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
735 #include "FieldFunctions.C"
737 // ************************************************************************* //