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
26 private member of meshToMesh.
27 Calculates mesh to mesh addressing pattern (for each cell from one mesh
28 find the closest cell centre in the other mesh).
30 \*---------------------------------------------------------------------------*/
32 #include "meshToMesh.H"
36 #include "octreeDataCell.H"
37 #include "octreeDataFace.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 void meshToMesh::calcAddressing()
50 Info<< "meshToMesh::calculateAddressing() : "
51 << "calculating mesh-to-mesh cell addressing" << endl;
54 // set reference to cells
55 const cellList& fromCells = fromMesh_.cells();
56 const pointField& fromPoints = fromMesh_.points();
58 // In an attempt to preserve the efficiency of linear search and prevent
59 // failure, a RESCUE mechanism will be set up. Here, we shall mark all
60 // cells next to the solid boundaries. If such a cell is found as the
61 // closest, the relationship between the origin and cell will be examined.
62 // If the origin is outside the cell, a global n-squared search is
67 // visit all boundaries and mark the cell next to the boundary.
71 Info<< "meshToMesh::calculateAddressing() : "
72 << "Setting up rescue" << endl;
75 List<bool> boundaryCell(fromCells.size(), false);
77 // set reference to boundary
78 const polyPatchList& patchesFrom = fromMesh_.boundaryMesh();
80 forAll (patchesFrom, patchI)
82 // get reference to cells next to the boundary
83 const unallocLabelList& bCells = patchesFrom[patchI].faceCells();
85 forAll (bCells, faceI)
87 boundaryCell[bCells[faceI]] = true;
91 treeBoundBox meshBb(fromPoints);
93 scalar typDim = meshBb.avgDim()/(2.0*cbrt(scalar(fromCells.size())));
95 treeBoundBox shiftedBb
98 meshBb.max() + vector(typDim, typDim, typDim)
103 Info<< "\nMesh" << endl;
104 Info<< " bounding box : " << meshBb << endl;
105 Info<< " bounding box (shifted) : " << shiftedBb << endl;
106 Info<< " typical dimension :" << shiftedBb.typDim() << endl;
109 // Wrap indices and mesh information into helper object
110 octreeDataCell shapes(fromMesh_);
112 octree<octreeDataCell> oc
114 shiftedBb, // overall bounding box
115 shapes, // all information needed to do checks on cells
117 10.0, // max. size of leaves
118 10.0 // maximum ratio of cubes v.s. cells
129 toMesh_.cellCentres(),
135 forAll (toMesh_.boundaryMesh(), patchi)
137 const polyPatch& toPatch = toMesh_.boundaryMesh()[patchi];
139 if (cuttingPatches_.found(toPatch.name()))
141 boundaryAddressing_[patchi].setSize(toPatch.size());
145 boundaryAddressing_[patchi],
146 toPatch.faceCentres(),
154 patchMap_.found(toPatch.name())
155 && fromMeshPatches_.found(patchMap_.find(toPatch.name())())
158 const polyPatch& fromPatch = fromMesh_.boundaryMesh()
160 fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
163 if (fromPatch.empty())
165 WarningIn("meshToMesh::calcAddressing()")
166 << "Source patch " << fromPatch.name()
167 << " has no faces. Not performing mapping for it."
169 boundaryAddressing_[patchi] = -1;
173 treeBoundBox wallBb(fromPatch.localPoints());
175 wallBb.avgDim()/(2.0*sqrt(scalar(fromPatch.size())));
177 treeBoundBox shiftedBb
180 wallBb.max() + vector(typDim, typDim, typDim)
183 // Wrap data for octree into container
184 octreeDataFace shapes(fromPatch);
186 octree<octreeDataFace> oc
188 shiftedBb, // overall search domain
189 shapes, // all information needed to do checks on cells
191 20.0, // maximum ratio of cubes v.s. cells
196 const vectorField::subField centresToBoundary =
197 toPatch.faceCentres();
199 boundaryAddressing_[patchi].setSize(toPatch.size());
201 treeBoundBox tightest;
206 tightest = wallBb; // starting search bb
207 tightestDist = Foam::GREAT; // starting max distance
209 boundaryAddressing_[patchi][toi] = oc.findNearest
211 centresToBoundary[toi],
222 Info<< "meshToMesh::calculateAddressing() : "
223 << "finished calculating mesh-to-mesh acell ddressing" << endl;
228 void meshToMesh::cellAddresses
230 labelList& cellAddressing_,
231 const pointField& points,
232 const fvMesh& fromMesh,
233 const List<bool>& boundaryCell,
234 const octree<octreeDataCell>& oc
237 // the implemented search method is a simple neighbour array search.
238 // It starts from a cell zero, searches its neighbours and finds one
239 // which is nearer to the target point than the current position.
240 // The location of the "current position" is reset to that cell and
241 // search through the neighbours continues. The search is finished
242 // when all the neighbours of the cell are farther from the target
243 // point than the current cell
245 // set curCell label to zero (start)
246 register label curCell = 0;
248 // set reference to cell to cell addressing
249 const vectorField& centresFrom = fromMesh.cellCentres();
250 const labelListList& cc = fromMesh.cellCells();
254 // pick up target position
255 const vector& p = points[toI];
257 // set the sqr-distance
258 scalar distSqr = magSqr(p - centresFrom[curCell]);
266 // set the current list of neighbouring cells
267 const labelList& neighbours = cc[curCell];
269 forAll (neighbours, nI)
272 magSqr(p - centresFrom[neighbours[nI]]);
274 // search through all the neighbours.
275 // If the cell is closer, reset current cell and distance
276 if (curDistSqr < (1 - SMALL)*distSqr)
278 curCell = neighbours[nI];
279 distSqr = curDistSqr;
280 closer = true; // a closer neighbour has been found
285 cellAddressing_[toI] = -1;
287 // Check point is actually in the nearest cell
288 if (fromMesh.pointInCell(p, curCell))
290 cellAddressing_[toI] = curCell;
294 // If curCell is a boundary cell then the point maybe either outside
295 // the domain or in an other region of the doamin, either way use
296 // the octree search to find it.
297 if (boundaryCell[curCell])
299 cellAddressing_[toI] = oc.find(p);
303 // If not on the boundary search the neighbours
306 // set the current list of neighbouring cells
307 const labelList& neighbours = cc[curCell];
309 forAll (neighbours, nI)
311 // search through all the neighbours.
312 // If point is in neighbour reset current cell
313 if (fromMesh.pointInCell(p, neighbours[nI]))
315 cellAddressing_[toI] = neighbours[nI];
323 // If still not found search the neighbour-neighbours
325 // set the current list of neighbouring cells
326 const labelList& neighbours = cc[curCell];
328 forAll (neighbours, nI)
330 // set the current list of neighbour-neighbouring cells
331 const labelList& nn = cc[neighbours[nI]];
335 // search through all the neighbours.
336 // If point is in neighbour reset current cell
337 if (fromMesh.pointInCell(p, nn[nI]))
339 cellAddressing_[toI] = nn[nI];
350 // Still not found so us the octree
351 cellAddressing_[toI] = oc.find(p);
359 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
361 } // End namespace Foam
363 // ************************************************************************* //