Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

pickBdy.C

Go to the documentation of this file.
00001 
00007 #include "TreeNode.h"
00008 #include "parUtils.h"
00009 
00010 #ifdef __DEBUG__
00011 #ifndef __DEBUG_OCT__
00012 #define __DEBUG_OCT__
00013 #endif
00014 #endif
00015 
00016 namespace ot {
00017 
00018   //Basic idea: Any octant with all possible neighbours inside blocks are
00019   //considered to be stable. This works on the assumption that the blocks are
00020   //internally balanced and inter-block boundaries are also balanced. So if all
00021   //possible neighbours of an octant are inside these blocks, then its entire
00022   //insulation layer is stable. Although, initially developed for checking
00023   //unstable inter-processor boundaries only,this idea is also applicable to
00024   //test stable remote octants in computing sendNodes for stage 2 communication
00025   //for balancing.
00026   //Assumptions: Blocks are sorted and unique and linear, nodes is sorted and unique and linear.
00027   //Every element in nodes is a decendant of or equal to some block.
00028   //Blocks are complete i.e. there are no gaps in the morton-space covered by
00029   //the blocks. 
00030   //Some Blocks may be empty.
00031 
00032 #define PICK_IPBB_SET_TN_VALUE res.push_back(nodes[nodeCnt]);
00033 
00034 #define PICK_IPBB_SET_UI_VALUE res.push_back(nodeCnt);
00035 
00036 #define PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(SetValueLine) {\
00037   res.clear();\
00038   unsigned int dim = firstBlock.getDim();\
00039   unsigned int maxDepth = firstBlock.getMaxDepth();\
00040   ot::TreeNode root(dim, maxDepth);\
00041   for(unsigned int nodeCnt = 0; nodeCnt < nodes.size(); nodeCnt++) {\
00042     unsigned int myMinX = nodes[nodeCnt].minX();\
00043     unsigned int myMinY = nodes[nodeCnt].minY();\
00044     unsigned int myMinZ = nodes[nodeCnt].minZ();\
00045     unsigned int myMaxX = nodes[nodeCnt].maxX();\
00046     unsigned int myMaxY = nodes[nodeCnt].maxY();\
00047     unsigned int myMaxZ = nodes[nodeCnt].maxZ();\
00048     unsigned int myLen = (myMaxX - myMinX);\
00049     unsigned int myLevel = nodes[nodeCnt].getLevel();\
00050     unsigned int negX = ((myMinX > 0) ? (myMinX - myLen) : myMinX);\
00051     unsigned int negY = ((myMinY > 0) ? (myMinY - myLen) : myMinY);\
00052     unsigned int negZ = ((myMinZ > 0) ? (myMinZ - myLen) : myMinZ);\
00053     unsigned int posX = ((myMaxX < (1u << maxDepth)) ? (myMaxX + myLen -1) : (myMaxX-1));\
00054     unsigned int posY = ((myMaxY < (1u << maxDepth)) ? (myMaxY + myLen -1) : (myMaxY-1));\
00055     unsigned int posZ = ((myMaxZ < (1u << maxDepth)) ? (myMaxZ + myLen -1) : (myMaxZ-1));\
00056     ot::TreeNode negCorner(negX, negY, negZ, myLevel, dim, maxDepth);\
00057     ot::TreeNode posCorner(posX, posY, posZ, maxDepth, dim, maxDepth);\
00058     bool add = true;\
00059     if( (negCorner >= firstBlock) && (posCorner <= lastBlock.getDLD()) ) {\
00060       add = false;\
00061     }\
00062     if (add) {\
00063       SetValueLine\
00064     }\
00065   }\
00066   return 1;\
00067 }
00068 
00069 //New Implementation
00070 
00071 int pickInterProcessorBoundaryNodes(const std::vector<ot::TreeNode> & nodes,
00072     std::vector<unsigned int> & res, const ot::TreeNode & firstBlock,
00073     const ot::TreeNode & lastBlock) {
00074   PROF_PICK_BND_BEGIN
00075 
00076   PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(PICK_IPBB_SET_UI_VALUE)
00077 
00078   PROF_PICK_BND_END
00079 }
00080 
00081 int pickInterProcessorBoundaryNodes(const std::vector<ot::TreeNode> & nodes,
00082     std::vector<ot::TreeNode> & res, const ot::TreeNode & firstBlock,
00083     const ot::TreeNode & lastBlock) {
00084   PROF_PICK_BND_BEGIN
00085 
00086   PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(PICK_IPBB_SET_TN_VALUE)
00087   
00088   PROF_PICK_BND_END
00089 }
00090 
00091 
00092 /*
00093 #define PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(SetValueLine) {\
00094 TreeNode root(dim,maxDepth);\
00095 res.clear();\
00096 unsigned int nodeCnt = 0;\
00097 unsigned int blkCnt = 0;\
00098 while ( ( blkCnt < blocks.size() ) && (  nodeCnt < nodes.size() )  ) {\
00099 if ( blocks[blkCnt] <= nodes[nodeCnt] ) {\
00100 *//*Check if Ancestor*//* \        
00101 if ( blocks[blkCnt].isAncestor(nodes[nodeCnt]) ) {\
00102   *//*Check if this node touches the internal boundary of the block.*//* \
00103     unsigned int myMinX = nodes[nodeCnt].minX();\
00104     unsigned int myMinY = nodes[nodeCnt].minY();\
00105     unsigned int myMinZ = nodes[nodeCnt].minZ();\
00106     unsigned int myMaxX = nodes[nodeCnt].maxX();\
00107     unsigned int myMaxY = nodes[nodeCnt].maxY();\
00108     unsigned int myMaxZ = nodes[nodeCnt].maxZ();\
00109     unsigned int bMinX = blocks[blkCnt].minX();\
00110     unsigned int bMinY = blocks[blkCnt].minY();\
00111     unsigned int bMinZ = blocks[blkCnt].minZ();\
00112     unsigned int bMaxX = blocks[blkCnt].maxX();\
00113     unsigned int bMaxY = blocks[blkCnt].maxY();\
00114     unsigned int bMaxZ = blocks[blkCnt].maxZ();\
00115     if ( (myMinX == bMinX) || (myMinY == bMinY) || (myMinZ == bMinZ) ||\
00116         (myMaxX == bMaxX) || (myMaxY == bMaxY) || (myMaxZ == bMaxZ) ) {\
00117       *//*node touches the boundary of this block from the inside*//* \
00118         std::vector<TreeNode> nh = nodes[nodeCnt].getAllNeighbours();\
00119         par::makeVectorUnique<ot::TreeNode>(nh, false);\
00120         unsigned int st = 0;\
00121         if (nh[0] == root) {\
00122           st = 1;\
00123         }\
00124       bool add = true;\
00125         *//*An indirect and cheap way to assert existence*//* \
00126         *//*of an ancestor is to*//* \
00127         *//*compare nh with the span of the domain owned by this processor
00128         *//* \
00129         *//*Note the second condition. You must compare the DLDs on both
00130         sides.*//*\
00131         *//* Just comparing reducedNh with last block or last block's DLD is
00132         not enough*//*\
00133         *//* This is because, the last block could be a decendant of
00134         reducedNh*//*\
00135         if(st < nh.size()) {\
00136           if( (nh[st] >= blocks[0]) &&\
00137               ((nh[nh.size()-1].getDLD())\
00138                <= (blocks[blocks.size()-1].getDLD())) ) {\
00139             add = false;\
00140           }\
00141         } else {\
00142           add = false;\
00143         }\
00144       if (add) {\
00145         SetValueLine\
00146       }\
00147     }\
00148   *//*There could be more nodes that are decendants of the same
00149     block.*//* \
00150     nodeCnt++;\
00151 } else if ( blocks[blkCnt] == nodes[nodeCnt] ) {\
00152   std::vector<TreeNode> nh = nodes[nodeCnt].getAllNeighbours();\
00153     par::makeVectorUnique<TreeNode>(nh,false);\
00154     unsigned int st = 0;\
00155     if (nh[0] == root) {\
00156       st = 1;\
00157     }\
00158   bool add = true;\
00159     *//*An indirect and cheap way to assert existence*//* \
00160     *//*of an ancestor is to*//* \
00161     *//*compare nh with the span of the domain owned by this processor *//* \
00162     if(st < nh.size()) {\
00163       if( (nh[st] >= blocks[0]) &&\
00164           ((nh[nh.size()-1].getDLD())\
00165            <= (blocks[blocks.size()-1].getDLD())) ) {\
00166         add = false;\
00167       }\
00168     } else {\
00169       add = false;\
00170     }\
00171   if (add) {\
00172     SetValueLine\
00173   }\
00174   blkCnt++;\
00175 } else {\
00176   *//*Neither Ancestor nor equal.*//* \
00177     blkCnt++;\
00178 }\
00179   } else {\
00180     *//*Block can't be an Ancestor of the node.*//* \
00181       nodeCnt++;\
00182   }\
00183   }\
00184   return 1;\
00185   }
00186 */
00187 
00188 /*
00189 //Old Implementation
00190 int pickInterProcessorBoundaryNodes(const std::vector<ot::TreeNode> & blocks, 
00191 const std::vector<ot::TreeNode> &nodes, 
00192 std::vector<unsigned int >& res, 
00193 unsigned int dim, unsigned int maxDepth) {
00194 PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(PICK_IPBB_SET_UI_VALUE)
00195 } // end pickboundary
00196 
00197 int pickInterProcessorBoundaryNodes(const std::vector<ot::TreeNode> & blocks, 
00198 const std::vector<ot::TreeNode> &nodes, 
00199 std::vector<ot::TreeNode>& res, 
00200 unsigned int dim, unsigned int maxDepth) {
00201 PICK_INTER_PROCESSOR_BOUNDARY_BLOCK(PICK_IPBB_SET_TN_VALUE)
00202 } // end pickboundary
00203 */
00204 
00205 #undef PICK_IPBB_SET_TN_VALUE 
00206 #undef PICK_IPBB_SET_UI_VALUE 
00207 #undef PICK_INTER_PROCESSOR_BOUNDARY_BLOCK
00208 
00209 
00210 // Oldest Implementation ...  
00211 /*
00212    int pickInterProcessorBoundaryNodes(const std::vector<ot::TreeNode> & blocks, const std::vector<ot::TreeNode> &nodes, std::vector<ot::TreeNode>& res, unsigned int dim, unsigned int maxDepth){
00213    TreeNode root(dim,maxDepth);
00214    unsigned int resLen=0;
00215    res.resize(nodes.size());
00216    for(unsigned int i=0;i<nodes.size();i++) {
00217 //A node is considered stable only if it is stable in all directions.
00218 std::vector<TreeNode> nh = nodes[i].getAllNeighbours();
00219 bool add=false;
00220 for(unsigned int k=0;k<nh.size();k++) {
00221 if(nh[k]==root){
00222 //Stable from this direction 
00223 continue;
00224 }
00225 bool foundAnc = false;
00226 for(unsigned int j=0;j<blocks.size();j++) {
00227 if((blocks[j] == nh[k]) || (blocks[j].isAncestor(nh[k]))){
00228 foundAnc=true;
00229 break;
00230 }
00231 }//end for j
00232 if(!foundAnc) {
00233 //Unstable from this direction 
00234 add=true;
00235 break;
00236 }
00237 }//end for k
00238 if(add){
00239 res[resLen] = nodes[i];
00240 resLen++;
00241 }
00242 }//end for i
00243 res.resize(resLen);
00244 return 1;
00245 }//end function
00246 */
00247 
00248 }//end namespace
00249 
00250 
00251 

Generated on Tue Mar 24 16:14:05 2009 for DENDRO by  doxygen 1.3.9.1