pointMapper.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "pointMapper.H"
30 #include "pointMesh.H"
31 #include "mapPolyMesh.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 void Foam::pointMapper::calcAddressing() const
36 {
37  if
38  (
39  directAddrPtr_
40  || interpAddrPtr_
41  || weightsPtr_
42  || insertedObjectsPtr_
43  )
44  {
46  << "Addressing already calculated."
47  << abort(FatalError);
48  }
49 
50  if (direct())
51  {
52  // Direct addressing, no weights
53 
54  directAddrPtr_ = std::make_unique<labelList>
55  (
56  // No retired points, so pointMap().size() == mapperLen_ anyhow
57  labelList::subList(mpm_.pointMap(), mapperLen_)
58  );
59  auto& directAddr = *directAddrPtr_;
60 
61  insertedObjectsPtr_ = std::make_unique<labelList>();
62  auto& inserted = *insertedObjectsPtr_;
63 
64  // The nInsertedObjects_ already counted in the constructor
65  if (nInsertedObjects_)
66  {
67  inserted.resize(nInsertedObjects_);
68 
69  label nInserted = 0;
70  forAll(directAddr, i)
71  {
72  if (directAddr[i] < 0)
73  {
74  // Found inserted
75  directAddr[i] = 0;
76  inserted[nInserted] = i;
77  ++nInserted;
78 
79  // TBD: check (nInsertedObjects_ < nInserted)?
80  #ifdef FULLDEBUG
81  if (nInsertedObjects_ < nInserted)
82  {
84  << "Unexpected insert of more than "
85  << nInsertedObjects_ << " items\n"
86  << abort(FatalError);
87  }
88  #endif
89  }
90  }
91  // TBD: check (nInserted < nInsertedObjects_)?
92  #ifdef FULLDEBUG
93  if (nInserted < nInsertedObjects_)
94  {
96  << "Found " << nInserted << " instead of "
97  << nInsertedObjects_ << " items to insert\n";
98  }
99  #endif
100  // The resize should be unnecessary
101  inserted.resize(nInserted);
102  }
103  }
104  else
105  {
106  // Interpolative addressing
107 
108  interpAddrPtr_ = std::make_unique<labelListList>(mapperLen_);
109  auto& addr = *interpAddrPtr_;
110 
111  weightsPtr_ = std::make_unique<scalarListList>(mapperLen_);
112  auto& wght = *weightsPtr_;
113 
114 
115  // Set the addressing and uniform weight
116  const auto setAddrWeights = [&]
117  (
118  const List<objectMap>& maps,
119  const char * const nameOfMap
120  )
121  {
122  for (const objectMap& map : maps)
123  {
124  // Get index, addressing
125  const label pointi = map.index();
126  const labelList& mo = map.masterObjects();
127  if (mo.empty()) continue; // safety
128 
129  if (addr[pointi].size())
130  {
132  << "Master point " << pointi
133  << " already mapped, cannot apply "
134  << nameOfMap
135  << flatOutput(mo) << abort(FatalError);
136  }
137 
138  // Map from masters, uniform weights
139  addr[pointi] = mo;
140  wght[pointi] = scalarList(mo.size(), 1.0/mo.size());
141  }
142  };
143 
144 
145  // Points created from other points (i.e. points merged into it).
146 
147  setAddrWeights(mpm_.pointsFromPointsMap(), "point points");
148 
149 
150  // Do mapped points.
151  // - may already have been set, so check if addressing still empty().
152 
153  {
154  const labelList& map = mpm_.pointMap();
155 
156  for (label pointi = 0; pointi < mapperLen_; ++pointi)
157  {
158  const label mappedi = map[pointi];
159 
160  if (mappedi >= 0 && addr[pointi].empty())
161  {
162  // Mapped from a single point
163  addr[pointi].resize(1, mappedi);
164  wght[pointi].resize(1, 1.0);
165  }
166  }
167  }
168 
169  // Grab inserted points (for them the size of addressing is still zero)
170 
171  insertedObjectsPtr_ = std::make_unique<labelList>();
172  auto& inserted = *insertedObjectsPtr_;
173 
174  // The nInsertedObjects_ already counted in the constructor
175  if (nInsertedObjects_)
176  {
177  inserted.resize(nInsertedObjects_);
178 
179  label nInserted = 0;
180  forAll(addr, i)
181  {
182  if (addr[i].empty())
183  {
184  // Mapped from dummy point 0
185  addr[i].resize(1, 0);
186  wght[i].resize(1, 1.0);
187 
188  inserted[nInserted] = i;
189  ++nInserted;
190 
191  // TBD: check (nInsertedObjects_ < nInserted)?
192  #ifdef FULLDEBUG
193  if (nInsertedObjects_ < nInserted)
194  {
196  << "Unexpected insert of more than "
197  << nInsertedObjects_ << " items\n"
198  << abort(FatalError);
199  }
200  #endif
201  }
202  }
203  // TBD: check (nInserted < nInsertedObjects_)?
204  #ifdef FULLDEBUG
205  if (nInserted < nInsertedObjects_)
206  {
208  << "Found " << nInserted << " instead of "
209  << nInsertedObjects_ << " items to insert\n";
210  }
211  #endif
212  // The resize should be unnecessary
213  inserted.resize(nInserted);
214  }
215  }
216 }
217 
218 
219 // void Foam::pointMapper::clearOut()
220 // {
221 // directAddrPtr_.reset(nullptr);
222 // interpAddrPtr_.reset(nullptr);
223 // weightsPtr_.reset(nullptr);
224 // insertedObjectsPtr_.reset(nullptr);
225 // }
226 
227 
228 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
229 
230 Foam::pointMapper::pointMapper(const pointMesh& pMesh, const mapPolyMesh& mpm)
231 :
232  mpm_(mpm),
233  mapperLen_(pMesh.size()),
234  nInsertedObjects_(0),
235  direct_
236  (
237  // Mapping without interpolation?
238  mpm.pointsFromPointsMap().empty()
239  )
240 {
241  const auto& directMap = mpm_.pointMap();
242 
243  if (!mapperLen_)
244  {
245  // Empty mesh
246  direct_ = true;
247  nInsertedObjects_ = 0;
248  }
249  else if (direct_)
250  {
251  // Number of inserted points (-ve values)
252  nInsertedObjects_ = std::count_if
253  (
254  directMap.cbegin(),
255  directMap.cbegin(mapperLen_),
256  [](label i) { return (i < 0); }
257  );
258  }
259  else
260  {
261  // Check if there are inserted points with no owner
262  // (check all lists)
263 
264  bitSet unmapped(mapperLen_, true);
265 
266  unmapped.unset(directMap); // direct mapped
267 
268  for (const objectMap& map : mpm_.pointsFromPointsMap())
269  {
270  if (!map.empty()) unmapped.unset(map.index());
271  }
272 
273  nInsertedObjects_ = label(unmapped.count());
274  }
275 }
276 
277 
278 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
281 {}
282 
283 
284 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
285 
286 Foam::label Foam::pointMapper::size() const
287 {
288  // OR: return mapperLen_;
289  return mpm_.pointMap().size();
290 }
291 
293 Foam::label Foam::pointMapper::sizeBeforeMapping() const
294 {
295  return mpm_.nOldPoints();
296 }
297 
298 
300 {
301  if (!direct())
302  {
304  << "Requested direct addressing for an interpolative mapper."
305  << abort(FatalError);
306  }
307 
308  if (!insertedObjects())
309  {
310  // No inserted points. Re-use pointMap
311  return mpm_.pointMap();
312  }
313  else
314  {
315  if (!directAddrPtr_)
316  {
317  calcAddressing();
318  }
319 
320  return *directAddrPtr_;
321  }
322 }
323 
324 
326 {
327  if (direct())
328  {
330  << "Requested interpolative addressing for a direct mapper."
331  << abort(FatalError);
332  }
333 
334  if (!interpAddrPtr_)
335  {
336  calcAddressing();
337  }
338 
339  return *interpAddrPtr_;
340 }
341 
342 
344 {
345  if (direct())
346  {
348  << "Requested interpolative weights for a direct mapper."
349  << abort(FatalError);
350  }
351 
352  if (!weightsPtr_)
353  {
354  calcAddressing();
355  }
356 
357  return *weightsPtr_;
358 }
359 
360 
362 {
363  if (!insertedObjectsPtr_)
364  {
365  if (!nInsertedObjects_)
366  {
367  // No inserted objects will be created
368  return labelList::null();
369  }
370 
371  calcAddressing();
372  }
373 
374  return *insertedObjectsPtr_;
375 }
376 
377 
378 // ************************************************************************* //
List< scalar > scalarList
List of scalar.
Definition: scalarList.H:32
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:420
label count_if(const ListType &input, const UnaryPredicate &pred, const label start=0)
Count the number of matching entries.
virtual const labelListList & addressing() const
Return interpolated addressing.
Definition: pointMapper.C:318
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
virtual label sizeBeforeMapping() const
Return size before mapping.
Definition: pointMapper.C:286
const labelList & insertedObjectLabels() const
Return list of inserted points.
Definition: pointMapper.C:354
virtual ~pointMapper()
Destructor.
Definition: pointMapper.C:273
SubList< label > subList
Declare type of subList.
Definition: List.H:144
An objectMap is a pair of labels defining the mapping of an object from another object, e.g. a cell mapped from a point.
Definition: objectMap.H:56
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:45
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
virtual const scalarListList & weights() const
Return interpolation weights.
Definition: pointMapper.C:336
virtual const labelUList & directAddressing() const
Return direct addressing.
Definition: pointMapper.C:292
virtual label size() const
The mapper size.
Definition: pointMapper.C:279
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:536
const labelList & pointMap() const noexcept
Old point map.
Definition: mapPolyMesh.H:484
virtual bool direct() const
Is the mapping direct.
Definition: pointMapper.H:155
errorManip< error > abort(error &err)
Definition: errorManip.H:139
const List< objectMap > & pointsFromPointsMap() const noexcept
Points originating from points.
Definition: mapPolyMesh.H:492
pointMapper(const pointMapper &)=delete
No copy construct.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
#define WarningInFunction
Report a warning using Foam::Warning.
List< label > labelList
A List of labels.
Definition: List.H:62
static const List< label > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
Definition: List.H:153
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225