DynamicFieldI.H
Go to the documentation of this file.
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.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
27 
28 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
30 :
31  Field<T>(0),
32  capacity_(Field<T>::size())
33 {}
34 
35 
36 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
38 (
39  const label nElem
40 )
41 :
42  Field<T>(nElem),
43  capacity_(Field<T>::size())
44 {
45  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
46  Field<T>::size(0);
47 }
48 
49 
50 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
52 (
53  const UList<T>& lst
54 )
55 :
56  Field<T>(lst),
57  capacity_(Field<T>::size())
58 {}
59 
60 
61 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
63 (
64  const Xfer<List<T> >& lst
65 )
66 :
67  Field<T>(lst),
68  capacity_(Field<T>::size())
69 {}
70 
71 
72 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
74 (
75  const UList<T>& mapF,
76  const labelList& mapAddressing
77 )
78 :
79  Field<T>(mapF, mapAddressing),
80  capacity_(Field<T>::size())
81 {}
82 
83 
84 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
86 (
87  const UList<T>& mapF,
88  const labelListList& mapAddressing,
89  const scalarListList& weights
90 )
91 :
92  Field<T>(mapF, mapAddressing, weights),
93  capacity_(Field<T>::size())
94 {}
95 
96 
97 //- Construct by mapping from the given field
98 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
100 (
101  const UList<T>& mapF,
102  const FieldMapper& map
103 )
104 :
105  Field<T>(mapF, map),
106  capacity_(Field<T>::size())
107 {}
108 
109 
110 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
112 (
114 )
115 :
116  Field<T>(lst),
117  capacity_(lst.capacity())
118 {}
119 
120 
121 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
123 (
125 )
126 :
127  Field<T>(lst),
128  capacity_(Field<T>::size())
129 {}
130 
131 
132 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
133 
134 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
136 const
137 {
138  return capacity_;
139 }
140 
141 
142 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
144 (
145  const label nElem
146 )
147 {
148  label nextFree = Field<T>::size();
149  capacity_ = nElem;
150 
151  if (nextFree > capacity_)
152  {
153  // truncate addressed sizes too
154  nextFree = capacity_;
155  }
156  // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
157 
158  Field<T>::setSize(capacity_);
159  Field<T>::size(nextFree);
160 }
161 
162 
163 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
165 (
166  const label nElem
167 )
168 {
169  // allocate more capacity?
170  if (nElem > capacity_)
171  {
172 // TODO: convince the compiler that division by zero does not occur
173 // if (SizeInc && (!SizeMult || !SizeDiv))
174 // {
175 // // resize with SizeInc as the granularity
176 // capacity_ = nElem;
177 // unsigned pad = SizeInc - (capacity_ % SizeInc);
178 // if (pad != SizeInc)
179 // {
180 // capacity_ += pad;
181 // }
182 // }
183 // else
184  {
185  capacity_ = max
186  (
187  nElem,
188  label(SizeInc + capacity_ * SizeMult / SizeDiv)
189  );
190  }
191 
192  // adjust allocated size, leave addressed size untouched
193  label nextFree = Field<T>::size();
194  Field<T>::setSize(capacity_);
195  Field<T>::size(nextFree);
196  }
197 }
198 
199 
200 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
202 (
203  const label nElem
204 )
205 {
206  // allocate more capacity?
207  if (nElem > capacity_)
208  {
209 // TODO: convince the compiler that division by zero does not occur
210 // if (SizeInc && (!SizeMult || !SizeDiv))
211 // {
212 // // resize with SizeInc as the granularity
213 // capacity_ = nElem;
214 // unsigned pad = SizeInc - (capacity_ % SizeInc);
215 // if (pad != SizeInc)
216 // {
217 // capacity_ += pad;
218 // }
219 // }
220 // else
221  {
222  capacity_ = max
223  (
224  nElem,
225  label(SizeInc + capacity_ * SizeMult / SizeDiv)
226  );
227  }
228 
229  Field<T>::setSize(capacity_);
230  }
231 
232  // adjust addressed size
233  Field<T>::size(nElem);
234 }
235 
236 
237 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
239 (
240  const label nElem,
241  const T& t
242 )
243 {
244  label nextFree = Field<T>::size();
245  setSize(nElem);
246 
247  // set new elements to constant value
248  while (nextFree < nElem)
249  {
250  this->operator[](nextFree++) = t;
251  }
252 }
253 
254 
255 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
257 (
258  const label nElem
259 )
260 {
261  this->setSize(nElem);
262 }
263 
264 
265 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
267 (
268  const label nElem,
269  const T& t
270 )
271 {
272  this->setSize(nElem, t);
273 }
274 
275 
276 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
278 {
279  Field<T>::size(0);
280 }
281 
282 
283 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
285 {
286  Field<T>::clear();
287  capacity_ = 0;
288 }
289 
290 
291 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
294 {
295  label nextFree = Field<T>::size();
296  if (capacity_ > nextFree)
297  {
298  // use the full list when resizing
299  Field<T>::size(capacity_);
300 
301  // the new size
302  capacity_ = nextFree;
303  Field<T>::setSize(capacity_);
304  Field<T>::size(nextFree);
305  }
306  return *this;
307 }
308 
309 
310 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
313 {
314  return xferMoveTo< List<T> >(*this);
315 }
316 
317 
318 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
321 (
322  const T& t
323 )
324 {
325  const label elemI = List<T>::size();
326  setSize(elemI + 1);
327 
328  this->operator[](elemI) = t;
329  return *this;
330 }
331 
332 
333 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
336 (
337  const UList<T>& lst
338 )
339 {
340  if (this == &lst)
341  {
343  (
344  "DynamicField<T, SizeInc, SizeMult, SizeDiv>::append"
345  "(const UList<T>&)"
346  ) << "attempted appending to self" << abort(FatalError);
347  }
348 
349  label nextFree = List<T>::size();
350  setSize(nextFree + lst.size());
351 
352  forAll(lst, elemI)
353  {
354  this->operator[](nextFree++) = lst[elemI];
355  }
356  return *this;
357 }
358 
359 
360 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
362 {
363  const label elemI = List<T>::size() - 1;
364 
365  if (elemI < 0)
366  {
368  (
369  "Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()"
370  ) << "List is empty" << abort(FatalError);
371  }
372 
373  const T& val = List<T>::operator[](elemI);
374 
375  List<T>::size(elemI);
376 
377  return val;
378 }
379 
380 
381 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
382 
383 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
385 (
386  const label elemI
387 )
388 {
389  if (elemI >= Field<T>::size())
390  {
391  setSize(elemI + 1);
392  }
393 
394  return this->operator[](elemI);
395 }
396 
397 
398 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
399 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
400 (
401  const T& t
402 )
403 {
405 }
406 
407 
408 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
409 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
410 (
412 )
413 {
414  if (this == &lst)
415  {
417  (
418  "DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator="
419  "(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&)"
420  ) << "attempted assignment to self" << abort(FatalError);
421  }
422 
423  if (capacity_ >= lst.size())
424  {
425  // can copy w/o reallocating, match initial size to avoid reallocation
426  Field<T>::size(lst.size());
427  Field<T>::operator=(lst);
428  }
429  else
430  {
431  // make everything available for the copy operation
432  Field<T>::size(capacity_);
433 
434  Field<T>::operator=(lst);
435  capacity_ = Field<T>::size();
436  }
437 }
438 
439 
440 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
441 inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
442 (
443  const UList<T>& lst
444 )
445 {
446  if (capacity_ >= lst.size())
447  {
448  // can copy w/o reallocating, match initial size to avoid reallocation
449  Field<T>::size(lst.size());
450  Field<T>::operator=(lst);
451  }
452  else
453  {
454  // make everything available for the copy operation
455  Field<T>::size(capacity_);
456 
457  Field<T>::operator=(lst);
458  capacity_ = Field<T>::size();
459  }
460 }
461 
462 
463 // ************************************************************************* //
DynamicField()
Construct null.
Definition: DynamicFieldI.H:29
void setSize(const label)
Alter the addressed list size.
Dynamically sized Field.
Definition: DynamicField.H:49
void setCapacity(const label)
Alter the size of the underlying storage.
void reserve(const label)
Reserve allocation space for at least this size.
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:43
tmp< Field< T > > T() const
Return the field transpose (only defined for second rank tensors)
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
void resize(const label)
Alter the addressed list size.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
void clearStorage()
Clear the list and delete storage.
const volScalarField & T
Definition: createFields.H:25
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
T & operator[](const label)
Return element of UList.
Definition: UListI.H:163
void clear()
Clear the list, i.e. set size to zero.
void setSize(const label)
Reset size of List.
void clear()
Clear the addressed list, i.e. set the size to zero.
void operator=(const Field< Type > &)
Definition: Field.C:672
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define forAll(list, i)
Definition: UList.H:421
T remove()
Remove and return the top element.
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
void map(const UList< T > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Pre-declare SubField and related Field type.
Definition: Field.H:57
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
void operator=(const T &)
Assignment of all entries to the given value.
Definition: UList.C:70
error FatalError
Xfer< List< T > > xfer()
Transfer contents to the Xfer container as a plain List.
label capacity() const
Size of the underlying storage.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
label size() const
Return the number of elements in the UList.
DynamicField< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
DynamicField< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
friend Ostream & operator(Ostream &, const Field< T > &)