1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 const scalar meshToMesh::cellCentreDistanceTol
46 debug::tolerances("meshToMeshCellCentreDistanceTol", 1e-3)
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 void meshToMesh::calcAddressing()
56 Info<< "meshToMesh::calculateAddressing() : "
57 << "calculating mesh-to-mesh cell addressing" << endl;
60 // set reference to cells
61 const cellList& fromCells = fromMesh_.cells();
62 const pointField& fromPoints = fromMesh_.points();
64 // In an attempt to preserve the efficiency of linear search and prevent
65 // failure, a RESCUE mechanism will be set up. Here, we shall mark all
66 // cells next to the solid boundaries. If such a cell is found as the
67 // closest, the relationship between the origin and cell will be examined.
68 // If the origin is outside the cell, a global n-squared search is
73 // visit all boundaries and mark the cell next to the boundary.
77 Info<< "meshToMesh::calculateAddressing() : "
78 << "Setting up rescue" << endl;
81 List<bool> boundaryCell(fromCells.size(), false);
83 // set reference to boundary
84 const polyPatchList& patchesFrom = fromMesh_.boundaryMesh();
86 forAll (patchesFrom, patchI)
88 // get reference to cells next to the boundary
89 const unallocLabelList& bCells = patchesFrom[patchI].faceCells();
91 forAll (bCells, faceI)
93 boundaryCell[bCells[faceI]] = true;
97 treeBoundBox meshBb(fromPoints);
99 scalar typDim = meshBb.avgDim()/(2.0*cbrt(scalar(fromCells.size())));
101 treeBoundBox shiftedBb
104 meshBb.max() + vector(typDim, typDim, typDim)
109 Info<< "\nMesh" << endl;
110 Info<< " bounding box : " << meshBb << endl;
111 Info<< " bounding box (shifted) : " << shiftedBb << endl;
112 Info<< " typical dimension :" << shiftedBb.typDim() << endl;
115 // Wrap indices and mesh information into helper object
116 octreeDataCell shapes(fromMesh_);
118 octree<octreeDataCell> oc
120 shiftedBb, // overall bounding box
121 shapes, // all information needed to do checks on cells
123 10.0, // max. size of leaves
124 10.0 // maximum ratio of cubes v.s. cells
135 toMesh_.cellCentres(),
142 forAll (toMesh_.boundaryMesh(), patchi)
145 const polyPatch& toPatch = toMesh_.boundaryMesh()[patchi];
147 if (cuttingPatches_.found(toPatch.name()))
150 boundaryAddressing_[patchi].setSize(toPatch.size());
154 boundaryAddressing_[patchi],
155 toPatch.faceCentres(),
164 patchMap_.found(toPatch.name())
165 && fromMeshPatches_.found(patchMap_.find(toPatch.name())())
168 const polyPatch& fromPatch = fromMesh_.boundaryMesh()
170 fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
173 if (fromPatch.empty())
175 WarningIn("meshToMesh::calcAddressing()")
176 << "Source patch " << fromPatch.name()
177 << " has no faces. Not performing mapping for it."
179 boundaryAddressing_[patchi] = -1;
183 treeBoundBox wallBb(fromPatch.localPoints());
185 wallBb.avgDim()/(2.0*sqrt(scalar(fromPatch.size())));
187 treeBoundBox shiftedBb
190 wallBb.max() + vector(typDim, typDim, typDim)
193 // Wrap data for octree into container
194 octreeDataFace shapes(fromPatch);
196 octree<octreeDataFace> oc
198 shiftedBb, // overall search domain
199 shapes, // all information needed to do checks on cells
201 20.0, // maximum ratio of cubes v.s. cells
206 const vectorField::subField centresToBoundary =
207 toPatch.faceCentres();
209 boundaryAddressing_[patchi].setSize(toPatch.size());
211 treeBoundBox tightest;
216 tightest = wallBb; // starting search bb
217 tightestDist = Foam::GREAT; // starting max distance
219 boundaryAddressing_[patchi][toi] = oc.findNearest
221 centresToBoundary[toi],
232 Info<< "meshToMesh::calculateAddressing() : "
233 << "finished calculating mesh-to-mesh acell ddressing" << endl;
238 void meshToMesh::cellAddresses
240 labelList& cellAddressing_,
241 const pointField& points,
242 const fvMesh& fromMesh,
243 const List<bool>& boundaryCell,
244 const octree<octreeDataCell>& oc,
249 label nCellsOutsideAddressing = 0;
251 // the implemented search method is a simple neighbour array search.
252 // It starts from a cell zero, searches its neighbours and finds one
253 // which is nearer to the target point than the current position.
254 // The location of the "current position" is reset to that cell and
255 // search through the neighbours continues. The search is finished
256 // when all the neighbours of the cell are farther from the target
257 // point than the current cell
259 // set curCell label to zero (start)
260 register label curCell = 0;
262 // set reference to cell to cell addressing
263 const vectorField& centresFrom = fromMesh.cellCentres();
264 const labelListList& cc = fromMesh.cellCells();
269 scalar localTol = cellCentreDistanceTol;
271 bool isBoundary = false;
273 // pick up target position
274 const vector& p = points[toI];
276 // set the sqr-distance
277 scalar distSqr = magSqr(p - centresFrom[curCell]);
285 // set the current list of neighbouring cells
286 const labelList& neighbours = cc[curCell];
288 forAll (neighbours, nI)
291 magSqr(p - centresFrom[neighbours[nI]]);
293 // search through all the neighbours.
294 // If the cell is closer, reset current cell and distance
295 if (curDistSqr < (1 - SMALL)*distSqr)
297 curCell = neighbours[nI];
298 distSqr = curDistSqr;
299 closer = true; // a closer neighbour has been found
304 cellAddressing_[toI] = -1;
306 // Check point is actually in the nearest cell
307 if (fromMesh.pointInCell(p, curCell))
309 cellAddressing_[toI] = curCell;
313 // If curCell is a boundary cell then the point maybe either
314 // outside the domain or in an other region of the doamin,
315 // either way use the octree search to find it.
316 if (boundaryCell[curCell])
319 cellAddressing_[toI] = oc.find(p);
323 // If not on the boundary search the neighbours
326 // set the current list of neighbouring cells
327 const labelList& neighbours = cc[curCell];
329 forAll (neighbours, nI)
331 // search through all the neighbours.
332 // If point is in neighbour reset current cell
333 if (fromMesh.pointInCell(p, neighbours[nI]))
335 cellAddressing_[toI] = neighbours[nI];
343 // If still not found search the neighbour-neighbours
345 // set the current list of neighbouring cells
346 const labelList& neighbours = cc[curCell];
348 forAll (neighbours, nI)
350 // set the current list of neighbour-neighbouring cells
351 const labelList& nn = cc[neighbours[nI]];
355 // search through all the neighbours.
356 // If point is in neighbour reset current cell
357 if (fromMesh.pointInCell(p, nn[nI]))
359 cellAddressing_[toI] = nn[nI];
370 // Still not found so use the octree
371 cellAddressing_[toI] = oc.find(p);
375 if (cellAddressing_[toI] < 0)
377 nCellsOutsideAddressing++;
379 if (isBoundary && forceFind)
381 // If still not found, get the closest cell within the
382 // specified tolerance
384 forAll(fromMesh.boundary(), patchi)
386 const fvPatch& patch = fromMesh.boundary()[patchi];
388 word name = patch.name();
391 toMesh_.boundaryMesh().findPatchID(name);
396 sizePatch = toMesh_.boundary()[patchID].size();
406 label celli = patch.faceCells()[facei];
408 const vector& centre = fromMesh.C()[celli];
409 if (mag(points[toI] - centre) < localTol)
411 localTol = mag(points[toI] - centre);
412 cellAddressing_[toI] = celli;
424 if (nCellsOutsideAddressing > 0)
426 Info<< "Found " << nCellsOutsideAddressing
427 << " cells outside of the addressing" << nl
428 << "Cell addressing size = " << cellAddressing_.size() << endl;
433 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
435 } // End namespace Foam
437 // ************************************************************************* //