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; }
CellTopoPtrLegacy getBottomTopology(MeshTopologyPtr meshTopo, IndexType cellID) { int spaceDim = meshTopo->getSpaceDim() - 1; // determine cell topology: vector<IndexType> cellVertexIndices = meshTopo->getCell(cellID)->vertices(); set<IndexType> bottomVertexIndices; int bottomNodeCount = cellVertexIndices.size() / 2; for (int i=0; i<bottomNodeCount; i++) { bottomVertexIndices.insert(cellVertexIndices[i]); } IndexType bottomEntityIndex = meshTopo->getEntityIndex(spaceDim, bottomVertexIndices); unsigned bottomCellTopoKey = meshTopo->getEntityTopology(spaceDim, bottomEntityIndex).getKey(); CellTopoPtrLegacy cellTopo = CamelliaCellTools::cellTopoForKey(bottomCellTopoKey); return cellTopo; }
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; }
bool checkConstraints( MeshTopologyPtr mesh, unsigned entityDim, map<unsigned,pair<IndexType,unsigned> > &expectedConstraints, string meshName = "mesh") { bool success = true; // check constraints for entities belonging to active cells set<IndexType> myActiveCells = mesh->getMyActiveCellIndices(); for (IndexType cellIndex : myActiveCells) { CellPtr cell = mesh->getCell(cellIndex); vector<unsigned> entitiesForCell = cell->getEntityIndices(entityDim); for (vector<unsigned>::iterator entityIt = entitiesForCell.begin(); entityIt != entitiesForCell.end(); entityIt++) { unsigned entityIndex = *entityIt; pair<IndexType,unsigned> constrainingEntity = mesh->getConstrainingEntity(entityDim, entityIndex); unsigned constrainingEntityIndex = constrainingEntity.first; unsigned constrainingEntityDim = constrainingEntity.second; if ((constrainingEntityIndex==entityIndex) && (constrainingEntityDim == entityDim)) { // then we should expect not to have an entry in expectedConstraints: if (expectedConstraints.find(entityIndex) != expectedConstraints.end()) { cout << "Expected entity constraint is not imposed in " << meshName << ".\n"; cout << "Expected " << typeString(entityDim) << " " << entityIndex << " to be constrained by "; cout << typeString(expectedConstraints[entityIndex].second) << " " << expectedConstraints[entityIndex].first << endl; cout << typeString(entityDim) << " " << entityIndex << " vertices:\n"; mesh->printEntityVertices(entityDim, entityIndex); cout << typeString(expectedConstraints[entityIndex].second) << " " << expectedConstraints[entityIndex].first << " vertices:\n"; mesh->printEntityVertices(entityDim, expectedConstraints[entityIndex].first); success = false; } } else { if (expectedConstraints.find(entityIndex) == expectedConstraints.end()) { cout << "Unexpected entity constraint is imposed in " << meshName << ".\n"; string entityType; if (entityDim==0) { entityType = "Vertex "; } else if (entityDim==1) { entityType = "Edge "; } else if (entityDim==2) { entityType = "Face "; } else if (entityDim==3) { entityType = "Volume "; } string constrainingEntityType; if (constrainingEntityDim==0) { constrainingEntityType = "Vertex "; } else if (constrainingEntityDim==1) { constrainingEntityType = "Edge "; } else if (constrainingEntityDim==2) { constrainingEntityType = "Face "; } else if (constrainingEntityDim==3) { constrainingEntityType = "Volume "; } cout << entityType << entityIndex << " unexpectedly constrained by " << constrainingEntityType << constrainingEntityIndex << endl; cout << entityType << entityIndex << " vertices:\n"; mesh->printEntityVertices(entityDim, entityIndex); cout << constrainingEntityType << constrainingEntityIndex << " vertices:\n"; mesh->printEntityVertices(constrainingEntityDim, constrainingEntityIndex); success = false; } else { unsigned expectedConstrainingEntity = expectedConstraints[entityIndex].first; if (expectedConstrainingEntity != constrainingEntityIndex) { cout << "The constraining entity is not the expected one in " << meshName << ".\n"; cout << "Expected " << typeString(entityDim) << " " << entityIndex << " to be constrained by "; cout << typeString(expectedConstraints[entityIndex].second) << " " << expectedConstrainingEntity; cout << "; was constrained by " << constrainingEntityIndex << endl; cout << typeString(entityDim) << " " << entityIndex << " vertices:\n"; mesh->printEntityVertices(entityDim, entityIndex); cout << typeString(expectedConstraints[entityIndex].second) << " " << expectedConstrainingEntity << " vertices:\n"; mesh->printEntityVertices(entityDim, expectedConstrainingEntity); cout << typeString(constrainingEntityDim) << " " << constrainingEntityIndex << " vertices:\n"; mesh->printEntityVertices(constrainingEntityDim, constrainingEntityIndex); success = false; } } } } } return success; }