BoxCollection.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "BoxCollection.hpp"
00029
00031
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
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
00090
00091
00092
00093
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
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
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
00141
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
00155 assert(num_boxes == mBoxes.size());
00156 }
00157
00158 template<unsigned DIM>
00159 unsigned BoxCollection<DIM>::CalculateContainingBox(Node<DIM>* pNode)
00160 {
00161
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
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
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
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
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
00225 mLocalBoxes.clear();
00226 for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00227 {
00228 std::set<unsigned> local_boxes;
00229
00230
00231 local_boxes.insert(box_index);
00232
00233
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
00245 mLocalBoxes.clear();
00246 for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00247 {
00248 std::set<unsigned> local_boxes;
00249
00250
00251 local_boxes.insert(box_index);
00252
00253
00254 if (box_index < mBoxes.size() - mNumBoxesEachDirection(0))
00255 {
00256 local_boxes.insert(box_index + mNumBoxesEachDirection(0));
00257
00258
00259 if (box_index % mNumBoxesEachDirection(0) != 0)
00260 {
00261 local_boxes.insert(box_index + mNumBoxesEachDirection(0) - 1);
00262 }
00263 }
00264
00265 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00266 {
00267 local_boxes.insert(box_index + 1);
00268
00269
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
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
00291 local_boxes.insert(box_index);
00292
00293
00294 if (box_index % num_boxes_xy < num_boxes_xy - mNumBoxesEachDirection(0))
00295 {
00296 local_boxes.insert(box_index + mNumBoxesEachDirection(0));
00297
00298
00299 if (box_index % mNumBoxesEachDirection(0) != 0)
00300 {
00301 local_boxes.insert(box_index + mNumBoxesEachDirection(0) - 1);
00302 }
00303 }
00304
00305 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00306 {
00307 local_boxes.insert(box_index + 1);
00308
00309
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
00316 if (box_index < mBoxes.size() - num_boxes_xy)
00317 {
00318 local_boxes.insert(box_index + num_boxes_xy);
00319
00320
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
00326 if (box_index % mNumBoxesEachDirection(0) != 0)
00327 {
00328 local_boxes.insert(box_index + num_boxes_xy + mNumBoxesEachDirection(0) - 1);
00329 }
00330 }
00331
00332 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00333 {
00334 local_boxes.insert(box_index + num_boxes_xy + 1);
00335
00336
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
00344 if (box_index >= num_boxes_xy)
00345 {
00346 local_boxes.insert(box_index - num_boxes_xy);
00347
00348
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
00354 if (box_index % mNumBoxesEachDirection(0) != 0)
00355 {
00356 local_boxes.insert(box_index - num_boxes_xy + mNumBoxesEachDirection(0) - 1);
00357 }
00358 }
00359
00360 if (box_index % mNumBoxesEachDirection(0) != mNumBoxesEachDirection(0)-1)
00361 {
00362 local_boxes.insert(box_index - num_boxes_xy + 1);
00363
00364
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
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);
00417 std::vector<bool> is_xmax(N*M);
00418 std::vector<bool> is_ymin(N*M);
00419 std::vector<bool> is_ymax(N*M);
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
00436 if(!is_xmin[i])
00437 {
00438 local_boxes.insert(i-1);
00439 }
00440
00441
00442 if(!is_xmax[i])
00443 {
00444 local_boxes.insert(i+1);
00445 }
00446
00447
00448 if(!is_ymin[i])
00449 {
00450 local_boxes.insert(i-M);
00451 }
00452
00453
00454 if(!is_ymax[i])
00455 {
00456 local_boxes.insert(i+M);
00457 }
00458
00459
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);
00494 std::vector<bool> is_xmax(N*M*P);
00495 std::vector<bool> is_ymin(N*M*P);
00496 std::vector<bool> is_ymax(N*M*P);
00497 std::vector<bool> is_zmin(N*M*P);
00498 std::vector<bool> is_zmax(N*M*P);
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
00515 local_boxes.insert(i);
00516
00517
00518
00519
00520 if(!is_xmin[i])
00521 {
00522 local_boxes.insert(i-1);
00523
00524
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
00547 if(!is_xmax[i])
00548 {
00549 local_boxes.insert(i+1);
00550
00551
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
00574 if(!is_ymin[i])
00575 {
00576 local_boxes.insert(i-M);
00577
00578
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
00591 if(!is_ymax[i])
00592 {
00593 local_boxes.insert(i+M);
00594
00595
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
00608 if(!is_zmin[i])
00609 {
00610 local_boxes.insert(i-N*M);
00611 }
00612
00613
00614 if(!is_zmax[i])
00615 {
00616 local_boxes.insert(i+N*M);
00617 }
00618
00619
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
00688 unsigned box_index = CalculateContainingBox(rNodes[node_index]);
00689
00690
00691 std::set<unsigned> local_boxes_indices = GetLocalBoxes(box_index);
00692
00693
00694 for (std::set<unsigned>::iterator box_iter = local_boxes_indices.begin();
00695 box_iter != local_boxes_indices.end();
00696 box_iter++)
00697 {
00698
00699 std::set< Node<DIM>* >& r_contained_nodes = mBoxes[*box_iter].rGetNodesContained();
00700
00701
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
00707 unsigned other_node_index = (*node_iter)->GetIndex();
00708
00709
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
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>;