void Foam::faPatch::calcPointLabels() const
{
    SLList<label> labels;

    UList<edge> edges =
        patchSlice(boundaryMesh().mesh().edges());

    forAll(edges, edgeI)
    {
        bool existStart = false;
        bool existEnd = false;

        for
        (
            SLList<label>::iterator iter = labels.begin();
            iter != labels.end();
            ++iter
        )
        {
            if(*iter == edges[edgeI].start())
            {
                existStart = true;
            }

            if(*iter == edges[edgeI].end())
            {
                existEnd = true;
            }
        }

        if(!existStart)
        {
            labels.append(edges[edgeI].start());
        }

        if(!existEnd)
        {
            labels.append(edges[edgeI].end());
        }
    }
            // Find a good edge
            forAll(singleEdges, edgeI)
            {
                SLList<label> pointChain;

                bool blockHead = false;
                bool blockTail = false;

                if (!singleEdgeUsage[edgeI])
                {
                    // found a new edge
                    singleEdgeUsage[edgeI] = true;

                    label newEdgeStart = singleEdges[edgeI].start();
                    label newEdgeEnd = singleEdges[edgeI].end();

                    pointChain.insert(newEdgeStart);
                    pointChain.append(newEdgeEnd);

#                   ifdef DEBUG_CHAIN
                    Info<< "found edge to start with: "
                        << singleEdges[edgeI] << endl;
#                   endif

                    // Check if head or tail are blocked
                    forAll(cellPoints, pointI)
                    {
                        if (cellPoints[pointI] == newEdgeStart)
                        {
                            if (pointUsage[pointI] > 2)
                            {
#                               ifdef DEBUG_CHAIN
                                Info<< "start head blocked" << endl;
#                               endif

                                blockHead = true;
                            }
                        }
                        else if (cellPoints[pointI] == newEdgeEnd)
                        {
                            if (pointUsage[pointI] > 2)
                            {
#                               ifdef DEBUG_CHAIN
                                Info<< "start tail blocked" << endl;
#                               endif

                                blockTail = true;
                            }
                        }
                    }

                    bool stopSearching = false;

                    // Go through the unused edges and try to chain them up
                    do
                    {
                        stopSearching = false;

                        forAll(singleEdges, addEdgeI)
                        {
                            if (!singleEdgeUsage[addEdgeI])
                            {
                                // Grab start and end of the candidate
                                label addStart =
                                    singleEdges[addEdgeI].start();

                                label addEnd =
                                    singleEdges[addEdgeI].end();

#                               ifdef DEBUG_CHAIN
                                Info<< "Trying candidate "
                                    << singleEdges[addEdgeI] << endl;
#                               endif

                                // Try to add the edge onto the head
                                if (!blockHead)
                                {
                                    if (pointChain.first() == addStart)
                                    {
                                        // Added at start mark as used
                                        pointChain.insert(addEnd);

                                        singleEdgeUsage[addEdgeI] = true;
                                    }
                                    else if (pointChain.first() == addEnd)
                                    {
                                        pointChain.insert(addStart);

                                        singleEdgeUsage[addEdgeI] = true;
                                    }
                                }

                                // Try the other end only if the first end
                                // did not add it
                                if (!blockTail && !singleEdgeUsage[addEdgeI])
                                {
                                    if (pointChain.last() == addStart)
                                    {
                                        // Added at start mark as used
                                        pointChain.append(addEnd);

                                        singleEdgeUsage[addEdgeI] = true;
                                    }
                                    else if (pointChain.last() == addEnd)
                                    {
                                        pointChain.append(addStart);

                                        singleEdgeUsage[addEdgeI] = true;
                                    }
                                }

                                // check if the new head or tail are blocked
                                label curEdgeStart = pointChain.first();
                                label curEdgeEnd = pointChain.last();

#                               ifdef DEBUG_CHAIN
                                Info<< "curEdgeStart: " << curEdgeStart
                                    << " curEdgeEnd: " << curEdgeEnd << endl;
#                               endif

                                forAll(cellPoints, pointI)
                                {
                                    if (cellPoints[pointI] == curEdgeStart)
                                    {
                                        if (pointUsage[pointI] > 2)
                                        {
#                                           ifdef DEBUG_CHAIN
                                            Info<< "head blocked" << endl;
#                                           endif

                                            blockHead = true;
                                        }
                                    }
                                    else if (cellPoints[pointI] == curEdgeEnd)
                                    {
                                        if (pointUsage[pointI] > 2)
                                        {
#                                           ifdef DEBUG_CHAIN
                                            Info<< "tail blocked" << endl;
#                                           endif

                                            blockTail = true;
                                        }
                                    }
                                }

                                // Check if the loop is closed
                                if (curEdgeStart == curEdgeEnd)
                                {
#                                   ifdef DEBUG_CHAIN
                                    Info<< "closed loop" << endl;
#                                   endif

                                    pointChain.removeHead();

                                    blockHead = true;
                                    blockTail = true;

                                    stopSearching = true;
                                }

#                               ifdef DEBUG_CHAIN
                                Info<< "current pointChain: " << pointChain
                                    << endl;
#                               endif

                                if (stopSearching) break;
                            }
                        }
                    } while (stopSearching);
                }
Example #3
0
// Constructor from components
Foam::labelList Foam::bandCompression(const labelListList& cellCellAddressing)
{
    labelList newOrder(cellCellAddressing.size());

    // the business bit of the renumbering
    SLList<label> nextCell;

    labelList visited(cellCellAddressing.size());

    label currentCell;
    label cellInOrder = 0;

    // reset the visited cells list
    forAll (visited, cellI)
    {
        visited[cellI] = 0;
    }

    // loop over the cells
    forAll (visited, cellI)
    {
        // find the first cell that has not been visited yet
        if (visited[cellI] == 0)
        {
            currentCell = cellI;

            // use this cell as a start
            nextCell.append(currentCell);

            // loop through the nextCell list. Add the first cell into the
            // cell order if it has not already been visited and ask for its
            // neighbours. If the neighbour in question has not been visited,
            // add it to the end of the nextCell list

            while (nextCell.size())
            {
                currentCell = nextCell.removeHead();

                if (visited[currentCell] == 0)
                {
                    visited[currentCell] = 1;

                    // add into cellOrder
                    newOrder[cellInOrder] = currentCell;
                    cellInOrder++;

                    // find if the neighbours have been visited
                    const labelList& neighbours =
                        cellCellAddressing[currentCell];

                    forAll (neighbours, nI)
                    {
                        if (visited[neighbours[nI]] == 0)
                        {
                            // not visited, add to the list
                            nextCell.append(neighbours[nI]);
                        }
                    }
                }
            }
        }
void Foam::immersedBoundaryFvPatch::makeTriAddressing() const
{
    if (debug)
    {
        InfoIn("void immersedBoundaryFvPatch::makeTriAddressing() const")
            << "creating tri addressing for immersed boundary " << name()
            << endl;
    }

    // It is an error to attempt to recalculate
    // if the pointer is already set
    if (cellsToTriAddrPtr_ || cellsToTriWeightsPtr_)
    {
        FatalErrorIn("immersedBoundaryFvPatch::makeTriAddressing() const")
            << "tri addressing already exist"
            << "for immersed boundary" << name()
            << abort(FatalError);
    }

    // Get reference to tri patch and hit faces
    const triSurface& triPatch = ibPolyPatch_.ibMesh();
    const vectorField& triCentres = triPatch.faceCentres();

    const labelList& hf = hitFaces();
    const vectorField& ibp = ibPoints();

    // Create a markup field and mark all tris containing an ib point with its
    // index
    labelList hitTris(triPatch.size(), -1);

    forAll (hf, hfI)
    {
        hitTris[hf[hfI]] = hfI;
    }

    // Allocate storage
    cellsToTriAddrPtr_ = new labelListList(triPatch.size());
    labelListList& addr = *cellsToTriAddrPtr_;

    cellsToTriWeightsPtr_ = new scalarListList(triPatch.size());
    scalarListList& w = *cellsToTriWeightsPtr_;

    // Algorithm:
    // For each tri face, check if it contains an IB point
    // - if so, set the addressing to the index of IB point and weight to 1
    // - if not, search the neighbouring faces of the visited faces until
    //   at least 3 IB points are found, or the neighbourhood is exhausted.
    //   When a sufficient number of points is found, calculate the weights
    //   using inverse distance weighting

    // Get addressing from the triangular patch
    const labelListList& pf = triPatch.pointFaces();

    forAll (triPatch, triI)
    {
        if (hitTris[triI] > -1)
        {
            // Triangle contains IB point
            addr[triI].setSize(1);
            w[triI].setSize(1);

            addr[triI] = hitTris[triI];
            w[triI] = 1;
        }
        else
        {
            // No direct hit.  Start a neighbourhood search

            // Record already visited faces
            labelHashSet visited;

            // Collect new faces to visit
            SLList<label> nextToVisit;

            // Collect IB points for interpolation
            labelHashSet ibPointsToUse;

            // Initialise with the original tri
            nextToVisit.insert(triI);

            do
            {
                const label curTri = nextToVisit.removeHead();

                // Discard tri if already visited
                if (visited[curTri]) continue;

                visited.insert(curTri);

                const triFace& curTriPoints = triPatch[curTri];

                // For all current points of face, pick up neighbouring faces
                forAll (curTriPoints, tpI)
                {
                    const labelList curNbrs = pf[curTriPoints[tpI]];

                    forAll (curNbrs, nbrI)
                    {
                        if (!visited.found(curNbrs[nbrI]))
                        {
                            // Found a face which is not visited.  Add it to
                            // the list of faces to visit
                            nextToVisit.append(curNbrs[nbrI]);

                            if (hitTris[curNbrs[nbrI]] > -1)
                            {
                                // Found a neighbour with a hit: use this
                                // IB point
                                ibPointsToUse.insert(hitTris[curNbrs[nbrI]]);
                            }
                        }
                    }
                }
            } while
            (
                ibPointsToUse.size() < 3
             && !nextToVisit.empty()
            );

            // Found neighbourhood: collect addressing and weights
            addr[triI] = ibPointsToUse.toc();
            w[triI].setSize(addr[triI].size());

            labelList& curAddr = addr[triI];
            scalarList& curW = w[triI];

            vector curTriCentre = triCentres[triI];

            scalar sumW = 0;

            forAll (curAddr, ibI)
            {
                curW[ibI] = 1/mag(curTriCentre - ibp[curAddr[ibI]]);
                sumW += curW[ibI];
            }

            // Divide weights by sum distance
            forAll (curW, ibI)
            {
                curW[ibI] /= sumW;
            }
        }
    }