Changeset 2506
- Timestamp:
- 05/31/23 12:20:29 (13 months ago)
- Location:
- XIOS2/trunk/extern/remap/src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS2/trunk/extern/remap/src/elt.hpp
r1614 r2506 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 }; -
XIOS2/trunk/extern/remap/src/intersection_ym.cpp
r1588 r2506 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) ; -
XIOS2/trunk/extern/remap/src/libmapper.cpp
r1639 r2506 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 } -
XIOS2/trunk/extern/remap/src/mapper.cpp
r1639 r2506 145 145 nIntersections++; 146 146 } 147 147 148 /* overallocate for NMAX neighbours for each elements */ 149 /* 148 150 remapMatrix = new double[nIntersections*NMAX]; 149 151 srcAddress = new int[nIntersections*NMAX]; … … 152 154 sourceWeightId =new long[nIntersections*NMAX]; 153 155 targetWeightId =new long[nIntersections*NMAX]; 154 156 */ 155 157 156 158 if (mpiRank == 0 && verbose) cout << "Remapping..." << endl; … … 186 188 187 189 int *nbSendElement = new int[mpiSize]; 190 int *nbSendVertex = new int[mpiSize]; 188 191 int **sendElement = new int*[mpiSize]; /* indices of elements required from other rank */ 189 192 double **recvValue = new double*[mpiSize]; 190 193 double **recvArea = new double*[mpiSize]; 191 194 double **recvGivenArea = new double*[mpiSize]; 195 int **recvVertexOffset = new int*[mpiSize]; 192 196 Coord **recvGrad = new Coord*[mpiSize]; 193 197 GloId **recvNeighIds = new GloId*[mpiSize]; /* ids of the of the source neighbours which also contribute through gradient */ … … 210 214 { 211 215 sendElement[rank] = new int[nbSendElement[rank]]; 212 recvValue[rank] = new double[nbSendElement[rank]];213 recvArea[rank] = new double[nbSendElement[rank]];214 recvGivenArea[rank] = new double[nbSendElement[rank]];215 if (order == 2)216 {217 recvNeighIds[rank] = new GloId[nbSendElement[rank]*(NMAX+1)];218 recvGrad[rank] = new Coord[nbSendElement[rank]*(NMAX+1)];219 }220 else221 recvNeighIds[rank] = new GloId[nbSendElement[rank]];222 223 216 last = -1; 224 217 index = -1; … … 235 228 /* communicate sizes of source elements to be sent (index lists and later values and gradients) */ 236 229 int *nbRecvElement = new int[mpiSize]; 230 int *nbRecvVertex = new int[mpiSize]; 237 231 MPI_Alltoall(nbSendElement, 1, MPI_INT, nbRecvElement, 1, MPI_INT, communicator); 238 232 … … 244 238 double **sendArea = new double*[mpiSize]; 245 239 double **sendGivenArea = new double*[mpiSize]; 240 int **sendVertexOffset = new int*[mpiSize]; 246 241 Coord **sendGrad = new Coord*[mpiSize]; 247 242 GloId **sendNeighIds = new GloId*[mpiSize]; 248 MPI_Request *sendRequest = new MPI_Request[ 5*mpiSize];249 MPI_Request *recvRequest = new MPI_Request[ 5*mpiSize];243 MPI_Request *sendRequest = new MPI_Request[6*mpiSize]; 244 MPI_Request *recvRequest = new MPI_Request[6*mpiSize]; 250 245 for (int rank = 0; rank < mpiSize; rank++) 251 246 { … … 259 254 { 260 255 recvElement[rank] = new int[nbRecvElement[rank]]; 256 MPI_Irecv(recvElement[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 257 nbRecvRequest++; 258 } 259 } 260 MPI_Status *status = new MPI_Status[6*mpiSize]; 261 262 MPI_Waitall(nbSendRequest, sendRequest, status); 263 MPI_Waitall(nbRecvRequest, recvRequest, status); 264 265 nbSendRequest = 0; 266 nbRecvRequest = 0; 267 268 for (int rank = 0; rank < mpiSize; rank++) 269 { 270 if (nbRecvElement[rank] > 0) 271 { 272 nbRecvVertex[rank]=0 ; 273 for (int j = 0; j < nbRecvElement[rank]; j++) nbRecvVertex[rank]+=sstree.localElements[recvElement[rank][j]].n+1; 274 MPI_Issend(&nbRecvVertex[rank], 1, MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 275 nbSendRequest++; 276 } 277 278 if (nbSendElement[rank] > 0) 279 { 280 MPI_Irecv(&nbSendVertex[rank], 1, MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 281 nbRecvRequest++; 282 } 283 } 284 285 MPI_Waitall(nbSendRequest, sendRequest, status); 286 MPI_Waitall(nbRecvRequest, recvRequest, status); 287 288 289 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ 290 nbSendRequest = 0; 291 nbRecvRequest = 0; 292 for (int rank = 0; rank < mpiSize; rank++) 293 { 294 if (nbRecvElement[rank] > 0) 295 { 261 296 sendValue[rank] = new double[nbRecvElement[rank]]; 262 297 sendArea[rank] = new double[nbRecvElement[rank]]; 263 298 sendGivenArea[rank] = new double[nbRecvElement[rank]]; 299 sendVertexOffset[rank] = new int[nbRecvElement[rank]]; 300 264 301 if (order == 2) 265 302 { 266 sendNeighIds[rank] = new GloId[nbRecvElement[rank]*(NMAX+1)]; 267 sendGrad[rank] = new Coord[nbRecvElement[rank]*(NMAX+1)]; 268 } 269 else 270 { 271 sendNeighIds[rank] = new GloId[nbRecvElement[rank]]; 272 } 273 MPI_Irecv(recvElement[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 274 nbRecvRequest++; 275 } 276 } 277 MPI_Status *status = new MPI_Status[5*mpiSize]; 278 279 MPI_Waitall(nbSendRequest, sendRequest, status); 280 MPI_Waitall(nbRecvRequest, recvRequest, status); 281 282 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ 283 nbSendRequest = 0; 284 nbRecvRequest = 0; 285 for (int rank = 0; rank < mpiSize; rank++) 286 { 287 if (nbRecvElement[rank] > 0) 288 { 303 sendNeighIds[rank] = new GloId[nbRecvVertex[rank]]; 304 sendGrad[rank] = new Coord[nbRecvVertex[rank]]; 305 } 306 else sendNeighIds[rank] = new GloId[nbRecvElement[rank]]; 307 289 308 int jj = 0; // jj == j if no weight writing 309 sendVertexOffset[rank][0]=0 ; 290 310 for (int j = 0; j < nbRecvElement[rank]; j++) 291 311 { … … 293 313 sendArea[rank][j] = sstree.localElements[recvElement[rank][j]].area; 294 314 sendGivenArea[rank][j] = sstree.localElements[recvElement[rank][j]].given_area; 315 316 if (j==0) 317 { 318 if (order==2) sendVertexOffset[rank][j]=sstree.localElements[recvElement[rank][j]].n+1 ; 319 else sendVertexOffset[rank][j]=1 ; 320 } 321 else 322 { 323 if (order == 2) sendVertexOffset[rank][j] = sendVertexOffset[rank][j-1]+sstree.localElements[recvElement[rank][j]].n+1 ; 324 else sendVertexOffset[rank][j] = sendVertexOffset[rank][j-1]+1 ; 325 } 326 295 327 if (order == 2) 296 328 { … … 299 331 sendNeighIds[rank][jj] = sstree.localElements[recvElement[rank][j]].src_id; 300 332 jj++; 301 for (int i = 0; i < NMAX; i++)333 for (int i = 0; i < sstree.localElements[recvElement[rank][j]].n ; i++) 302 334 { 303 335 sendGrad[rank][jj] = sstree.localElements[recvElement[rank][j]].gradNeigh[i]; … … 316 348 MPI_Issend(sendGivenArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 317 349 nbSendRequest++; 350 MPI_Issend(sendVertexOffset[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 351 nbSendRequest++; 352 318 353 if (order == 2) 319 354 { 320 MPI_Issend(sendGrad[rank], 3*nbRecv Element[rank]*(NMAX+1), MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]);355 MPI_Issend(sendGrad[rank], 3*nbRecvVertex[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 321 356 nbSendRequest++; 322 MPI_Issend(sendNeighIds[rank], 4*nbRecv Element[rank]*(NMAX+1), MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]);357 MPI_Issend(sendNeighIds[rank], 4*nbRecvVertex[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 323 358 //ym --> attention taille GloId 324 359 nbSendRequest++; … … 333 368 if (nbSendElement[rank] > 0) 334 369 { 370 recvValue[rank] = new double[nbSendElement[rank]]; 371 recvArea[rank] = new double[nbSendElement[rank]]; 372 recvGivenArea[rank] = new double[nbSendElement[rank]]; 373 recvVertexOffset[rank] = new int[nbSendElement[rank]]; 374 375 if (order == 2) 376 { 377 recvNeighIds[rank] = new GloId[nbSendVertex[rank]]; 378 recvGrad[rank] = new Coord[nbSendVertex[rank]]; 379 } 380 else recvNeighIds[rank] = new GloId[nbSendElement[rank]]; 381 382 335 383 MPI_Irecv(recvValue[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 336 384 nbRecvRequest++; … … 339 387 MPI_Irecv(recvGivenArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 340 388 nbRecvRequest++; 389 MPI_Irecv(recvVertexOffset[rank], nbSendElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 390 nbRecvRequest++; 391 341 392 if (order == 2) 342 393 { 343 MPI_Irecv(recvGrad[rank], 3*nbSendElement[rank]*(NMAX+1), 344 MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 394 MPI_Irecv(recvGrad[rank], 3*nbSendVertex[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 345 395 nbRecvRequest++; 346 MPI_Irecv(recvNeighIds[rank], 4*nbSend Element[rank]*(NMAX+1), MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]);396 MPI_Irecv(recvNeighIds[rank], 4*nbSendVertex[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 347 397 //ym --> attention taille GloId 348 398 nbRecvRequest++; … … 357 407 } 358 408 359 409 MPI_Waitall(nbSendRequest, sendRequest, status); 360 410 MPI_Waitall(nbRecvRequest, recvRequest, status); 361 411 … … 388 438 389 439 /* first order: src value times weight (weight = supermesh area), later divide by target area */ 390 int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 391 GloId neighID = recvNeighIds[rank][kk]; 440 // int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 441 int offset ; 442 int nvertex ; 443 if (n1==0) 444 { 445 offset=0 ; 446 nvertex=recvVertexOffset[rank][0] ; 447 } 448 else 449 { 450 offset = recvVertexOffset[rank][n1-1]; 451 nvertex = recvVertexOffset[rank][n1]-recvVertexOffset[rank][n1-1]; 452 } 453 454 GloId neighID = recvNeighIds[rank][offset]; 392 455 wgt_map[neighID] += w; 393 456 394 457 if (order == 2) 395 458 { 396 for (int k = 0; k < NMAX+1; k++)459 for (int k = 0; k < nvertex; k++) 397 460 { 398 int kk = n1 * (NMAX + 1)+ k;461 int kk = offset + k; 399 462 GloId neighID = recvNeighIds[rank][kk]; 400 463 if (neighID.ind != -1) wgt_map[neighID] += w * scalarprod(recvGrad[rank][kk], (*it)->x); … … 414 477 for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) 415 478 { 416 if (quantity) this->remapMatrix [i] = (it->second ) / renorm;417 else this->remapMatrix [i] = (it->second / e.area) / renorm;418 this->srcAddress [i] = it->first.ind;419 this->srcRank [i] = it->first.rank;420 this->dstAddress [i] = j;421 this->sourceWeightId [i]= it->first.globalId;422 this->targetWeightId [i]= targetGlobalId[j];479 if (quantity) this->remapMatrix.push_back((it->second ) / renorm); 480 else this->remapMatrix.push_back((it->second / e.area) / renorm); 481 this->srcAddress.push_back(it->first.ind); 482 this->srcRank.push_back(it->first.rank); 483 this->dstAddress.push_back(j); 484 this->sourceWeightId.push_back(it->first.globalId) ; 485 this->targetWeightId.push_back(targetGlobalId[j]) ; 423 486 i++; 424 487 } … … 434 497 delete[] recvArea[rank]; 435 498 delete[] recvGivenArea[rank]; 499 delete[] recvVertexOffset[rank]; 436 500 if (order == 2) 437 501 { … … 446 510 delete[] sendArea[rank]; 447 511 delete[] sendGivenArea[rank]; 512 delete[] sendVertexOffset[rank]; 448 513 if (order == 2) 449 514 delete[] sendGrad[rank]; … … 457 522 delete[] nbSendElement; 458 523 delete[] nbRecvElement; 524 delete[] nbSendVertex; 525 delete[] nbRecvVertex; 459 526 delete[] sendElement; 460 527 delete[] recvElement; … … 939 1006 Mapper::~Mapper() 940 1007 { 941 delete [] remapMatrix; 942 delete [] srcAddress; 943 delete [] srcRank; 944 delete [] dstAddress; 945 if (neighbourElements) delete [] neighbourElements; 946 } 947 948 } 1008 1009 } 1010 1011 } -
XIOS2/trunk/extern/remap/src/mapper.hpp
r2088 r2506 41 41 */ 42 42 /* where weights are returned after call to `computeWeights` */ 43 double *remapMatrix;44 int *srcAddress;45 int *srcRank;46 int *dstAddress;43 std::vector<double> remapMatrix; 44 std::vector<int> srcAddress; 45 std::vector<int> srcRank; 46 std::vector<int> dstAddress; 47 47 int nWeights; 48 long int*sourceWeightId ;49 long int*targetWeightId ;48 std::vector<long int> sourceWeightId ; 49 std::vector<long int> targetWeightId ; 50 50 51 51 private: -
XIOS2/trunk/extern/remap/src/meshutil.cpp
r2502 r2506 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 } -
XIOS2/trunk/extern/remap/src/polyg.cpp
r2500 r2506 298 298 e.n = *((int *) & (buffer[pos])); 299 299 pos += sizeof(int); 300 300 301 e.allocate() ; 302 301 303 for (int i = 0; i < e.n; i++) 302 304 {
Note: See TracChangeset
for help on using the changeset viewer.