00001
00002
00003 int coordEqual(double *key1, double *key2) {
00004 int maxUlps=200;
00005
00006 int x1Int = *(int*)&(key1[0]),
00007 x2Int = *(int*)&(key2[0]);
00008 if (x1Int < 0) x1Int = 0x80000000 - x1Int;
00009 if (x2Int < 0) x2Int = 0x80000000 - x2Int;
00010 int y1Int = *(int*)&(key1[1]),
00011 y2Int = *(int*)&(key2[1]);
00012 if (y1Int < 0) y1Int = 0x80000000 - y1Int;
00013 if (y2Int < 0) y2Int = 0x80000000 - y2Int;
00014 int z1Int = *(int*)&(key1[2]),
00015 z2Int = *(int*)&(key2[2]);
00016 if (z1Int < 0) z1Int = 0x80000000 - z1Int;
00017 if (z2Int < 0) z2Int = 0x80000000 - z2Int;
00018
00019 int xIntDiff = abs(x1Int - x2Int);
00020 int yIntDiff = abs(y1Int - y2Int);
00021 int zIntDiff = abs(z1Int - z2Int);
00022 return((xIntDiff<=maxUlps) && (yIntDiff<=maxUlps) && (zIntDiff<=maxUlps));
00023 }
00024
00025 void derive_shared_nodes(int parfum_mesh, MPI_comm comm) {
00026 int comm_size, rank;
00027 MPI_Comm_size(comm, &comm_size);
00028 MPI_Comm_rank(comm, &rank);
00029
00030 int *sharedNodeCounts;
00031 int **sharedNodeLists;
00032
00033 sharedNodeCounts = (int *)malloc(comm_size*sizeof(int));
00034 sharedNodeLists = (int **)malloc(comm_size*sizeof(int *));
00035 for (int i=0; i<comm_size; i++) {
00036 sharedNodeLists[i] = NULL;
00037 sharedNodeCounts[i] = 0;
00038 }
00039
00040 int numNodes;
00041 int coord_msg_tag=42, sharedlist_msg_tag=43;
00042 double *nodeCoords;
00043 numNodes = FEM_Mesh_get_length(parfum_mesh,FEM_NODE);
00044 nodeCoords = (double *)malloc(3*numNodes*sizeof(double));
00045 FEM_Mesh_data(parfum_mesh,FEM_NODE,FEM_COORD, nodeCoords, 0, numNodes,
00046 FEM_DOUBLE, 3);
00047
00048
00049 for (int i=rank+1; i<comm_size; i++) {
00050 MPI_Send(nodeCoords, 3*numNodes, MPI_DOUBLE, i, coord_msg_tag, comm);
00051 }
00052
00053 for (int i=0; i<rank; i++) {
00054 std::vector<int> remoteSharedNodes, localSharedNodes;
00055 double *recvNodeCoords;
00056 MPI_Status *status;
00057 int source, length;
00058
00059 MPI_Probe(MPI_ANY_SOURCE, coord_msg_tag, MPI_Comm comm, status);
00060 source = status.MPI_SOURCE;
00061 length = status.MPI_LENGTH;
00062
00063 recvNodeCoords = (double *)malloc(length*sizeof(double));
00064 MPI_Recv((void*)recvNodeCoords, length, MPI_DOUBLE, source,
00065 coord_msg_tag, comm);
00066
00067
00068 int recvNodeCount = length/3;
00069 for (int j=0; j<numNodes; j++) {
00070 for (int k=0; k<recvNodeCount; k++) {
00071 if (coordEqual(nodeCoords[j*3], recvNodeCoords[k*3])) {
00072 localSharedNodes.push_back(j);
00073 remoteSharedNodes.push_back(k);
00074 break;
00075 }
00076 }
00077 }
00078
00079 int *localSharedNodeList = (int *)malloc(localSharedNodes.size()*sizeof(int));
00080 for (int m=0; m<localSharedNodes.size(); m++) {
00081 localSharedNodeList[m] = localSharedNodes[m];
00082 }
00083 sharedNodeCounts[source] = localSharedNodes.size();
00084 sharedNodeLists[source] = localSharedNodeList;
00085
00086
00087 MPI_Send((int *)&remoteSharedNodes[0], remoteSharedNodes.size(), MPI_INT, source,
00088 sharedlist_msg_tag, comm);
00089
00090 free(recvNodeCoords);
00091 }
00092 for (int i=rank+1; i<comm_size; i++) {
00093 int *sharedNodes;
00094 MPI_Status *status;
00095 int source, length;
00096
00097 MPI_Probe(MPI_ANY_SOURCE, sharedlist_msg_tag, MPI_Comm comm, status);
00098 source = status.MPI_SOURCE;
00099 length = status.MPI_LENGTH;
00100
00101 sharedNodes = (int *)malloc(length*sizeof(int));
00102 MPI_Recv((void*)sharedNodes, length, MPI_INT, source, sharedlist_msg_tag, comm);
00103
00104 sharedNodeCounts[source] = length;
00105 sharedNodeLists[source] = sharedNodes;
00106
00107
00108 }
00109
00110
00111
00112
00113 free(nodeCoords);
00114 free(sharedNodeCounts);
00115 for (int i=0; i<comm_size; i++) {
00116 if (sharedNodeLists[i])
00117 free(sharedNodeLists[i]);
00118 }
00119 free(sharedNodeLists);
00120 }