Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / dynamicMesh / dynamicTopoFvMesh / coupledMesh / coupleMap.C
blob0f542aa7508ce851d59974ca1e4ba01bbeb6b854
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend 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 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 Class
25     coupleMap
27 Description
28     Implementation of the coupleMap class
30 Author
31     Sandeep Menon
32     University of Massachusetts Amherst
33     All rights reserved
35 \*---------------------------------------------------------------------------*/
37 #include "coupleMap.H"
38 #include "boolList.H"
39 #include "demandDrivenData.H"
41 namespace Foam
44 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46 const char* coupleMap::names[coupleMap::INVALID + 1] =
48     "BISECTION",
49     "COLLAPSE_FIRST",
50     "COLLAPSE_SECOND",
51     "COLLAPSE_MIDPOINT",
52     "REMOVE_CELL",
53     "MOVE_POINT",
54     "CONVERT_PATCH",
55     "CONVERT_PHYSICAL",
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
209         label nfe = nfeBuffer[faceI];
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 void coupleMap::makeInternalFaceMap() const
285     // It is an error to attempt to recalculate
286     // if the map is already calculated
287     if (internalFaceMap_.size())
288     {
289         FatalErrorIn("void coupleMap::makeInternalFaceMap() const")
290             << "internal faceMap has already been calculated."
291             << abort(FatalError);
292     }
294     // Slice for internal faces
295     internalFaceMap_ = SubList<label>(faceMap(), nEntities(INTERNAL_FACE));
299 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
301 pointField& coupleMap::pointBuffer() const
303     return pointBuffer_;
307 pointField& coupleMap::oldPointBuffer() const
309     return oldPointBuffer_;
313 labelList& coupleMap::subMeshPoints() const
315     return subMeshPoints_;
319 List<labelPair>& coupleMap::globalProcPoints() const
321     return globalProcPoints_;
325 void coupleMap::allocateBuffers() const
327     forAll(nEntities_, entityI)
328     {
329         if (nEntities_[entityI] < 0)
330         {
331             FatalErrorIn("void coupleMap::allocateBuffers() const")
332                 << " Entity sizes are not valid." << nl
333                 << " nEntities: " << nEntities_
334                 << abort(FatalError);
335         }
336     }
338     // Size up point buffers
339     pointBuffer().setSize(nEntities(POINT));
340     oldPointBuffer().setSize(nEntities(POINT));
342     // Size up connectivity buffers
343     entityBuffer(POINT).setSize
344     (
345         nEntities(GLOBAL_POINT)
346       - nEntities(SHARED_POINT)
347     );
349     // Set edge buffer
350     entityBuffer(EDGE).setSize(2 * nEntities(EDGE));
352     // Set addressing buffers
353     entityBuffer(OWNER).setSize(nEntities(FACE));
354     entityBuffer(NEIGHBOUR).setSize(nEntities(INTERNAL_FACE));
356     // Size up boundary buffers
357     entityBuffer(FACE_STARTS).setSize(nEntities(NBDY));
358     entityBuffer(FACE_SIZES).setSize(nEntities(NBDY));
359     entityBuffer(EDGE_STARTS).setSize(nEntities(NBDY));
360     entityBuffer(EDGE_SIZES).setSize(nEntities(NBDY));
361     entityBuffer(PATCH_ID).setSize(nEntities(NBDY));
363     // Set face-sizes
364     entityBuffer(NFE_BUFFER).setSize(nEntities(FACE));
366     // Allocate for variable size face-lists
367     entityBuffer(FACE).setSize(nEntities(NFE_SIZE));
368     entityBuffer(FACE_EDGE).setSize(nEntities(NFE_SIZE));
372 label coupleMap::findSlave
374     const label eType,
375     const label Index
376 ) const
378     Map<label>::const_iterator it = entityMap_[eType].find(Index);
380     if (it == entityMap_[eType].end())
381     {
382         return -1;
383     }
384     else
385     {
386         return it();
387     }
391 label coupleMap::findMaster
393     const label eType,
394     const label Index
395 ) const
397     Map<label>::const_iterator it = reverseEntityMap_[eType].find(Index);
399     if (it == reverseEntityMap_[eType].end())
400     {
401         return -1;
402     }
403     else
404     {
405         return it();
406     }
410 void coupleMap::removeSlave
412     const label eType,
413     const label Index
414 ) const
416     Map<label>::iterator it = reverseEntityMap_[eType].find(Index);
418     if (it != reverseEntityMap_[eType].end())
419     {
420         reverseEntityMap_[eType].erase(it);
421     }
425 void coupleMap::removeMaster
427     const label eType,
428     const label Index
429 ) const
431     Map<label>::iterator it = entityMap_[eType].find(Index);
433     if (it != entityMap_[eType].end())
434     {
435         entityMap_[eType].erase(it);
436     }
440 void coupleMap::mapSlave
442     const label eType,
443     const label master,
444     const label slave
445 ) const
447     entityMap_[eType].set(master, slave);
451 void coupleMap::mapMaster
453     const label eType,
454     const label slave,
455     const label master
456 ) const
458     reverseEntityMap_[eType].set(slave, master);
462 void coupleMap::pushOperation
464     const label index,
465     const opType oType
466 ) const
468     entityIndices_.setSize(entityIndices_.size() + 1, index);
469     entityOperations_.setSize(entityOperations_.size() + 1, oType);
473 void coupleMap::pushOperation
475     const label index,
476     const opType oType,
477     const label pIndex
478 ) const
480     if (oType == coupleMap::CONVERT_PHYSICAL)
481     {
482         entityIndices_.setSize(entityIndices_.size() + 1, index);
483         entityOperations_.setSize(entityOperations_.size() + 1, oType);
485         patchIndices_.setSize(patchIndices_.size() + 1, pIndex);
486     }
487     else
488     {
489         opType t = (oType < coupleMap::INVALID ? oType : coupleMap::INVALID);
491         FatalErrorIn("void coupleMap::pushOperation() const")
492             << " Expected CONVERT_PHYSICAL" << nl
493             << " Found: " << coupleMap::names[t]
494             << abort(FatalError);
495     }
499 void coupleMap::pushOperation
501     const label index,
502     const opType oType,
503     const point& newPoint,
504     const point& oldPoint
505 ) const
507     entityIndices_.setSize(entityIndices_.size() + 1, index);
508     entityOperations_.setSize(entityOperations_.size() + 1, oType);
510     if
511     (
512         oType == coupleMap::MOVE_POINT ||
513         oType == coupleMap::CONVERT_PATCH
514     )
515     {
516         moveNewPoints_.setSize(moveNewPoints_.size() + 1, newPoint);
517         moveOldPoints_.setSize(moveOldPoints_.size() + 1, oldPoint);
518     }
519     else
520     {
521         opType t = (oType < coupleMap::INVALID ? oType : coupleMap::INVALID);
523         FatalErrorIn("void coupleMap::pushOperation() const")
524             << " Expected either MOVE_POINT or CONVERT_PATCH" << nl
525             << " Found: " << coupleMap::names[t]
526             << abort(FatalError);
527     }
531 void coupleMap::transferMaps
533     const label eType,
534     Map<label>& newEntityMap,
535     Map<label>& newReverseEntityMap
536 ) const
538     entityMap_[eType].transfer(newEntityMap);
539     reverseEntityMap_[eType].transfer(newReverseEntityMap);
543 void coupleMap::clearMaps() const
545     faceMap_.clear();
546     cellMap_.clear();
547     internalFaceMap_.clear();
549     subMeshPointMap_.clear();
550     subMeshEdgeMap_.clear();
552     forAll(entityMap_, mapI)
553     {
554         entityMap_[mapI].clear();
555         reverseEntityMap_[mapI].clear();
556     }
560 void coupleMap::clearBuffers() const
562     pointBuffer_.clear();
563     oldPointBuffer_.clear();
565     subMeshPoints_.clear();
566     globalProcPoints_.clear();
568     forAll(entityBuffer_, bufferI)
569     {
570         entityBuffer_[bufferI].clear();
571     }
573     entityIndices_.clear();
574     entityOperations_.clear();
576     patchIndices_.clear();
577     moveNewPoints_.clear();
578     moveOldPoints_.clear();
582 label coupleMap::nInternalFaces() const
584     return nEntities(INTERNAL_FACE);
588 const labelList& coupleMap::owner() const
590     return entityBuffer(OWNER);
594 const labelList& coupleMap::neighbour() const
596     return entityBuffer(NEIGHBOUR);
600 const edgeList& coupleMap::edges() const
602     if (!edgesPtr_)
603     {
604         makeEdges();
605     }
607     return *edgesPtr_;
611 const faceList& coupleMap::faces() const
613     if (!facesPtr_)
614     {
615         makeFaces();
616     }
618     return *facesPtr_;
622 const labelListList& coupleMap::faceEdges() const
624     if (!faceEdgesPtr_)
625     {
626         makeFaces();
627     }
629     return *faceEdgesPtr_;
633 const labelList& coupleMap::faceMap() const
635     if (faceMap_.empty())
636     {
637         makeFaceMap();
638     }
640     return faceMap_;
644 const labelList& coupleMap::cellMap() const
646     if (cellMap_.empty())
647     {
648         makeCellMap();
649     }
651     return cellMap_;
655 const labelList& coupleMap::internalFaceMap() const
657     if (internalFaceMap_.empty())
658     {
659         makeInternalFaceMap();
660     }
662     return internalFaceMap_;
666 bool coupleMap::readData(Istream& is)
668     Map<label> tmpMap(is);
670     entityMap(coupleMap::POINT).transfer(tmpMap);
672     // Prepare the reversePointMap as well.
673     const Map<label>& pMap = entityMap(coupleMap::POINT);
674     Map<label>& rpMap = reverseEntityMap(coupleMap::POINT);
676     forAllConstIter(Map<label>, pMap, pIter)
677     {
678         rpMap.set(pIter(), pIter.key());
679     }
681     return !is.bad();
685 bool coupleMap::writeData(Ostream& os) const
687     // Only write-out point-map information
688     // to avoid geometric checking.
689     // The rest can be constructed topologically.
690     return (os << entityMap(coupleMap::POINT)).good();;
694 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
696 void coupleMap::operator=(const coupleMap& rhs)
698     // Check for assignment to self
699     if (this == &rhs)
700     {
701         FatalErrorIn("coupleMap::operator=(const coupleMap&)")
702             << "Attempted assignment to self"
703             << abort(FatalError);
704     }
708 } // End namespace Foam
710 // ************************************************************************* //