Ejemplo n.º 1
0
bool MeshTestUtility::checkConstraintConsistency(MeshPtr meshMinimumRule)
{
  MeshTopologyViewPtr meshTopo = meshMinimumRule->getTopology();
  GDAMinimumRule* minRule = dynamic_cast<GDAMinimumRule*>(meshMinimumRule->globalDofAssignment().get());
  
  bool consistent = true;
  
  for (IndexType cellID : meshMinimumRule->cellIDsInPartition())
  {
    CellConstraints constraints = minRule->getCellConstraints(cellID);
    CellPtr cell = meshTopo->getCell(cellID);
    CellTopoPtr cellTopo = cell->topology();
    
    for (int d=0; d<cellTopo->getDimension(); d++)
    {
      int scCount = cellTopo->getSubcellCount(d);
      for (int scord=0; scord<scCount; scord++)
      {
        IndexType entityIndex = cell->entityIndex(d, scord);
        
        AnnotatedEntity constrainingEntity = constraints.subcellConstraints[d][scord];
        bool isConsistent = constraintIsConsistent(meshTopo, constrainingEntity, d, entityIndex, true);
        
        if (!isConsistent)
        {
          cout << "Failed consistency test for standard constraints on cell " << cellID << ", " << CamelliaCellTools::entityTypeString(d) << " " << scord << endl;
          
          consistent = false;
          break;
        }
        
        // now, check space-only constraints (for space-time meshes), if these are defined for this subcell
        if (constraints.spatialSliceConstraints != Teuchos::null)
        {
          AnnotatedEntity constrainingEntityForSpatialSlice = constraints.spatialSliceConstraints->subcellConstraints[d][scord];
          if (constrainingEntityForSpatialSlice.cellID != -1) {
            isConsistent = constraintIsConsistent(meshTopo, constrainingEntityForSpatialSlice, d, entityIndex, true);
            
          }
          if (!isConsistent)
          {
            cout << "Failed consistency test for spatial slice on cell " << cellID << ", " << CamelliaCellTools::entityTypeString(d) << " " << scord << endl;
            
            consistent = false;
            break;
          }
        }
      }
      if (!consistent) break;
    }
    if (!consistent) break;
  }
  return consistent;
}
Ejemplo n.º 2
0
MeshPartitionPolicyPtr MeshPartitionPolicy::inducedPartitionPolicyFromRefinedMesh(MeshTopologyViewPtr inducedMeshTopo, MeshPtr inducingRefinedMesh)
{
    // generate using the inducing mesh
    vector<GlobalIndexTypeToCast> myEntries;

    auto myCellIDs = &inducingRefinedMesh->cellIDsInPartition();
    bool rotateChildOrdinalThatOwns = false; // the 6-27-16 modification -- I don't think this actually helps with load balance, the way things are presently implemented, and it may introduce additional communication costs
    if (rotateChildOrdinalThatOwns)
    {
        /*
         Modification 6-27-16: instead of assigning parent to owner of first child,
         assign parent to owner of child with ordinal equal to the level of the
         parent, modulo the number of children.  This should result in better load
         balancing for multigrid.
         */
        for (GlobalIndexType myCellID : *myCellIDs)
        {
            IndexType ancestralCellIndex = myCellID;
            bool hasMatchingChild = true;
            while (inducingRefinedMesh->getTopology()->isValidCellIndex(ancestralCellIndex)
                    && !inducedMeshTopo->isValidCellIndex(ancestralCellIndex))
            {
                CellPtr myCell = inducingRefinedMesh->getTopology()->getCell(ancestralCellIndex);
                CellPtr parent = myCell->getParent();
                TEUCHOS_TEST_FOR_EXCEPTION(parent == Teuchos::null, std::invalid_argument, "ancestor not found in inducedMeshTopo");
                int childOrdinal = parent->findChildOrdinal(myCell->cellIndex());
                int numChildren = parent->numChildren();
                hasMatchingChild = ((parent->level() % numChildren) == childOrdinal);
                ancestralCellIndex = parent->cellIndex();
            }
            if (hasMatchingChild)
            {
                myEntries.push_back(ancestralCellIndex);
                myEntries.push_back(myCellID);
            }
        }
    }
    else
    {
        // first child is always owner
        for (GlobalIndexType myCellID : *myCellIDs)
        {
            IndexType ancestralCellIndex = myCellID;
            bool isFirstChild = true;
            while (isFirstChild && !inducedMeshTopo->isValidCellIndex(ancestralCellIndex))
            {
                CellPtr myCell = inducingRefinedMesh->getTopology()->getCell(ancestralCellIndex);
                CellPtr parent = myCell->getParent();
                TEUCHOS_TEST_FOR_EXCEPTION(parent == Teuchos::null, std::invalid_argument, "ancestor not found in inducedMeshTopo");
                int childOrdinal = parent->findChildOrdinal(myCell->cellIndex());
                isFirstChild = (childOrdinal == 0);
                ancestralCellIndex = parent->cellIndex();
            }
            if (isFirstChild)
            {
                myEntries.push_back(ancestralCellIndex);
                myEntries.push_back(myCellID);
            }
        }
    }
    // all-gather the entries
    vector<GlobalIndexTypeToCast> allEntries;
    vector<int> offsets;
    MPIWrapper::allGatherVariable(*inducingRefinedMesh->Comm(), allEntries, myEntries, offsets);

    map<GlobalIndexType,GlobalIndexType> cellIDMap;
    for (int i=0; i<allEntries.size()/2; i++)
    {
        GlobalIndexType ancestralCellIndex = allEntries[2*i+0];
        GlobalIndexType inducingMeshCellID = allEntries[2*i+1];
        cellIDMap[ancestralCellIndex] = inducingMeshCellID;
    }

    return Teuchos::rcp( new InducedMeshPartitionPolicy(inducingRefinedMesh, cellIDMap) );
}