00001 #ifndef _DISTRIBUTED_MESH_HPP_
00002 #define _DISTRIBUTED_MESH_HPP_
00003
00004 #include <mpi.h>
00005
00006
00007 #include "compressed_mesh.hpp"
00008
00009 namespace fpcm
00010 {
00011 namespace DistributedMesh
00012 {
00013 using namespace fpcm::CompressedMesh;
00014
00018
00019 const int MAX_EL_NEIG = 5;
00020 const int NO_NEIG = 0;
00021
00022 struct Element
00023 {
00024 GID neigs[MAX_EL_NEIG];
00025 };
00026
00027 enum MeshEntityType { EVertex=0, EEdge, EFace, EElement, EN_MeshEntityTypes };
00028
00029
00033 struct DistributedMesh
00034 {
00035 typedef coucal HashMap;
00036
00037
00038 CoordMesh global_mesh_base;
00039
00040
00041 HashMap extern_faces_neighs;
00042
00043
00044 HashMap foreign_owners[EN_MeshEntityTypes];
00045
00047 HashMap elements_core,
00049 elements_boundary;
00050
00052 HashMap overlap_elements_owners;
00053
00054
00055 HashMap boundary_vts;
00056
00057 void Init(int* elem_GIDs,
00058 const double* const vertices_coordinates = NULL,
00059 const int n_vertices = 0,
00060 const double* const elems_center_pts = NULL,
00061 int* elem_neigs = NULL,
00062 const int* elem_domain = NULL,
00063 const int n_elems = 0
00064 ) {
00065
00067 extern_faces_neighs = coucal_new(0);
00068 elements_core = coucal_new(0);
00069 elements_boundary = coucal_new(0);
00070
00071 for(int i=0; i < EN_MeshEntityTypes; ++i) {
00072 foreign_owners[i] = coucal_new(0);
00073 }
00074
00075 Clear();
00076
00078 if(MPI_Comm_rank(MPI_COMM_WORLD,NULL) == 0) {
00079 mf_check_mem(vertices_coordinates);
00080
00081 global_mesh_base.createMeshBase(vertices_coordinates, n_vertices);
00082 }
00083
00084 MPI_Bcast(global_mesh_base.origin, 3, MPI_DOUBLE,0,MPI_COMM_WORLD);
00085 MPI_Bcast(global_mesh_base.d, 3, MPI_DOUBLE,0,MPI_COMM_WORLD);
00086
00087
00088 MPI_Bcast(global_mesh_base.binary_oper, 3, MPI_INT,0,MPI_COMM_WORLD);
00089
00090 MPI_Bcast(& global_mesh_base.in_line_digits, 1, MPI_BYTE,0,MPI_COMM_WORLD);
00091 MPI_Bcast(& global_mesh_base.line_digits, 1, MPI_BYTE,0,MPI_COMM_WORLD);
00092 MPI_Bcast(& global_mesh_base.layer_digits, 1, MPI_BYTE,0,MPI_COMM_WORLD);
00093 MPI_Bcast(& global_mesh_base.shift, 1, MPI_BYTE,0,MPI_COMM_WORLD);
00094
00095
00097 for(int e=0; e < n_elems; ++e) {
00098 elem_GIDs[e] = global_mesh_base.encode( & elems_center_pts[3*e] );
00099 mf_check(elem_GIDs[e] != NO_NEIG,"Incorrect GID for %d!",e);
00100 }
00101
00102 for(int n=0; n < MAX_EL_NEIG*n_elems; ++n) {
00103 if(elem_neigs[n] != NO_NEIG) {
00104 elem_neigs[n]=elem_GIDs[ elem_neigs[n] ];
00105 }
00106 }
00107
00108
00110 for(int e=0; e < n_elems; ++e) {
00111 Element *p_el = new Element();
00112
00113
00114
00115
00116
00117
00118 }
00119
00120
00121 MPI_Barrier(MPI_COMM_WORLD);
00122 }
00123
00124 void Clear() {
00125 for(int i=0; i < EN_MeshEntityTypes; ++ i) {
00126 if(coucal_created(foreign_owners[i]) ) {
00127 coucal_delete(& foreign_owners[i]);
00128 foreign_owners[i] = coucal_new(0);
00129 }
00130 }
00131
00132 if(coucal_created(extern_faces_neighs) ) {
00133 coucal_delete(& extern_faces_neighs);
00134 extern_faces_neighs = coucal_new(0);
00135 }
00136
00137 }
00138
00139
00140
00141
00142 DistributedMesh() {
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 template<MeshEntityType TType>
00157 int getOwner(const GID id) const {
00158 int *p_owner=NULL;
00159 coucal_read_pvoid(foreign_owners[TType],&id,(void**) &p_owner);
00160 return p_owner==NULL ? MPI_Comm_rank(MPI_COMM_WORLD,NULL) : *p_owner;
00161 }
00162
00163 template<MeshEntityType TType>
00164 void setOwner(const GID id, const int owner) {
00165 coucal_add(foreign_owners[TType],id,owner);
00166 }
00167
00168 void DomainDecompositionProcessor();
00169 void OverlapProcessor();
00170 void AdaptationProcessor();
00171
00172 };
00173
00174 }
00175 }
00176
00177
00178 #endif // _DISTRIBUTED_MESH_HPP_