Loading...
Searching...
No Matches
bitSet.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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2018-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "bitSet.H"
29#include "IOstreams.H"
30#include "UPstream.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
38
39 // TBD: add IO support of compound type?
40 // defineNamedCompoundTypeName(bitSet, List<1>);
41 // addNamedCompoundToRunTimeSelectionTable(bitSet, bitSet, List<1>);
42}
43
44// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
45
47{
48 if (&other == this)
49 {
50 // Self '-=' : clears all bits
51 if (debug & 2)
52 {
54 << "Perform -= on self: clears all bits" << nl;
55 }
56
57 reset();
58 return *this;
59 }
60 else if (none() || other.none())
61 {
62 // no-op: nothing can change
63 return *this;
64 }
65
66 // The operation (on overlapping blocks)
67 {
68 const label nblocks = num_blocks(std::min(size(), other.size()));
69 const auto& rhs = other.blocks_;
70
71 for (label blocki = 0; blocki < nblocks; ++blocki)
72 {
73 blocks_[blocki] &= ~rhs[blocki];
74 }
75 }
76
77 return *this;
78}
79
80
81Foam::bitSet& Foam::bitSet::andEq(const bitSet& other)
82{
83 if (FOAM_UNLIKELY(&other == this))
84 {
85 // Self '&=' : no-op
86
87 if (debug & 2)
88 {
90 << "Perform &= on self: ignore" << nl;
91 }
92
93 return *this;
94 }
95 else if (none())
96 {
97 // no-op: nothing is set - no intersection possible
98 return *this;
99 }
100 else if (other.none())
101 {
102 // no-op: other has nothing set - no intersection possible
103 reset();
104 return *this;
105 }
106
107
108 const label origSize(size());
109 const label otherSize(other.size());
110
111 if (origSize > otherSize)
112 {
113 // Clear bits (and blocks) that do not overlap at all
114 resize(otherSize);
115 resize(origSize);
116 }
117
118 // The operation (on overlapping blocks)
119 {
120 const label nblocks = num_blocks(std::min(origSize, otherSize));
121 const auto& rhs = other.blocks_;
122
123 for (label blocki = 0; blocki < nblocks; ++blocki)
124 {
125 blocks_[blocki] &= rhs[blocki];
127 }
128
129 return *this;
130}
131
132
133Foam::bitSet& Foam::bitSet::orEq(const bitSet& other)
134{
135 if (&other == this)
136 {
137 // Self '|=' : no-op
138
139 if (debug & 2)
140 {
142 << "Perform |= on self: ignore" << nl;
143 }
144
145 return *this;
146 }
147 else if (other.none())
148 {
149 // no-op: nothing can change
150 return *this;
151 }
152
153
154 // Largest new bit that could be introduced
155 const label otherMax(other.find_last());
156
157 if (otherMax >= size())
158 {
159 // Extend to accommodate bits from 'other'
160 resize(otherMax+1);
161 }
162
163 // The operation (on overlapping blocks)
164 {
165 const label nblocks = num_blocks(std::min(size(), other.size()));
166 const auto& rhs = other.blocks_;
167
168 for (label blocki = 0; blocki < nblocks; ++blocki)
169 {
170 blocks_[blocki] |= rhs[blocki];
172 }
173
174 return *this;
175}
176
177
178Foam::bitSet& Foam::bitSet::xorEq(const bitSet& other)
179{
180 if (&other == this)
181 {
182 // Self '^=' : clears all bits
183
184 if (debug & 2)
185 {
187 << "Perform ^= on self: clears all bits" << nl;
188 }
189
190 reset();
191 return *this;
192 }
193 else if (other.none())
194 {
195 // no-op: nothing can change
196 return *this;
197 }
198
199
200 // Largest new bit that could be introduced
201 const label otherMax(other.find_last());
202
203 if (otherMax >= size())
204 {
205 // Extend to accommodate bits from 'other'
206 resize(otherMax+1);
207 }
208
209 // The operation (on overlapping blocks)
210 {
211 const label nblocks = num_blocks(std::min(size(), other.size()));
212 const auto& rhs = other.blocks_;
213
214 for (label blocki = 0; blocki < nblocks; ++blocki)
215 {
216 blocks_[blocki] ^= rhs[blocki];
217 }
218 }
220 return *this;
221}
222
223
224// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
225
228 PackedList<1>()
229{
230 is >> *this;
231}
232
233
234Foam::bitSet::bitSet(const bitSet& bitset, const labelUList& addr)
235:
236 bitSet(addr.size())
237{
238 const label len = addr.size();
239
240 for (label i = 0; i < len; ++i)
241 {
242 set(i, bitset.get(addr[i]));
243 }
244}
245
246
247Foam::bitSet::bitSet(const bitSet& bitset, const labelRange& range)
248:
249 bitSet(range.size())
250{
251 label pos = range.start();
252 const label len = range.size();
253
254 for (label i = 0; i < len; ++i)
256 set(i, bitset.get(pos));
257 ++pos;
258 }
259}
260
261
262Foam::bitSet::bitSet(const label n, const labelRange& range)
264 bitSet(n)
265{
266 this->set(range);
267}
268
269
272 this->set(range);
273}
274
275
276// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
277
278void Foam::bitSet::assign(const UList<bool>& bools)
279{
280 fill(false);
281 resize(bools.size());
282
283 unsigned bitIdx = 0u;
284 auto* packed = blocks_.data();
285
286 // Set according to indices that are true
287 for (const auto b : bools)
288 {
289 if (b)
290 {
291 *packed |= (1u << bitIdx);
292 }
293
294 if (++bitIdx >= PackedList<1>::elem_per_block)
295 {
296 bitIdx = 0u;
297 ++packed;
298 }
299 }
300}
301
302
303bool Foam::bitSet::intersects(const bitSet& other) const
304{
305 if (size() && other.size())
306 {
307 const label nblocks = num_blocks(std::min(size(), other.size()));
308 const auto& rhs = other.blocks_;
309
310 for (label blocki = 0; blocki < nblocks; ++blocki)
311 {
312 if (bool(blocks_[blocki] & rhs[blocki]))
313 {
314 return true;
315 }
317 }
318
319 return false;
320}
321
322
324{
325 labelRange slice(range);
326 slice.adjust(); // No negative start, size adjusted accordingly
327
328 // Range is invalid (zero-sized or entirely negative) - noop
329 if (slice.empty())
330 {
331 return;
332 }
333
334 // Range finishes at or beyond the right side.
335 // - zero fill any gaps that we might create.
336 // - flood-fill the reset, which now corresponds to the full range.
337 //
338 // NB: use labelRange end_value() for the exclusive end-value, which
339 // corresponds to our new set size.
340 if (slice.end_value() >= size())
341 {
342 reserve(slice.end_value());
343 resize(slice.begin_value(), false);
344 resize(slice.end_value(), true);
345 return;
346 }
347
348 // The more difficult case - everything in between.
349 // 1. sequence may begin/end in the same block
350 // 2. Cover more than one block
351 // a. with partial coverage in the first block
352 // b. with partial coverage in the end block
353
354 // The begin block/offset
355 unsigned int bblock = slice.begin_value() / elem_per_block;
356 unsigned int bmask = slice.begin_value() % elem_per_block;
357
358 // The end block/offset
359 unsigned int eblock = slice.end_value() / elem_per_block;
360 unsigned int emask = slice.end_value() % elem_per_block;
361
362 // Transform offsets to lower bit masks
363 if (bmask) bmask = mask_lower(bmask);
364 if (emask) emask = mask_lower(emask);
365
366 if (bblock == eblock)
367 {
368 // Same block - flll between the begin/end bits.
369 // Example:
370 // bmask = 0000000000001111 (lower bits)
371 // emask = 0000111111111111 (lower bits)
372 // -> set 0000111111110000 (xor)
373
374 blocks_[bblock] |= (emask^bmask);
375 }
376 else
377 {
378 if (bmask)
379 {
380 // The first (partial) block
381 // - set everything above the bmask.
382 blocks_[bblock] |= (~bmask);
383 ++bblock;
384 }
385
386 // Fill these blocks
387 for (unsigned blocki = bblock; blocki < eblock; ++blocki)
388 {
389 blocks_[blocki] = (~0u);
390 }
391
392 if (emask)
393 {
394 // The last (partial) block.
395 // - set everything below emask.
396 blocks_[eblock] |= (emask);
397 }
398 }
399}
400
401
403{
404 // Require intersection with the current bitset
405 const labelRange slice = range.subset0(size());
406
407 // Range does not intersect (invalid, empty, bitset is empty)
408 if (slice.empty())
409 {
410 return;
411 }
412
413 // Range finishes at or beyond the right side.
414 //
415 // NB: use labelRange end_value() for the exclusive end-value, which
416 // corresponds to our new set size.
417 if (slice.end_value() >= size())
418 {
419 // The original size
420 const label orig = size();
421
422 resize(slice.begin_value(), false);
423 resize(orig, false);
424 return;
425 }
426
427
428 // The more difficult case - everything in between.
429 // 1. sequence may begin/end in the same block
430 // 2. Cover more than one block
431 // a. with partial coverage in the first block
432 // b. with partial coverage in the end block
433
434 // The begin block/offset
435 unsigned int bblock = slice.begin_value() / elem_per_block;
436 unsigned int bmask = slice.begin_value() % elem_per_block;
437
438 // The end block/offset
439 unsigned int eblock = slice.end_value() / elem_per_block;
440 unsigned int emask = slice.end_value() % elem_per_block;
441
442 // Transform offsets to lower bit masks
443 if (bmask) bmask = mask_lower(bmask);
444 if (emask) emask = mask_lower(emask);
445
446 if (bblock == eblock)
447 {
448 // Same block - flll between the begin/end bits.
449 // Example:
450 // bmask = 0000000000001111 (lower bits)
451 // emask = 0000111111111111 (lower bits)
452 // -> set 0000111111110000 (xor)
453 // -> ~ 1111000000001111
454
455 blocks_[bblock] &= (~(emask^bmask));
456 }
457 else
458 {
459 if (bmask)
460 {
461 // The first (partial) block
462 // - only retain things below bmask.
463 blocks_[bblock] &= (bmask);
464 ++bblock;
465 }
466
467 // Clear these blocks
468 for (unsigned blocki = bblock; blocki < eblock; ++blocki)
469 {
470 blocks_[blocki] = (0u);
471 }
472
473 if (emask)
474 {
475 // The last (partial) block.
476 // - only retain things above bmask.
477 blocks_[eblock] &= (~emask);
478 }
479 }
480}
481
482
484{
485 // Number of used (set) entries
486 const label total = any() ? count() : 0;
487
488 if (!total)
489 {
490 return labelList();
491 }
492
493 labelList output(total);
494 label nItem = 0;
495
496 // Process block-wise, detecting any '1' bits
497
498 const label nblocks = num_blocks(size());
499 for (label blocki = 0; blocki < nblocks; ++blocki)
500 {
501 unsigned int blockval = blocks_[blocki];
502
503 if (blockval)
504 {
505 for (label pos = (blocki * elem_per_block); blockval; ++pos)
506 {
507 if (blockval & 1u)
508 {
509 output[nItem] = pos;
510 ++nItem;
511 }
512 blockval >>= 1u;
513 }
514 if (nItem == total) break; // Terminate early
516 }
517
518 return output;
519}
520
521
522Foam::List<bool> Foam::bitSet::values() const
523{
524 List<bool> output(size(), false);
525
526 // Process block-wise, detecting any '1' bits
527
528 const label nblocks = num_blocks(size());
529 for (label blocki = 0; blocki < nblocks; ++blocki)
530 {
531 label pos = (blocki * elem_per_block);
532
533 for
534 (
535 unsigned int blockval = blocks_[blocki];
536 blockval;
537 blockval >>= 1u
538 )
539 {
540 if (blockval & 1u)
541 {
542 output[pos] = true;
543 }
544 ++pos;
545 }
546 }
547
548 return output;
549}
550
551
552// * * * * * * * * * * * * * * Parallel Functions * * * * * * * * * * * * * //
553
554namespace
555{
556
557// Special purpose broadcast for bitSet which is more efficient than
558// either a regular broadcast (with serialization) or the usual
559// broadcast for lists.
560//
561// The initial broadcast sends both count (bits=on) and the length.
562// The receive clears out its bits and resizes (ie, all zeros and the proper
563// length).
564// This allows the final broadcast to be skipped if either
565// the length or the content is zero.
566//
567// With syncSizes=false it assumes that the lengths are identical on all ranks
568// and doesn't do the initial broadcast. In this case it can only decide
569// about the final broadcast based on the length information allow.
570
571void broadcast_bitSet
572(
573 Foam::bitSet& bitset,
574 int communicator,
575 int root,
576 bool syncSizes
577)
578{
579 using namespace Foam;
580
581 if (!UPstream::is_parallel(communicator)) // Probably already checked...
582 {
583 return;
584 }
585
586 // Broadcast data content?
587 bool bcastContent(true);
588
589 if (syncSizes)
590 {
591 int64_t count_size[2] = { 0, 0 };
592
593 if (root == UPstream::myProcNo(communicator))
594 {
595 // Sender: knows the count/size
596 count_size[0] = static_cast<int64_t>(bitset.count());
597 count_size[1] = static_cast<int64_t>(bitset.size());
598
599 UPstream::broadcast(count_size, 2, communicator, root);
600 }
601 else
602 {
603 // Receiver: gets the count/size and makes a clean bitset
604 UPstream::broadcast(count_size, 2, communicator, root);
605
606 bitset.clear(); // Clear old contents
607 bitset.resize(count_size[1]);
608 }
609
610 if (count_size[0] == 0)
611 {
612 // All content is zero, don't need to broadcast it
613 bcastContent = false;
614 }
615 }
616
617 if (bcastContent && !bitset.empty())
618 {
619 // Only broadcast with non-empty content
621 (
622 bitset.data(),
624 communicator,
625 root
626 );
627 }
628}
629
630} // End anonymous namespace
631
632
634(
635 std::pair<int,int> communicator_root,
636 bool syncSizes
637)
638{
639 int comm = communicator_root.first;
640 int root = communicator_root.second;
641
643 {
644 broadcast_bitSet(*this, comm, root, syncSizes);
645 }
646}
647
648
649void Foam::bitSet::broadcast(int communicator, bool syncSizes)
650{
651 if (communicator < 0)
652 {
653 communicator = UPstream::worldComm;
654 }
655
656 if (UPstream::is_parallel(communicator))
657 {
658 broadcast_bitSet(*this, communicator, UPstream::masterNo(), syncSizes);
659 }
660}
661
662
663void Foam::bitSet::reduceAnd(int communicator, bool syncSizes)
664{
665 if (communicator < 0)
666 {
667 communicator = UPstream::worldComm;
668 }
669
670 if (!UPstream::is_parallel(communicator))
671 {
672 return;
673 }
674
675 const label origSize(size());
676
677 if (syncSizes)
678 {
679 // Operation is an intersection
680 // - common size may be smaller than the original size
681 int64_t commonSize(size());
682
684 (
685 &commonSize,
686 1,
687 communicator
688 );
689 resize(commonSize);
690 }
691
692 if (!empty())
693 {
695 (
696 this->data(),
697 this->num_blocks(),
698 communicator
699 );
700
701 clear_trailing_bits(); // safety
702 }
703
704 // Undo side effects from the reduction
705 if (syncSizes)
706 {
707 resize(origSize);
708 }
709}
710
711
712void Foam::bitSet::reduceOr(int communicator, bool syncSizes)
713{
714 if (communicator < 0)
715 {
716 communicator = UPstream::worldComm;
717 }
718
719 if (!UPstream::is_parallel(communicator))
720 {
721 return;
722 }
723
724 // const label origSize(size());
725
726 if (syncSizes)
727 {
728 // Operation can increase the addressed size
729
730 // Extend size based on the addressed length.
731 // This is greedy, but produces consistent sizing
732 int64_t commonSize(size());
733
734 // Alternative: Extend size based on the bits used.
735 // - tighter, but inconsistent sizes result
736 // // label commonSize(find_last()+1);
737
739 (
740 &commonSize,
741 1,
742 communicator
743 );
744
745 extend(commonSize);
746 }
747
748 if (!empty())
749 {
751 (
752 this->data(),
753 this->num_blocks(),
754 communicator
755 );
756
757 clear_trailing_bits(); // safety
758 }
759}
760
761
762Foam::bitSet Foam::bitSet::gatherValues(bool localValue, int communicator)
763{
764 if (communicator < 0)
765 {
766 communicator = UPstream::worldComm;
767 }
768
769 bitSet allValues;
770
771 if (!UPstream::is_parallel(communicator))
772 {
773 // non-parallel: return own value
774 // TBD: only when UPstream::is_rank(communicator) as well?
775 allValues.resize(1);
776 allValues.set(0, localValue);
777 }
778 else
779 {
781 if (UPstream::master(communicator))
782 {
783 bools.resize(UPstream::nProcs(communicator), false);
784 }
785
787 (
788 &localValue, // Send
789 bools.data(), // Recv
790 1, // Num send/recv data per rank
791 communicator
792 );
793
794 // Transcribe to bitSet (on master)
795 allValues.assign(bools);
796 }
797
798 return allValues;
799}
801
802// Note that for allGather()
803// - MPI_Gather of individual bool values and broadcast the packed result
804// - this avoids bit_or on 32bit values everywhere, since we know a priori
805// that each rank only contributes 1bit of info
806
807Foam::bitSet Foam::bitSet::allGather(bool localValue, int communicator)
808{
809 if (communicator < 0)
810 {
811 communicator = UPstream::worldComm;
812 }
813
814 bitSet allValues(bitSet::gatherValues(localValue, communicator));
815
816 if (UPstream::is_parallel(communicator))
817 {
818 // Identical size on all ranks
819 allValues.resize(UPstream::nProcs(communicator));
820
821 // Sizes are consistent - broadcast without resizing
822 allValues.broadcast(communicator, false);
823 }
824
825 return allValues;
826}
827
828
829// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
scalar range
label n
Macros for easy insertion into run-time selection tables.
bool empty() const noexcept
True if range is empty (zero-sized).
Definition IntRange.H:198
IntType begin_value() const noexcept
The value at the beginning of the range - same as min(), start().
Definition IntRangeI.H:61
IntType end_value() const noexcept
The value 1 beyond the end of the range.
Definition IntRangeI.H:68
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
block_type * data() noexcept
A pointer to the raw storage.
Definition PackedList.H:586
static constexpr block_type mask_lower(unsigned elementOffset)
Definition PackedList.H:206
block_container blocks_
The blocks of raw data.
Definition PackedList.H:224
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition PackedList.H:387
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
unsigned int get(const label i) const
Get value at index i or 0 for out-of-range.
constexpr PackedList() noexcept
static constexpr unsigned elem_per_block
The number of elements stored per data block.
Definition PackedList.H:174
static constexpr label num_blocks(label numElem) noexcept
Definition PackedList.H:196
label size() const noexcept
Definition PackedList.H:392
void clear()
Clear the list, i.e. set addressable size to zero.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
T & first()
Access first element of the list, position [0].
Definition UList.H:957
T * data() noexcept
Return pointer to the underlying array serving as data storage.
Definition UListI.H:274
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition UPstream.H:1691
static void mpiGather(const Type *sendData, Type *recvData, int count, const int communicator=UPstream::worldComm)
Receive identically-sized (contiguous) data from all ranks.
static void mpiAllReduce(T values[], int count, const UPstream::opCodes opCodeId, const int communicator)
MPI_Allreduce (blocking) for known operators.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition UPstream.H:1743
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
unsigned int count(const bool on=true) const
Count number of bits set.
Definition bitSetI.H:420
void fill(const bool val)
Assign all entries to the given value.
Definition bitSetI.H:474
void reduceAnd(int communicator=-1, bool syncSizes=true)
Inplace bit_and parallel reduction.
Definition bitSet.C:656
label find_last() const
Locate the last bit set.
Definition bitSetI.H:321
static bitSet gatherValues(bool localValue, int communicator=-1)
Gather individual values into bitSet locations.
Definition bitSet.C:755
void broadcast(int communicator=-1, bool syncSizes=true)
Broadcast the contents.
Definition bitSet.C:642
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition bitSetI.H:502
bool none() const
True if no bits in this bitset are set.
Definition bitSetI.H:414
constexpr bitSet() noexcept
Default construct an empty, zero-sized bitSet.
Definition bitSetI.H:23
bitSet & xorEq(const bitSet &other)
The set logical XOR.
Definition bitSet.C:171
labelList toc() const
The indices of the on bits as a sorted labelList.
Definition bitSet.C:476
void reduceOr(int communicator=-1, bool syncSizes=true)
Inplace bit_or parallel reduction.
Definition bitSet.C:705
void assign(const UList< bool > &bools)
Copy assign all entries from a list of bools.
Definition bitSet.C:271
List< bool > values() const
Return the bitset values as a boolList.
Definition bitSet.C:515
bitSet & andEq(const bitSet &other)
The set logical AND.
Definition bitSet.C:74
bitSet & orEq(const bitSet &other)
The set logical OR.
Definition bitSet.C:126
static bitSet allGather(bool localValue, int communicator=-1)
Allgather individual values into bitSet locations.
Definition bitSet.C:800
bitSet & unset(const bitSet &other)
Unset (subtract) the bits specified in the other bitset, which is a set difference corresponds to the...
Definition bitSetI.H:540
bool intersects(const bitSet &other) const
True if any bits in the other bitset intersect (are the same).
Definition bitSet.C:296
bitSet & minusEq(const bitSet &other)
The set difference.
Definition bitSet.C:39
bool any() const
True if any bits in this bitset are set.
Definition bitSetI.H:408
bitSet & extend(const label minSize)
Ensure that minSize is covered by the bitSet.
Definition bitSetI.H:587
A range or interval of labels defined by a start and a size.
Definition labelRange.H:66
void adjust() noexcept
Adjust the start to avoid negative indices.
labelRange subset0(label len) const
Calculate the intersection with the given 0/size range.
Definition labelRangeI.H:87
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
patchWriters resize(patchIds.size())
#define InfoInFunction
Report an information message using Foam::Info.
bool any(const UList< bool > &bools)
True if any entries are 'true'.
Definition BitOps.H:90
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition BitOps.H:73
bitSet bitset(const labelHashSet &locations)
Transform the on locations to a bitSet.
Definition HashOps.C:63
List< bool > bools(const labelHashSet &locations)
Transform the on locations to a boolList, with true for each non-negative location and false for all ...
Definition HashOps.C:72
Namespace for handling debugging switches.
Definition debug.C:45
Namespace for OpenFOAM.
dimensionedScalar pos(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition List.H:62
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
triangles reserve(surf.size())
volScalarField & b
#define FOAM_UNLIKELY(cond)
Definition stdFoam.H:64