NodeBoxCollection.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
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 "NodeBoxCollection.hpp"
00029 
00031 // NodeBox methods
00033 
00034 
00035 template<unsigned DIM>
00036 NodeBox<DIM>::NodeBox(c_vector<double, 2*DIM> minAndMaxValues)
00037 {
00038     mMinAndMaxValues = minAndMaxValues;
00039 }
00040 
00041 template<unsigned DIM>
00042 c_vector<double, 2*DIM>& NodeBox<DIM>::rGetMinAndMaxValues()
00043 {
00044     return mMinAndMaxValues;
00045 }
00046 
00047 template<unsigned DIM>
00048 void NodeBox<DIM>::AddNode(Node<DIM>* pNode)
00049 {
00050     mNodesContained.insert(pNode);
00051 }
00052 
00053 template<unsigned DIM>
00054 void NodeBox<DIM>::RemoveNode(Node<DIM>* pNode)
00055 {
00056     mNodesContained.erase(pNode);
00057 }
00058 
00059 template<unsigned DIM>
00060 std::set< Node<DIM>* >& NodeBox<DIM>::rGetNodesContained()
00061 {
00062     return mNodesContained;
00063 }
00064 
00065 
00067 // NodeBoxCollection methods
00069 
00070 
00071 template<unsigned DIM>
00072 NodeBoxCollection<DIM>::NodeBoxCollection(double cutOffLength, c_vector<double, 2*DIM> domainSize)
00073     : mDomainSize(domainSize),
00074       mCutOffLength(cutOffLength)
00075 {
00076     assert(DIM==2); 
00077     switch (DIM)
00078     {
00081 //
00082 //        case 1:
00083 //        {
00084 //            mNumBoxesEachDirection(0) = 0;
00085 //            double box_min_x = domainSize(0);
00086 //            while (box_min_x <=  domainSize(1))
00087 //            {
00088 //                c_vector<double, 2*DIM> box_coords;
00089 //                box_coords(0) = box_min_x;
00090 //                box_coords(1) = box_min_x + cutOffLength;
00091 //
00092 //                NodeBox<DIM> new_box(box_coords);
00093 //                mBoxes.push_back(new_box);
00094 //                mNumBoxesEachDirection(0)++;
00095 //
00096 //                box_min_x += cutOffLength;
00097 //            }
00098 //
00099 //            break;
00100 //        }
00101         case 2:
00102         {
00103             mNumBoxesEachDirection(0) = 0;
00104             double box_min_x = domainSize(0);
00105             while (box_min_x <=  domainSize(1))
00106             {
00107                 double box_min_y = domainSize(2);
00108                 mNumBoxesEachDirection(1) = 0;
00109                 while (box_min_y <= domainSize(3))
00110                 {
00111                     c_vector<double, 2*DIM> box_coords;
00112                     box_coords(0) = box_min_x;
00113                     box_coords(1) = box_min_x + cutOffLength;
00114                     box_coords(2) = box_min_y;
00115                     box_coords(3) = box_min_y + cutOffLength;
00116 
00117                     NodeBox<DIM> new_box(box_coords);
00118                     mBoxes.push_back(new_box);
00119                     mNumBoxesEachDirection(1)++;
00120 
00121                     box_min_y += cutOffLength;
00122                 }
00123                 mNumBoxesEachDirection(0)++;
00124                 box_min_x += cutOffLength;
00125             }
00126             assert(mNumBoxesEachDirection(0)*mNumBoxesEachDirection(1)==mBoxes.size());
00127             break;
00128         }
00129     }
00130     CalculateLocalBoxes();
00131 }
00132 
00133 template<unsigned DIM>
00134 unsigned NodeBoxCollection<DIM>::CalculateContainingBox(Node<DIM>* pNode)
00135 {
00136     assert(DIM==2);
00137 
00138     double x = pNode->rGetLocation()[0];
00139     double y = pNode->rGetLocation()[1];
00140 
00141     for (unsigned i=0; i<DIM; i++)
00142     {
00143         assert(pNode->rGetLocation()[i] >= mDomainSize(2*i));
00144         assert(pNode->rGetLocation()[i] <= mDomainSize(2*i+1));
00145     }
00146     unsigned box_x_index = (unsigned) floor((x-mDomainSize(0))/mCutOffLength);
00147     unsigned box_y_index = (unsigned) floor((y-mDomainSize(2))/mCutOffLength);
00148     assert(mNumBoxesEachDirection(1)*box_x_index + box_y_index < mBoxes.size());
00149     return mNumBoxesEachDirection(1)*box_x_index + box_y_index;
00150 }
00151 
00152 template<unsigned DIM>
00153 NodeBox<DIM>& NodeBoxCollection<DIM>::rGetBox(unsigned boxIndex)
00154 {
00155     assert(boxIndex < mBoxes.size());
00156     return mBoxes[boxIndex];
00157 }
00158 
00159 template<unsigned DIM>
00160 unsigned NodeBoxCollection<DIM>::GetNumBoxes()
00161 {
00162     return mBoxes.size();
00163 }
00164 
00165 template<unsigned DIM>
00166 void NodeBoxCollection<DIM>::CalculateLocalBoxes()
00167 {
00168     assert(DIM==2);
00169 
00170     mLocalBoxes.clear();
00171     for (unsigned box_index=0; box_index<mBoxes.size(); box_index++)
00172     {
00173         std::set<unsigned> local_boxes;
00174         local_boxes.insert(box_index);
00175 
00176         if (!IsBottomRow(box_index))
00177         {
00178             local_boxes.insert(box_index-1);
00179         }
00180 
00181         if (!IsTopRow(box_index))
00182         {
00183             local_boxes.insert(box_index+1);
00184         }
00185 
00186         if (!IsLeftColumn(box_index))
00187         {
00188             local_boxes.insert(box_index-mNumBoxesEachDirection(1));
00189         }
00190 
00191         if (!IsRightColumn(box_index))
00192         {
00193             local_boxes.insert(box_index+mNumBoxesEachDirection(1));
00194         }
00195 
00196         if ( (!IsBottomRow(box_index)) && (!IsLeftColumn(box_index)) )
00197         {
00198             local_boxes.insert(box_index-mNumBoxesEachDirection(1)-1);
00199         }
00200 
00201         if ( (!IsBottomRow(box_index)) && (!IsRightColumn(box_index)) )
00202         {
00203             local_boxes.insert(box_index+mNumBoxesEachDirection(1)-1);
00204         }
00205 
00206         if ( (!IsTopRow(box_index)) && (!IsRightColumn(box_index)) )
00207         {
00208             local_boxes.insert(box_index+mNumBoxesEachDirection(1)+1);
00209         }
00210 
00211         if ( (!IsTopRow(box_index)) && (!IsLeftColumn(box_index)) )
00212         {
00213             local_boxes.insert(box_index-mNumBoxesEachDirection(1)+1);
00214         }
00215 
00216         mLocalBoxes.push_back(local_boxes);
00217     }
00218 }
00219 
00220 template<unsigned DIM>
00221 std::set<unsigned> NodeBoxCollection<DIM>::GetLocalBoxes(unsigned boxIndex)
00222 {
00223     assert(boxIndex < mLocalBoxes.size());
00224     return mLocalBoxes[boxIndex];
00225 }
00226 
00227 template<unsigned DIM>
00228 void NodeBoxCollection<DIM>::CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::set<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs)
00229 {
00230     rNodePairs.clear();
00231     for (unsigned node_index=0; node_index<rNodes.size(); node_index++)
00232     {
00233         // Get the box containing this node
00234         unsigned box_index = CalculateContainingBox(rNodes[node_index]);
00235 
00236         // Get the local boxes to this node
00237         std::set<unsigned> local_boxes_indices = GetLocalBoxes(box_index);
00238 
00239         // Loop over all the local boxes
00240         for (std::set<unsigned>::iterator iter = local_boxes_indices.begin();
00241              iter != local_boxes_indices.end();
00242              iter++)
00243         {
00244             NodeBox<DIM>& r_box = mBoxes[*iter];
00245             std::set< Node<DIM>* >& r_contained_nodes = r_box.rGetNodesContained();
00246 
00247             // Get all the nodes in the local boxes in the original node
00248             for (typename std::set<Node<DIM>*>::iterator node_iter = r_contained_nodes.begin();
00249                 node_iter != r_contained_nodes.end();
00250                 ++node_iter)
00251             {
00252                 unsigned index2 = (*node_iter)->GetIndex();
00253 
00254                 // If node_index1 < node_index2 add the pair to the set.
00255                 if (node_index < index2)
00256                 {
00257                     rNodePairs.insert(std::pair<Node<DIM>*,Node<DIM>*>(rNodes[node_index],rNodes[index2]));
00258                 }
00259             }
00260         }
00261     }
00262 }
00263 
00265 // Explicit instantiation
00267 
00268 template class NodeBox<1>;
00269 template class NodeBox<2>;
00270 template class NodeBox<3>;
00271 template class NodeBoxCollection<1>;
00272 template class NodeBoxCollection<2>;
00273 template class NodeBoxCollection<3>;

Generated on Tue Aug 4 16:10:21 2009 for Chaste by  doxygen 1.5.5