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
00029
00030
00031
00032
00033
00034
00035 #ifndef DISTRIBUTEDBOXCOLLECTION_HPP_
00036 #define DISTRIBUTEDBOXCOLLECTION_HPP_
00037
00038 #include "ChasteSerialization.hpp"
00039 #include <boost/serialization/vector.hpp>
00040
00041 #include "Node.hpp"
00042 #include "Element.hpp"
00043 #include "Box.hpp"
00044 #include "PetscTools.hpp"
00045 #include "DistributedVectorFactory.hpp"
00046 #include <map>
00047 #include <vector>
00048
00049
00053 template<unsigned DIM>
00054 class DistributedBoxCollection
00055 {
00056 private:
00057 friend class TestDistributedBoxCollection;
00058
00060 std::vector< Box<DIM> > mBoxes;
00061
00063 std::vector< Box<DIM> > mHaloBoxes;
00064
00066 std::vector<unsigned> mHalosRight;
00067
00069 std::vector<unsigned> mHalosLeft;
00070
00072 std::vector<unsigned> mHaloNodesRight;
00073
00075 std::vector<unsigned> mHaloNodesLeft;
00076
00078 std::map<unsigned, unsigned> mBoxesMapping;
00079
00081 std::map<unsigned, unsigned> mHaloBoxesMapping;
00082
00084 c_vector<double, 2*DIM> mDomainSize;
00085
00087 double mBoxWidth;
00088
00090 unsigned mNumBoxes;
00091
00093 c_vector<unsigned, DIM> mNumBoxesEachDirection;
00094
00096 unsigned mNumBoxesInAFace;
00097
00099 std::vector< std::set<unsigned> > mLocalBoxes;
00100
00102 unsigned mMinBoxIndex;
00103
00105 unsigned mMaxBoxIndex;
00106
00108 bool mIsPeriodicInX;
00109
00111 bool mAreLocalBoxesSet;
00112
00114 static const double msFudge;
00115
00117 DistributedVectorFactory* mpDistributedBoxStackFactory;
00118
00120 bool mCalculateNodeNeighbours;
00121
00123 friend class boost::serialization::access;
00124
00131 template<class Archive>
00132 void serialize(Archive & archive, const unsigned int version)
00133 {
00134
00135 }
00136
00137 public:
00138
00150 DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, int localRows = PETSC_DECIDE);
00151
00152
00156 ~DistributedBoxCollection();
00157
00161 void EmptyBoxes();
00162
00168 void SetupHaloBoxes();
00169
00174 void UpdateHaloBoxes();
00175
00179 unsigned GetNumLocalRows() const;
00180
00185 bool GetBoxOwnership(unsigned globalIndex);
00186
00194 bool IsInteriorBox(unsigned globalIndex);
00195
00200 bool GetHaloBoxOwnership(unsigned globalIndex);
00201
00208 unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> coordinateIndices);
00209
00214 unsigned CalculateContainingBox(Node<DIM>* pNode);
00215
00220 unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
00221
00228 c_vector<unsigned, DIM> CalculateCoordinateIndices(unsigned globalIndex);
00229
00234 Box<DIM>& rGetBox(unsigned boxIndex);
00235
00241 Box<DIM>& rGetHaloBox(unsigned boxIndex);
00242
00246 unsigned GetNumBoxes();
00247
00251 unsigned GetNumLocalBoxes();
00252
00256 c_vector<double, 2*DIM> rGetDomainSize() const;
00257
00261 bool GetAreLocalBoxesSet() const;
00262
00266 double GetBoxWidth() const;
00267
00271 unsigned GetNumRowsOfBoxes() const;
00272
00280 int LoadBalance(std::vector<int> localDistribution);
00281
00287 void SetupLocalBoxesHalfOnly();
00288
00292 void SetupAllLocalBoxes();
00293
00300 std::set<unsigned> GetLocalBoxes(unsigned boxIndex);
00301
00306 bool IsOwned(Node<DIM>* pNode);
00307
00312 bool IsOwned(c_vector<double, DIM>& location);
00313
00321 unsigned GetProcessOwningNode(Node<DIM>* pNode);
00322
00326 std::vector<unsigned>& rGetHaloNodesRight();
00327
00331 std::vector<unsigned>& rGetHaloNodesLeft();
00332
00338 void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
00339
00350 void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00351
00359 void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00360
00368 void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00369
00377 void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00378
00384 std::vector<int> CalculateNumberOfNodesInEachStrip();
00385 };
00386
00387 #include "SerializationExportWrapper.hpp"
00388
00389 EXPORT_TEMPLATE_CLASS_SAME_DIMS(DistributedBoxCollection)
00390
00391
00392 namespace boost
00393 {
00394 namespace serialization
00395 {
00399 template<class Archive, unsigned DIM>
00400 inline void save_construct_data(
00401 Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00402 {
00403
00404
00405 int num_local_rows = (int)(t->GetNumRowsOfBoxes());
00406 std::vector<int> num_rows(PetscTools::GetNumProcs());
00407 MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
00408
00409 if (PetscTools::AmMaster())
00410 {
00411 bool are_boxes_set = t->GetAreLocalBoxesSet();
00412 ar << are_boxes_set;
00413
00414 c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
00415 for (unsigned i=0; i<2*DIM; i++)
00416 {
00417 ar << domain_size[i];
00418 }
00419
00420 double box_width = t->GetBoxWidth();
00421 ar << box_width;
00422
00423 unsigned num_procs = PetscTools::GetNumProcs();
00424 ar << num_procs;
00425
00426 std::vector<int> const const_num_rows = num_rows;
00427 ar << const_num_rows;
00428 }
00429 }
00433 template<class Archive, unsigned DIM>
00434 inline void load_construct_data(
00435 Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00436 {
00437 bool are_boxes_set;
00438 ar >> are_boxes_set;
00439
00440
00441 c_vector<double,2*DIM> domain_size;
00442 for (unsigned i=0; i<2*DIM; i++)
00443 {
00444 double coordinate;
00445 ar & coordinate;
00446 domain_size[i] = coordinate;
00447 }
00448
00449
00450 for (unsigned i=0; i<DIM; i++)
00451 {
00452 domain_size[2*i+1] -= 1e-14;
00453 }
00454 double cut_off;
00455 ar >> cut_off;
00456
00457 unsigned num_original_procs;
00458 ar >> num_original_procs;
00459
00460 int num_rows = PETSC_DECIDE;
00461 std::vector<int> original_rows;
00462 ar >> original_rows;
00463 if (num_original_procs == PetscTools::GetNumProcs())
00464 {
00465 num_rows = original_rows[PetscTools::GetMyRank()];
00466 }
00467
00468
00469 ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, num_rows);
00470
00471 if (are_boxes_set)
00472 {
00473 t->SetupHaloBoxes();
00474 t->SetupLocalBoxesHalfOnly();
00475 }
00476 }
00477 }
00478 }
00479
00480
00481 #endif