00001
00002
00008 #if !defined(__elc_EulerianComm_h__)
00009 #define __elc_EulerianComm_h__
00010
00011
00012 #if defined(DEBUG_elc) && !defined(DEBUG_EulerianComm)
00013 #define DEBUG_EulerianComm
00014 #endif
00015
00016 #ifdef DEBUG_EulerianComm
00017 #ifndef DEBUG_ELComm
00018 #define DEBUG_ELComm
00019 #endif
00020 #endif
00021
00022 #include "ELComm.h"
00023
00024 #if defined(ELC_USE_CPP_INTERFACE) && !defined(PT2PT_BBOX_USE_CPP_INTERFACE)
00025 #define PT2PT_BBOX_USE_CPP_INTERFACE
00026 #endif
00027 #include "../concurrent/pt2pt_bbox.h"
00028
00029 #include "../ads/iterator/TrivialOutputIterator.h"
00030 #include "../ads/functor/select.h"
00031
00032 #include "../geom/mesh/iss/set.h"
00033
00034 #include "../third-party/loki/TypeManip.h"
00035
00036 #include <set>
00037 #include <map>
00038
00039 BEGIN_NAMESPACE_ELC
00040
00041
00043
00049 template<int N, typename T>
00050 class EulerianComm :
00051 public ELComm<N,T> {
00052
00053
00054
00055
00056 private:
00057
00058 typedef ELComm<N,T> Base;
00059
00060
00061
00062
00063
00064 protected:
00065
00067 typedef typename Base::Number Number;
00069 typedef typename Base::Point Point;
00071 typedef typename Base::BBox BBox;
00073 typedef typename Base::MpiRequest MpiRequest;
00075 typedef typename Base::MpiStatus MpiStatus;
00077 typedef ads::FixedArray<N,int> IndexedFace;
00078
00079
00080
00081
00082
00083 protected:
00084
00086 using Base::_comm;
00088 using Base::_mpiNumber;
00090 using Base::_vertexIdentifierStyle;
00091
00093 using Base::TagPressures;
00094
00095 private:
00096
00098 using Base::TagIdentifiers;
00100 using Base::TagPositions;
00102 using Base::TagVelocities;
00104 using Base::TagFaceData;
00105
00106
00107
00108
00109
00110 protected:
00111
00112 #ifdef ELC_USE_CPP_INTERFACE
00113
00114 MPI::Intracomm _eulerianCommunicator;
00115 #else
00116
00117 MPI_Comm _eulerianCommunicator;
00118 #endif
00119
00121 int _lagrangianRoot;
00122
00124 std::vector<ads::Array<1,int> > _identifiers;
00126 std::vector<ads::Array<1,Point> > _positions;
00128 std::vector<ads::Array<1,Point> > _velocities;
00130 std::vector<ads::Array<1,IndexedFace> > _connectivities;
00132 std::vector<ads::Array<1,Number> > _pressures;
00133
00134
00136 std::map<int,int> _identifierToIndex;
00137
00138
00139
00141 ads::Array<1,Point> _assembledPositions;
00143 ads::Array<1,Point> _assembledVelocities;
00145 ads::Array<1,IndexedFace> _assembledConnectivities;
00147 ads::Array<1,Number> _assembledPressures;
00148
00150 concurrent::PtToPt2Grp1Dom<N, T, int, ads::FixedArray<3,int> >
00151 _pointToPoint;
00152
00154 std::vector<ads::FixedArray<3,int> > _lagrangianData;
00155
00157 ads::Array<1,Point> _faceNormals;
00159 ads::Array<1,Point> _faceCentroids;
00160
00161 private:
00162
00163 std::vector<MpiRequest> _identifierRequests;
00164 std::vector<MpiRequest> _positionRequests;
00165 std::vector<MpiRequest> _velocityRequests;
00166 std::vector<MpiRequest> _connectivityRequests;
00167
00168
00169
00170
00171
00172 private:
00173
00174
00175 EulerianComm();
00176
00177
00178 EulerianComm(const EulerianComm&);
00179
00180
00181 EulerianComm&
00182 operator=(const EulerianComm&);
00183
00184 public:
00185
00186
00188
00189
00190 #ifdef ELC_USE_CPP_INTERFACE
00191
00192
00201 EulerianComm(const MPI::Comm& comm, const MPI::Intracomm& eulerian,
00202 const int lagrangianSize, const int lagrangianRoot,
00203 VertexIdentifierStyle vertexIdentifierStyle) :
00204 Base(comm, vertexIdentifierStyle),
00205 _eulerianCommunicator(eulerian.Dup()),
00206 _lagrangianRoot(lagrangianRoot),
00207 _pointToPoint(comm, eulerian, lagrangianSize, lagrangianRoot)
00208 {}
00209 #else
00210
00211
00220 EulerianComm(const MPI_Comm comm, const MPI_Comm eulerian,
00221 const int lagrangianSize, const int lagrangianRoot,
00222 VertexIdentifierStyle vertexIdentifierStyle) :
00223 Base(comm, vertexIdentifierStyle),
00224 _eulerianCommunicator(),
00225 _lagrangianRoot(lagrangianRoot),
00226 _pointToPoint(comm, eulerian, lagrangianSize, lagrangianRoot) {
00227 MPI_Comm_dup(eulerian, &_eulerianCommunicator);
00228 }
00229 #endif
00230
00232 virtual
00233 ~EulerianComm() {
00234 #ifdef ELC_USE_CPP_INTERFACE
00235 _eulerianCommunicator.Free();
00236 #else
00237 MPI_Comm_free(&_eulerianCommunicator);
00238 #endif
00239 }
00240
00241
00242
00244
00245
00247 int
00248 getNumberOfNodes() const {
00249 return _assembledPositions.size();
00250 }
00251
00253 int
00254 getNumberOfFaces() const {
00255 return _assembledConnectivities.size();
00256 }
00257
00259 const ads::Array<1,Point>&
00260 getPositions() const {
00261 return _assembledPositions;
00262 }
00263
00265 const Number*
00266 getPositionsData() const {
00267 return reinterpret_cast<const Number*>(_assembledPositions.data());
00268 }
00269
00271 const ads::Array<1,Point>&
00272 getVelocities() const {
00273 return _assembledVelocities;
00274 }
00275
00277 const Number*
00278 getVelocitiesData() const {
00279 return reinterpret_cast<const Number*>(_assembledVelocities.data());
00280 }
00281
00283 const ads::Array<1,IndexedFace>&
00284 getConnectivities() const {
00285 return _assembledConnectivities;
00286 }
00287
00289 const int*
00290 getConnectivitiesData() const {
00291 return reinterpret_cast<const int*>(_assembledConnectivities.data());
00292 }
00293
00294
00295
00297
00298
00300 const ads::Array<1,Point>&
00301 getFaceNormals() const {
00302 return _faceNormals;
00303 }
00304
00306 const Number*
00307 getFaceNormalsData() const {
00308 return reinterpret_cast<const Number*>(_faceNormals.data());
00309 }
00310
00312 const Point&
00313 getFaceNormal(const int n) const {
00314 return _faceNormals[n];
00315 }
00316
00318 const Number*
00319 getFaceNormalData(const int n) const {
00320 return reinterpret_cast<const Number*>(_faceNormals[n].data());
00321 }
00322
00324 const ads::Array<1,Point>&
00325 getFaceCentroids() const {
00326 return _faceCentroids;
00327 }
00328
00330 const Number*
00331 getFaceCentroidsData() const {
00332 return reinterpret_cast<const Number*>(_faceCentroids.data());
00333 }
00334
00336 const Point&
00337 getFaceCentroid(const int n) const {
00338 return _faceCentroids[n];
00339 }
00340
00342 const Number*
00343 getFaceCentroidData(const int n) const {
00344 return reinterpret_cast<const Number*>(_faceCentroids[n].data());
00345 }
00346
00347
00348
00350
00351
00353 ads::Array<1,Number>&
00354 getPressures() {
00355 return _assembledPressures;
00356 }
00357
00359 Number*
00360 getPressuresData() {
00361 return reinterpret_cast<Number*>(_assembledPressures.data());
00362 }
00363
00364
00365
00367
00368
00370
00373 void
00374 receiveMesh(const BBox& domain);
00375
00377
00383 void
00384 receiveMesh(const Number* domain) {
00385 receive_mesh(BBox(domain));
00386 }
00387
00389
00392 void
00393 waitForMesh();
00394
00395
00397
00400 virtual
00401 void
00402 sendPressure() = 0;
00403
00405
00408 virtual
00409 void
00410 waitForPressure() = 0;
00411
00412
00414
00417 void
00418 computeFaceNormals();
00419
00421
00424 void
00425 computeFaceCentroids();
00426
00428
00434 virtual
00435 void
00436 initializePressure() = 0;
00437
00438
00439
00440 private:
00441
00443 void
00444 computeFaceNormal(const int n, Point* normal) const;
00445
00447 void
00448 computeFaceCentroid(const int n, Point* centroid) const;
00449
00451 void
00452 generateIdentifiers();
00453
00454 };
00455
00456
00457 END_NAMESPACE_ELC
00458
00459 #define __elc_EulerianComm_ipp__
00460 #include "EulerianComm.ipp"
00461 #undef __elc_EulerianComm_ipp__
00462
00463 #endif