1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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/>.
28 Various utility functions that perform mesh-related operations.
32 University of Massachusetts Amherst
35 \*---------------------------------------------------------------------------*/
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 // Utility method to find the common edge between two faces.
50 inline bool findCommonEdge
54 const UList<labelList>& faceEdges,
60 const labelList& fEi = faceEdges[first];
61 const labelList& fEj = faceEdges[second];
67 if (fEi[edgeI] == fEj[edgeJ])
86 // Utility method to find the interior (quad) / boundary (tri) faces
87 // for an input quad-face and adjacent triangle-prism cell.
88 inline void findPrismFaces
92 const UList<face>& faces,
93 const UList<cell>& cells,
94 const UList<label>& neighbour,
95 FixedList<face,2>& bdyf,
96 FixedList<label,2>& bidx,
97 FixedList<face,2>& intf,
98 FixedList<label,2>& iidx
101 label indexO = 0, indexI = 0;
103 const cell& c = cells[cIndex];
107 label faceIndex = c[i];
109 // Don't count the face under consideration
110 if (faceIndex != fIndex)
112 const face& fi = faces[faceIndex];
114 if (neighbour[faceIndex] == -1)
118 // Triangular face on the boundary
119 bidx[indexO] = faceIndex;
124 // This seems to be a non-triangular face on the boundary
125 // Consider this as "interior" and move on
126 iidx[indexI] = faceIndex;
132 // Face on the interior
133 iidx[indexI] = faceIndex;
141 // Utility method to find the isolated point given two triangular faces.
142 // - Returns the point on checkFace that does not belong to baseFace.
143 inline label findIsolatedPoint
145 const face& baseFace,
146 const face& checkFace
149 // Get the fourth point
150 forAll(checkFace, pointI)
154 checkFace[pointI] != baseFace[0] &&
155 checkFace[pointI] != baseFace[1] &&
156 checkFace[pointI] != baseFace[2]
159 return checkFace[pointI];
167 // Utility method to find the isolated point on a triangular face
168 // that doesn't lie on the specified edge. Also returns the point next to it.
169 inline void findIsolatedPoint
177 // Check the first point
178 if ( f[0] != e.start() && f[0] != e.end() )
185 // Check the second point
186 if ( f[1] != e.start() && f[1] != e.end() )
193 // Check the third point
194 if ( f[2] != e.start() && f[2] != e.end() )
201 // This bit should never happen.
204 "inline void meshOps::findIsolatedPoint"
205 "(const face&, const edge&, label&, label&)"
207 << "Cannot find isolated point in face " << f << endl
208 << " Using edge: " << e
209 << abort(FatalError);
213 // Given a face and cell index, find the apex point for a tet cell.
214 inline label tetApexPoint
218 const UList<face>& faces,
219 const UList<cell>& cells
222 label apexPoint = -1;
223 bool foundApex = false;
225 const cell& cellToCheck = cells[cIndex];
226 const face& baseFace = faces[fIndex];
228 forAll(cellToCheck, faceI)
230 const face& faceToCheck = faces[cellToCheck[faceI]];
232 apexPoint = findIsolatedPoint(baseFace, faceToCheck);
243 Pout<< "fIndex: " << fIndex << ":: " << faces[fIndex] << endl;
244 Pout<< "cIndex: " << cIndex << ":: " << cellToCheck << endl;
246 forAll(cellToCheck, faceI)
248 Pout<< '\t' << cellToCheck[faceI] << ":: "
249 << faces[cellToCheck[faceI]] << endl;
255 "inline label meshOps::tetApexPoint\n"
257 " const label cIndex,\n"
258 " const label fIndex,\n"
259 " const UList<face>& faces,\n"
260 " const UList<cell>& cells\n"
263 << "Could not find an apex point in cell: " << cIndex
264 << " given face: " << fIndex
265 << abort(FatalError);
272 // Given a cell index, find the centroid / volume of a cell.
273 // - If checking is enabled, return whether the cell is closed
274 inline void cellCentreAndVolume
277 const vectorField& points,
278 const UList<face>& faces,
279 const UList<cell>& cells,
280 const UList<label>& owner,
287 centre = vector::zero;
289 const cell& cellToCheck = cells[cIndex];
291 // Average face-centres to get an estimate centroid
292 vector cEst(vector::zero), fCentre(vector::zero);
294 forAll(cellToCheck, faceI)
296 const face& checkFace = faces[cellToCheck[faceI]];
298 cEst += checkFace.centre(points);
301 cEst /= cellToCheck.size();
303 forAll(cellToCheck, faceI)
305 const face& checkFace = faces[cellToCheck[faceI]];
307 if (checkFace.size() == 3)
311 points[checkFace[2]],
312 points[checkFace[1]],
313 points[checkFace[0]],
317 scalar tetVol = tpr.mag();
320 if (owner[cellToCheck[faceI]] != cIndex)
325 // Accumulate volume-weighted tet centre
326 centre += tetVol*tpr.centre();
328 // Accumulate tet volume
333 forAll(checkFace, pI)
337 points[checkFace[pI]],
338 points[checkFace.prevLabel(pI)],
339 checkFace.centre(points),
343 scalar tetVol = tpr.mag();
346 if (owner[cellToCheck[faceI]] != cIndex)
351 // Accumulate volume-weighted tet centre
352 centre += tetVol*tpr.centre();
354 // Accumulate tet volume
360 centre /= volume + VSMALL;
364 // Determine whether a segment intersects a triangular face
365 inline bool segmentTriFaceIntersection
367 const triPointRef& faceToCheck,
368 const linePointRef& edgeToCheck,
373 const vector& p1 = edgeToCheck.start();
374 const vector& p2 = edgeToCheck.end();
376 // Define face-normal
377 vector n = faceToCheck.normal();
378 n /= mag(n) + VSMALL;
381 scalar numerator = n & (faceToCheck.a() - p1);
382 scalar denominator = n & (p2 - p1);
384 // Check if the edge is parallel to the face
385 if (mag(denominator) < VSMALL)
390 scalar u = (numerator / denominator);
392 // Check for intersection along line.
393 if ((u >= 0.0) && (u <= 1.0))
395 // Compute point of intersection
396 intPoint = p1 + u*(p2 - p1);
398 // Also make sure that intPoint lies within the face
399 if (pointInTriFace(faceToCheck, intPoint, false))
405 // Failed to fall within edge-bounds, or within face
410 // Determine whether the particular point lies
411 // inside the given triangular face
412 inline bool pointInTriFace
414 const triPointRef& faceToCheck,
420 const vector& a = faceToCheck.a();
421 const vector& b = faceToCheck.b();
422 const vector& c = faceToCheck.c();
424 // Compute the normal
425 vector nf = faceToCheck.normal();
427 if ( ((0.5 * ((b - a)^(cP - a))) & nf) < 0.0)
432 if ( ((0.5 * ((c - b)^(cP - b))) & nf) < 0.0)
437 if ( ((0.5 * ((a - c)^(cP - c))) & nf) < 0.0)
447 nf /= mag(nf) + VSMALL;
448 ftp /= mag(ftp) + VSMALL;
450 if (mag(ftp & nf) > VSMALL)
456 // Passed test with all edges
461 // Parallel blocking send
471 (blocking ? Pstream::blocking : Pstream::nonBlocking),
473 reinterpret_cast<const char*>(&data),
479 // Parallel blocking receive
489 (blocking ? Pstream::blocking : Pstream::nonBlocking),
491 reinterpret_cast<char*>(&data),
497 // Parallel non-blocking send for fixed lists
498 template <class Type, unsigned Size>
502 const FixedList<Type, Size>& data
509 reinterpret_cast<const char*>(&data[0]),
515 // Parallel non-blocking receive for fixed lists
516 template <class Type, unsigned Size>
520 FixedList<Type, Size>& data
527 reinterpret_cast<char*>(data.begin()),
533 // Parallel non-blocking send for lists
534 template <class Type>
538 const UList<Type>& data
543 Pstream::nonBlocking,
545 reinterpret_cast<const char*>(&data[0]),
546 data.size()*sizeof(Type)
551 // Parallel non-blocking receive for lists
552 template <class Type>
561 Pstream::nonBlocking,
563 reinterpret_cast<char*>(&data[0]),
564 data.size()*sizeof(Type)
569 // Wait for buffer transfer completion.
570 inline void waitForBuffers()
572 if (Pstream::parRun())
574 OPstream::waitRequests();
575 IPstream::waitRequests();
580 // Method to insert a label between two labels in a list
581 // Assumes that all labels are unique.
582 inline void insertLabel
584 const label newLabel,
592 label origSize = list.size();
593 labelList newList(origSize + 1);
595 label index = 0, nextI = -1;
597 // Start a linear search
600 newList[index++] = list[itemI];
602 nextI = list.fcIndex(itemI);
607 (list[itemI] == labelA && list[nextI] == labelB) ||
608 (list[itemI] == labelB && list[nextI] == labelA)
614 newList[index++] = newLabel;
622 "inline void meshOps::insertLabel"
623 "(const label, const label, const label, labelList&)"
624 ) << nl << "Cannot insert " << newLabel
625 << " in list: " << list << nl
627 << labelA << " and " << labelB
628 << " were not found in sequence."
629 << abort(FatalError);
633 list.transfer(newList);
637 // Utility method to replace a label in a given list
638 inline void replaceLabel
640 const label original,
641 const label replacement,
647 if ((index = findIndex(list, original)) > -1)
649 list[index] = replacement;
655 "inline void label meshOps::replaceLabel"
656 "(const label, const label, labelList&)"
657 ) << nl << "Cannot find " << original
658 << " in list: " << list << nl
659 << " Label: " << replacement
660 << " was not used in replacement."
661 << abort(FatalError);
666 // Utility method to size-up the list to include an item
667 template <class Type>
668 inline void sizeUpList
674 list.setSize(list.size() + 1, item);
678 // Utility method to size-down the list to remove an item
679 template <class Type>
680 inline void sizeDownList
688 if ((index = findIndex(list, item)) > -1)
690 meshOps::removeIndex(index, list);
696 "inline void meshOps::sizeDownList"
697 "(const Type& item, List<Type>& list)"
699 << nl << "Item: " << item
700 << " was not found in list. " << nl
701 << " List: " << nl << list
702 << abort(FatalError);
707 // Remove an item at a particular index in the list
708 template <class Type>
709 inline void removeIndex
716 List<Type> newList(list.size() - 1);
718 // Copy individual items
728 newList[n++] = list[itemI];
732 list.transfer(newList);
736 } // End namespace meshOps
739 } // End namespace Foam
741 // ************************************************************************* //