1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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 \*---------------------------------------------------------------------------*/
27 #include "blockMesh.H"
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 Foam::labelList Foam::blockMesh::createMergeList()
33 Info<< nl << "Creating merge list " << flush;
35 labelList MergeList(nPoints_, -1);
37 blockMesh& blocks = *this;
39 const pointField& blockPoints = topology().points();
40 const cellList& blockCells = topology().cells();
41 const faceList& blockFaces = topology().faces();
42 const labelList& faceOwnerBlocks = topology().faceOwner();
44 // For efficiency, create merge pairs in the first pass
45 labelListListList glueMergePairs(blockFaces.size());
47 const labelList& faceNeighbourBlocks = topology().faceNeighbour();
49 forAll(blockFaces, blockFaceLabel)
51 label blockPlabel = faceOwnerBlocks[blockFaceLabel];
52 const pointField& blockPpoints = blocks[blockPlabel].points();
53 const labelList& blockPfaces = blockCells[blockPlabel];
55 bool foundFace = false;
56 label blockPfaceLabel;
60 blockPfaceLabel < blockPfaces.size();
66 blockFaces[blockPfaces[blockPfaceLabel]]
67 == blockFaces[blockFaceLabel]
77 FatalErrorIn("blockMesh::createMergeList()")
78 << "Cannot find merge face for block " << blockPlabel
82 const labelListList& blockPfaceFaces =
83 blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
85 labelListList& curPairs = glueMergePairs[blockFaceLabel];
86 curPairs.setSize(blockPfaceFaces.size());
88 // Calculate sqr of the merge tolerance as 1/10th of the min sqr
89 // point to point distance on the block face.
90 // At the same time merge collated points on the block's faces
91 // (removes boundary poles etc.)
92 // Collated points detected by initally taking a constant factor of
93 // the size of the block.
95 boundBox bb(blockCells[blockPlabel].points(blockFaces, blockPoints));
96 const scalar mergeSqrDist = SMALL*magSqr(bb.span());
98 // This is an N^2 algorithm
100 scalar sqrMergeTol = GREAT;
102 forAll(blockPfaceFaces, blockPfaceFaceLabel)
104 const labelList& blockPfaceFacePoints
105 = blockPfaceFaces[blockPfaceFaceLabel];
107 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
109 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel2)
111 if (blockPfaceFacePointLabel != blockPfaceFacePointLabel2)
113 scalar magSqrDist = magSqr
115 blockPpoints[blockPfaceFacePoints
116 [blockPfaceFacePointLabel]]
117 - blockPpoints[blockPfaceFacePoints
118 [blockPfaceFacePointLabel2]]
121 if (magSqrDist < mergeSqrDist)
124 blockPfaceFacePoints[blockPfaceFacePointLabel]
125 + blockOffsets_[blockPlabel];
128 blockPfaceFacePoints[blockPfaceFacePointLabel2]
129 + blockOffsets_[blockPlabel];
131 label minPP2 = min(PpointLabel, PpointLabel2);
133 if (MergeList[PpointLabel] != -1)
135 minPP2 = min(minPP2, MergeList[PpointLabel]);
138 if (MergeList[PpointLabel2] != -1)
140 minPP2 = min(minPP2, MergeList[PpointLabel2]);
143 MergeList[PpointLabel] = MergeList[PpointLabel2]
148 sqrMergeTol = min(sqrMergeTol, magSqrDist);
158 if (topology().isInternalFace(blockFaceLabel))
160 label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
161 const pointField& blockNpoints = blocks[blockNlabel].points();
162 const labelList& blockNfaces = blockCells[blockNlabel];
165 label blockNfaceLabel;
169 blockNfaceLabel < blockNfaces.size();
175 blockFaces[blockNfaces[blockNfaceLabel]]
176 == blockFaces[blockFaceLabel]
186 FatalErrorIn("blockMesh::createMergeList()")
187 << "Cannot find merge face for block " << blockNlabel
191 const labelListList& blockNfaceFaces =
192 blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
194 if (blockPfaceFaces.size() != blockNfaceFaces.size())
196 FatalErrorIn("blockMesh::createMergeList()")
197 << "Inconsistent number of faces between block pair "
198 << blockPlabel << " and " << blockNlabel
205 // N-squared point search over all points of all faces of
206 // master block over all point of all faces of slave block
207 forAll(blockPfaceFaces, blockPfaceFaceLabel)
209 const labelList& blockPfaceFacePoints
210 = blockPfaceFaces[blockPfaceFaceLabel];
212 labelList& cp = curPairs[blockPfaceFaceLabel];
213 cp.setSize(blockPfaceFacePoints.size());
216 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
220 forAll(blockNfaceFaces, blockNfaceFaceLabel)
222 const labelList& blockNfaceFacePoints
223 = blockNfaceFaces[blockNfaceFaceLabel];
225 forAll(blockNfaceFacePoints, blockNfaceFacePointLabel)
232 [blockPfaceFacePoints[blockPfaceFacePointLabel]]
234 [blockNfaceFacePoints[blockNfaceFacePointLabel]]
241 cp[blockPfaceFacePointLabel] =
242 blockNfaceFacePoints[blockNfaceFacePointLabel];
245 blockPfaceFacePoints[blockPfaceFacePointLabel]
246 + blockOffsets_[blockPlabel];
249 blockNfaceFacePoints[blockNfaceFacePointLabel]
250 + blockOffsets_[blockNlabel];
252 label minPN = min(PpointLabel, NpointLabel);
254 if (MergeList[PpointLabel] != -1)
256 minPN = min(minPN, MergeList[PpointLabel]);
259 if (MergeList[NpointLabel] != -1)
261 minPN = min(minPN, MergeList[NpointLabel]);
264 MergeList[PpointLabel] = MergeList[NpointLabel]
270 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
272 if (cp[blockPfaceFacePointLabel] == -1)
274 FatalErrorIn("blockMesh::createMergeList()")
275 << "Inconsistent point locations between block pair "
276 << blockPlabel << " and " << blockNlabel << nl
277 << " probably due to inconsistent grading."
286 const faceList::subList blockInternalFaces
289 topology().nInternalFaces()
292 bool changedPointMerge = false;
297 changedPointMerge = false;
300 forAll(blockInternalFaces, blockFaceLabel)
302 label blockPlabel = faceOwnerBlocks[blockFaceLabel];
303 label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
305 const labelList& blockPfaces = blockCells[blockPlabel];
306 const labelList& blockNfaces = blockCells[blockNlabel];
308 const labelListList& curPairs = glueMergePairs[blockFaceLabel];
310 bool foundFace = false;
311 label blockPfaceLabel;
315 blockPfaceLabel < blockPfaces.size();
321 blockFaces[blockPfaces[blockPfaceLabel]]
322 == blockInternalFaces[blockFaceLabel]
331 label blockNfaceLabel;
335 blockNfaceLabel < blockNfaces.size();
341 blockFaces[blockNfaces[blockNfaceLabel]]
342 == blockInternalFaces[blockFaceLabel]
350 const labelListList& blockPfaceFaces =
351 blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
353 forAll(blockPfaceFaces, blockPfaceFaceLabel)
355 const labelList& blockPfaceFacePoints
356 = blockPfaceFaces[blockPfaceFaceLabel];
358 const labelList& cp = curPairs[blockPfaceFaceLabel];
360 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
363 blockPfaceFacePoints[blockPfaceFacePointLabel]
364 + blockOffsets_[blockPlabel];
367 cp[blockPfaceFacePointLabel]
368 + blockOffsets_[blockNlabel];
372 MergeList[PpointLabel]
373 != MergeList[NpointLabel]
376 changedPointMerge = true;
378 MergeList[PpointLabel]
379 = MergeList[NpointLabel]
382 MergeList[PpointLabel],
383 MergeList[NpointLabel]
389 Info << "." << flush;
393 FatalErrorIn("blockMesh::createMergeList()")
394 << "Point merging failed after max number of passes."
395 << abort(FatalError);
398 while (changedPointMerge);
401 forAll(blockInternalFaces, blockFaceLabel)
403 label blockPlabel = faceOwnerBlocks[blockFaceLabel];
404 label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
406 const labelList& blockPfaces = blockCells[blockPlabel];
407 const labelList& blockNfaces = blockCells[blockNlabel];
409 const pointField& blockPpoints = blocks[blockPlabel].points();
410 const pointField& blockNpoints = blocks[blockNlabel].points();
412 bool foundFace = false;
413 label blockPfaceLabel;
417 blockPfaceLabel < blockPfaces.size();
423 blockFaces[blockPfaces[blockPfaceLabel]]
424 == blockInternalFaces[blockFaceLabel]
434 FatalErrorIn("blockMesh::createMergeList()")
435 << "Cannot find merge face for block " << blockPlabel
440 label blockNfaceLabel;
444 blockNfaceLabel < blockNfaces.size();
450 blockFaces[blockNfaces[blockNfaceLabel]]
451 == blockInternalFaces[blockFaceLabel]
461 FatalErrorIn("blockMesh::createMergeList()")
462 << "Cannot find merge face for block " << blockNlabel
466 const labelListList& blockPfaceFaces =
467 blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
469 const labelListList& blockNfaceFaces =
470 blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
472 forAll(blockPfaceFaces, blockPfaceFaceLabel)
474 const labelList& blockPfaceFacePoints
475 = blockPfaceFaces[blockPfaceFaceLabel];
477 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
480 blockPfaceFacePoints[blockPfaceFacePointLabel]
481 + blockOffsets_[blockPlabel];
483 if (MergeList[PpointLabel] == -1)
485 FatalErrorIn("blockMesh::createMergeList()")
486 << "Unable to merge point "
487 << blockPfaceFacePointLabel
488 << ' ' << blockPpoints[blockPfaceFacePointLabel]
498 forAll(blockNfaceFaces, blockNfaceFaceLabel)
500 const labelList& blockNfaceFacePoints
501 = blockNfaceFaces[blockNfaceFaceLabel];
503 forAll(blockNfaceFacePoints, blockNfaceFacePointLabel)
506 blockNfaceFacePoints[blockNfaceFacePointLabel]
507 + blockOffsets_[blockNlabel];
509 if (MergeList[NpointLabel] == -1)
511 FatalErrorIn("blockMesh::createMergeList()")
512 << "unable to merge point "
513 << blockNfaceFacePointLabel
514 << ' ' << blockNpoints[blockNfaceFacePointLabel]
526 // sort merge list to return new point label (in new shorter list)
527 // given old point label
528 label newPointLabel = 0;
530 forAll(MergeList, pointLabel)
532 if (MergeList[pointLabel] > pointLabel)
534 FatalErrorIn("blockMesh::createMergeList()")
535 << "ouch" << exit(FatalError);
540 (MergeList[pointLabel] == -1)
541 || MergeList[pointLabel] == pointLabel
544 MergeList[pointLabel] = newPointLabel;
549 MergeList[pointLabel] = MergeList[MergeList[pointLabel]];
553 nPoints_ = newPointLabel;
559 // ************************************************************************* //