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; }
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; }