Changeset 2538
- Timestamp:
- 07/24/23 11:55:12 (18 months ago)
- Location:
- XIOS3/trunk/extern/remap/src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS3/trunk/extern/remap/src/elt.hpp
r1614 r2538 3 3 #include <list> 4 4 #include "triple.hpp" 5 #include <vector> 5 6 6 #define NMAX 10 /**< maximum number of vertices for polygons */7 #define NMAX 0 /**< maximum number of vertices for polygons */ 7 8 8 9 #define NOT_FOUND -1 … … 58 59 { 59 60 int k = 0; 61 vertex.resize(max_num_vert) ; 60 62 vertex[k++] = xyz(bounds_lon[0], bounds_lat[0]); 61 63 for (int i = 1; i < max_num_vert; i++) … … 72 74 } 73 75 n = k; 74 x = barycentre(vertex, n); 76 vertex.resize(n) ; 77 vertex.shrink_to_fit(); 78 allocate() ; 79 80 x = barycentre(vertex.data(), n); 75 81 } 76 82 void allocate(void) 83 { 84 vertex.resize(n) ; 85 neighbour.resize(n) ; 86 d.resize(n) ; 87 edge.resize(n) ; 88 gradNeigh.resize(n) ; 89 neighId.resize(n) ; 90 } 77 91 Elt& operator=(const Elt& rhs) 78 92 { … … 87 101 is = rhs.is; 88 102 89 for(int i = 0; i < NMAX; i++) 90 { 91 neighbour[i] = rhs.neighbour[i]; 92 d[i] = rhs.d[i]; 93 edge[i] = rhs.edge[i]; 94 vertex[i] = rhs.vertex[i]; 95 gradNeigh[i] = rhs.gradNeigh[i]; 96 } 103 neighbour = rhs.neighbour; 104 d = rhs.d; 105 edge = rhs.edge; 106 vertex = rhs.vertex; 107 gradNeigh = rhs.gradNeigh; 97 108 return *this; 98 109 } … … 109 120 void insert_vertex(int i, const Coord& v) 110 121 { 122 vertex.resize(n+1) ; 123 edge.resize(n+1) ; 124 d.resize(n+1) ; 125 neighbour.resize(n+1) ; 126 gradNeigh.resize(n+1) ; 127 neighId.resize(n+1) ; 128 111 129 for(int j=n; j > i ; j--) 112 130 { … … 120 138 } 121 139 122 int neighbour[NMAX];123 double d[NMAX]; /**< distance of centre of small circle to origin, zero if great circle */140 std::vector<int> neighbour; 141 std::vector<double> d; /**< distance of centre of small circle to origin, zero if great circle */ 124 142 double val; /**< value (sample if src element, interpolated if dest element) */ 125 Coord vertex[NMAX];126 Coord edge[NMAX]; /**< edge normals: if great circle tangential to sphere, if small circle parallel to pole */143 std::vector<Coord> vertex; 144 std::vector<Coord> edge; /**< edge normals: if great circle tangential to sphere, if small circle parallel to pole */ 127 145 Coord grad; /**< gradient of the reconstructed linear function over this element */ 128 Coord gradNeigh[NMAX]; /**< for weight computation: gradients for val=1 at individual neighbours */129 st ruct GloId neighId[NMAX]; /**< weight computation needs to know global IDs for all sources with "link" */146 std::vector<Coord> gradNeigh; /**< for weight computation: gradients for val=1 at individual neighbours */ 147 std::vector<struct GloId> neighId; /**< weight computation needs to know global IDs for all sources with "link" */ 130 148 std::list<Polyg*> is; /**< intersections */ 131 149 }; -
XIOS3/trunk/extern/remap/src/intersection_ym.cpp
r2269 r2538 47 47 Coord *b_gno = new Coord[nb]; 48 48 49 Coord OC=barycentre(a->vertex ,a->n) ;49 Coord OC=barycentre(a->vertex.data(),a->n) ; 50 50 Coord Oz=OC ; 51 51 Coord Ox=crossprod(Coord(0,0,1),Oz) ; -
XIOS3/trunk/extern/remap/src/libmapper.cpp
r1639 r2538 138 138 extern "C" void remap_get_weights(double* weights, int* src_indices, int* dst_indices) 139 139 { 140 memcpy(weights, mapper->remapMatrix , mapper->nWeights*sizeof(double));141 memcpy(src_indices, mapper->srcAddress , mapper->nWeights*sizeof(int));142 memcpy(dst_indices, mapper->dstAddress , mapper->nWeights*sizeof(int));140 memcpy(weights, mapper->remapMatrix.data(), mapper->nWeights*sizeof(double)); 141 memcpy(src_indices, mapper->srcAddress.data(), mapper->nWeights*sizeof(int)); 142 memcpy(dst_indices, mapper->dstAddress.data(), mapper->nWeights*sizeof(int)); 143 143 delete mapper; 144 144 } -
XIOS3/trunk/extern/remap/src/mapper.cpp
r2269 r2538 154 154 nIntersections++; 155 155 } 156 156 157 /* overallocate for NMAX neighbours for each elements */ 158 /* 157 159 remapMatrix = new double[nIntersections*NMAX]; 158 160 srcAddress = new int[nIntersections*NMAX]; … … 161 163 sourceWeightId =new long[nIntersections*NMAX]; 162 164 targetWeightId =new long[nIntersections*NMAX]; 163 165 */ 164 166 165 167 if (mpiRank == 0 && verbose) cout << "Remapping..." << endl; … … 195 197 196 198 int *nbSendElement = new int[mpiSize]; 199 int *nbSendVertex = new int[mpiSize]; 197 200 int **sendElement = new int*[mpiSize]; /* indices of elements required from other rank */ 198 201 double **recvValue = new double*[mpiSize]; 199 202 double **recvArea = new double*[mpiSize]; 200 203 double **recvGivenArea = new double*[mpiSize]; 204 int **recvVertexOffset = new int*[mpiSize]; 201 205 Coord **recvGrad = new Coord*[mpiSize]; 202 206 GloId **recvNeighIds = new GloId*[mpiSize]; /* ids of the of the source neighbours which also contribute through gradient */ … … 219 223 { 220 224 sendElement[rank] = new int[nbSendElement[rank]]; 221 recvValue[rank] = new double[nbSendElement[rank]];222 recvArea[rank] = new double[nbSendElement[rank]];223 recvGivenArea[rank] = new double[nbSendElement[rank]];224 if (order == 2)225 {226 recvNeighIds[rank] = new GloId[nbSendElement[rank]*(NMAX+1)];227 recvGrad[rank] = new Coord[nbSendElement[rank]*(NMAX+1)];228 }229 else230 recvNeighIds[rank] = new GloId[nbSendElement[rank]];231 232 225 last = -1; 233 226 index = -1; … … 244 237 /* communicate sizes of source elements to be sent (index lists and later values and gradients) */ 245 238 int *nbRecvElement = new int[mpiSize]; 239 int *nbRecvVertex = new int[mpiSize]; 246 240 MPI_Alltoall(nbSendElement, 1, MPI_INT, nbRecvElement, 1, MPI_INT, communicator); 247 241 … … 253 247 double **sendArea = new double*[mpiSize]; 254 248 double **sendGivenArea = new double*[mpiSize]; 249 int **sendVertexOffset = new int*[mpiSize]; 255 250 Coord **sendGrad = new Coord*[mpiSize]; 256 251 GloId **sendNeighIds = new GloId*[mpiSize]; 257 MPI_Request *sendRequest = new MPI_Request[ 5*mpiSize];258 MPI_Request *recvRequest = new MPI_Request[ 5*mpiSize];252 MPI_Request *sendRequest = new MPI_Request[6*mpiSize]; 253 MPI_Request *recvRequest = new MPI_Request[6*mpiSize]; 259 254 for (int rank = 0; rank < mpiSize; rank++) 260 255 { … … 268 263 { 269 264 recvElement[rank] = new int[nbRecvElement[rank]]; 265 MPI_Irecv(recvElement[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 266 nbRecvRequest++; 267 } 268 } 269 MPI_Status *status = new MPI_Status[6*mpiSize]; 270 271 MPI_Waitall(nbSendRequest, sendRequest, status); 272 MPI_Waitall(nbRecvRequest, recvRequest, status); 273 274 nbSendRequest = 0; 275 nbRecvRequest = 0; 276 277 for (int rank = 0; rank < mpiSize; rank++) 278 { 279 if (nbRecvElement[rank] > 0) 280 { 281 nbRecvVertex[rank]=0 ; 282 for (int j = 0; j < nbRecvElement[rank]; j++) nbRecvVertex[rank]+=sstree.localElements[recvElement[rank][j]].n+1; 283 MPI_Issend(&nbRecvVertex[rank], 1, MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 284 nbSendRequest++; 285 } 286 287 if (nbSendElement[rank] > 0) 288 { 289 MPI_Irecv(&nbSendVertex[rank], 1, MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 290 nbRecvRequest++; 291 } 292 } 293 294 MPI_Waitall(nbSendRequest, sendRequest, status); 295 MPI_Waitall(nbRecvRequest, recvRequest, status); 296 297 298 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ 299 nbSendRequest = 0; 300 nbRecvRequest = 0; 301 for (int rank = 0; rank < mpiSize; rank++) 302 { 303 if (nbRecvElement[rank] > 0) 304 { 270 305 sendValue[rank] = new double[nbRecvElement[rank]]; 271 306 sendArea[rank] = new double[nbRecvElement[rank]]; 272 307 sendGivenArea[rank] = new double[nbRecvElement[rank]]; 308 sendVertexOffset[rank] = new int[nbRecvElement[rank]]; 309 273 310 if (order == 2) 274 311 { 275 sendNeighIds[rank] = new GloId[nbRecvElement[rank]*(NMAX+1)]; 276 sendGrad[rank] = new Coord[nbRecvElement[rank]*(NMAX+1)]; 277 } 278 else 279 { 280 sendNeighIds[rank] = new GloId[nbRecvElement[rank]]; 281 } 282 MPI_Irecv(recvElement[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 283 nbRecvRequest++; 284 } 285 } 286 MPI_Status *status = new MPI_Status[5*mpiSize]; 287 288 MPI_Waitall(nbSendRequest, sendRequest, status); 289 MPI_Waitall(nbRecvRequest, recvRequest, status); 290 291 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ 292 nbSendRequest = 0; 293 nbRecvRequest = 0; 294 for (int rank = 0; rank < mpiSize; rank++) 295 { 296 if (nbRecvElement[rank] > 0) 297 { 312 sendNeighIds[rank] = new GloId[nbRecvVertex[rank]]; 313 sendGrad[rank] = new Coord[nbRecvVertex[rank]]; 314 } 315 else sendNeighIds[rank] = new GloId[nbRecvElement[rank]]; 316 298 317 int jj = 0; // jj == j if no weight writing 318 sendVertexOffset[rank][0]=0 ; 299 319 for (int j = 0; j < nbRecvElement[rank]; j++) 300 320 { … … 302 322 sendArea[rank][j] = sstree.localElements[recvElement[rank][j]].area; 303 323 sendGivenArea[rank][j] = sstree.localElements[recvElement[rank][j]].given_area; 324 325 if (j==0) 326 { 327 if (order==2) sendVertexOffset[rank][j]=sstree.localElements[recvElement[rank][j]].n+1 ; 328 else sendVertexOffset[rank][j]=1 ; 329 } 330 else 331 { 332 if (order == 2) sendVertexOffset[rank][j] = sendVertexOffset[rank][j-1]+sstree.localElements[recvElement[rank][j]].n+1 ; 333 else sendVertexOffset[rank][j] = sendVertexOffset[rank][j-1]+1 ; 334 } 335 304 336 if (order == 2) 305 337 { … … 308 340 sendNeighIds[rank][jj] = sstree.localElements[recvElement[rank][j]].src_id; 309 341 jj++; 310 for (int i = 0; i < NMAX; i++)342 for (int i = 0; i < sstree.localElements[recvElement[rank][j]].n ; i++) 311 343 { 312 344 sendGrad[rank][jj] = sstree.localElements[recvElement[rank][j]].gradNeigh[i]; … … 325 357 MPI_Issend(sendGivenArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 326 358 nbSendRequest++; 359 MPI_Issend(sendVertexOffset[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 360 nbSendRequest++; 361 327 362 if (order == 2) 328 363 { 329 MPI_Issend(sendGrad[rank], 3*nbRecv Element[rank]*(NMAX+1), MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]);364 MPI_Issend(sendGrad[rank], 3*nbRecvVertex[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 330 365 nbSendRequest++; 331 MPI_Issend(sendNeighIds[rank], 4*nbRecv Element[rank]*(NMAX+1), MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]);366 MPI_Issend(sendNeighIds[rank], 4*nbRecvVertex[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 332 367 //ym --> attention taille GloId 333 368 nbSendRequest++; … … 342 377 if (nbSendElement[rank] > 0) 343 378 { 379 recvValue[rank] = new double[nbSendElement[rank]]; 380 recvArea[rank] = new double[nbSendElement[rank]]; 381 recvGivenArea[rank] = new double[nbSendElement[rank]]; 382 recvVertexOffset[rank] = new int[nbSendElement[rank]]; 383 384 if (order == 2) 385 { 386 recvNeighIds[rank] = new GloId[nbSendVertex[rank]]; 387 recvGrad[rank] = new Coord[nbSendVertex[rank]]; 388 } 389 else recvNeighIds[rank] = new GloId[nbSendElement[rank]]; 390 391 344 392 MPI_Irecv(recvValue[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 345 393 nbRecvRequest++; … … 348 396 MPI_Irecv(recvGivenArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 349 397 nbRecvRequest++; 398 MPI_Irecv(recvVertexOffset[rank], nbSendElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 399 nbRecvRequest++; 400 350 401 if (order == 2) 351 402 { 352 MPI_Irecv(recvGrad[rank], 3*nbSendElement[rank]*(NMAX+1), 353 MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 403 MPI_Irecv(recvGrad[rank], 3*nbSendVertex[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 354 404 nbRecvRequest++; 355 MPI_Irecv(recvNeighIds[rank], 4*nbSend Element[rank]*(NMAX+1), MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]);405 MPI_Irecv(recvNeighIds[rank], 4*nbSendVertex[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 356 406 //ym --> attention taille GloId 357 407 nbRecvRequest++; … … 366 416 } 367 417 368 418 MPI_Waitall(nbSendRequest, sendRequest, status); 369 419 MPI_Waitall(nbRecvRequest, recvRequest, status); 370 420 … … 397 447 398 448 /* first order: src value times weight (weight = supermesh area), later divide by target area */ 399 int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 400 GloId neighID = recvNeighIds[rank][kk]; 449 // int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 450 int offset ; 451 int nvertex ; 452 if (n1==0) 453 { 454 offset=0 ; 455 nvertex=recvVertexOffset[rank][0] ; 456 } 457 else 458 { 459 offset = recvVertexOffset[rank][n1-1]; 460 nvertex = recvVertexOffset[rank][n1]-recvVertexOffset[rank][n1-1]; 461 } 462 463 GloId neighID = recvNeighIds[rank][offset]; 401 464 wgt_map[neighID] += w; 402 465 403 466 if (order == 2) 404 467 { 405 for (int k = 0; k < NMAX+1; k++)468 for (int k = 0; k < nvertex; k++) 406 469 { 407 int kk = n1 * (NMAX + 1)+ k;470 int kk = offset + k; 408 471 GloId neighID = recvNeighIds[rank][kk]; 409 472 if (neighID.ind != -1) wgt_map[neighID] += w * scalarprod(recvGrad[rank][kk], (*it)->x); … … 423 486 for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) 424 487 { 425 if (quantity) this->remapMatrix [i] = (it->second ) / renorm;426 else this->remapMatrix [i] = (it->second / e.area) / renorm;427 this->srcAddress [i] = it->first.ind;428 this->srcRank [i] = it->first.rank;429 this->dstAddress [i] = j;430 this->sourceWeightId [i]= it->first.globalId;431 this->targetWeightId [i]= targetGlobalId[j];488 if (quantity) this->remapMatrix.push_back((it->second ) / renorm); 489 else this->remapMatrix.push_back((it->second / e.area) / renorm); 490 this->srcAddress.push_back(it->first.ind); 491 this->srcRank.push_back(it->first.rank); 492 this->dstAddress.push_back(j); 493 this->sourceWeightId.push_back(it->first.globalId) ; 494 this->targetWeightId.push_back(targetGlobalId[j]) ; 432 495 i++; 433 496 } … … 443 506 delete[] recvArea[rank]; 444 507 delete[] recvGivenArea[rank]; 508 delete[] recvVertexOffset[rank]; 445 509 if (order == 2) 446 510 { … … 455 519 delete[] sendArea[rank]; 456 520 delete[] sendGivenArea[rank]; 521 delete[] sendVertexOffset[rank]; 457 522 if (order == 2) 458 523 delete[] sendGrad[rank]; … … 466 531 delete[] nbSendElement; 467 532 delete[] nbRecvElement; 533 delete[] nbSendVertex; 534 delete[] nbRecvVertex; 468 535 delete[] sendElement; 469 536 delete[] recvElement; … … 956 1023 Mapper::~Mapper() 957 1024 { 958 delete [] remapMatrix;959 delete [] srcAddress;960 delete [] srcRank;961 delete [] dstAddress;962 delete [] sourceWeightId ;963 delete [] targetWeightId ;964 if (neighbourElements) delete [] neighbourElements;1025 //delete [] remapMatrix; 1026 //delete [] srcAddress; 1027 //delete [] srcRank; 1028 //delete [] dstAddress; 1029 //delete [] sourceWeightId ; 1030 //delete [] targetWeightId ; 1031 //if (neighbourElements) delete [] neighbourElements; 965 1032 CTimer::release() ; 966 1033 } -
XIOS3/trunk/extern/remap/src/mapper.hpp
r2269 r2538 42 42 */ 43 43 /* where weights are returned after call to `computeWeights` */ 44 double *remapMatrix;45 int *srcAddress;46 int *srcRank;47 int *dstAddress;44 std::vector<double> remapMatrix; 45 std::vector<int> srcAddress; 46 std::vector<int> srcRank; 47 std::vector<int> dstAddress; 48 48 int nWeights; 49 long int*sourceWeightId ;50 long int*targetWeightId ;49 std::vector<long int> sourceWeightId ; 50 std::vector<long int> targetWeightId ; 51 51 52 52 private: -
XIOS3/trunk/extern/remap/src/meshutil.cpp
r2534 r2538 24 24 Coord *a_gno = new Coord[na]; 25 25 26 Coord OC=barycentre(a.vertex ,a.n) ;26 Coord OC=barycentre(a.vertex.data(),a.n) ; 27 27 Coord Oz=OC ; 28 28 Coord Ox=crossprod(Coord(0,0,1),Oz) ; … … 67 67 { 68 68 bary = bary * (-1.) ; 69 switchOrientation(a.n, a.vertex ,a.edge,a.d) ;69 switchOrientation(a.n, a.vertex.data(),a.edge.data(),a.d.data()) ; 70 70 } 71 71 … … 79 79 void cptEltGeom(Elt& elt, const Coord &pole) 80 80 { 81 orient(elt.n, elt.vertex , elt.edge, elt.d, elt.x);81 orient(elt.n, elt.vertex.data(), elt.edge.data(), elt.d.data(), elt.x); 82 82 normals(elt, pole); 83 83 // Coord gg; … … 205 205 elts[j]->val = 0; 206 206 207 Elt *neighbours[NMAX];207 // Elt *neighbours[NMAX]; 208 208 for (int j = 0; j < N; j++) 209 209 { 210 vector<Elt*> neighbours(elts[j]->n) ; 211 210 212 for (int i = 0; i < elts[j]->n; i++) 211 213 if ( elts[j]->neighbour[i]== NOT_FOUND) neighbours[i]=NULL ; // no neighbour … … 223 225 /* for weight computation all values are always kept zero and only set to one when used .. */ 224 226 neighbours[i]->val = 1; 225 elts[j]->gradNeigh[i] = gradient(*(elts[j]), neighbours );227 elts[j]->gradNeigh[i] = gradient(*(elts[j]), neighbours.data()); 226 228 /* .. and right after zeroed again */ 227 229 neighbours[i]->val = 0; … … 234 236 } 235 237 238 /* not needed anymore 236 239 for(int i = elts[j]->n ; i < NMAX; i++) 237 240 { … … 239 242 elts[j]->neighId[i].ind = -1; // mark end 240 243 } 244 */ 241 245 /* For the most naive algorithm the case where the element itself is one must also be considered. 242 246 Thomas says this can later be optimized out. */ 243 247 elts[j]->val = 1; 244 elts[j]->grad = gradient(*(elts[j]), neighbours );248 elts[j]->grad = gradient(*(elts[j]), neighbours.data()); 245 249 elts[j]->val = 0; 246 250 } -
XIOS3/trunk/extern/remap/src/polyg.cpp
r2537 r2538 304 304 e.n = *((int *) & (buffer[pos])); 305 305 pos += sizeof(int); 306 306 307 e.allocate() ; 308 307 309 for (int i = 0; i < e.n; i++) 308 310 {
Note: See TracChangeset
for help on using the changeset viewer.