FreeFOAM The Cross-Platform CFD Toolkit
ListOpsTemplates.C
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 #include <OpenFOAM/ListOps.H>
27 
28 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
29 
30 template<class ListType>
31 ListType Foam::renumber
32 (
33  const UList<label>& oldToNew,
34  const ListType& lst
35 )
36 {
37  // Create copy
38  ListType newLst(lst.size());
39 
40  forAll(lst, elemI)
41  {
42  if (lst[elemI] >= 0)
43  {
44  newLst[elemI] = oldToNew[lst[elemI]];
45  }
46  }
47 
48  return newLst;
49 }
50 
51 
52 template<class ListType>
54 (
55  const UList<label>& oldToNew,
56  ListType& lst
57 )
58 {
59  forAll(lst, elemI)
60  {
61  if (lst[elemI] >= 0)
62  {
63  lst[elemI] = oldToNew[lst[elemI]];
64  }
65  }
66 }
67 
68 
69 template<class ListType>
70 ListType Foam::reorder
71 (
72  const UList<label>& oldToNew,
73  const ListType& lst
74 )
75 {
76  // Create copy
77  ListType newLst(lst.size());
78 
79  forAll(lst, elemI)
80  {
81  if (oldToNew[elemI] >= 0)
82  {
83  newLst[oldToNew[elemI]] = lst[elemI];
84  }
85  else
86  {
87  newLst[elemI] = lst[elemI];
88  }
89  }
90  return newLst;
91 }
92 
93 
94 template<class ListType>
96 (
97  const UList<label>& oldToNew,
98  ListType& lst
99 )
100 {
101  // Create copy
102  ListType newLst(lst.size());
103 
104  forAll(lst, elemI)
105  {
106  if (oldToNew[elemI] >= 0)
107  {
108  newLst[oldToNew[elemI]] = lst[elemI];
109  }
110  else
111  {
112  newLst[elemI] = lst[elemI];
113  }
114  }
115 
116  lst.transfer(newLst);
117 }
118 
119 
120 template<class Container>
122 (
123  const UList<label>& oldToNew,
124  Container& lst
125 )
126 {
127  for
128  (
129  typename Container::iterator iter = lst.begin();
130  iter != lst.end();
131  ++iter
132  )
133  {
134  if (iter() >= 0)
135  {
136  iter() = oldToNew[iter()];
137  }
138  }
139 }
140 
141 
142 template<class Container>
144 (
145  const UList<label>& oldToNew,
146  Container& lst
147 )
148 {
149  Container newLst(lst.size());
150 
151  for
152  (
153  typename Container::iterator iter = lst.begin();
154  iter != lst.end();
155  ++iter
156  )
157  {
158  if (iter.key() >= 0)
159  {
160  newLst.insert(oldToNew[iter.key()], iter());
161  }
162  }
163 
164  lst.transfer(newLst);
165 }
166 
167 
168 template<class T>
170 (
171  const UList<T>& lst,
172  labelList& order
173 )
174 {
175  // list lengths must be identical
176  if (order.size() != lst.size())
177  {
178  // avoid copying any elements, they are overwritten anyhow
179  order.clear();
180  order.setSize(lst.size());
181  }
182 
183  forAll(order, elemI)
184  {
185  order[elemI] = elemI;
186  }
187  Foam::stableSort(order, typename UList<T>::less(lst));
188 }
189 
190 
191 template<class T>
193 (
194  const UList<T>& lst,
195  labelList& order
196 )
197 {
198  if (lst.size() < 2)
199  {
200  order.clear();
201  return;
202  }
203 
204  sortedOrder(lst, order);
205 
206  label n = 0;
207  for (label i = 0; i < order.size() - 1; ++i)
208  {
209  if (lst[order[i]] == lst[order[i+1]])
210  {
211  order[n++] = order[i];
212  }
213  }
214  order.setSize(n);
215 }
216 
217 
218 template<class T>
220 (
221  const UList<T>& lst,
222  labelList& order
223 )
224 {
225  sortedOrder(lst, order);
226 
227  if (order.size() > 1)
228  {
229  label n = 0;
230  for (label i = 0; i < order.size() - 1; ++i)
231  {
232  if (lst[order[i]] != lst[order[i+1]])
233  {
234  order[n++] = order[i];
235  }
236  }
237  order.setSize(n);
238  }
239 }
240 
241 
242 template<class T, class ListType>
243 ListType Foam::subset
244 (
245  const UList<T>& select,
246  const T& value,
247  const ListType& lst
248 )
249 {
250  // select must at least cover the list range
251  if (select.size() < lst.size())
252  {
253  FatalErrorIn("subset(const UList<T>&, const T&, const ListType&)")
254  << "select is of size " << select.size()
255  << "; but it must index a list of size " << lst.size()
256  << abort(FatalError);
257  }
258 
259  ListType newLst(lst.size());
260 
261  label nElem = 0;
262  forAll(lst, elemI)
263  {
264  if (select[elemI] == value)
265  {
266  newLst[nElem++] = lst[elemI];
267  }
268  }
269  newLst.setSize(nElem);
270 
271  return newLst;
272 }
273 
274 
275 template<class T, class ListType>
277 (
278  const UList<T>& select,
279  const T& value,
280  ListType& lst
281 )
282 {
283  // select must at least cover the list range
284  if (select.size() < lst.size())
285  {
286  FatalErrorIn("inplaceSubset(const UList<T>&, const T&, ListType&)")
287  << "select is of size " << select.size()
288  << "; but it must index a list of size " << lst.size()
289  << abort(FatalError);
290  }
291 
292  label nElem = 0;
293  forAll(lst, elemI)
294  {
295  if (select[elemI] == value)
296  {
297  if (nElem != elemI)
298  {
299  lst[nElem] = lst[elemI];
300  }
301  ++nElem;
302  }
303  }
304 
305  lst.setSize(nElem);
306 }
307 
308 
309 template<class BoolListType, class ListType>
310 ListType Foam::subset
311 (
312  const BoolListType& select,
313  const ListType& lst
314 )
315 {
316  // select can have a different size
317  // eg, when it is a PackedBoolList or a labelHashSet
318 
319  ListType newLst(lst.size());
320 
321  label nElem = 0;
322  forAll(lst, elemI)
323  {
324  if (select[elemI])
325  {
326  newLst[nElem++] = lst[elemI];
327  }
328  }
329  newLst.setSize(nElem);
330 
331  return newLst;
332 }
333 
334 
335 template<class BoolListType, class ListType>
337 (
338  const BoolListType& select,
339  ListType& lst
340 )
341 {
342  // select can have a different size
343  // eg, when it is a PackedBoolList or a labelHashSet
344 
345  label nElem = 0;
346  forAll(lst, elemI)
347  {
348  if (select[elemI])
349  {
350  if (nElem != elemI)
351  {
352  lst[nElem] = lst[elemI];
353  }
354  ++nElem;
355  }
356  }
357 
358  lst.setSize(nElem);
359 }
360 
361 
362 // As clarification:
363 // coded as inversion from pointEdges to edges but completely general.
364 template<class InList, class OutList>
366 (
367  const label nEdges,
368  const UList<InList>& pointEdges,
369  List<OutList>& edges
370 )
371 {
372  // Number of points per edge
373  labelList nPointsPerEdge(nEdges, 0);
374 
375  forAll(pointEdges, pointI)
376  {
377  const InList& pEdges = pointEdges[pointI];
378 
379  forAll(pEdges, j)
380  {
381  nPointsPerEdge[pEdges[j]]++;
382  }
383  }
384 
385  // Size edges
386  edges.setSize(nEdges);
387 
388  forAll(nPointsPerEdge, edgeI)
389  {
390  edges[edgeI].setSize(nPointsPerEdge[edgeI]);
391  }
392  nPointsPerEdge = 0;
393 
394  // Fill edges
395  forAll(pointEdges, pointI)
396  {
397  const InList& pEdges = pointEdges[pointI];
398 
399  forAll(pEdges, j)
400  {
401  label edgeI = pEdges[j];
402 
403  edges[edgeI][nPointsPerEdge[edgeI]++] = pointI;
404  }
405  }
406 }
407 
408 
409 template<class ListType>
410 Foam::label Foam::findIndex
411 (
412  const ListType& l,
413  typename ListType::const_reference t,
414  const label start
415 )
416 {
417  label index = -1;
418 
419  for (label i = start; i < l.size(); i++)
420  {
421  if (l[i] == t)
422  {
423  index = i;
424  break;
425  }
426  }
427 
428  return index;
429 }
430 
431 
432 template<class ListType>
434 (
435  const ListType& l,
436  typename ListType::const_reference t,
437  const label start
438 )
439 {
440  // Count occurrences
441  label n = 0;
442 
443  for (label i = start; i < l.size(); i++)
444  {
445  if (l[i] == t)
446  {
447  n++;
448  }
449  }
450 
451  // Create and fill
452  labelList indices(n);
453  n = 0;
454 
455  for (label i = start; i < l.size(); i++)
456  {
457  if (l[i] == t)
458  {
459  indices[n++] = i;
460  }
461  }
462 
463  return indices;
464 }
465 
466 
467 template<class ListType>
468 void Foam::setValues
469 (
470  ListType& l,
471  const UList<label>& indices,
472  typename ListType::const_reference t
473 )
474 {
475  forAll(indices, i)
476  {
477  l[indices[i]] = t;
478  }
479 }
480 
481 
482 template<class ListType>
483 ListType Foam::createWithValues
484 (
485  const label sz,
486  const typename ListType::const_reference initValue,
487  const UList<label>& indices,
488  typename ListType::const_reference setValue
489 )
490 {
491  ListType l(sz, initValue);
492  setValues(l, indices, setValue);
493  return l;
494 }
495 
496 
497 template<class ListType>
498 Foam::label Foam::findMax(const ListType& l, const label start)
499 {
500  if (start >= l.size())
501  {
502  return -1;
503  }
504 
505  label index = start;
506 
507  for (label i = start+1; i < l.size(); i++)
508  {
509  if (l[i] > l[index])
510  {
511  index = i;
512  }
513  }
514 
515  return index;
516 }
517 
518 
519 template<class ListType>
520 Foam::label Foam::findMin(const ListType& l, const label start)
521 {
522  if (start >= l.size())
523  {
524  return -1;
525  }
526 
527  label index = start;
528 
529  for (label i = start+1; i < l.size(); i++)
530  {
531  if (l[i] < l[index])
532  {
533  index = i;
534  }
535  }
536 
537  return index;
538 }
539 
540 
541 template<class ListType>
542 Foam::label Foam::findSortedIndex
543 (
544  const ListType& l,
545  typename ListType::const_reference t,
546  const label start
547 )
548 {
549  if (start >= l.size())
550  {
551  return -1;
552  }
553 
554  label low = start;
555  label high = l.size() - 1;
556 
557  while (low <= high)
558  {
559  label mid = (low + high)/2;
560 
561  if (t < l[mid])
562  {
563  high = mid - 1;
564  }
565  else if (t > l[mid])
566  {
567  low = mid + 1;
568  }
569  else
570  {
571  return mid;
572  }
573  }
574 
575  return -1;
576 }
577 
578 
579 template<class ListType>
580 Foam::label Foam::findLower
581 (
582  const ListType& l,
583  typename ListType::const_reference t,
584  const label start
585 )
586 {
587  if (start >= l.size())
588  {
589  return -1;
590  }
591 
592  label low = start;
593  label high = l.size() - 1;
594 
595  while ((high - low) > 1)
596  {
597  label mid = (low + high)/2;
598 
599  if (l[mid] < t)
600  {
601  low = mid;
602  }
603  else
604  {
605  high = mid;
606  }
607  }
608 
609  if (l[high] < t)
610  {
611  return high;
612  }
613  else
614  {
615  if (l[low] < t)
616  {
617  return low;
618  }
619  else
620  {
621  return -1;
622  }
623  }
624 }
625 
626 
627 template<class Container, class T, int nRows>
629 {
630  List<Container> lst(nRows);
631 
632  forAll(lst, rowI)
633  {
634  lst[rowI] = Container(elems[rowI]);
635  }
636  return lst;
637 }
638 
639 
640 template<class Container, class T, int nRows, int nColumns>
641 Foam::List<Container> Foam::initListList(const T elems[nRows][nColumns])
642 {
643  List<Container> lst(nRows);
644 
645  Container cols(nColumns);
646  forAll(lst, rowI)
647  {
648  forAll(cols, colI)
649  {
650  cols[colI] = elems[rowI][colI];
651  }
652  lst[rowI] = cols;
653  }
654  return lst;
655 }
656 
657 
658 // ************************ vim: set sw=4 sts=4 et: ************************ //