BoxCollection.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 #include "BoxCollection.hpp"
00029 
00031 // Box methods
00033 
00034 
00035 template<unsigned DIM>
00036 Box<DIM>::Box(c_vector<double, 2*DIM>& rMinAndMaxValues)
00037 {
00038     mMinAndMaxValues = rMinAndMaxValues;
00039 }
00040 
00041 template<unsigned DIM>
00042 c_vector<double, 2*DIM>& Box<DIM>::rGetMinAndMaxValues()
00043 {
00044     return mMinAndMaxValues;
00045 }
00046 
00047 template<unsigned DIM>
00048 void Box<DIM>::AddNode(Node<DIM>* pNode)
00049 {
00050     mNodesContained.insert(pNode);
00051 }
00052 
00053 template<unsigned DIM>
00054 void Box<DIM>::RemoveNode(Node<DIM>* pNode)
00055 {
00056     mNodesContained.erase(pNode);
00057 }
00058 
00059 template<unsigned DIM>
00060 std::set< Node<DIM>* >& Box<DIM>::rGetNodesContained()
00061 {
00062     return mNodesContained;
00063 }
00064 
00065 template<unsigned DIM>
00066 void Box<DIM>::AddElement(Element<DIM,DIM>* pElement)
00067 {
00068     mElementsContained.insert(pElement);
00069 }
00070 
00071 template<unsigned DIM>
00072 std::set< Element<DIM,DIM>* >& Box<DIM>::rGetElementsContained()
00073 {
00074     return mElementsContained;
00075 }
00076 
00077 
00079 // BoxCollection methods
00081 
00082 
00083 template<unsigned DIM>
00084 BoxCollection<DIM>::BoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize)
00085     : mDomainSize(domainSize),
00086       mBoxWidth(boxWidth)
00087 {
00088     /*
00089      * Start by calculating the number of boxes in each direction and total number of boxes.
00090      * Also create a helper vector of coefficients, whose first entry is 1 and whose i-th
00091      * entry (for i>1) is the i-th partial product of the vector mNumBoxesEachDirection. This
00092      * vector of coefficients will be used in the next code block to compute how many boxes
00093      * along in each dimension each box, given its index.
00094      */
00095     unsigned num_boxes = 1;
00096     std::vector<unsigned> coefficients;
00097     coefficients.push_back(1);
00098 
00099     for (unsigned i=0; i<DIM; i++)
00100     {
00101         mNumBoxesEachDirection(i) = (unsigned)((domainSize(2*i+1) - domainSize(2*i))/boxWidth) + 1;
00102         num_boxes *= mNumBoxesEachDirection(i);
00103         coefficients.push_back(coefficients[i]*mNumBoxesEachDirection(i));
00104     }
00105 
00106     for (unsigned box_index=0; box_index<num_boxes; box_index++)
00107     {
00108         /*
00109          * The code block below computes how many boxes along in each dimension the
00110          * current box is and stores this information in the second, ..., (DIM+1)th
00111          * entries of the vector current_box_indices. The first entry of
00112          * current_box_indices is zero to ensure that the for loop works correctly.
00113          *
00114          * Our convention is that in 3D the index of each box, box_index, is related
00115          * to its indices (i,j,k) by
00116          *
00117          * box_index = i + mNumBoxesEachDirection(0)*j
00118          *               + mNumBoxesEachDirection(0)*mNumBoxesEachDirection(1)*k,
00119          *
00120          * while in 2D, box_index is related to (i,j) by
00121          *
00122          * box_index = i + mNumBoxesEachDirection(0)*j
00123          *
00124          * and in 1D we simply have box_index = i.
00125          */
00126         c_vector<unsigned, DIM+1> current_box_indices;
00127         current_box_indices[0] = 0;
00128 
00129         for (unsigned i=0; i<DIM; i++)
00130         {
00131             unsigned temp = 0;
00132             for (unsigned j=1; j<i; j++)
00133             {
00134                 temp += coefficients[j]*current_box_indices[j-1];
00135             }
00136             current_box_indices[i+1] = (box_index%coefficients[i+1] - temp)/coefficients[i];
00137         }
00138 
00139         /*
00140          * We now use the information stores in current_box_indices to construct the
00141          * Box, which we add to mBoxes.
00142          */
00143         c_vector<double, 2*DIM> box_coords;
00144         for (unsigned l=0; l<DIM; l++)
00145         {
00146             box_coords(2*l) = domainSize(2*l) + current_box_indices(l+1)*boxWidth;
00147             box_coords(2*l+1) = domainSize(2*l) + (current_box_indices(l+1)+1)*boxWidth;
00148         }
00149 
00150         Box<DIM> new_box(box_coords);
00151         mBoxes.push_back(new_box);
00152     }
00153 
00154     // Check that we have the correct number of boxes
00155     assert(num_boxes == mBoxes.size());
00156 }
00157 
00158 template<unsigned DIM>
00159 unsigned BoxCollection<DIM>::CalculateContainingBox(Node<DIM>* pNode)
00160 {
00161     // Get the location of the node
00162     c_vector<double, DIM> location = pNode->rGetLocation();
00163     return CalculateContainingBox(location);
00164 }
00165 
00166 
00167 template<unsigned DIM>
00168 unsigned BoxCollection<DIM>::CalculateContainingBox(c_vector<double, DIM>& rLocation)
00169 {
00170     // The node must lie inside the boundary of the box collection
00171     for (unsigned i=0; i<DIM; i++)
00172     {
00173         if( (rLocation[i] < mDomainSize(2*i)) || (rLocation[i] > mDomainSize(2*i+1)) )
00174         {
00175             EXCEPTION("The point provided in outside all of the boxes");
00176         }
00177     }
00178 
00179     // Compute the containing box index in each dimension
00180     c_vector<unsigned, DIM> containing_box_indices;
00181     for (unsigned i=0; i<DIM; i++)
00182     {
00183         containing_box_indices[i] = (unsigned) floor((rLocation[i] - mDomainSize(2*i))/mBoxWidth);
00184     }
00185 
00186     // Use these to compute the index of the containing box
00187     unsigned containing_box_index = 0;
00188     for (unsigned i=0; i<DIM; i++)
00189     {
00190         unsigned temp = 1;
00191         for (unsigned j=0; j<i; j++)
00192         {
00193             temp *= mNumBoxesEachDirection(j);
00194         }
00195         containing_box_index += temp*containing_box_indices[i];
00196     }
00197 
00198     // This index must be less than the number of boxes
00199     assert(containing_box_index < mBoxes.size());
00200 
00201     return containing_box_index;
00202 }
00203 
00204 template<unsigned DIM>
00205 Box<DIM>& BoxCollection<DIM>::rGetBox(unsigned boxIndex)
00206 {
00207     assert(boxIndex < mBoxes.size());
00208     return mBoxes[boxIndex];
00209 }
00210 
00211 template<unsigned DIM>
00212 unsigned BoxCollection<DIM>::GetNumBoxes()
00213 {
00214     return mBoxes.size();
00215 }
00216 
00217 template<unsigned DIM>
00218 void BoxCollection<DIM>::SetupLocalBoxesHalfOnly()
00219 {
00220     switch (DIM)
00221     {
00222         case 1:
00223         {
00224             // We only need to look for neighbours in the current and successive boxes
00225             mLocalBoxes.clear();
00226             for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00227             {
00228                 std::set<unsigned> local_boxes;
00229 
00230                 // Insert the current box
00231                 local_boxes.insert(box_index);
00232 
00233                 // If we're not at the right-most box, then insert the box to the right
00234                 if (box_index < mNumBoxesEachDirection(0)-1)
00235                 {
00236                     local_boxes.insert(box_index+1);
00237                 }
00238                 mLocalBoxes.push_back(local_boxes);
00239             }
00240             break;
00241         }
00242         case 2:
00243         {
00244             // We only need to look for neighbours in the current box and half the neighbouring boxes
00245             mLocalBoxes.clear();
00246             for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00247             {
00248                 std::set<unsigned> local_boxes;
00249 
00250                 // Insert the current box
00251                 local_boxes.insert(box_index);
00252 
00253                 // If we're not on the top-most row, then insert the box above
00254                 if (box_index < mBoxes.size() - mNumBoxesEachDirection(0))
00255                 {
00256                     local_boxes.insert(box_index + mNumBoxesEachDirection(0));
00257 
00258                     // If we're also not on the left-most column, then insert the box above-left
00259                     if (box_index % mNumBoxesEachDirection(0) != 0)
00260                     {
00261                         local_boxes.insert(box_index + mNumBoxesEachDirection(0) - 1);
00262                     }
00263                 }
00264                 // If we're not on the right-most column, then insert the box to the right
00265                 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00266                 {
00267                     local_boxes.insert(box_index + 1);
00268 
00269                     // If we're also not on the top-most row, then insert the box above-right
00270                     if (box_index < mBoxes.size() - mNumBoxesEachDirection(0))
00271                     {
00272                         local_boxes.insert(box_index + mNumBoxesEachDirection(0) + 1);
00273                     }
00274                 }
00275 
00276                 mLocalBoxes.push_back(local_boxes);
00277             }
00278             break;
00279         }
00280         case 3:
00281         {
00282             // We only need to look for neighbours in the current box and half the neighbouring boxes
00283             mLocalBoxes.clear();
00284             unsigned num_boxes_xy = mNumBoxesEachDirection(0)*mNumBoxesEachDirection(1);
00285 
00286             for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00287             {
00288                 std::set<unsigned> local_boxes;
00289 
00290                 // Insert the current box
00291                 local_boxes.insert(box_index);
00292 
00293                 // If we're not on the far face (y max), then insert the far box
00294                 if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00295                 {
00296                     local_boxes.insert(box_index + mNumBoxesEachDirection(0));
00297 
00298                     // If we're also not on the left face (x min), then insert the box to the left
00299                     if (box_index % mNumBoxesEachDirection(0) != 0)
00300                     {
00301                         local_boxes.insert(box_index + mNumBoxesEachDirection(0) - 1);
00302                     }
00303                 }
00304                 // If we're not on the right face (x max), then insert the box to the right
00305                 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00306                 {
00307                     local_boxes.insert(box_index + 1);
00308 
00309                     // If we're also not on the far face (y max) row, then insert the box to the far-right
00310                     if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00311                     {
00312                         local_boxes.insert(box_index + mNumBoxesEachDirection(0) + 1);
00313                     }
00314                 }
00315                 // If we're not on the top face (z max), then insert the box above
00316                 if (box_index < mBoxes.size() - num_boxes_xy)
00317                 {
00318                     local_boxes.insert(box_index + num_boxes_xy);
00319 
00320                     // If we're also not on the far face (y max), then insert the above-far box
00321                     if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00322                     {
00323                         local_boxes.insert(box_index + num_boxes_xy + mNumBoxesEachDirection(0));
00324 
00325                         // If we're also not on the left face (x min), then insert the box to the above-left
00326                         if (box_index % mNumBoxesEachDirection(0) != 0)
00327                         {
00328                             local_boxes.insert(box_index + num_boxes_xy + mNumBoxesEachDirection(0) - 1);
00329                         }
00330                     }
00331                     // If we're also not on the right face (x max), then insert the box to the above-right
00332                     if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00333                     {
00334                         local_boxes.insert(box_index + num_boxes_xy + 1);
00335 
00336                         // If we're also not on the far face (y max) row, then insert the box to the above-far-right
00337                         if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00338                         {
00339                             local_boxes.insert(box_index + num_boxes_xy + mNumBoxesEachDirection(0) + 1);
00340                         }
00341                     }
00342                 }
00343                 // If we're not on the bottom face (z min), then insert the box above
00344                 if (box_index >= num_boxes_xy)
00345                 {
00346                     local_boxes.insert(box_index - num_boxes_xy);
00347 
00348                     // If we're also not on the far face (y max), then insert the below-far box
00349                     if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00350                     {
00351                         local_boxes.insert(box_index - num_boxes_xy + mNumBoxesEachDirection(0));
00352 
00353                         // If we're also not on the left face (x min), then insert the box to the below-left
00354                         if (box_index % mNumBoxesEachDirection(0) != 0)
00355                         {
00356                             local_boxes.insert(box_index - num_boxes_xy + mNumBoxesEachDirection(0) - 1);
00357                         }
00358                     }
00359                     // If we're also not on the right face (x max), then insert the box to the below-right
00360                     if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00361                     {
00362                         local_boxes.insert(box_index - num_boxes_xy + 1);
00363 
00364                         // If we're also not on the far face (y max) row, then insert the box to the below-far-right
00365                         if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00366                         {
00367                             local_boxes.insert(box_index - num_boxes_xy + mNumBoxesEachDirection(0) + 1);
00368                         }
00369                     }
00370                 }
00371                 mLocalBoxes.push_back(local_boxes);
00372             }
00373             break;
00374         }
00375         default:
00376             NEVER_REACHED;
00377     }
00378 }
00379 
00380 
00381 
00382 template<unsigned DIM>
00383 void BoxCollection<DIM>::SetupAllLocalBoxes()
00384 {
00385     switch (DIM)
00386     {
00387         case 1:
00388         {
00389             for (unsigned i=0; i<mBoxes.size(); i++)
00390             {
00391                 std::set<unsigned> local_boxes;
00392 
00393                 local_boxes.insert(i);
00394              
00395                 // add the two neighbours   
00396                 if(i!=0)
00397                 {
00398                     local_boxes.insert(i-1);
00399                 }
00400                 if(i+1 != mNumBoxesEachDirection(0))
00401                 {
00402                     local_boxes.insert(i+1);
00403                 }
00404                 
00405                 mLocalBoxes.push_back(local_boxes);
00406             }
00407             break;
00408         }
00409         case 2:
00410         {
00411             mLocalBoxes.clear();
00412             
00413             unsigned M = mNumBoxesEachDirection(0);
00414             unsigned N = mNumBoxesEachDirection(1);
00415 
00416             std::vector<bool> is_xmin(N*M); // far left
00417             std::vector<bool> is_xmax(N*M); // far right
00418             std::vector<bool> is_ymin(N*M); // bottom
00419             std::vector<bool> is_ymax(N*M); // top
00420             
00421             for(unsigned i=0; i<M*N; i++)
00422             {
00423                 is_xmin[i] = (i%M==0);
00424                 is_xmax[i] = ((i+1)%M==0);
00425                 is_ymin[i] = (i%(M*N)<M);
00426                 is_ymax[i] = (i%(M*N)>=(N-1)*M);
00427             }
00428 
00429             for (unsigned i=0; i<mBoxes.size(); i++)
00430             {
00431                 std::set<unsigned> local_boxes;
00432 
00433                 local_boxes.insert(i);
00434                 
00435                 // add the box to the left
00436                 if(!is_xmin[i])
00437                 {
00438                     local_boxes.insert(i-1);
00439                 }
00440         
00441                 // add the box to the right
00442                 if(!is_xmax[i])
00443                 {
00444                     local_boxes.insert(i+1);
00445                 }
00446                 
00447                 // add the one below
00448                 if(!is_ymin[i])
00449                 {
00450                     local_boxes.insert(i-M);
00451                 }
00452                 
00453                 // add the one above
00454                 if(!is_ymax[i])
00455                 {
00456                     local_boxes.insert(i+M);
00457                 }
00458                 
00459                 // add the four corner boxes
00460         
00461                 if( (!is_xmin[i]) && (!is_ymin[i]) )
00462                 {
00463                     local_boxes.insert(i-1-M);
00464                 }
00465         
00466                 if( (!is_xmin[i]) && (!is_ymax[i]) )
00467                 {
00468                     local_boxes.insert(i-1+M);
00469                 }
00470         
00471                 if( (!is_xmax[i]) && (!is_ymin[i]) )
00472                 {
00473                     local_boxes.insert(i+1-M);
00474                 }
00475         
00476                 if( (!is_xmax[i]) && (!is_ymax[i]) )
00477                 {
00478                     local_boxes.insert(i+1+M);
00479                 }
00480 
00481                 mLocalBoxes.push_back(local_boxes);
00482             }
00483             break;
00484         }
00485         case 3:
00486         {
00487             mLocalBoxes.clear();
00488             
00489             unsigned M = mNumBoxesEachDirection(0);
00490             unsigned N = mNumBoxesEachDirection(1);
00491             unsigned P = mNumBoxesEachDirection(2);
00492 
00493             std::vector<bool> is_xmin(N*M*P); // far left
00494             std::vector<bool> is_xmax(N*M*P); // far right
00495             std::vector<bool> is_ymin(N*M*P); // nearest
00496             std::vector<bool> is_ymax(N*M*P); // furthest
00497             std::vector<bool> is_zmin(N*M*P); // bottom layer
00498             std::vector<bool> is_zmax(N*M*P); // top layer
00499     
00500             for(unsigned i=0; i<M*N*P; i++)
00501             {
00502                 is_xmin[i] = (i%M==0);
00503                 is_xmax[i] = ((i+1)%M==0);
00504                 is_ymin[i] = (i%(M*N)<M);
00505                 is_ymax[i] = (i%(M*N)>=(N-1)*M);
00506                 is_zmin[i] = (i<M*N);
00507                 is_zmax[i] = (i>=M*N*(P-1));
00508             }
00509 
00510             for (unsigned i=0; i<mBoxes.size(); i++)
00511             {
00512                 std::set<unsigned> local_boxes;
00513 
00514                 // add itself as a local box
00515                 local_boxes.insert(i);
00516                 
00517                 // now add all 26 other neighbours.....
00518                 
00519                 // add the box left
00520                 if(!is_xmin[i])
00521                 {
00522                     local_boxes.insert(i-1);
00523                     
00524                     // plus some others towards the left
00525                     if(!is_ymin[i])
00526                     {
00527                         local_boxes.insert(i-1-M);
00528                     }
00529         
00530                     if(!is_ymax[i])
00531                     {
00532                         local_boxes.insert(i-1+M);
00533                     }
00534         
00535                     if(!is_zmin[i])
00536                     {
00537                         local_boxes.insert(i-1-M*N);
00538                     }
00539         
00540                     if(!is_zmax[i])
00541                     {
00542                         local_boxes.insert(i-1+M*N);
00543                     }
00544                 }
00545         
00546                 // add the box to the right
00547                 if(!is_xmax[i])
00548                 {
00549                     local_boxes.insert(i+1);
00550 
00551                     // plus some others towards the right
00552                     if(!is_ymin[i])
00553                     {
00554                         local_boxes.insert(i+1-M);
00555                     }
00556         
00557                     if(!is_ymax[i])
00558                     {
00559                         local_boxes.insert(i+1+M);
00560                     }
00561         
00562                     if(!is_zmin[i])
00563                     {
00564                         local_boxes.insert(i+1-M*N);
00565                     }
00566         
00567                     if(!is_zmax[i])
00568                     {
00569                         local_boxes.insert(i+1+M*N);
00570                     }
00571                 }
00572                 
00573                 // add the boxes next along the y axis
00574                 if(!is_ymin[i])
00575                 {
00576                     local_boxes.insert(i-M);
00577                     
00578                     // and more in this plane
00579                     if(!is_zmin[i])
00580                     {
00581                         local_boxes.insert(i-M-M*N);
00582                     }
00583         
00584                     if(!is_zmax[i])
00585                     {
00586                         local_boxes.insert(i-M+M*N);
00587                     }
00588                 }
00589                 
00590                 // add the boxes next along the y axis
00591                 if(!is_ymax[i])
00592                 {
00593                     local_boxes.insert(i+M);
00594         
00595                     // and more in this plane
00596                     if(!is_zmin[i])
00597                     {
00598                         local_boxes.insert(i+M-M*N);
00599                     }
00600         
00601                     if(!is_zmax[i])
00602                     {
00603                         local_boxes.insert(i+M+M*N);
00604                     }
00605                 }
00606                 
00607                 // add the box directly above
00608                 if(!is_zmin[i])
00609                 {
00610                     local_boxes.insert(i-N*M);
00611                 }            
00612                 
00613                 // add the box directly below
00614                 if(!is_zmax[i])
00615                 {
00616                     local_boxes.insert(i+N*M);
00617                 }
00618         
00619                 // finally, the 8 corners are left
00620         
00621                 if( (!is_xmin[i]) && (!is_ymin[i]) && (!is_zmin[i]) )
00622                 {
00623                     local_boxes.insert(i-1-M-M*N);
00624                 }
00625         
00626                 if( (!is_xmin[i]) && (!is_ymin[i]) && (!is_zmax[i]) )
00627                 {
00628                     local_boxes.insert(i-1-M+M*N);
00629                 }
00630         
00631                 if( (!is_xmin[i]) && (!is_ymax[i]) && (!is_zmin[i]) )
00632                 {
00633                     local_boxes.insert(i-1+M-M*N);
00634                 }
00635         
00636                 if( (!is_xmin[i]) && (!is_ymax[i]) && (!is_zmax[i]) )
00637                 {
00638                     local_boxes.insert(i-1+M+M*N);
00639                 }
00640         
00641                 if( (!is_xmax[i]) && (!is_ymin[i]) && (!is_zmin[i]) )
00642                 {
00643                     local_boxes.insert(i+1-M-M*N);
00644                 }
00645         
00646                 if( (!is_xmax[i]) && (!is_ymin[i]) && (!is_zmax[i]) )
00647                 {
00648                     local_boxes.insert(i+1-M+M*N);
00649                 }
00650         
00651                 if( (!is_xmax[i]) && (!is_ymax[i]) && (!is_zmin[i]) )
00652                 {
00653                     local_boxes.insert(i+1+M-M*N);
00654                 }
00655         
00656                 if( (!is_xmax[i]) && (!is_ymax[i]) && (!is_zmax[i]) )
00657                 {
00658                     local_boxes.insert(i+1+M+M*N);
00659                 }
00660 
00661                 mLocalBoxes.push_back(local_boxes);
00662             }
00663             break;
00664         }
00665         default:
00666             NEVER_REACHED;
00667     }
00668 }
00669 
00670 
00671 
00672 
00673 
00674 template<unsigned DIM>
00675 std::set<unsigned> BoxCollection<DIM>::GetLocalBoxes(unsigned boxIndex)
00676 {
00677     assert(boxIndex < mLocalBoxes.size());
00678     return mLocalBoxes[boxIndex];
00679 }
00680 
00681 template<unsigned DIM>
00682 void BoxCollection<DIM>::CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::set<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs)
00683 {
00684     rNodePairs.clear();
00685     for (unsigned node_index=0; node_index<rNodes.size(); node_index++)
00686     {
00687         // Get the box containing this node
00688         unsigned box_index = CalculateContainingBox(rNodes[node_index]);
00689 
00690         // Get the local boxes to this node
00691         std::set<unsigned> local_boxes_indices = GetLocalBoxes(box_index);
00692 
00693         // Loop over all the local boxes
00694         for (std::set<unsigned>::iterator box_iter = local_boxes_indices.begin();
00695              box_iter != local_boxes_indices.end();
00696              box_iter++)
00697         {
00698             // Get the set of nodes contained in this box
00699             std::set< Node<DIM>* >& r_contained_nodes = mBoxes[*box_iter].rGetNodesContained();
00700 
00701             // Loop over these nodes
00702             for (typename std::set<Node<DIM>*>::iterator node_iter = r_contained_nodes.begin();
00703                  node_iter != r_contained_nodes.end();
00704                  ++node_iter)
00705             {
00706                 // Get the index of the other node
00707                 unsigned other_node_index = (*node_iter)->GetIndex();
00708 
00709                 // If we're in the same box, then take care not to store the node pair twice
00710                 if (*box_iter == box_index)
00711                 {
00712                     if (other_node_index > node_index)
00713                     {
00714                         rNodePairs.insert(std::pair<Node<DIM>*, Node<DIM>*>(rNodes[node_index], rNodes[other_node_index]));
00715                     }
00716                 }
00717                 else
00718                 {
00719                     rNodePairs.insert(std::pair<Node<DIM>*, Node<DIM>*>(rNodes[node_index], rNodes[other_node_index]));
00720                 }
00721             }
00722         }
00723     }
00724 }
00725 
00727 // Explicit instantiation
00729 
00730 template class Box<1>;
00731 template class Box<2>;
00732 template class Box<3>;
00733 template class BoxCollection<1>;
00734 template class BoxCollection<2>;
00735 template class BoxCollection<3>;

Generated by  doxygen 1.6.2