FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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>
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 // ************************ vim: set sw=4 sts=4 et: ************************ //