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
00145 DistributedBoxCollection(double boxWidth, c_vector<double, 2*DIM> domainSize, bool isPeriodicInX = false, int localRows = PETSC_DECIDE);
00146
00147
00151 ~DistributedBoxCollection();
00152
00156 void EmptyBoxes();
00157
00163 void SetupHaloBoxes();
00164
00169 void UpdateHaloBoxes();
00170
00174 unsigned GetNumLocalRows() const;
00175
00180 bool GetBoxOwnership(unsigned globalIndex);
00181
00189 bool IsInteriorBox(unsigned globalIndex);
00190
00195 bool GetHaloBoxOwnership(unsigned globalIndex);
00196
00203 unsigned CalculateGlobalIndex(c_vector<unsigned, DIM> coordinateIndices);
00204
00209 unsigned CalculateContainingBox(Node<DIM>* pNode);
00210
00215 unsigned CalculateContainingBox(c_vector<double, DIM>& rLocation);
00216
00223 c_vector<unsigned, DIM> CalculateCoordinateIndices(unsigned globalIndex);
00224
00229 Box<DIM>& rGetBox(unsigned boxIndex);
00230
00236 Box<DIM>& rGetHaloBox(unsigned boxIndex);
00237
00241 unsigned GetNumBoxes();
00242
00246 unsigned GetNumLocalBoxes();
00247
00251 c_vector<double, 2*DIM> rGetDomainSize() const;
00252
00256 bool GetAreLocalBoxesSet() const;
00257
00261 double GetBoxWidth() const;
00262
00266 unsigned GetNumRowsOfBoxes() const;
00267
00275 int LoadBalance(std::vector<int> localDistribution);
00276
00282 void SetupLocalBoxesHalfOnly();
00283
00287 void SetupAllLocalBoxes();
00288
00295 std::set<unsigned> GetLocalBoxes(unsigned boxIndex);
00296
00301 bool IsOwned(Node<DIM>* pNode);
00302
00307 bool IsOwned(c_vector<double, DIM>& location);
00308
00316 unsigned GetProcessOwningNode(Node<DIM>* pNode);
00317
00321 std::vector<unsigned>& rGetHaloNodesRight();
00322
00326 std::vector<unsigned>& rGetHaloNodesLeft();
00327
00333 void SetCalculateNodeNeighbours(bool calculateNodeNeighbours);
00334
00345 void CalculateNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00346
00354 void CalculateInteriorNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00355
00363 void CalculateBoundaryNodePairs(std::vector<Node<DIM>*>& rNodes, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00364
00372 void AddPairsFromBox(unsigned boxIndex, std::vector<std::pair<Node<DIM>*, Node<DIM>*> >& rNodePairs, std::map<unsigned, std::set<unsigned> >& rNodeNeighbours);
00373
00379 std::vector<int> CalculateNumberOfNodesInEachStrip();
00380 };
00381
00382 #include "SerializationExportWrapper.hpp"
00383
00384 EXPORT_TEMPLATE_CLASS_SAME_DIMS(DistributedBoxCollection)
00385
00386
00387 namespace boost
00388 {
00389 namespace serialization
00390 {
00394 template<class Archive, unsigned DIM>
00395 inline void save_construct_data(
00396 Archive & ar, const DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00397 {
00398
00399
00400 int num_local_rows = (int)(t->GetNumRowsOfBoxes());
00401 std::vector<int> num_rows(PetscTools::GetNumProcs());
00402 MPI_Gather(&num_local_rows, 1, MPI_INT, &num_rows[0], 1, MPI_INT, 0, PETSC_COMM_WORLD);
00403
00404 if (PetscTools::AmMaster())
00405 {
00406 bool are_boxes_set = t->GetAreLocalBoxesSet();
00407 ar << are_boxes_set;
00408
00409 c_vector<double, 2*DIM> domain_size = t->rGetDomainSize();
00410 for (unsigned i=0; i<2*DIM; i++)
00411 {
00412 ar << domain_size[i];
00413 }
00414
00415 double box_width = t->GetBoxWidth();
00416 ar << box_width;
00417
00418 unsigned num_procs = PetscTools::GetNumProcs();
00419 ar << num_procs;
00420
00421 std::vector<int> const const_num_rows = num_rows;
00422 ar << const_num_rows;
00423 }
00424 }
00428 template<class Archive, unsigned DIM>
00429 inline void load_construct_data(
00430 Archive & ar, DistributedBoxCollection<DIM> * t, const unsigned int file_version)
00431 {
00432 bool are_boxes_set;
00433 ar >> are_boxes_set;
00434
00435
00436 c_vector<double,2*DIM> domain_size;
00437 for (unsigned i=0; i<2*DIM; i++)
00438 {
00439 double coordinate;
00440 ar & coordinate;
00441 domain_size[i] = coordinate;
00442 }
00443
00444
00445 for (unsigned i=0; i<DIM; i++)
00446 {
00447 domain_size[2*i+1] -= 1e-14;
00448 }
00449 double cut_off;
00450 ar >> cut_off;
00451
00452 unsigned num_original_procs;
00453 ar >> num_original_procs;
00454
00455 int num_rows = PETSC_DECIDE;
00456 std::vector<int> original_rows;
00457 ar >> original_rows;
00458 if (num_original_procs == PetscTools::GetNumProcs())
00459 {
00460 num_rows = original_rows[PetscTools::GetMyRank()];
00461 }
00462
00463
00464 ::new(t)DistributedBoxCollection<DIM>(cut_off, domain_size, false, num_rows);
00465
00466 if (are_boxes_set)
00467 {
00468 t->SetupHaloBoxes();
00469 t->SetupLocalBoxesHalfOnly();
00470 }
00471 }
00472 }
00473 }
00474
00475
00476 #endif