コード例 #1
0
ファイル: DofOrdering.cpp プロジェクト: Kun-Qu/Camellia
int DofOrdering::getDofIndex(int varID, int basisDofOrdinal, int sideIndex, int subSideIndex) { 
  TEUCHOS_TEST_FOR_EXCEPTION( ( _indexNeedsToBeRebuilt ),
                     std::invalid_argument,
                     "getDofIndex called when _indexNeedsToBeRebuilt = true.  Call rebuildIndex() first.");
  if (subSideIndex >= 0) {
    // then we've got a MultiBasis, and the basisDofOrdinal we have is *relative* to the subbasis
    BasisPtr basis = getBasis(varID,sideIndex);
    if ( ! BasisFactory::basisFactory()->isMultiBasis(basis) ) {
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "subSideIndex >= 0 for non-MultiBasis...");
    }
    MultiBasis<>* multiBasis = (MultiBasis<>*) basis.get();
    //cout << "(basisDofOrdinal, subSideIndex) : (" << basisDofOrdinal << ", " << subSideIndex << ") --> ";
    basisDofOrdinal = multiBasis->relativeToAbsoluteDofOrdinal(basisDofOrdinal,subSideIndex);
    //cout << basisDofOrdinal << endl;
  }
  
  pair<int,int> key = make_pair(varID, sideIndex);
  map< pair<int,int>, vector<int> >::iterator entryIt = indices.find(key);
  if ( entryIt != indices.end() ) {
    int dofIndex = ((*entryIt).second)[basisDofOrdinal];
    if ((dofIndex < 0) || (dofIndex >= _nextIndex)) {
      cout << "dofIndex out of bounds.\n";
      TEUCHOS_TEST_FOR_EXCEPTION( (dofIndex < 0) || (dofIndex >= _nextIndex), std::invalid_argument, "dofIndex out of bounds.");
    }
    return dofIndex;
  } else {
    cout << "No entry found for dofIndex\n";
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "No entry found for DofIndex.");
    return -1;
  }
}
コード例 #2
0
bool MeshTestUtility::checkMeshDofConnectivities(Teuchos::RCP<Mesh> mesh)
{
  int numCells = mesh->activeElements().size();
  bool success = true;
  int numGlobalDofs = mesh->numGlobalDofs();
  vector<int> globalDofIndexHitCount(numGlobalDofs,0);
  for (int cellIndex=0; cellIndex<numCells; cellIndex++)
  {
    Teuchos::RCP<Element> elem = mesh->activeElements()[cellIndex];
    GlobalIndexType cellID = elem->cellID();
    DofOrdering trialOrder = *(elem->elementType()->trialOrderPtr.get());
    vector< int > trialIDs = mesh->bilinearForm()->trialIDs();
    for (vector< int >::iterator trialIt = trialIDs.begin(); trialIt != trialIDs.end(); trialIt++)
    {
      int trialID = *(trialIt);
      const vector<int>* sidesForVar = &trialOrder.getSidesForVarID(trialID);
      for (vector<int>::const_iterator sideIt = sidesForVar->begin(); sideIt != sidesForVar->end(); sideIt++)
      {
        int sideIndex = *sideIt;
        int numBasisDofs = trialOrder.getBasisCardinality(trialID, sideIndex);
        for (int dofOrdinal=0; dofOrdinal<numBasisDofs; dofOrdinal++)
        {
          // a very basic check on the mesh dof ordering: the globalDofIndices for all localDofs should not be negative!
          int localDofIndex = trialOrder.getDofIndex(trialID, dofOrdinal, sideIndex);
          int globalDofIndex = mesh->globalDofIndex(cellID,localDofIndex);
          if (globalDofIndex < 0)
          {
            cout << "mesh->globalDofIndex(" << cellID << "," << localDofIndex << ") = " << globalDofIndex << " < 0.  Error!";
            success = false;
          }
          else if (globalDofIndex >= mesh->numGlobalDofs())
          {
            cout << "mesh->globalDofIndex(" << cellID << "," << localDofIndex << ") = " << globalDofIndex << " >= mymesh->numGlobalDofs().  Error!";
            success = false;
          }
          else
          {
            globalDofIndexHitCount[globalDofIndex]++;
          }
        }

        // now a more subtle check: given the mesh layout (that all vertices are specified CCW),
        // the dofs for boundary variables (fluxes & traces) should be reversed between element and its neighbor
        if (mesh->bilinearForm()->isFluxOrTrace(trialID))
        {
          CellPtr cell = mesh->getTopology()->getCell(cellID);
          if (! mesh->getTopology()->getCell(cellID)->isBoundary(sideIndex))   // not boundary...
          {
            //            if (neighbor->cellID() != -1) { // not boundary...
            int ancestralSideIndexInNeighbor;
            Teuchos::RCP<Element> neighbor = mesh->ancestralNeighborForSide(elem, sideIndex, ancestralSideIndexInNeighbor);

            Teuchos::RCP<DofOrdering> neighborTrialOrder = neighbor->elementType()->trialOrderPtr;
            int neighborNumBasisDofs = neighborTrialOrder->getBasisCardinality(trialID,ancestralSideIndexInNeighbor);
            if (neighborNumBasisDofs != numBasisDofs)
            {
              if ( mesh->usePatchBasis() )
              {
                cout << "FAILURE: usePatchBasis==true, but neighborNumBasisDofs != numBasisDofs.\n";
                success = false;
                continue;
              }
              if ( neighbor->isParent() )
              {
                // Here, we need to deal with the possibility that neighbor is a parent, broken along the shared side
                //  -- if so, we have a MultiBasis, and we need to match with each of neighbor's descendants along that side...
                vector< pair<int,int> > descendantsForSide = neighbor->getDescendantsForSide(ancestralSideIndexInNeighbor);
                vector< pair<int,int> >:: iterator entryIt;
                int descendantIndex = -1;
                for (entryIt = descendantsForSide.begin(); entryIt != descendantsForSide.end(); entryIt++)
                {
                  descendantIndex++;
                  int neighborSubSideIndexInMe = GDAMaximumRule2D::neighborChildPermutation(descendantIndex, descendantsForSide.size());
                  int neighborCellID = (*entryIt).first;
                  int mySideIndexInNeighbor = (*entryIt).second;
                  neighbor = mesh->getElement(neighborCellID);
                  int neighborNumDofs = neighbor->elementType()->trialOrderPtr->getBasisCardinality(trialID,mySideIndexInNeighbor);

                  for (int dofOrdinal=0; dofOrdinal<neighborNumDofs; dofOrdinal++)
                  {
                    int myLocalDofIndex;
                    if ((descendantsForSide.size() > 1) && !mesh->usePatchBasis())
                    {
                      myLocalDofIndex = elem->elementType()->trialOrderPtr->getDofIndex(trialID,dofOrdinal,sideIndex,neighborSubSideIndexInMe);
                    }
                    else
                    {
                      myLocalDofIndex = elem->elementType()->trialOrderPtr->getDofIndex(trialID,dofOrdinal,sideIndex);
                    }
                    int globalDofIndex = mesh->globalDofIndex(cellID,myLocalDofIndex);

                    // neighbor's dofs are in reverse order from mine along each side
                    int permutedDofOrdinal = GDAMaximumRule2D::neighborDofPermutation(dofOrdinal,neighborNumDofs);

                    int neighborLocalDofIndex = neighbor->elementType()->trialOrderPtr->getDofIndex(trialID,permutedDofOrdinal,mySideIndexInNeighbor);
                    int neighborsGlobalDofIndex = mesh->globalDofIndex(neighbor->cellID(),neighborLocalDofIndex);
                    if (neighborsGlobalDofIndex != globalDofIndex)
                    {

                      cout << "FAILURE: checkDofConnectivities--(cellID, localDofIndex) : (" << cellID << ", " << myLocalDofIndex << ") != (";
                      cout << neighborCellID << ", " << neighborLocalDofIndex << ") -- ";
                      cout << globalDofIndex << " != " << neighborsGlobalDofIndex << "\n";
                      success = false;
                    }
                  }
                }
              }
              else if (neighbor->getNeighborCellID(ancestralSideIndexInNeighbor) != cellID)
              {
                // elem is small, neighbor big
                // first, find my leaf index in neighbor:
                int ancestorCellID = neighbor->getNeighborCellID(ancestralSideIndexInNeighbor);
                Teuchos::RCP<Element> ancestor = mesh->getElement(ancestorCellID);
                int ancestorSideIndex = neighbor->getSideIndexInNeighbor(ancestralSideIndexInNeighbor);
                vector< pair<int,int> > descendantsForSide = ancestor->getDescendantsForSide(ancestorSideIndex);
                int descendantIndex = 0;
                int leafIndexInNeighbor = -1;
                for (vector< pair<int,int> >::iterator entryIt = descendantsForSide.begin();
                     entryIt != descendantsForSide.end();  entryIt++, descendantIndex++)
                {
                  if (entryIt->first == cellID)
                  {
                    leafIndexInNeighbor = GDAMaximumRule2D::neighborChildPermutation(descendantIndex, descendantsForSide.size());
                    break;
                  }
                }
                if (leafIndexInNeighbor == -1)
                {
                  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "Could not determine leafIndexInNeigbor.");
                }
                // check whether the basis is the right size:
                MultiBasis<>* neighborMultiBasis = (MultiBasis<>*) neighbor->elementType()->trialOrderPtr->getBasis(trialID,ancestralSideIndexInNeighbor).get();
                BasisPtr neighborLeafBasis = neighborMultiBasis->getLeafBasis(leafIndexInNeighbor);
                if (numBasisDofs != neighborLeafBasis->getCardinality())
                {
                  success = false;
                  cout << "FAILURE: cellID " << cellID << "'s basis for trialID " << trialID;
                  cout << " along sideIndex " << sideIndex << " has cardinality " << numBasisDofs;
                  cout << ", but neighbor leaf basis along that side (cellID " << neighbor->cellID();
                  cout << ", sideIndex " << ancestralSideIndexInNeighbor;
                  cout << ", leaf node " << leafIndexInNeighbor;
                  cout << ") has cardinality " << neighborLeafBasis->getCardinality() << endl;
                }
                else
                {
                  // cardinalities match, check that global dofs line up
                  for (int dofOrdinal = 0; dofOrdinal < numBasisDofs; dofOrdinal++)
                  {
                    int permutedDofOrdinal = GDAMaximumRule2D::neighborDofPermutation(dofOrdinal, numBasisDofs);
                    int neighborDofOrdinal = neighborMultiBasis->relativeToAbsoluteDofOrdinal(permutedDofOrdinal,
                                             leafIndexInNeighbor);
                    int neighborLocalDofIndex = neighbor->elementType()->trialOrderPtr->getDofIndex(trialID, neighborDofOrdinal,ancestralSideIndexInNeighbor);
                    int neighborGlobalDofIndex = mesh->globalDofIndex(neighbor->cellID(), neighborLocalDofIndex);
                    int myLocalDofIndex = elem->elementType()->trialOrderPtr->getDofIndex(trialID, dofOrdinal, sideIndex);
                    int myGlobalDofIndex = mesh->globalDofIndex(cellID, myLocalDofIndex);
                    if (neighborGlobalDofIndex != myGlobalDofIndex)
                    {
                      success = false;
                      cout << "FAILURE: checkDofConnectivities--(cellID, localDofIndex) : (" << cellID << ", ";
                      cout << myLocalDofIndex << ") != (";
                      cout << neighbor->cellID() << ", " << neighborLocalDofIndex << ") -- ";
                      cout << myGlobalDofIndex << " != " << neighborGlobalDofIndex << "\n";
                    }
                  }
                }
              }
              else
              {
                cout << "FAILURE: cellID " << cellID << "'s basis for trialID " << trialID;
                cout << " along sideIndex " << sideIndex << " has cardinality " << numBasisDofs;
                cout << ", but neighbor along that side (cellID " << neighbor->cellID();
                cout << ", sideIndex " << ancestralSideIndexInNeighbor << ") has cardinality " << neighborNumBasisDofs << endl;
                success = false;
              }
            }
            else     // (neighborNumBasisDofs == numBasisDofs)
            {
              if (! neighbor->isParent() )
              {
                for (int dofOrdinal=0; dofOrdinal<numBasisDofs; dofOrdinal++)
                {
                  int permutedDofOrdinal = GDAMaximumRule2D::neighborDofPermutation(dofOrdinal,numBasisDofs);
                  int neighborsLocalDofIndex = neighborTrialOrder->getDofIndex(trialID, permutedDofOrdinal, ancestralSideIndexInNeighbor);
                  GlobalIndexType neighborsGlobalDofIndex = mesh->globalDofIndex(neighbor->cellID(),neighborsLocalDofIndex);
                  int localDofIndex = trialOrder.getDofIndex(trialID, dofOrdinal, sideIndex);
                  GlobalIndexType globalDofIndex = mesh->globalDofIndex(cellID,localDofIndex);
                  if (neighborsGlobalDofIndex != globalDofIndex)
                  {
                    cout << "FAILURE: cellID " << cellID << "'s neighbor " << sideIndex << "'s globalDofIndex " << neighborsGlobalDofIndex << " doesn't match element globalDofIndex " << globalDofIndex << ". (trialID, element dofOrdinal)=(" << trialID << "," << dofOrdinal << ")" << endl;
                    success = false;
                  }
                }
              }
              else     // neighbor->isParent()
              {
                // for PatchBasis:
                for (int dofOrdinal=0; dofOrdinal<numBasisDofs; dofOrdinal++)
                {
                  int localDofIndex = trialOrder.getDofIndex(trialID, dofOrdinal, sideIndex);
                  GlobalIndexType globalDofIndex = mesh->globalDofIndex(cellID,localDofIndex);
                  vector< pair<int,int> > descendantsForSide = neighbor->getDescendantsForSide(ancestralSideIndexInNeighbor);
                  vector< pair<int,int> >:: iterator entryIt;
                  for (entryIt = descendantsForSide.begin(); entryIt != descendantsForSide.end(); entryIt++)
                  {
                    GlobalIndexType neighborCellID = (*entryIt).first;
                    int mySideIndexInNeighbor = (*entryIt).second;
                    neighbor = mesh->getElement(neighborCellID);
                    neighborTrialOrder = neighbor->elementType()->trialOrderPtr;
                    int permutedDofOrdinal = GDAMaximumRule2D::neighborDofPermutation(dofOrdinal,numBasisDofs);
                    int neighborsLocalDofIndex = neighborTrialOrder->getDofIndex(trialID, permutedDofOrdinal, mySideIndexInNeighbor);
                    GlobalIndexType neighborsGlobalDofIndex = mesh->globalDofIndex(neighbor->cellID(),neighborsLocalDofIndex);
                    if (neighborsGlobalDofIndex != globalDofIndex)
                    {
                      cout << "FAILURE: cellID " << cellID << "'s neighbor on side " << sideIndex;
                      cout << " (cellID " << neighborCellID << ")'s globalDofIndex " << neighborsGlobalDofIndex;
                      cout << " doesn't match element globalDofIndex " << globalDofIndex;
                      cout << ". (trialID, element dofOrdinal): (" << trialID << "," << dofOrdinal << ")" << endl;
                      cout << "         (cellID,localDofIndex): (" << cellID << "," << localDofIndex << ") ≠ (";
                      cout << neighborCellID << "," << neighborsLocalDofIndex << ")\n";
                      success = false;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  for (int i=0; i<numGlobalDofs; i++)
  {
    if ( globalDofIndexHitCount[i] == 0 )
    {
      success = false;
      cout << "FAILURE: meshDofConnectivity: globalDofIndex " << i << " is unreachable.\n";
    }
  }
  return success;
}