BUGFIX: Illegal use of uninitialised value (backport)
[foam-extend-3.2.git] / src / dynamicMesh / dynamicFvMesh / dynamicTopoFvMesh / coupleMap.C
blobabe0e895a852cefda9812c82812f077f0623ea3e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Class
26     coupleMap
28 Description
29     Implementation of the coupleMap class
31 Author
32     Sandeep Menon
33     University of Massachusetts Amherst
34     All rights reserved
36 \*---------------------------------------------------------------------------*/
38 #include "coupleMap.H"
39 #include "boolList.H"
40 #include "demandDrivenData.H"
42 namespace Foam
45 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
47 const char* coupleMap::names[coupleMap::INVALID + 1] =
49     "BISECTION",
50     "COLLAPSE_FIRST",
51     "COLLAPSE_SECOND",
52     "COLLAPSE_MIDPOINT",
53     "REMOVE_CELL",
54     "MOVE_POINT",
55     "CONVERT_PATCH",
56     "INVALID"
59 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
61 const char* coupleMap::asText(const opType oType)
63     return names[oType];
66 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
68 coupleMap::coupleMap
70     const IOobject& io,
71     const bool twoDMesh,
72     const bool isLocal,
73     const bool isSend,
74     const label patchIndex,
75     const label masterIndex,
76     const label slaveIndex
79     regIOobject(io),
80     twoDMesh_(twoDMesh),
81     isLocal_(isLocal),
82     isSend_(isSend),
83     patchIndex_(patchIndex),
84     masterIndex_(masterIndex),
85     slaveIndex_(slaveIndex),
86     nEntities_(-1),
87     edgesPtr_(NULL),
88     facesPtr_(NULL),
89     faceEdgesPtr_(NULL)
91     if
92     (
93         (io.readOpt() == IOobject::MUST_READ)
94      || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
95     )
96     {
97         // Construct an Istream and read from disk.
98         readData(readStream(typeName));
99         close();
100     }
104 // Construct as copy
105 coupleMap::coupleMap(const coupleMap& cm)
107     regIOobject(cm, true),
108     twoDMesh_(cm.twoDMesh_),
109     isLocal_(cm.isLocal_),
110     isSend_(cm.isSend_),
111     patchIndex_(cm.patchIndex_),
112     masterIndex_(cm.masterIndex_),
113     slaveIndex_(cm.slaveIndex_),
114     nEntities_(cm.nEntities_),
115     edgesPtr_(NULL),
116     facesPtr_(NULL),
117     faceEdgesPtr_(NULL)
119     if
120     (
121         (cm.readOpt() == IOobject::MUST_READ)
122      || (cm.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
123     )
124     {
125         // Construct an Istream and read from disk.
126         readData(readStream(typeName));
127         close();
128     }
132 // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
134 coupleMap::~coupleMap()
136     clearMaps();
137     clearBuffers();
138     clearAddressing();
142 // * * * * * * * * * * * * * * * Private Functions * * * * * * * * * * * * * //
144 void coupleMap::clearAddressing() const
146     deleteDemandDrivenData(edgesPtr_);
147     deleteDemandDrivenData(facesPtr_);
148     deleteDemandDrivenData(faceEdgesPtr_);
152 void coupleMap::makeEdges() const
154     // It is an error to attempt to recalculate
155     // if the pointer is already set
156     if (edgesPtr_)
157     {
158         FatalErrorIn("void coupleMap::makeEdges() const")
159             << "Edges have already been calculated."
160             << abort(FatalError);
161     }
163     label nEdges = nEntities(coupleMap::EDGE);
164     const labelList& eBuffer = entityBuffer(coupleMap::EDGE);
166     edgesPtr_ = new edgeList(nEdges);
168     edgeList& edges = *edgesPtr_;
170     forAll(edges, edgeI)
171     {
172         edges[edgeI][0] = eBuffer[(2*edgeI)+0];
173         edges[edgeI][1] = eBuffer[(2*edgeI)+1];
174     }
178 void coupleMap::makeFaces() const
180     // It is an error to attempt to recalculate
181     // if the pointer is already set
182     if (facesPtr_ || faceEdgesPtr_)
183     {
184         FatalErrorIn("void coupleMap::makeFaces() const")
185             << "Faces have already been calculated."
186             << abort(FatalError);
187     }
189     label nFaces = nEntities(coupleMap::FACE);
191     const labelList& fBuffer = entityBuffer(coupleMap::FACE);
192     const labelList& feBuffer = entityBuffer(coupleMap::FACE_EDGE);
193     const labelList& nfeBuffer = entityBuffer(coupleMap::NFE_BUFFER);
195     facesPtr_ = new faceList(nFaces);
196     faceEdgesPtr_ = new labelListList(nFaces);
198     faceList& faces = *facesPtr_;
199     labelListList& faceEdges = *faceEdgesPtr_;
201     label sumNFE = 0;
203     forAll(faces, faceI)
204     {
205         face& f = faces[faceI];
206         labelList& fe = faceEdges[faceI];
208         // Fetch the buffer value for 2D meshes
209         label nfe = twoDMesh_ ? nfeBuffer[faceI] : 3;
211         // Size up the lists
212         f.setSize(nfe, -1);
213         fe.setSize(nfe, -1);
215         for (label p = 0; p < nfe; p++)
216         {
217             f[p] = fBuffer[sumNFE + p];
218             fe[p] = feBuffer[sumNFE + p];
219         }
221         sumNFE += nfe;
222     }
224     if (sumNFE != nEntities(coupleMap::NFE_SIZE))
225     {
226         FatalErrorIn("void coupleMap::makeFaces() const")
227             << " Mismatched buffer." << nl
228             << " sumNFE: " << sumNFE << nl
229             << " NFE_SIZE: " << nEntities(coupleMap::NFE_SIZE) << nl
230             << abort(FatalError);
231     }
235 void coupleMap::makeFaceMap() const
237     // It is an error to attempt to recalculate
238     // if the map is already calculated
239     if (faceMap_.size())
240     {
241         FatalErrorIn("void coupleMap::makeFaceMap() const")
242             << "faceMap has already been calculated."
243             << abort(FatalError);
244     }
246     const Map<label>& mapFaces = entityMap(coupleMap::FACE);
248     // Size the list
249     faceMap_.setSize(mapFaces.size(), -1);
251     // Fill-in entries
252     forAllConstIter(Map<label>, mapFaces, fIter)
253     {
254         faceMap_[fIter.key()] = fIter();
255     }
259 void coupleMap::makeCellMap() const
261     // It is an error to attempt to recalculate
262     // if the map is already calculated
263     if (cellMap_.size())
264     {
265         FatalErrorIn("void coupleMap::makeCellMap() const")
266             << "cellMap has already been calculated."
267             << abort(FatalError);
268     }
270     const Map<label>& mapCells = entityMap(coupleMap::CELL);
272     // Size the list
273     cellMap_.setSize(mapCells.size(), -1);
275     // Fill-in entries
276     forAllConstIter(Map<label>, mapCells, cIter)
277     {
278         cellMap_[cIter.key()] = cIter();
279     }
283 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
285 pointField& coupleMap::pointBuffer() const
287     return pointBuffer_;
291 pointField& coupleMap::oldPointBuffer() const
293     return oldPointBuffer_;
297 labelList& coupleMap::subMeshPoints() const
299     return subMeshPoints_;
303 List<labelPair>& coupleMap::globalProcPoints() const
305     return globalProcPoints_;
309 void coupleMap::allocateBuffers() const
311     forAll(nEntities_, entityI)
312     {
313         if (nEntities_[entityI] < 0)
314         {
315             FatalErrorIn("void coupleMap::allocateBuffers() const")
316                 << " Entity sizes are not valid." << nl
317                 << " nEntities: " << nEntities_
318                 << abort(FatalError);
319         }
320     }
322     // Size up point buffers
323     pointBuffer().setSize(nEntities(POINT));
324     oldPointBuffer().setSize(nEntities(POINT));
326     // Size up connectivity buffers
327     entityBuffer(POINT).setSize
328     (
329         nEntities(GLOBAL_POINT)
330       - nEntities(SHARED_POINT)
331     );
333     // Set edge buffer
334     entityBuffer(EDGE).setSize(2 * nEntities(EDGE));
336     // Set addressing buffers
337     entityBuffer(OWNER).setSize(nEntities(FACE));
338     entityBuffer(NEIGHBOUR).setSize(nEntities(INTERNAL_FACE));
340     // Size up boundary buffers
341     entityBuffer(FACE_STARTS).setSize(nEntities(NBDY));
342     entityBuffer(FACE_SIZES).setSize(nEntities(NBDY));
343     entityBuffer(EDGE_STARTS).setSize(nEntities(NBDY));
344     entityBuffer(EDGE_SIZES).setSize(nEntities(NBDY));
345     entityBuffer(PATCH_ID).setSize(nEntities(NBDY));
347     // nFaceEdges buffer is required only for 2D,
348     // due to a mix of triangle / quad faces
349     if (twoDMesh_)
350     {
351         entityBuffer(NFE_BUFFER).setSize(nEntities(FACE));
352     }
354     // Allocate for variable size face-lists
355     entityBuffer(FACE).setSize(nEntities(NFE_SIZE));
356     entityBuffer(FACE_EDGE).setSize(nEntities(NFE_SIZE));
360 label coupleMap::findSlave
362     const label eType,
363     const label Index
364 ) const
366     Map<label>::const_iterator it = entityMap_[eType].find(Index);
368     if (it == entityMap_[eType].end())
369     {
370         return -1;
371     }
372     else
373     {
374         return it();
375     }
379 label coupleMap::findMaster
381     const label eType,
382     const label Index
383 ) const
385     Map<label>::const_iterator it = reverseEntityMap_[eType].find(Index);
387     if (it == reverseEntityMap_[eType].end())
388     {
389         return -1;
390     }
391     else
392     {
393         return it();
394     }
398 void coupleMap::removeSlave
400     const label eType,
401     const label Index
402 ) const
404     Map<label>::iterator it = reverseEntityMap_[eType].find(Index);
406     if (it != reverseEntityMap_[eType].end())
407     {
408         reverseEntityMap_[eType].erase(it);
409     }
413 void coupleMap::removeMaster
415     const label eType,
416     const label Index
417 ) const
419     Map<label>::iterator it = entityMap_[eType].find(Index);
421     if (it != entityMap_[eType].end())
422     {
423         entityMap_[eType].erase(it);
424     }
428 void coupleMap::mapSlave
430     const label eType,
431     const label master,
432     const label slave
433 ) const
435     entityMap_[eType].set(master, slave);
439 void coupleMap::mapMaster
441     const label eType,
442     const label slave,
443     const label master
444 ) const
446     reverseEntityMap_[eType].set(slave, master);
450 void coupleMap::pushOperation
452     const label index,
453     const opType oType,
454     const point& newPoint,
455     const point& oldPoint
456 ) const
458     entityIndices_.setSize(entityIndices_.size() + 1, index);
459     entityOperations_.setSize(entityOperations_.size() + 1, oType);
461     if
462     (
463         oType == coupleMap::MOVE_POINT ||
464         oType == coupleMap::CONVERT_PATCH
465     )
466     {
467         moveNewPoints_.setSize(moveNewPoints_.size() + 1, newPoint);
468         moveOldPoints_.setSize(moveOldPoints_.size() + 1, oldPoint);
469     }
473 void coupleMap::transferMaps
475     const label eType,
476     Map<label>& newEntityMap,
477     Map<label>& newReverseEntityMap
478 ) const
480     entityMap_[eType].transfer(newEntityMap);
481     reverseEntityMap_[eType].transfer(newReverseEntityMap);
485 void coupleMap::clearMaps() const
487     faceMap_.clear();
488     cellMap_.clear();
490     forAll(entityMap_, mapI)
491     {
492         entityMap_[mapI].clear();
493         reverseEntityMap_[mapI].clear();
494     }
498 void coupleMap::clearBuffers() const
500     pointBuffer_.clear();
501     oldPointBuffer_.clear();
503     subMeshPoints_.clear();
504     globalProcPoints_.clear();
506     forAll(entityBuffer_, bufferI)
507     {
508         entityBuffer_[bufferI].clear();
509     }
511     entityIndices_.clear();
512     entityOperations_.clear();
514     moveNewPoints_.clear();
515     moveOldPoints_.clear();
519 label coupleMap::nInternalFaces() const
521     return nEntities(INTERNAL_FACE);
525 const labelList& coupleMap::owner() const
527     return entityBuffer(OWNER);
531 const labelList& coupleMap::neighbour() const
533     return entityBuffer(NEIGHBOUR);
537 const edgeList& coupleMap::edges() const
539     if (!edgesPtr_)
540     {
541         makeEdges();
542     }
544     return *edgesPtr_;
548 const faceList& coupleMap::faces() const
550     if (!facesPtr_)
551     {
552         makeFaces();
553     }
555     return *facesPtr_;
559 const labelListList& coupleMap::faceEdges() const
561     if (!faceEdgesPtr_)
562     {
563         makeFaces();
564     }
566     return *faceEdgesPtr_;
570 const labelList& coupleMap::faceMap() const
572     if (faceMap_.empty())
573     {
574         makeFaceMap();
575     }
577     return faceMap_;
581 const labelList& coupleMap::cellMap() const
583     if (cellMap_.empty())
584     {
585         makeCellMap();
586     }
588     return cellMap_;
592 bool coupleMap::readData(Istream& is)
594     Map<label> tmpMap(is);
596     entityMap(coupleMap::POINT).transfer(tmpMap);
598     // Prepare the reversePointMap as well.
599     const Map<label>& pMap = entityMap(coupleMap::POINT);
600     Map<label>& rpMap = reverseEntityMap(coupleMap::POINT);
602     forAllConstIter(Map<label>, pMap, pIter)
603     {
604         rpMap.set(pIter(), pIter.key());
605     }
607     return !is.bad();
611 bool coupleMap::writeData(Ostream& os) const
613     // Only write-out point-map information
614     // to avoid geometric checking.
615     // The rest can be constructed topologically.
616     return (os << entityMap(coupleMap::POINT)).good();;
620 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
622 void coupleMap::operator=(const coupleMap& rhs)
624     // Check for assignment to self
625     if (this == &rhs)
626     {
627         FatalErrorIn("coupleMap::operator=(const coupleMap&)")
628             << "Attempted assignment to self"
629             << abort(FatalError);
630     }
634 } // End namespace Foam
636 // ************************************************************************* //