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

DynamicFieldI.H

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 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00027 
00028 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00029 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField()
00030 :
00031     Field<T>(0),
00032     capacity_(Field<T>::size())
00033 {}
00034 
00035 
00036 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00037 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00038 (
00039     const label nElem
00040 )
00041 :
00042     Field<T>(nElem),
00043     capacity_(Field<T>::size())
00044 {
00045     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
00046     Field<T>::size(0);
00047 }
00048 
00049 
00050 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00051 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00052 (
00053     const UList<T>& lst
00054 )
00055 :
00056     Field<T>(lst),
00057     capacity_(Field<T>::size())
00058 {}
00059 
00060 
00061 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00062 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00063 (
00064     const Xfer<List<T> >& lst
00065 )
00066 :
00067     Field<T>(lst),
00068     capacity_(Field<T>::size())
00069 {}
00070 
00071 
00072 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00073 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00074 (
00075     const UList<T>& mapF,
00076     const labelList& mapAddressing
00077 )
00078 :
00079     Field<T>(mapF, mapAddressing),
00080     capacity_(Field<T>::size())
00081 {}
00082 
00083 
00084 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00085 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00086 (
00087     const UList<T>& mapF,
00088     const labelListList& mapAddressing,
00089     const scalarListList& weights
00090 )
00091 :
00092     Field<T>(mapF, mapAddressing, weights),
00093     capacity_(Field<T>::size())
00094 {}
00095 
00096 
00097 //- Construct by mapping from the given field
00098 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00099 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00100 (
00101     const UList<T>& mapF,
00102     const FieldMapper& map
00103 )
00104 :
00105     Field<T>(mapF, map),
00106     capacity_(Field<T>::size())
00107 {}
00108 
00109 
00110 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00111 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00112 (
00113     const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
00114 )
00115 :
00116     Field<T>(lst),
00117     capacity_(lst.capacity())
00118 {}
00119 
00120 
00121 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00122 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
00123 (
00124     const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >& lst
00125 )
00126 :
00127     Field<T>(lst),
00128     capacity_(Field<T>::size())
00129 {}
00130 
00131 
00132 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00133 
00134 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00135 inline Foam::label Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::capacity()
00136 const
00137 {
00138     return capacity_;
00139 }
00140 
00141 
00142 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00143 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity
00144 (
00145     const label nElem
00146 )
00147 {
00148     label nextFree = Field<T>::size();
00149     capacity_ = nElem;
00150 
00151     if (nextFree > capacity_)
00152     {
00153         // truncate addressed sizes too
00154         nextFree = capacity_;
00155     }
00156     // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
00157 
00158     Field<T>::setSize(capacity_);
00159     Field<T>::size(nextFree);
00160 }
00161 
00162 
00163 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00164 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::reserve
00165 (
00166     const label nElem
00167 )
00168 {
00169     // allocate more capacity?
00170     if (nElem > capacity_)
00171     {
00172 // TODO: convince the compiler that division by zero does not occur
00173 //        if (SizeInc && (!SizeMult || !SizeDiv))
00174 //        {
00175 //            // resize with SizeInc as the granularity
00176 //            capacity_ = nElem;
00177 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
00178 //            if (pad != SizeInc)
00179 //            {
00180 //                capacity_ += pad;
00181 //            }
00182 //        }
00183 //        else
00184         {
00185             capacity_ = max
00186             (
00187                 nElem,
00188                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
00189             );
00190         }
00191 
00192         // adjust allocated size, leave addressed size untouched
00193         label nextFree = Field<T>::size();
00194         Field<T>::setSize(capacity_);
00195         Field<T>::size(nextFree);
00196     }
00197 }
00198 
00199 
00200 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00201 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
00202 (
00203     const label nElem
00204 )
00205 {
00206     // allocate more capacity?
00207     if (nElem > capacity_)
00208     {
00209 // TODO: convince the compiler that division by zero does not occur
00210 //        if (SizeInc && (!SizeMult || !SizeDiv))
00211 //        {
00212 //            // resize with SizeInc as the granularity
00213 //            capacity_ = nElem;
00214 //            unsigned pad = SizeInc - (capacity_ % SizeInc);
00215 //            if (pad != SizeInc)
00216 //            {
00217 //                capacity_ += pad;
00218 //            }
00219 //        }
00220 //        else
00221         {
00222             capacity_ = max
00223             (
00224                 nElem,
00225                 label(SizeInc + capacity_ * SizeMult / SizeDiv)
00226             );
00227         }
00228 
00229         Field<T>::setSize(capacity_);
00230     }
00231 
00232     // adjust addressed size
00233     Field<T>::size(nElem);
00234 }
00235 
00236 
00237 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00238 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
00239 (
00240     const label nElem,
00241     const T& t
00242 )
00243 {
00244     label nextFree = Field<T>::size();
00245     setSize(nElem);
00246 
00247     // set new elements to constant value
00248     while (nextFree < nElem)
00249     {
00250         this->operator[](nextFree++) = t;
00251     }
00252 }
00253 
00254 
00255 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00256 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
00257 (
00258     const label nElem
00259 )
00260 {
00261     this->setSize(nElem);
00262 }
00263 
00264 
00265 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00266 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
00267 (
00268     const label nElem,
00269     const T& t
00270 )
00271 {
00272     this->setSize(nElem, t);
00273 }
00274 
00275 
00276 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00277 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clear()
00278 {
00279     Field<T>::size(0);
00280 }
00281 
00282 
00283 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00284 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
00285 {
00286     Field<T>::clear();
00287     capacity_ = 0;
00288 }
00289 
00290 
00291 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00292 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
00293 Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink()
00294 {
00295     label nextFree = Field<T>::size();
00296     if (capacity_ > nextFree)
00297     {
00298         // use the full list when resizing
00299         Field<T>::size(capacity_);
00300 
00301         // the new size
00302         capacity_ = nextFree;
00303         Field<T>::setSize(capacity_);
00304         Field<T>::size(nextFree);
00305     }
00306     return *this;
00307 }
00308 
00309 
00310 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00311 inline Foam::Xfer<Foam::List<T> >
00312 Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::xfer()
00313 {
00314     return xferMoveTo< List<T> >(*this);
00315 }
00316 
00317 
00318 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00319 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
00320 Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
00321 (
00322     const T& t
00323 )
00324 {
00325     const label elemI = List<T>::size();
00326     setSize(elemI + 1);
00327 
00328     this->operator[](elemI) = t;
00329     return *this;
00330 }
00331 
00332 
00333 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00334 inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
00335 Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
00336 (
00337     const UList<T>& lst
00338 )
00339 {
00340     if (this == &lst)
00341     {
00342         FatalErrorIn
00343         (
00344             "DynamicField<T, SizeInc, SizeMult, SizeDiv>::append"
00345             "(const UList<T>&)"
00346         )   << "attempted appending to self" << abort(FatalError);
00347     }
00348 
00349     label nextFree = List<T>::size();
00350     setSize(nextFree + lst.size());
00351 
00352     forAll(lst, elemI)
00353     {
00354         this->operator[](nextFree++) = lst[elemI];
00355     }
00356     return *this;
00357 }
00358 
00359 
00360 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00361 inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()
00362 {
00363     const label elemI = List<T>::size() - 1;
00364 
00365     if (elemI < 0)
00366     {
00367         FatalErrorIn
00368         (
00369             "Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()"
00370         )   << "List is empty" << abort(FatalError);
00371     }
00372 
00373     const T& val = List<T>::operator[](elemI);
00374 
00375     List<T>::size(elemI);
00376 
00377     return val;
00378 }
00379 
00380 
00381 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00382 
00383 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00384 inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator()
00385 (
00386     const label elemI
00387 )
00388 {
00389     if (elemI >= Field<T>::size())
00390     {
00391         setSize(elemI + 1);
00392     }
00393 
00394     return this->operator[](elemI);
00395 }
00396 
00397 
00398 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00399 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
00400 (
00401     const T& t
00402 )
00403 {
00404     UList<T>::operator=(t);
00405 }
00406 
00407 
00408 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00409 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
00410 (
00411     const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
00412 )
00413 {
00414     if (this == &lst)
00415     {
00416         FatalErrorIn
00417         (
00418             "DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator="
00419             "(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&)"
00420         )   << "attempted assignment to self" << abort(FatalError);
00421     }
00422 
00423     if (capacity_ >= lst.size())
00424     {
00425         // can copy w/o reallocating, match initial size to avoid reallocation
00426         Field<T>::size(lst.size());
00427         Field<T>::operator=(lst);
00428     }
00429     else
00430     {
00431         // make everything available for the copy operation
00432         Field<T>::size(capacity_);
00433 
00434         Field<T>::operator=(lst);
00435         capacity_ = Field<T>::size();
00436     }
00437 }
00438 
00439 
00440 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
00441 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
00442 (
00443     const UList<T>& lst
00444 )
00445 {
00446     if (capacity_ >= lst.size())
00447     {
00448         // can copy w/o reallocating, match initial size to avoid reallocation
00449         Field<T>::size(lst.size());
00450         Field<T>::operator=(lst);
00451     }
00452     else
00453     {
00454         // make everything available for the copy operation
00455         Field<T>::size(capacity_);
00456 
00457         Field<T>::operator=(lst);
00458         capacity_ = Field<T>::size();
00459     }
00460 }
00461 
00462 
00463 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines