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

ListOpsTemplates.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 <OpenFOAM/ListOps.H>
00027 
00028 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
00029 
00030 template<class ListType>
00031 ListType Foam::renumber
00032 (
00033     const UList<label>& oldToNew,
00034     const ListType& lst
00035 )
00036 {
00037     // Create copy
00038     ListType newLst(lst.size());
00039 
00040     forAll(lst, elemI)
00041     {
00042         if (lst[elemI] >= 0)
00043         {
00044             newLst[elemI] = oldToNew[lst[elemI]];
00045         }
00046     }
00047 
00048     return newLst;
00049 }
00050 
00051 
00052 template<class ListType>
00053 void Foam::inplaceRenumber
00054 (
00055     const UList<label>& oldToNew,
00056     ListType& lst
00057 )
00058 {
00059     forAll(lst, elemI)
00060     {
00061         if (lst[elemI] >= 0)
00062         {
00063             lst[elemI] = oldToNew[lst[elemI]];
00064         }
00065     }
00066 }
00067 
00068 
00069 template<class ListType>
00070 ListType Foam::reorder
00071 (
00072     const UList<label>& oldToNew,
00073     const ListType& lst
00074 )
00075 {
00076     // Create copy
00077     ListType newLst(lst.size());
00078 
00079     forAll(lst, elemI)
00080     {
00081         if (oldToNew[elemI] >= 0)
00082         {
00083             newLst[oldToNew[elemI]] = lst[elemI];
00084         }
00085         else
00086         {
00087             newLst[elemI] = lst[elemI];
00088         }
00089     }
00090     return newLst;
00091 }
00092 
00093 
00094 template<class ListType>
00095 void Foam::inplaceReorder
00096 (
00097     const UList<label>& oldToNew,
00098     ListType& lst
00099 )
00100 {
00101     // Create copy
00102     ListType newLst(lst.size());
00103 
00104     forAll(lst, elemI)
00105     {
00106         if (oldToNew[elemI] >= 0)
00107         {
00108             newLst[oldToNew[elemI]] = lst[elemI];
00109         }
00110         else
00111         {
00112             newLst[elemI] = lst[elemI];
00113         }
00114     }
00115 
00116     lst.transfer(newLst);
00117 }
00118 
00119 
00120 template<class Container>
00121 void Foam::inplaceMapValue
00122 (
00123     const UList<label>& oldToNew,
00124     Container& lst
00125 )
00126 {
00127     for
00128     (
00129         typename Container::iterator iter = lst.begin();
00130         iter != lst.end();
00131         ++iter
00132     )
00133     {
00134         if (iter() >= 0)
00135         {
00136             iter() = oldToNew[iter()];
00137         }
00138     }
00139 }
00140 
00141 
00142 template<class Container>
00143 void Foam::inplaceMapKey
00144 (
00145     const UList<label>& oldToNew,
00146     Container& lst
00147 )
00148 {
00149     Container newLst(lst.size());
00150 
00151     for
00152     (
00153         typename Container::iterator iter = lst.begin();
00154         iter != lst.end();
00155         ++iter
00156     )
00157     {
00158         if (iter.key() >= 0)
00159         {
00160             newLst.insert(oldToNew[iter.key()], iter());
00161         }
00162     }
00163 
00164     lst.transfer(newLst);
00165 }
00166 
00167 
00168 template<class T>
00169 void Foam::sortedOrder
00170 (
00171     const UList<T>& lst,
00172     labelList& order
00173 )
00174 {
00175     // list lengths must be identical
00176     if (order.size() != lst.size())
00177     {
00178         // avoid copying any elements, they are overwritten anyhow
00179         order.clear();
00180         order.setSize(lst.size());
00181     }
00182 
00183     forAll(order, elemI)
00184     {
00185         order[elemI] = elemI;
00186     }
00187     Foam::stableSort(order, typename UList<T>::less(lst));
00188 }
00189 
00190 
00191 template<class T>
00192 void Foam::duplicateOrder
00193 (
00194     const UList<T>& lst,
00195     labelList& order
00196 )
00197 {
00198     if (lst.size() < 2)
00199     {
00200         order.clear();
00201         return;
00202     }
00203 
00204     sortedOrder(lst, order);
00205 
00206     label n = 0;
00207     for (label i = 0; i < order.size() - 1; ++i)
00208     {
00209         if (lst[order[i]] == lst[order[i+1]])
00210         {
00211             order[n++] = order[i];
00212         }
00213     }
00214     order.setSize(n);
00215 }
00216 
00217 
00218 template<class T>
00219 void Foam::uniqueOrder
00220 (
00221     const UList<T>& lst,
00222     labelList& order
00223 )
00224 {
00225     sortedOrder(lst, order);
00226 
00227     if (order.size() > 1)
00228     {
00229         label n = 0;
00230         for (label i = 0; i < order.size() - 1; ++i)
00231         {
00232             if (lst[order[i]] != lst[order[i+1]])
00233             {
00234                 order[n++] = order[i];
00235             }
00236         }
00237         order.setSize(n);
00238     }
00239 }
00240 
00241 
00242 template<class T, class ListType>
00243 ListType Foam::subset
00244 (
00245     const UList<T>& select,
00246     const T& value,
00247     const ListType& lst
00248 )
00249 {
00250     // select must at least cover the list range
00251     if (select.size() < lst.size())
00252     {
00253         FatalErrorIn("subset(const UList<T>&, const T&, const ListType&)")
00254             << "select is of size " << select.size()
00255             << "; but it must index a list of size " << lst.size()
00256             << abort(FatalError);
00257     }
00258 
00259     ListType newLst(lst.size());
00260 
00261     label nElem = 0;
00262     forAll(lst, elemI)
00263     {
00264         if (select[elemI] == value)
00265         {
00266             newLst[nElem++] = lst[elemI];
00267         }
00268     }
00269     newLst.setSize(nElem);
00270 
00271     return newLst;
00272 }
00273 
00274 
00275 template<class T, class ListType>
00276 void Foam::inplaceSubset
00277 (
00278     const UList<T>& select,
00279     const T& value,
00280     ListType& lst
00281 )
00282 {
00283     // select must at least cover the list range
00284     if (select.size() < lst.size())
00285     {
00286         FatalErrorIn("inplaceSubset(const UList<T>&, const T&, ListType&)")
00287             << "select is of size " << select.size()
00288             << "; but it must index a list of size " << lst.size()
00289             << abort(FatalError);
00290     }
00291 
00292     label nElem = 0;
00293     forAll(lst, elemI)
00294     {
00295         if (select[elemI] == value)
00296         {
00297             if (nElem != elemI)
00298             {
00299                 lst[nElem] = lst[elemI];
00300             }
00301             ++nElem;
00302         }
00303     }
00304 
00305     lst.setSize(nElem);
00306 }
00307 
00308 
00309 template<class BoolListType, class ListType>
00310 ListType Foam::subset
00311 (
00312     const BoolListType& select,
00313     const ListType& lst
00314 )
00315 {
00316     // select can have a different size
00317     // eg, when it is a PackedBoolList or a labelHashSet
00318 
00319     ListType newLst(lst.size());
00320 
00321     label nElem = 0;
00322     forAll(lst, elemI)
00323     {
00324         if (select[elemI])
00325         {
00326             newLst[nElem++] = lst[elemI];
00327         }
00328     }
00329     newLst.setSize(nElem);
00330 
00331     return newLst;
00332 }
00333 
00334 
00335 template<class BoolListType, class ListType>
00336 void Foam::inplaceSubset
00337 (
00338     const BoolListType& select,
00339     ListType& lst
00340 )
00341 {
00342     // select can have a different size
00343     // eg, when it is a PackedBoolList or a labelHashSet
00344 
00345     label nElem = 0;
00346     forAll(lst, elemI)
00347     {
00348         if (select[elemI])
00349         {
00350             if (nElem != elemI)
00351             {
00352                 lst[nElem] = lst[elemI];
00353             }
00354             ++nElem;
00355         }
00356     }
00357 
00358     lst.setSize(nElem);
00359 }
00360 
00361 
00362 // As clarification:
00363 // coded as inversion from pointEdges to edges but completely general.
00364 template<class InList, class OutList>
00365 void Foam::invertManyToMany
00366 (
00367     const label nEdges,
00368     const UList<InList>& pointEdges,
00369     List<OutList>& edges
00370 )
00371 {
00372     // Number of points per edge
00373     labelList nPointsPerEdge(nEdges, 0);
00374 
00375     forAll(pointEdges, pointI)
00376     {
00377         const InList& pEdges = pointEdges[pointI];
00378 
00379         forAll(pEdges, j)
00380         {
00381             nPointsPerEdge[pEdges[j]]++;
00382         }
00383     }
00384 
00385     // Size edges
00386     edges.setSize(nEdges);
00387 
00388     forAll(nPointsPerEdge, edgeI)
00389     {
00390         edges[edgeI].setSize(nPointsPerEdge[edgeI]);
00391     }
00392     nPointsPerEdge = 0;
00393 
00394     // Fill edges
00395     forAll(pointEdges, pointI)
00396     {
00397         const InList& pEdges = pointEdges[pointI];
00398 
00399         forAll(pEdges, j)
00400         {
00401             label edgeI = pEdges[j];
00402 
00403             edges[edgeI][nPointsPerEdge[edgeI]++] = pointI;
00404         }
00405     }
00406 }
00407 
00408 
00409 template<class ListType>
00410 Foam::label Foam::findIndex
00411 (
00412     const ListType& l,
00413     typename ListType::const_reference t,
00414     const label start
00415 )
00416 {
00417     label index = -1;
00418 
00419     for (label i = start; i < l.size(); i++)
00420     {
00421         if (l[i] == t)
00422         {
00423             index = i;
00424             break;
00425         }
00426     }
00427 
00428     return index;
00429 }
00430 
00431 
00432 template<class ListType>
00433 Foam::labelList Foam::findIndices
00434 (
00435     const ListType& l,
00436     typename ListType::const_reference t,
00437     const label start
00438 )
00439 {
00440     // Count occurrences
00441     label n = 0;
00442 
00443     for (label i = start; i < l.size(); i++)
00444     {
00445         if (l[i] == t)
00446         {
00447             n++;
00448         }
00449     }
00450 
00451     // Create and fill
00452     labelList indices(n);
00453     n = 0;
00454 
00455     for (label i = start; i < l.size(); i++)
00456     {
00457         if (l[i] == t)
00458         {
00459             indices[n++] = i;
00460         }
00461     }
00462 
00463     return indices;
00464 }
00465 
00466 
00467 template<class ListType>
00468 void Foam::setValues
00469 (
00470     ListType& l,
00471     const UList<label>& indices,
00472     typename ListType::const_reference t
00473 )
00474 {
00475     forAll(indices, i)
00476     {
00477         l[indices[i]] = t;
00478     }
00479 }
00480 
00481 
00482 template<class ListType>
00483 ListType Foam::createWithValues
00484 (
00485     const label sz,
00486     const typename ListType::const_reference initValue,
00487     const UList<label>& indices,
00488     typename ListType::const_reference setValue
00489 )
00490 {
00491     ListType l(sz, initValue);
00492     setValues(l, indices, setValue);
00493     return l;
00494 }
00495 
00496 
00497 template<class ListType>
00498 Foam::label Foam::findMax(const ListType& l, const label start)
00499 {
00500     if (start >= l.size())
00501     {
00502         return -1;
00503     }
00504 
00505     label index = start;
00506 
00507     for (label i = start+1; i < l.size(); i++)
00508     {
00509         if (l[i] > l[index])
00510         {
00511             index = i;
00512         }
00513     }
00514 
00515     return index;
00516 }
00517 
00518 
00519 template<class ListType>
00520 Foam::label Foam::findMin(const ListType& l, const label start)
00521 {
00522     if (start >= l.size())
00523     {
00524         return -1;
00525     }
00526 
00527     label index = start;
00528 
00529     for (label i = start+1; i < l.size(); i++)
00530     {
00531         if (l[i] < l[index])
00532         {
00533             index = i;
00534         }
00535     }
00536 
00537     return index;
00538 }
00539 
00540 
00541 template<class ListType>
00542 Foam::label Foam::findSortedIndex
00543 (
00544     const ListType& l,
00545     typename ListType::const_reference t,
00546     const label start
00547 )
00548 {
00549     if (start >= l.size())
00550     {
00551         return -1;
00552     }
00553 
00554     label low = start;
00555     label high = l.size() - 1;
00556 
00557     while (low <= high)
00558     {
00559         label mid = (low + high)/2;
00560 
00561         if (t < l[mid])
00562         {
00563             high = mid - 1;
00564         }
00565         else if (t > l[mid])
00566         {
00567             low = mid + 1;
00568         }
00569         else
00570         {
00571             return mid;
00572         }
00573     }
00574 
00575     return -1;
00576 }
00577 
00578 
00579 template<class ListType>
00580 Foam::label Foam::findLower
00581 (
00582     const ListType& l,
00583     typename ListType::const_reference t,
00584     const label start
00585 )
00586 {
00587     if (start >= l.size())
00588     {
00589         return -1;
00590     }
00591 
00592     label low = start;
00593     label high = l.size() - 1;
00594 
00595     while ((high - low) > 1)
00596     {
00597         label mid = (low + high)/2;
00598 
00599         if (l[mid] < t)
00600         {
00601             low = mid;
00602         }
00603         else
00604         {
00605             high = mid;
00606         }
00607     }
00608 
00609     if (l[high] < t)
00610     {
00611         return high;
00612     }
00613     else
00614     {
00615         if (l[low] < t)
00616         {
00617             return low;
00618         }
00619         else
00620         {
00621             return -1;
00622         }
00623     }
00624 }
00625 
00626 
00627 template<class Container, class T, int nRows>
00628 Foam::List<Container> Foam::initList(const T elems[nRows])
00629 {
00630     List<Container> lst(nRows);
00631 
00632     forAll(lst, rowI)
00633     {
00634         lst[rowI] = Container(elems[rowI]);
00635     }
00636     return lst;
00637 }
00638 
00639 
00640 template<class Container, class T, int nRows, int nColumns>
00641 Foam::List<Container> Foam::initListList(const T elems[nRows][nColumns])
00642 {
00643     List<Container> lst(nRows);
00644 
00645     Container cols(nColumns);
00646     forAll(lst, rowI)
00647     {
00648         forAll(cols, colI)
00649         {
00650             cols[colI] = elems[rowI][colI];
00651         }
00652         lst[rowI] = cols;
00653     }
00654     return lst;
00655 }
00656 
00657 
00658 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines