Exemple #1
0
MeshPtr MeshTools::timeSliceMesh(MeshPtr spaceTimeMesh, double t,
                                 map<GlobalIndexType, GlobalIndexType> &sliceCellIDToSpaceTimeCellID, int H1OrderForSlice) {
  MeshTopologyPtr meshTopo = spaceTimeMesh->getTopology();
  set<IndexType> cellIDsToCheck = meshTopo->getRootCellIndices();
  set<IndexType> activeCellIDsForTime;
  
  set<IndexType> allActiveCellIDs = meshTopo->getActiveCellIndices();
  
  int spaceDim = meshTopo->getSpaceDim() - 1;  // # of true spatial dimensions
  
  MeshTopologyPtr sliceTopo = Teuchos::rcp( new MeshTopology(spaceDim) );
  set<IndexType> rootCellIDs = meshTopo->getRootCellIndices();
  for (set<IndexType>::iterator rootCellIt = rootCellIDs.begin(); rootCellIt != rootCellIDs.end(); rootCellIt++) {
    IndexType rootCellID = *rootCellIt;
    FieldContainer<double> physicalNodes = spaceTimeMesh->physicalCellNodesForCell(rootCellID);
    if (cellMatches(physicalNodes, t)) { // cell and some subset of its descendents should be included in slice mesh
      vector< vector< double > > sliceNodes = timeSliceForCell(physicalNodes, t);
      CellTopoPtrLegacy cellTopo = getBottomTopology(meshTopo, rootCellID);
      CellPtr sliceCell = sliceTopo->addCell(cellTopo, sliceNodes);
      sliceCellIDToSpaceTimeCellID[sliceCell->cellIndex()] = rootCellID;
    }
  }
  
  MeshPtr sliceMesh = Teuchos::rcp( new Mesh(sliceTopo, spaceTimeMesh->bilinearForm(), H1OrderForSlice, spaceDim) );
  
  // process refinements.  For now, we assume isotropic refinements, which means that each refinement in spacetime induces a refinement in the spatial slice
  set<IndexType> sliceCellIDsToCheckForRefinement = sliceTopo->getActiveCellIndices();
  while (sliceCellIDsToCheckForRefinement.size() > 0) {
    set<IndexType>::iterator cellIt = sliceCellIDsToCheckForRefinement.begin();
    IndexType sliceCellID = *cellIt;
    sliceCellIDsToCheckForRefinement.erase(cellIt);
    
    CellPtr sliceCell = sliceTopo->getCell(sliceCellID);
    CellPtr spaceTimeCell = meshTopo->getCell(sliceCellIDToSpaceTimeCellID[sliceCellID]);
    if (spaceTimeCell->isParent()) {
      set<GlobalIndexType> cellsToRefine;
      cellsToRefine.insert(sliceCellID);
      sliceMesh->hRefine(cellsToRefine, RefinementPattern::regularRefinementPattern(sliceCell->topology()->getKey()));
      vector<IndexType> spaceTimeChildren = spaceTimeCell->getChildIndices();
      for (int childOrdinal=0; childOrdinal<spaceTimeChildren.size(); childOrdinal++) {
        IndexType childID = spaceTimeChildren[childOrdinal];
        FieldContainer<double> childNodes = meshTopo->physicalCellNodesForCell(childID);
        if (cellMatches(childNodes, t)) {
          vector< vector<double> > childSlice = timeSliceForCell(childNodes, t);
          CellPtr childSliceCell = sliceTopo->findCellWithVertices(childSlice);
          sliceCellIDToSpaceTimeCellID[childSliceCell->cellIndex()] = childID;
          sliceCellIDsToCheckForRefinement.insert(childSliceCell->cellIndex());
        }
      }
    }
  }
  
  return sliceMesh;
}
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) );
}
Exemple #3
0
MeshPtr MeshTools::timeSliceMesh(MeshPtr spaceTimeMesh, double t,
                                 map<GlobalIndexType, GlobalIndexType> &sliceCellIDToSpaceTimeCellID, int H1OrderForSlice)
{
  MeshTopology* meshTopo = dynamic_cast<MeshTopology*>(spaceTimeMesh->getTopology().get());
  TEUCHOS_TEST_FOR_EXCEPTION(!meshTopo, std::invalid_argument, "timeSliceMesh() called with spaceTimeMesh that appears to be pure MeshTopologyView.  This is not supported.");
  set<IndexType> cellIDsToCheck = meshTopo->getRootCellIndices();
  set<IndexType> activeCellIDsForTime;

  set<IndexType> allActiveCellIDs = meshTopo->getActiveCellIndices();

  int spaceDim = meshTopo->getDimension() - 1;  // # of true spatial dimensions

  MeshTopologyPtr sliceTopo = Teuchos::rcp( new MeshTopology(spaceDim) );
  set<IndexType> rootCellIDs = meshTopo->getRootCellIndices();
  for (set<IndexType>::iterator rootCellIt = rootCellIDs.begin(); rootCellIt != rootCellIDs.end(); rootCellIt++)
  {
    IndexType rootCellID = *rootCellIt;
    FieldContainer<double> physicalNodes = spaceTimeMesh->physicalCellNodesForCell(rootCellID);
    if (cellMatches(physicalNodes, t))   // cell and some subset of its descendents should be included in slice mesh
    {
      vector< vector< double > > sliceNodes = timeSliceForCell(physicalNodes, t);
      CellTopoPtr cellTopo = getBottomTopology(meshTopo, rootCellID);
      GlobalIndexType newCellID = sliceTopo->cellCount();
      CellPtr sliceCell = sliceTopo->addCell(newCellID, cellTopo, sliceNodes); // for consistency, this is only valid if run on every MPI rank.
      sliceCellIDToSpaceTimeCellID[sliceCell->cellIndex()] = rootCellID;
    }
  }

  MeshPtr sliceMesh = Teuchos::rcp( new Mesh(sliceTopo, spaceTimeMesh->bilinearForm(), H1OrderForSlice, spaceDim) );

  // process refinements.  For now, we assume isotropic refinements, which means that each refinement in spacetime induces a refinement in the spatial slice
  set<IndexType> sliceCellIDsToCheckForRefinement = sliceTopo->getActiveCellIndices();
  while (sliceCellIDsToCheckForRefinement.size() > 0)
  {
    set<IndexType>::iterator cellIt = sliceCellIDsToCheckForRefinement.begin();
    IndexType sliceCellID = *cellIt;
    sliceCellIDsToCheckForRefinement.erase(cellIt);

    CellPtr sliceCell = sliceTopo->getCell(sliceCellID);
    CellPtr spaceTimeCell = meshTopo->getCell(sliceCellIDToSpaceTimeCellID[sliceCellID]);
    if (spaceTimeCell->isParent(spaceTimeMesh->getTopology()))
    {
      set<GlobalIndexType> cellsToRefine;
      cellsToRefine.insert(sliceCellID);
      sliceMesh->hRefine(cellsToRefine, RefinementPattern::regularRefinementPattern(sliceCell->topology()));
      vector<IndexType> spaceTimeChildren = spaceTimeCell->getChildIndices(spaceTimeMesh->getTopology());
      for (int childOrdinal=0; childOrdinal<spaceTimeChildren.size(); childOrdinal++)
      {
        IndexType childID = spaceTimeChildren[childOrdinal];
        FieldContainer<double> childNodes = meshTopo->physicalCellNodesForCell(childID);
        if (cellMatches(childNodes, t))
        {
          vector< vector<double> > childSlice = timeSliceForCell(childNodes, t);
          CellPtr childSliceCell = sliceTopo->findCellWithVertices(childSlice);
          sliceCellIDToSpaceTimeCellID[childSliceCell->cellIndex()] = childID;
          sliceCellIDsToCheckForRefinement.insert(childSliceCell->cellIndex());
        }
      }
    }
  }

  MeshPartitionPolicyPtr partitionPolicy = MeshPartitionPolicy::inducedPartitionPolicy(sliceMesh, spaceTimeMesh, sliceCellIDToSpaceTimeCellID);

  sliceMesh->setPartitionPolicy(partitionPolicy);

  return sliceMesh;
}