void LocalMultiBlockInfo3D::computePeriodicOverlaps ( SparseBlockStructure3D const& sparseBlock, plint blockId ) { Box3D intersection; // Temporary variable. std::vector<plint> neighbors; // Temporary variable. SmartBulk3D bulk(sparseBlock, envelopeWidth, blockId); for (plint dx=-1; dx<=+1; dx+=1) { for (plint dy=-1; dy<=+1; dy+=1) { for (plint dz=-1; dz<=+1; dz+=1) { if (dx!=0 || dy!=0 || dz!=0) { // The new block is shifted by the length of the full multi block in each space // direction. Consequently, overlaps between the original multi block and the // shifted new block are identified as periodic overlaps. plint shiftX = dx*sparseBlock.getBoundingBox().getNx(); plint shiftY = dy*sparseBlock.getBoundingBox().getNy(); plint shiftZ = dz*sparseBlock.getBoundingBox().getNz(); Box3D shiftedBulk(bulk.getBulk().shift(shiftX,shiftY,shiftZ)); Box3D shiftedEnvelope(bulk.computeEnvelope().shift(shiftX,shiftY,shiftZ)); // Speed optimization: perform following checks only if the shifted // domain touches the bounding box. Box3D dummyIntersection; if (intersect(shiftedEnvelope, sparseBlock.getBoundingBox(), dummyIntersection)) { neighbors.clear(); sparseBlock.findNeighbors(shiftedBulk, envelopeWidth, neighbors); // Check overlap with each existing block in the neighborhood, including with the newly added one. for (pluint iNeighbor=0; iNeighbor<neighbors.size(); ++iNeighbor) { plint neighborId = neighbors[iNeighbor]; SmartBulk3D neighborBulk(sparseBlock, envelopeWidth, neighborId); // Does the envelope of the shifted new block overlap with the bulk of a previous // block? If yes, add an overlap, in which the previous block has the "original // position", and the new block has the "overlap position". if (intersect(neighborBulk.getBulk(), shiftedEnvelope, intersection)) { PeriodicOverlap3D overlap ( Overlap3D(neighborId, blockId, intersection, shiftX, shiftY, shiftZ), dx, dy, dz ); periodicOverlaps.push_back(overlap); periodicOverlapWithRemoteData.push_back(overlap); } // Does the bulk of the shifted new block overlap with the envelope of a previous // block? If yes, add an overlap, in which the new block has the "original position", // and the previous block has the "overlap position". // If we are in the situation in which the newly added block is periodic with itself, // this step must be skipped, because otherwise the overlap is counted twice. if (!(neighborId==blockId) && intersect(shiftedBulk, neighborBulk.computeEnvelope(), intersection)) { intersection = intersection.shift(-shiftX,-shiftY, -shiftZ); periodicOverlaps.push_back ( PeriodicOverlap3D ( Overlap3D(blockId, neighborId, intersection, -shiftX, -shiftY, -shiftZ), -dx, -dy, -dz ) ); } } } } } } } }
Box3D SmartBulk3D::toLocal(Box3D const& coord) const { return Box3D( coord.shift(-bulk.x0+envelopeWidth, -bulk.y0+envelopeWidth, -bulk.z0+envelopeWidth) ); }