FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

Field.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "FieldMapper.H"
00027 #include "FieldM.H"
00028 #include <OpenFOAM/dictionary.H>
00029 #include <OpenFOAM/contiguous.H>
00030 
00031 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00032 
00033 namespace Foam
00034 {
00035 
00036 // * * * * * * * * * * * * * * * Static Members  * * * * * * * * * * * * * * //
00037 
00038 template<class Type>
00039 const char* const Field<Type>::typeName("Field");
00040 
00041 
00042 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00043 
00044 template<class Type>
00045 Field<Type>::Field()
00046 :
00047     List<Type>()
00048 {}
00049 
00050 
00051 template<class Type>
00052 Field<Type>::Field(const label size)
00053 :
00054     List<Type>(size)
00055 {}
00056 
00057 
00058 template<class Type>
00059 Field<Type>::Field(const label size, const Type& t)
00060 :
00061     List<Type>(size, t)
00062 {}
00063 
00064 
00065 template<class Type>
00066 Field<Type>::Field
00067 (
00068     const UList<Type>& mapF,
00069     const unallocLabelList& mapAddressing
00070 )
00071 :
00072     List<Type>(mapAddressing.size())
00073 {
00074     map(mapF, mapAddressing);
00075 }
00076 
00077 template<class Type>
00078 Field<Type>::Field
00079 (
00080     const tmp<Field<Type> >& tmapF,
00081     const unallocLabelList& mapAddressing
00082 )
00083 :
00084     List<Type>(mapAddressing.size())
00085 {
00086     map(tmapF, mapAddressing);
00087 }
00088 
00089 
00090 template<class Type>
00091 Field<Type>::Field
00092 (
00093     const UList<Type>& mapF,
00094     const labelListList& mapAddressing,
00095     const scalarListList& mapWeights
00096 )
00097 :
00098     List<Type>(mapAddressing.size())
00099 {
00100     map(mapF, mapAddressing, mapWeights);
00101 }
00102 
00103 template<class Type>
00104 Field<Type>::Field
00105 (
00106     const tmp<Field<Type> >& tmapF,
00107     const labelListList& mapAddressing,
00108     const scalarListList& mapWeights
00109 )
00110 :
00111     List<Type>(mapAddressing.size())
00112 {
00113     map(tmapF, mapAddressing, mapWeights);
00114 }
00115 
00116 
00117 template<class Type>
00118 Field<Type>::Field
00119 (
00120     const UList<Type>& mapF,
00121     const FieldMapper& mapper
00122 )
00123 :
00124     List<Type>(mapper.size())
00125 {
00126     map(mapF, mapper);
00127 }
00128 
00129 template<class Type>
00130 Field<Type>::Field
00131 (
00132     const tmp<Field<Type> >& tmapF,
00133     const FieldMapper& mapper
00134 )
00135 :
00136     List<Type>(mapper.size())
00137 {
00138     map(tmapF, mapper);
00139 }
00140 
00141 
00142 template<class Type>
00143 Field<Type>::Field(const Field<Type>& f)
00144 :
00145     refCount(),
00146     List<Type>(f)
00147 {}
00148 
00149 
00150 template<class Type>
00151 Field<Type>::Field(Field<Type>& f, bool reUse)
00152 :
00153     List<Type>(f, reUse)
00154 {}
00155 
00156 
00157 template<class Type>
00158 Field<Type>::Field(const Xfer<List<Type> >& f)
00159 :
00160     List<Type>(f)
00161 {}
00162 
00163 
00164 template<class Type>
00165 Field<Type>::Field(const Xfer<Field<Type> >& f)
00166 :
00167     List<Type>(f)
00168 {}
00169 
00170 
00171 template<class Type>
00172 Field<Type>::Field(const typename Field<Type>::subField& sf)
00173 :
00174     List<Type>(sf)
00175 {}
00176 
00177 
00178 template<class Type>
00179 Field<Type>::Field(const UList<Type>& list)
00180 :
00181     List<Type>(list)
00182 {}
00183 
00184 
00185 // Construct as copy of tmp<Field>
00186 #ifdef ConstructFromTmp
00187 template<class Type>
00188 Field<Type>::Field(const tmp<Field<Type> >& tf)
00189 :
00190     List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
00191 {
00192     const_cast<Field<Type>&>(tf()).resetRefCount();
00193 }
00194 #endif
00195 
00196 
00197 template<class Type>
00198 Field<Type>::Field(Istream& is)
00199 :
00200     List<Type>(is)
00201 {}
00202 
00203 
00204 template<class Type>
00205 Field<Type>::Field
00206 (
00207     const word& keyword,
00208     const dictionary& dict,
00209     const label s
00210 )
00211 {
00212     if (s)
00213     {
00214         ITstream& is = dict.lookup(keyword);
00215 
00216         // Read first token
00217         token firstToken(is);
00218 
00219         if (firstToken.isWord())
00220         {
00221             if (firstToken.wordToken() == "uniform")
00222             {
00223                 this->setSize(s);
00224                 operator=(pTraits<Type>(is));
00225             }
00226             else if (firstToken.wordToken() == "nonuniform")
00227             {
00228                 is >> static_cast<List<Type>&>(*this);
00229                 if (this->size() != s)
00230                 {
00231                     FatalIOErrorIn
00232                     (
00233                         "Field<Type>::Field"
00234                         "(const word& keyword, const dictionary&, const label)",
00235                         dict
00236                     )   << "size " << this->size()
00237                         << " is not equal to the given value of " << s
00238                         << exit(FatalIOError);
00239                 }
00240             }
00241             else
00242             {
00243                 FatalIOErrorIn
00244                 (
00245                     "Field<Type>::Field"
00246                     "(const word& keyword, const dictionary&, const label)",
00247                     dict
00248                 )   << "expected keyword 'uniform' or 'nonuniform', found "
00249                     << firstToken.wordToken()
00250                     << exit(FatalIOError);
00251             }
00252         }
00253         else
00254         {
00255             if (is.version() == 2.0)
00256             {
00257                 IOWarningIn
00258                 (
00259                     "Field<Type>::Field"
00260                     "(const word& keyword, const dictionary&, const label)",
00261                     dict
00262                 )   << "expected keyword 'uniform' or 'nonuniform', "
00263                        "assuming deprecated Field format from "
00264                        "Foam version 2.0." << endl;
00265 
00266                 this->setSize(s);
00267 
00268                 is.putBack(firstToken);
00269                 operator=(pTraits<Type>(is));
00270             }
00271             else
00272             {
00273                 FatalIOErrorIn
00274                 (
00275                     "Field<Type>::Field"
00276                     "(const word& keyword, const dictionary&, const label)",
00277                     dict
00278                 )   << "expected keyword 'uniform' or 'nonuniform', found "
00279                     << firstToken.info()
00280                     << exit(FatalIOError);
00281             }
00282         }
00283     }
00284 }
00285 
00286 
00287 template<class Type>
00288 tmp<Field<Type> > Field<Type>::clone() const
00289 {
00290     return tmp<Field<Type> >(new Field<Type>(*this));
00291 }
00292 
00293 
00294 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00295 
00296 template<class Type>
00297 void Field<Type>::map
00298 (
00299     const UList<Type>& mapF,
00300     const unallocLabelList& mapAddressing
00301 )
00302 {
00303     Field<Type>& f = *this;
00304 
00305     if (f.size() != mapAddressing.size())
00306     {
00307         f.setSize(mapAddressing.size());
00308     }
00309 
00310     if (mapF.size() > 0)
00311     {
00312         forAll(f, i)
00313         {
00314             label mapI = mapAddressing[i];
00315 
00316             if (mapI >= 0)
00317             {
00318                 f[i] = mapF[mapI];
00319             }
00320         }
00321     }
00322 }
00323 
00324 
00325 template<class Type>
00326 void Field<Type>::map
00327 (
00328     const tmp<Field<Type> >& tmapF,
00329     const unallocLabelList& mapAddressing
00330 )
00331 {
00332     map(tmapF(), mapAddressing);
00333     tmapF.clear();
00334 }
00335 
00336 
00337 template<class Type>
00338 void Field<Type>::map
00339 (
00340     const UList<Type>& mapF,
00341     const labelListList& mapAddressing,
00342     const scalarListList& mapWeights
00343 )
00344 {
00345     Field<Type>& f = *this;
00346 
00347     if (f.size() != mapAddressing.size())
00348     {
00349         f.setSize(mapAddressing.size());
00350     }
00351 
00352     if (mapWeights.size() != mapAddressing.size())
00353     {
00354         FatalErrorIn
00355         (
00356             "void Field<Type>::map\n"
00357             "(\n"
00358             "    const UList<Type>& mapF,\n"
00359             "    const labelListList& mapAddressing,\n"
00360             "    const scalarListList& mapWeights\n"
00361             ")"
00362         ) << "Weights and addressing map have different sizes.  Weights size: "
00363             << mapWeights.size() << " map size: " << mapAddressing.size()
00364             << abort(FatalError);
00365     }
00366 
00367     forAll(f, i)
00368     {
00369         const labelList&  localAddrs   = mapAddressing[i];
00370         const scalarList& localWeights = mapWeights[i];
00371 
00372         f[i] = pTraits<Type>::zero;
00373 
00374         forAll(localAddrs, j)
00375         {
00376             f[i] += localWeights[j]*mapF[localAddrs[j]];
00377         }
00378     }
00379 }
00380 
00381 template<class Type>
00382 void Field<Type>::map
00383 (
00384     const tmp<Field<Type> >& tmapF,
00385     const labelListList& mapAddressing,
00386     const scalarListList& mapWeights
00387 )
00388 {
00389     map(tmapF(), mapAddressing, mapWeights);
00390     tmapF.clear();
00391 }
00392 
00393 
00394 template<class Type>
00395 void Field<Type>::map
00396 (
00397     const UList<Type>& mapF,
00398     const FieldMapper& mapper
00399 )
00400 {
00401     if
00402     (
00403         mapper.direct()
00404      && &mapper.directAddressing()
00405      && mapper.directAddressing().size()
00406     )
00407     {
00408         map(mapF, mapper.directAddressing());
00409     }
00410     else if (!mapper.direct() && mapper.addressing().size())
00411     {
00412         map(mapF, mapper.addressing(), mapper.weights());
00413     }
00414 }
00415 
00416 template<class Type>
00417 void Field<Type>::map
00418 (
00419     const tmp<Field<Type> >& tmapF,
00420     const FieldMapper& mapper
00421 )
00422 {
00423     map(tmapF(), mapper);
00424     tmapF.clear();
00425 }
00426 
00427 
00428 template<class Type>
00429 void Field<Type>::autoMap
00430 (
00431     const FieldMapper& mapper
00432 )
00433 {
00434     if
00435     (
00436         (
00437             mapper.direct()
00438          && &mapper.directAddressing()
00439          && mapper.directAddressing().size()
00440         )
00441      || (!mapper.direct() && mapper.addressing().size())
00442     )
00443     {
00444         Field<Type> fCpy(*this);
00445         map(fCpy, mapper);
00446     }
00447     else
00448     {
00449         this->setSize(mapper.size());
00450     }
00451 }
00452 
00453 
00454 template<class Type>
00455 void Field<Type>::rmap
00456 (
00457     const UList<Type>& mapF,
00458     const unallocLabelList& mapAddressing
00459 )
00460 {
00461     Field<Type>& f = *this;
00462 
00463     forAll(mapF, i)
00464     {
00465         label mapI = mapAddressing[i];
00466 
00467         if (mapI >= 0)
00468         {
00469             f[mapI] = mapF[i];
00470         }
00471     }
00472 }
00473 
00474 template<class Type>
00475 void Field<Type>::rmap
00476 (
00477     const tmp<Field<Type> >& tmapF,
00478     const unallocLabelList& mapAddressing
00479 )
00480 {
00481     rmap(tmapF(), mapAddressing);
00482     tmapF.clear();
00483 }
00484 
00485 
00486 template<class Type>
00487 void Field<Type>::rmap
00488 (
00489     const UList<Type>& mapF,
00490     const unallocLabelList& mapAddressing,
00491     const scalarList& mapWeights
00492 )
00493 {
00494     Field<Type>& f = *this;
00495 
00496     f = pTraits<Type>::zero;
00497 
00498     forAll(mapF, i)
00499     {
00500         f[mapAddressing[i]] += mapF[i]*mapWeights[i];
00501     }
00502 }
00503 
00504 template<class Type>
00505 void Field<Type>::rmap
00506 (
00507     const tmp<Field<Type> >& tmapF,
00508     const unallocLabelList& mapAddressing,
00509     const scalarList& mapWeights
00510 )
00511 {
00512     rmap(tmapF(), mapAddressing, mapWeights);
00513     tmapF.clear();
00514 }
00515 
00516 
00517 template<class Type>
00518 void Field<Type>::negate()
00519 {
00520     TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
00521 }
00522 
00523 
00524 template<class Type>
00525 tmp<Field<typename Field<Type>::cmptType> > Field<Type>::component
00526 (
00527     const direction d
00528 ) const
00529 {
00530     tmp<Field<cmptType> > Component(new Field<cmptType>(this->size()));
00531     ::Foam::component(Component(), *this, d);
00532     return Component;
00533 }
00534 
00535 
00536 template<class Type>
00537 void Field<Type>::replace
00538 (
00539     const direction d,
00540     const UList<cmptType>& sf
00541 )
00542 {
00543     TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
00544         cmptType, sf)
00545 }
00546 
00547 
00548 template<class Type>
00549 void Field<Type>::replace
00550 (
00551     const direction d,
00552     const tmp<Field<cmptType> >& tsf
00553 )
00554 {
00555     replace(d, tsf());
00556     tsf.clear();
00557 }
00558 
00559 
00560 template<class Type>
00561 void Field<Type>::replace
00562 (
00563     const direction d,
00564     const cmptType& c
00565 )
00566 {
00567     TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
00568         cmptType, c)
00569 }
00570 
00571 
00572 template<class Type>
00573 tmp<Field<Type> > Field<Type>::T() const
00574 {
00575     tmp<Field<Type> > transpose(new Field<Type>(this->size()));
00576     ::Foam::T(transpose(), *this);
00577     return transpose;
00578 }
00579 
00580 
00581 template<class Type>
00582 void Field<Type>::writeEntry(const word& keyword, Ostream& os) const
00583 {
00584     os.writeKeyword(keyword);
00585 
00586     bool uniform = false;
00587 
00588     if (this->size() && contiguous<Type>())
00589     {
00590         uniform = true;
00591 
00592         forAll(*this, i)
00593         {
00594             if (this->operator[](i) != this->operator[](0))
00595             {
00596                 uniform = false;
00597                 break;
00598             }
00599         }
00600     }
00601 
00602     if (uniform)
00603     {
00604         os << "uniform " << this->operator[](0) << token::END_STATEMENT;
00605     }
00606     else
00607     {
00608         os << "nonuniform ";
00609         List<Type>::writeEntry(os);
00610         os << token::END_STATEMENT;
00611     }
00612 
00613     os << endl;
00614 }
00615 
00616 
00617 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00618 
00619 template<class Type>
00620 void Field<Type>::operator=(const Field<Type>& rhs)
00621 {
00622     if (this == &rhs)
00623     {
00624         FatalErrorIn("Field<Type>::operator=(const Field<Type>&)")
00625             << "attempted assignment to self"
00626             << abort(FatalError);
00627     }
00628 
00629     List<Type>::operator=(rhs);
00630 }
00631 
00632 
00633 template<class Type>
00634 void Field<Type>::operator=(const SubField<Type>& rhs)
00635 {
00636     List<Type>::operator=(rhs);
00637 }
00638 
00639 
00640 template<class Type>
00641 void Field<Type>::operator=(const UList<Type>& rhs)
00642 {
00643     List<Type>::operator=(rhs);
00644 }
00645 
00646 
00647 template<class Type>
00648 void Field<Type>::operator=(const tmp<Field>& rhs)
00649 {
00650     if (this == &(rhs()))
00651     {
00652         FatalErrorIn("Field<Type>::operator=(const tmp<Field>&)")
00653             << "attempted assignment to self"
00654             << abort(FatalError);
00655     }
00656 
00657     // This is dodgy stuff, don't try it at home.
00658     Field* fieldPtr = rhs.ptr();
00659     List<Type>::transfer(*fieldPtr);
00660     delete fieldPtr;
00661 }
00662 
00663 
00664 template<class Type>
00665 void Field<Type>::operator=(const Type& t)
00666 {
00667     List<Type>::operator=(t);
00668 }
00669 
00670 
00671 template<class Type>
00672 template<class Form, class Cmpt, int nCmpt>
00673 void Field<Type>::operator=(const VectorSpace<Form,Cmpt,nCmpt>& vs)
00674 {
00675     typedef VectorSpace<Form,Cmpt,nCmpt> VSType;
00676     TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
00677 }
00678 
00679 
00680 #define COMPUTED_ASSIGNMENT(TYPE, op)                                         \
00681                                                                               \
00682 template<class Type>                                                          \
00683 void Field<Type>::operator op(const UList<TYPE>& f)                           \
00684 {                                                                             \
00685     TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f)                                 \
00686 }                                                                             \
00687                                                                               \
00688 template<class Type>                                                          \
00689 void Field<Type>::operator op(const tmp<Field<TYPE> >& tf)                    \
00690 {                                                                             \
00691     operator op(tf());                                                        \
00692     tf.clear();                                                               \
00693 }                                                                             \
00694                                                                               \
00695 template<class Type>                                                          \
00696 void Field<Type>::operator op(const TYPE& t)                                  \
00697 {                                                                             \
00698     TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t)                                 \
00699 }
00700 
00701 COMPUTED_ASSIGNMENT(Type, +=)
00702 COMPUTED_ASSIGNMENT(Type, -=)
00703 COMPUTED_ASSIGNMENT(scalar, *=)
00704 COMPUTED_ASSIGNMENT(scalar, /=)
00705 
00706 #undef COMPUTED_ASSIGNMENT
00707 
00708 
00709 // * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
00710 
00711 template<class Type>
00712 Ostream& operator<<(Ostream& os, const Field<Type>& f)
00713 {
00714     os << static_cast<const List<Type>&>(f);
00715     return os;
00716 }
00717 
00718 
00719 template<class Type>
00720 Ostream& operator<<(Ostream& os, const tmp<Field<Type> >& tf)
00721 {
00722     os << tf();
00723     tf.clear();
00724     return os;
00725 }
00726 
00727 
00728 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00729 
00730 } // End namespace Foam
00731 
00732 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00733 
00734 #   include "FieldFunctions.C"
00735 
00736 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines