// Given a subset of cells determine the new global indices. The problem
// is in the cells from neighbouring processors which need to be renumbered.
void Foam::multiLevelDecomp::subsetGlobalCellCells
(
    const label nDomains,
    const label domainI,
    const labelList& dist,

    const labelListList& cellCells,
    const labelList& set,
    labelListList& subCellCells,
    labelList& cutConnections
) const
{
    // Determine new index for cells by inverting subset
    labelList oldToNew(invert(cellCells.size(), set));

    globalIndex globalCells(cellCells.size());

    // Subset locally the elements for which I have data
    subCellCells = UIndirectList<labelList>(cellCells, set);

    // Get new indices for neighbouring processors
    List<Map<label>> compactMap;
    mapDistribute map(globalCells, subCellCells, compactMap);
    map.distribute(oldToNew);
    labelList allDist(dist);
    map.distribute(allDist);

    // Now we have:
    // oldToNew : the locally-compact numbering of all our cellCells. -1 if
    //            cellCell is not in set.
    // allDist  : destination domain for all our cellCells
    // subCellCells : indexes into oldToNew and allDist

    // Globally compact numbering for cells in set.
    globalIndex globalSubCells(set.size());

    // Now subCellCells contains indices into oldToNew which are the
    // new locations of the neighbouring cells.

    cutConnections.setSize(nDomains);
    cutConnections = 0;

    forAll(subCellCells, subCelli)
    {
        labelList& cCells = subCellCells[subCelli];

        // Keep the connections to valid mapped cells
        label newI = 0;
        forAll(cCells, i)
        {
            // Get locally-compact cell index of neighbouring cell
            label nbrCelli = oldToNew[cCells[i]];
            if (nbrCelli == -1)
            {
                cutConnections[allDist[cCells[i]]]++;
            }
            else
            {
                // Reconvert local cell index into global one

                // Get original neighbour
                label celli = set[subCelli];
                label oldNbrCelli = cellCells[celli][i];
                // Get processor from original neighbour
                label proci = globalCells.whichProcID(oldNbrCelli);
                // Convert into global compact numbering
                cCells[newI++] = globalSubCells.toGlobal(proci, nbrCelli);
            }
        }
Exemple #2
0
// Determine order for faces:
// - upper-triangular order for internal faces
// - external faces after internal faces (were already so)
Foam::labelList Foam::polyDualMesh::getFaceOrder
(
    const labelList& faceOwner,
    const labelList& faceNeighbour,
    const cellList& cells,
    label& nInternalFaces
)
{
    labelList oldToNew(faceOwner.size(), -1);

    // First unassigned face
    label newFacei = 0;

    forAll(cells, celli)
    {
        const labelList& cFaces = cells[celli];

        SortableList<label> nbr(cFaces.size());

        forAll(cFaces, i)
        {
            label facei = cFaces[i];

            label nbrCelli = faceNeighbour[facei];

            if (nbrCelli != -1)
            {
                // Internal face. Get cell on other side.
                if (nbrCelli == celli)
                {
                    nbrCelli = faceOwner[facei];
                }

                if (celli < nbrCelli)
                {
                    // Celli is master
                    nbr[i] = nbrCelli;
                }
                else
                {
                    // nbrCell is master. Let it handle this face.
                    nbr[i] = -1;
                }
            }
            else
            {
                // External face. Do later.
                nbr[i] = -1;
            }
        }

        nbr.sort();

        forAll(nbr, i)
        {
            if (nbr[i] != -1)
            {
                oldToNew[cFaces[nbr.indices()[i]]] = newFacei++;
            }
        }
    }
Foam::labelList Foam::manualRenumber::renumber
(
    const polyMesh& mesh,
    const pointField& points
) const
{
    labelIOList newToOld
    (
        IOobject
        (
            dataFile_,
            mesh.facesInstance(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE,
            false
        )
    );

    // check if the final renumbering is OK

    if (newToOld.size() != points.size())
    {
        FatalErrorIn
        (
            "manualRenumber::renumber(const pointField&, const scalarField&)"
        )   << "Size of renumber list does not correspond "
            << "to the number of points.  Size: "
            << newToOld.size() << " Number of points: "
            << points.size()
            << ".\n" << "Manual renumbering data read from file "
            << dataFile_ << "." << endl
            << exit(FatalError);
    }

    // Invert to see if one to one
    labelList oldToNew(points.size(), -1);
    forAll(newToOld, i)
    {
        label origCellI = newToOld[i];

        if (origCellI < 0 || origCellI >= points.size())
        {
            FatalErrorIn
            (
                "manualRenumber::renumber(const pointField&"
                ", const scalarField&)"
            )   << "Renumbering is not one-to-one. Index "
                << i << " maps onto original cell " << origCellI
                << ".\n" << "Manual renumbering data read from file "
                << dataFile_ << "." << endl
                << exit(FatalError);
        }

        if (oldToNew[origCellI] == -1)
        {
            oldToNew[origCellI] = i;
        }
        else
        {
            FatalErrorIn
            (
                "manualRenumber::renumber(const pointField&"
                ", const scalarField&)"
            )   << "Renumbering is not one-to-one. Both index "
                << oldToNew[origCellI]
                << " and " << i << " map onto " << origCellI
                << ".\n" << "Manual renumbering data read from file "
                << dataFile_ << "." << endl
                << exit(FatalError);
        }
    }