Changeset 1630
- Timestamp:
- 12/21/18 09:19:12 (4 years ago)
- Location:
- XIOS/dev/dev_trunk_omp
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_trunk_omp/extern/remap/src/elt.hpp
r1619 r1630 48 48 int n; /* number of vertices */ 49 49 double area; 50 double given_area ;51 50 Coord x; /* barycentre */ 52 51 }; … … 81 80 n = rhs.n; 82 81 area = rhs.area; 83 given_area = rhs.given_area;84 82 x = rhs.x; 85 83 val = rhs.val; -
XIOS/dev/dev_trunk_omp/extern/remap/src/libmapper.cpp
r1619 r1630 43 43 assert(n_cell_dst >= 4); 44 44 assert(1 <= order && order <= 2); 45 double* src_area=NULL ; 46 double* dst_area=NULL ; 45 47 46 mapper = new Mapper(MPI_COMM_WORLD); 48 47 mapper->setVerbosity(PROGRESS) ; 49 mapper->setSourceMesh(src_bounds_lon, src_bounds_lat, src_area,n_vert_per_cell_src, n_cell_src, src_pole ) ;50 mapper->setTargetMesh(dst_bounds_lon, dst_bounds_lat, dst_area,n_vert_per_cell_dst, n_cell_dst, dst_pole ) ;48 mapper->setSourceMesh(src_bounds_lon, src_bounds_lat, n_vert_per_cell_src, n_cell_src, src_pole ) ; 49 mapper->setTargetMesh(dst_bounds_lon, dst_bounds_lat, n_vert_per_cell_dst, n_cell_dst, dst_pole ) ; 51 50 52 51 /* -
XIOS/dev/dev_trunk_omp/extern/remap/src/mapper.cpp
r1619 r1630 29 29 void cptOffsetsFromLengths(const int *lengths, int *offsets, int sz) 30 30 { 31 32 33 34 } 35 36 37 void Mapper::setSourceMesh(const double* boundsLon, const double* boundsLat, const double* area,int nVertex, int nbCells, const double* pole, const long int* globalId)31 offsets[0] = 0; 32 for (int i = 1; i < sz; i++) 33 offsets[i] = offsets[i-1] + lengths[i-1]; 34 } 35 36 37 void Mapper::setSourceMesh(const double* boundsLon, const double* boundsLat, int nVertex, int nbCells, const double* pole, const long int* globalId) 38 38 { 39 39 srcGrid.pole = Coord(pole[0], pole[1], pole[2]); 40 40 41 42 43 44 45 46 41 int mpiRank, mpiSize; 42 MPI_Comm_rank(communicator, &mpiRank); 43 MPI_Comm_size(communicator, &mpiSize); 44 45 sourceElements.reserve(nbCells); 46 sourceMesh.reserve(nbCells); 47 47 sourceGlobalId.resize(nbCells) ; 48 48 … … 57 57 else sourceGlobalId.assign(globalId,globalId+nbCells); 58 58 59 60 61 62 63 64 59 for (int i = 0; i < nbCells; i++) 60 { 61 int offs = i*nVertex; 62 Elt elt(boundsLon + offs, boundsLat + offs, nVertex); 63 elt.src_id.rank = mpiRank; 64 elt.src_id.ind = i; 65 65 elt.src_id.globalId = sourceGlobalId[i]; 66 sourceElements.push_back(elt); 67 sourceMesh.push_back(Node(elt.x, cptRadius(elt), &sourceElements.back())); 68 cptEltGeom(sourceElements[i], Coord(pole[0], pole[1], pole[2])); 69 if (area!=NULL) sourceElements[i].given_area=area[i] ; 70 else sourceElements[i].given_area=sourceElements[i].area ; 71 } 72 73 } 74 75 void Mapper::setTargetMesh(const double* boundsLon, const double* boundsLat, const double* area, int nVertex, int nbCells, const double* pole, const long int* globalId) 66 sourceElements.push_back(elt); 67 sourceMesh.push_back(Node(elt.x, cptRadius(elt), &sourceElements.back())); 68 cptEltGeom(sourceElements[i], Coord(pole[0], pole[1], pole[2])); 69 } 70 71 } 72 73 void Mapper::setTargetMesh(const double* boundsLon, const double* boundsLat, int nVertex, int nbCells, const double* pole, const long int* globalId) 76 74 { 77 75 tgtGrid.pole = Coord(pole[0], pole[1], pole[2]); 78 76 79 80 81 82 83 84 77 int mpiRank, mpiSize; 78 MPI_Comm_rank(communicator, &mpiRank); 79 MPI_Comm_size(communicator, &mpiSize); 80 81 targetElements.reserve(nbCells); 82 targetMesh.reserve(nbCells); 85 83 86 84 targetGlobalId.resize(nbCells) ; … … 95 93 else targetGlobalId.assign(globalId,globalId+nbCells); 96 94 97 for (int i = 0; i < nbCells; i++) 98 { 99 int offs = i*nVertex; 100 Elt elt(boundsLon + offs, boundsLat + offs, nVertex); 101 targetElements.push_back(elt); 102 targetMesh.push_back(Node(elt.x, cptRadius(elt), &sourceElements.back())); 103 cptEltGeom(targetElements[i], Coord(pole[0], pole[1], pole[2])); 104 if (area!=NULL) targetElements[i].given_area=area[i] ; 105 else targetElements[i].given_area=targetElements[i].area ; 106 } 95 for (int i = 0; i < nbCells; i++) 96 { 97 int offs = i*nVertex; 98 Elt elt(boundsLon + offs, boundsLat + offs, nVertex); 99 targetElements.push_back(elt); 100 targetMesh.push_back(Node(elt.x, cptRadius(elt), &sourceElements.back())); 101 cptEltGeom(targetElements[i], Coord(pole[0], pole[1], pole[2])); 102 } 107 103 108 104 … … 123 119 vector<double> Mapper::computeWeights(int interpOrder, bool renormalize, bool quantity) 124 120 { 125 126 127 128 121 vector<double> timings; 122 int mpiSize, mpiRank; 123 MPI_Comm_size(communicator, &mpiSize); 124 MPI_Comm_rank(communicator, &mpiRank); 129 125 130 126 this->buildSSTree(sourceMesh, targetMesh); 131 127 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 128 if (mpiRank == 0 && verbose) cout << "Computing intersections ..." << endl; 129 double tic = cputime(); 130 computeIntersection(&targetElements[0], targetElements.size()); 131 timings.push_back(cputime() - tic); 132 133 tic = cputime(); 134 if (interpOrder == 2) { 135 if (mpiRank == 0 && verbose) cout << "Computing grads ..." << endl; 136 buildMeshTopology(); 137 computeGrads(); 138 } 139 timings.push_back(cputime() - tic); 140 141 /* Prepare computation of weights */ 142 /* compute number of intersections which for the first order case 147 143 corresponds to the number of edges in the remap matrix */ 148 149 150 151 152 153 154 155 156 157 158 159 144 int nIntersections = 0; 145 for (int j = 0; j < targetElements.size(); j++) 146 { 147 Elt &elt = targetElements[j]; 148 for (list<Polyg*>::iterator it = elt.is.begin(); it != elt.is.end(); it++) 149 nIntersections++; 150 } 151 /* overallocate for NMAX neighbours for each elements */ 152 remapMatrix = new double[nIntersections*NMAX]; 153 srcAddress = new int[nIntersections*NMAX]; 154 srcRank = new int[nIntersections*NMAX]; 155 dstAddress = new int[nIntersections*NMAX]; 160 156 sourceWeightId =new long[nIntersections*NMAX]; 161 157 targetWeightId =new long[nIntersections*NMAX]; 162 158 163 159 164 165 166 167 160 if (mpiRank == 0 && verbose) cout << "Remapping..." << endl; 161 tic = cputime(); 162 nWeights = remap(&targetElements[0], targetElements.size(), interpOrder, renormalize, quantity); 163 timings.push_back(cputime() - tic); 168 164 169 165 for (int i = 0; i < targetElements.size(); i++) targetElements[i].delete_intersections(); 170 166 171 167 return timings; 172 168 } 173 169 … … 180 176 int Mapper::remap(Elt *elements, int nbElements, int order, bool renormalize, bool quantity) 181 177 { 182 int mpiSize, mpiRank; 183 MPI_Comm_size(communicator, &mpiSize); 184 MPI_Comm_rank(communicator, &mpiRank); 185 186 /* create list of intersections (super mesh elements) for each rank */ 187 multimap<int, Polyg *> *elementList = new multimap<int, Polyg *>[mpiSize]; 188 for (int j = 0; j < nbElements; j++) 189 { 190 Elt& e = elements[j]; 191 for (list<Polyg *>::iterator it = e.is.begin(); it != e.is.end(); it++) 192 elementList[(*it)->id.rank].insert(pair<int, Polyg *>((*it)->id.ind, *it)); 193 } 194 195 int *nbSendElement = new int[mpiSize]; 196 int **sendElement = new int*[mpiSize]; /* indices of elements required from other rank */ 197 double **recvValue = new double*[mpiSize]; 198 double **recvArea = new double*[mpiSize]; 199 double **recvGivenArea = new double*[mpiSize]; 200 Coord **recvGrad = new Coord*[mpiSize]; 201 GloId **recvNeighIds = new GloId*[mpiSize]; /* ids of the of the source neighbours which also contribute through gradient */ 202 for (int rank = 0; rank < mpiSize; rank++) 203 { 204 /* get size for allocation */ 205 int last = -1; /* compares unequal to any index */ 206 int index = -1; /* increased to starting index 0 in first iteration */ 207 for (multimap<int, Polyg *>::iterator it = elementList[rank].begin(); it != elementList[rank].end(); ++it) 208 { 209 if (last != it->first) 210 index++; 211 (it->second)->id.ind = index; 212 last = it->first; 213 } 214 nbSendElement[rank] = index + 1; 215 216 /* if size is non-zero allocate and collect indices of elements on other ranks that we intersect */ 217 if (nbSendElement[rank] > 0) 218 { 219 sendElement[rank] = new int[nbSendElement[rank]]; 220 recvValue[rank] = new double[nbSendElement[rank]]; 221 recvArea[rank] = new double[nbSendElement[rank]]; 222 recvGivenArea[rank] = new double[nbSendElement[rank]]; 223 if (order == 2) 224 { 225 recvNeighIds[rank] = new GloId[nbSendElement[rank]*(NMAX+1)]; 226 recvGrad[rank] = new Coord[nbSendElement[rank]*(NMAX+1)]; 227 } 228 else 229 recvNeighIds[rank] = new GloId[nbSendElement[rank]]; 230 231 last = -1; 232 index = -1; 233 for (multimap<int, Polyg *>::iterator it = elementList[rank].begin(); it != elementList[rank].end(); ++it) 234 { 235 if (last != it->first) 236 index++; 237 sendElement[rank][index] = it->first; 238 last = it->first; 239 } 240 } 241 } 242 243 /* communicate sizes of source elements to be sent (index lists and later values and gradients) */ 244 int *nbRecvElement = new int[mpiSize]; 245 MPI_Alltoall(nbSendElement, 1, MPI_INT, nbRecvElement, 1, MPI_INT, communicator); 246 247 /* communicate indices of source elements on other ranks whoes value and gradient we need (since intersection) */ 248 int nbSendRequest = 0; 249 int nbRecvRequest = 0; 250 int **recvElement = new int*[mpiSize]; 251 double **sendValue = new double*[mpiSize]; 252 double **sendArea = new double*[mpiSize]; 253 double **sendGivenArea = new double*[mpiSize]; 254 Coord **sendGrad = new Coord*[mpiSize]; 255 GloId **sendNeighIds = new GloId*[mpiSize]; 256 MPI_Request *sendRequest = new MPI_Request[5*mpiSize]; 257 MPI_Request *recvRequest = new MPI_Request[5*mpiSize]; 258 for (int rank = 0; rank < mpiSize; rank++) 259 { 260 if (nbSendElement[rank] > 0) 261 { 262 MPI_Issend(sendElement[rank], nbSendElement[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 263 nbSendRequest++; 264 } 265 266 if (nbRecvElement[rank] > 0) 267 { 268 recvElement[rank] = new int[nbRecvElement[rank]]; 269 sendValue[rank] = new double[nbRecvElement[rank]]; 270 sendArea[rank] = new double[nbRecvElement[rank]]; 271 sendGivenArea[rank] = new double[nbRecvElement[rank]]; 272 if (order == 2) 273 { 274 sendNeighIds[rank] = new GloId[nbRecvElement[rank]*(NMAX+1)]; 275 sendGrad[rank] = new Coord[nbRecvElement[rank]*(NMAX+1)]; 276 } 277 else 278 { 279 sendNeighIds[rank] = new GloId[nbRecvElement[rank]]; 280 } 281 MPI_Irecv(recvElement[rank], nbRecvElement[rank], MPI_INT, rank, 0, communicator, &recvRequest[nbRecvRequest]); 282 nbRecvRequest++; 283 } 284 } 285 MPI_Status *status = new MPI_Status[5*mpiSize]; 286 287 MPI_Waitall(nbSendRequest, sendRequest, status); 178 int mpiSize, mpiRank; 179 MPI_Comm_size(communicator, &mpiSize); 180 MPI_Comm_rank(communicator, &mpiRank); 181 182 /* create list of intersections (super mesh elements) for each rank */ 183 multimap<int, Polyg *> *elementList = new multimap<int, Polyg *>[mpiSize]; 184 for (int j = 0; j < nbElements; j++) 185 { 186 Elt& e = elements[j]; 187 for (list<Polyg *>::iterator it = e.is.begin(); it != e.is.end(); it++) 188 elementList[(*it)->id.rank].insert(pair<int, Polyg *>((*it)->id.ind, *it)); 189 } 190 191 int *nbSendElement = new int[mpiSize]; 192 int **sendElement = new int*[mpiSize]; /* indices of elements required from other rank */ 193 double **recvValue = new double*[mpiSize]; 194 double **recvArea = new double*[mpiSize]; 195 Coord **recvGrad = new Coord*[mpiSize]; 196 GloId **recvNeighIds = new GloId*[mpiSize]; /* ids of the of the source neighbours which also contribute through gradient */ 197 for (int rank = 0; rank < mpiSize; rank++) 198 { 199 /* get size for allocation */ 200 int last = -1; /* compares unequal to any index */ 201 int index = -1; /* increased to starting index 0 in first iteration */ 202 for (multimap<int, Polyg *>::iterator it = elementList[rank].begin(); it != elementList[rank].end(); ++it) 203 { 204 if (last != it->first) 205 index++; 206 (it->second)->id.ind = index; 207 last = it->first; 208 } 209 nbSendElement[rank] = index + 1; 210 211 /* if size is non-zero allocate and collect indices of elements on other ranks that we intersect */ 212 if (nbSendElement[rank] > 0) 213 { 214 sendElement[rank] = new int[nbSendElement[rank]]; 215 recvValue[rank] = new double[nbSendElement[rank]]; 216 recvArea[rank] = new double[nbSendElement[rank]]; 217 if (order == 2) 218 { 219 recvNeighIds[rank] = new GloId[nbSendElement[rank]*(NMAX+1)]; 220 recvGrad[rank] = new Coord[nbSendElement[rank]*(NMAX+1)]; 221 } 222 else 223 recvNeighIds[rank] = new GloId[nbSendElement[rank]]; 224 225 last = -1; 226 index = -1; 227 for (multimap<int, Polyg *>::iterator it = elementList[rank].begin(); it != elementList[rank].end(); ++it) 228 { 229 if (last != it->first) 230 index++; 231 sendElement[rank][index] = it->first; 232 last = it->first; 233 } 234 } 235 } 236 237 /* communicate sizes of source elements to be sent (index lists and later values and gradients) */ 238 int *nbRecvElement = new int[mpiSize]; 239 MPI_Alltoall(nbSendElement, 1, MPI_INT, nbRecvElement, 1, MPI_INT, communicator); 240 241 /* communicate indices of source elements on other ranks whoes value and gradient we need (since intersection) */ 242 int nbSendRequest = 0; 243 int nbRecvRequest = 0; 244 int **recvElement = new int*[mpiSize]; 245 double **sendValue = new double*[mpiSize]; 246 double **sendArea = new double*[mpiSize]; 247 Coord **sendGrad = new Coord*[mpiSize]; 248 GloId **sendNeighIds = new GloId*[mpiSize]; 249 MPI_Request *sendRequest = new MPI_Request[4*mpiSize]; 250 MPI_Request *recvRequest = new MPI_Request[4*mpiSize]; 251 for (int rank = 0; rank < mpiSize; rank++) 252 { 253 if (nbSendElement[rank] > 0) 254 { 255 MPI_Issend(sendElement[rank], nbSendElement[rank], MPI_INT, rank, 0, communicator, &sendRequest[nbSendRequest]); 256 nbSendRequest++; 257 } 258 259 if (nbRecvElement[rank] > 0) 260 { 261 recvElement[rank] = new int[nbRecvElement[rank]]; 262 sendValue[rank] = new double[nbRecvElement[rank]]; 263 sendArea[rank] = new double[nbRecvElement[rank]]; 264 if (order == 2) 265 { 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[4*mpiSize]; 278 279 MPI_Waitall(nbSendRequest, sendRequest, status); 288 280 MPI_Waitall(nbRecvRequest, recvRequest, status); 289 281 290 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ 291 nbSendRequest = 0; 292 nbRecvRequest = 0; 293 for (int rank = 0; rank < mpiSize; rank++) 294 { 295 if (nbRecvElement[rank] > 0) 296 { 297 int jj = 0; // jj == j if no weight writing 298 for (int j = 0; j < nbRecvElement[rank]; j++) 299 { 300 sendValue[rank][j] = sstree.localElements[recvElement[rank][j]].val; 301 sendArea[rank][j] = sstree.localElements[recvElement[rank][j]].area; 302 sendGivenArea[rank][j] = sstree.localElements[recvElement[rank][j]].given_area; 303 if (order == 2) 304 { 305 sendGrad[rank][jj] = sstree.localElements[recvElement[rank][j]].grad; 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 { 289 int jj = 0; // jj == j if no weight writing 290 for (int j = 0; j < nbRecvElement[rank]; j++) 291 { 292 sendValue[rank][j] = sstree.localElements[recvElement[rank][j]].val; 293 sendArea[rank][j] = sstree.localElements[recvElement[rank][j]].area; 294 if (order == 2) 295 { 296 sendGrad[rank][jj] = sstree.localElements[recvElement[rank][j]].grad; 306 297 // cout<<"grad "<<jj<<" "<<recvElement[rank][j]<<" "<<sendGrad[rank][jj]<<" "<<sstree.localElements[recvElement[rank][j]].grad<<endl ; 307 308 309 310 311 298 sendNeighIds[rank][jj] = sstree.localElements[recvElement[rank][j]].src_id; 299 jj++; 300 for (int i = 0; i < NMAX; i++) 301 { 302 sendGrad[rank][jj] = sstree.localElements[recvElement[rank][j]].gradNeigh[i]; 312 303 // cout<<"grad "<<jj<<" "<<sendGrad[rank][jj]<<" "<<sstree.localElements[recvElement[rank][j]].grad<<endl ; 313 304 sendNeighIds[rank][jj] = sstree.localElements[recvElement[rank][j]].neighId[i]; 314 jj++; 315 } 316 } 317 else 318 sendNeighIds[rank][j] = sstree.localElements[recvElement[rank][j]].src_id; 319 } 320 MPI_Issend(sendValue[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 321 nbSendRequest++; 322 MPI_Issend(sendArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 1, communicator, &sendRequest[nbSendRequest]); 323 nbSendRequest++; 324 MPI_Issend(sendGivenArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 4, communicator, &sendRequest[nbSendRequest]); 325 nbSendRequest++; 326 if (order == 2) 327 { 328 MPI_Issend(sendGrad[rank], 3*nbRecvElement[rank]*(NMAX+1), MPI_DOUBLE, rank, 2, communicator, &sendRequest[nbSendRequest]); 329 nbSendRequest++; 330 MPI_Issend(sendNeighIds[rank], 4*nbRecvElement[rank]*(NMAX+1), MPI_INT, rank, 3, communicator, &sendRequest[nbSendRequest]); 305 jj++; 306 } 307 } 308 else 309 sendNeighIds[rank][j] = sstree.localElements[recvElement[rank][j]].src_id; 310 } 311 MPI_Issend(sendValue[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 312 nbSendRequest++; 313 MPI_Issend(sendArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 1, communicator, &sendRequest[nbSendRequest]); 314 nbSendRequest++; 315 if (order == 2) 316 { 317 MPI_Issend(sendGrad[rank], 3*nbRecvElement[rank]*(NMAX+1), 318 MPI_DOUBLE, rank, 2, communicator, &sendRequest[nbSendRequest]); 319 nbSendRequest++; 320 MPI_Issend(sendNeighIds[rank], 4*nbRecvElement[rank]*(NMAX+1), MPI_INT, rank, 3, communicator, &sendRequest[nbSendRequest]); 331 321 //ym --> attention taille GloId 332 333 334 335 336 MPI_Issend(sendNeighIds[rank], 4*nbRecvElement[rank], MPI_INT, rank, 5, communicator, &sendRequest[nbSendRequest]);322 nbSendRequest++; 323 } 324 else 325 { 326 MPI_Issend(sendNeighIds[rank], 4*nbRecvElement[rank], MPI_INT, rank, 4, communicator, &sendRequest[nbSendRequest]); 337 327 //ym --> attention taille GloId 338 nbSendRequest++; 339 } 340 } 341 if (nbSendElement[rank] > 0) 342 { 343 MPI_Irecv(recvValue[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 344 nbRecvRequest++; 345 MPI_Irecv(recvArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 1, communicator, &recvRequest[nbRecvRequest]); 346 nbRecvRequest++; 347 MPI_Irecv(recvGivenArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 4, communicator, &recvRequest[nbRecvRequest]); 348 nbRecvRequest++; 349 if (order == 2) 350 { 351 MPI_Irecv(recvGrad[rank], 3*nbSendElement[rank]*(NMAX+1), 352 MPI_DOUBLE, rank, 2, communicator, &recvRequest[nbRecvRequest]); 353 nbRecvRequest++; 354 MPI_Irecv(recvNeighIds[rank], 4*nbSendElement[rank]*(NMAX+1), MPI_INT, rank, 3, communicator, &recvRequest[nbRecvRequest]); 328 nbSendRequest++; 329 } 330 } 331 if (nbSendElement[rank] > 0) 332 { 333 MPI_Irecv(recvValue[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 334 nbRecvRequest++; 335 MPI_Irecv(recvArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 1, communicator, &recvRequest[nbRecvRequest]); 336 nbRecvRequest++; 337 if (order == 2) 338 { 339 MPI_Irecv(recvGrad[rank], 3*nbSendElement[rank]*(NMAX+1), 340 MPI_DOUBLE, rank, 2, communicator, &recvRequest[nbRecvRequest]); 341 nbRecvRequest++; 342 MPI_Irecv(recvNeighIds[rank], 4*nbSendElement[rank]*(NMAX+1), MPI_INT, rank, 3, communicator, &recvRequest[nbRecvRequest]); 355 343 //ym --> attention taille GloId 356 357 358 359 360 MPI_Irecv(recvNeighIds[rank], 4*nbSendElement[rank], MPI_INT, rank, 5, communicator, &recvRequest[nbRecvRequest]);344 nbRecvRequest++; 345 } 346 else 347 { 348 MPI_Irecv(recvNeighIds[rank], 4*nbSendElement[rank], MPI_INT, rank, 4, communicator, &recvRequest[nbRecvRequest]); 361 349 //ym --> attention taille GloId 362 363 364 365 350 nbRecvRequest++; 351 } 352 } 353 } 366 354 367 355 MPI_Waitall(nbSendRequest, sendRequest, status); 368 MPI_Waitall(nbRecvRequest, recvRequest, status); 369 370 371 /* now that all values and gradients are available use them to computed interpolated values on target 372 and also to compute weights */ 373 int i = 0; 374 for (int j = 0; j < nbElements; j++) 375 { 376 Elt& e = elements[j]; 377 378 /* since for the 2nd order case source grid elements can contribute to a destination grid element over several "paths" 379 (step1: gradient is computed using neighbours on same grid, step2: intersection uses several elements on other grid) 380 accumulate them so that there is only one final weight between two elements */ 381 map<GloId,double> wgt_map; 382 383 /* for destination element `e` loop over all intersetions/the corresponding source elements */ 384 for (list<Polyg *>::iterator it = e.is.begin(); it != e.is.end(); it++) 385 { 386 /* it is the intersection element, so it->x and it->area are barycentre and area of intersection element (super mesh) 387 but it->id is id of the source element that it intersects */ 388 int n1 = (*it)->id.ind; 389 int rank = (*it)->id.rank; 390 double fk = recvValue[rank][n1]; 391 double srcArea = recvArea[rank][n1]; 392 double srcGivenArea = recvGivenArea[rank][n1]; 393 double w = (*it)->area; 356 MPI_Waitall(nbRecvRequest, recvRequest, status); 357 358 359 /* now that all values and gradients are available use them to computed interpolated values on target 360 and also to compute weights */ 361 int i = 0; 362 for (int j = 0; j < nbElements; j++) 363 { 364 Elt& e = elements[j]; 365 366 /* since for the 2nd order case source grid elements can contribute to a destination grid element over several "paths" 367 (step1: gradient is computed using neighbours on same grid, step2: intersection uses several elements on other grid) 368 accumulate them so that there is only one final weight between two elements */ 369 map<GloId,double> wgt_map; 370 371 /* for destination element `e` loop over all intersetions/the corresponding source elements */ 372 for (list<Polyg *>::iterator it = e.is.begin(); it != e.is.end(); it++) 373 { 374 /* it is the intersection element, so it->x and it->area are barycentre and area of intersection element (super mesh) 375 but it->id is id of the source element that it intersects */ 376 int n1 = (*it)->id.ind; 377 int rank = (*it)->id.rank; 378 double fk = recvValue[rank][n1]; 379 double srcArea = recvArea[rank][n1]; 380 double w = (*it)->area; 394 381 if (quantity) w/=srcArea ; 395 else w=w*srcGivenArea/srcArea*e.area/e.given_area ; 396 397 /* first order: src value times weight (weight = supermesh area), later divide by target area */ 398 int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 399 GloId neighID = recvNeighIds[rank][kk]; 400 wgt_map[neighID] += w; 401 402 if (order == 2) 403 { 404 for (int k = 0; k < NMAX+1; k++) 405 { 406 int kk = n1 * (NMAX + 1) + k; 407 GloId neighID = recvNeighIds[rank][kk]; 408 if (neighID.ind != -1) wgt_map[neighID] += w * scalarprod(recvGrad[rank][kk], (*it)->x); 409 } 410 411 } 412 } 382 383 /* first order: src value times weight (weight = supermesh area), later divide by target area */ 384 int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 385 GloId neighID = recvNeighIds[rank][kk]; 386 wgt_map[neighID] += w; 387 388 if (order == 2) 389 { 390 for (int k = 0; k < NMAX+1; k++) 391 { 392 int kk = n1 * (NMAX + 1) + k; 393 GloId neighID = recvNeighIds[rank][kk]; 394 if (neighID.ind != -1) wgt_map[neighID] += w * scalarprod(recvGrad[rank][kk], (*it)->x); 395 } 396 397 } 398 } 413 399 414 400 double renorm=0; 415 401 if (renormalize) 416 { 417 if (quantity) for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) renorm+=it->second ; 418 else for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) renorm+=it->second / e.area; 419 } 402 for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) renorm+=it->second / e.area; 420 403 else renorm=1. ; 421 404 422 405 for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) 423 406 { 424 407 if (quantity) this->remapMatrix[i] = (it->second ) / renorm; 425 426 427 428 408 else this->remapMatrix[i] = (it->second / e.area) / renorm; 409 this->srcAddress[i] = it->first.ind; 410 this->srcRank[i] = it->first.rank; 411 this->dstAddress[i] = j; 429 412 this->sourceWeightId[i]= it->first.globalId ; 430 413 this->targetWeightId[i]= targetGlobalId[j] ; 431 i++; 432 } 433 } 434 435 /* free all memory allocated in this function */ 436 for (int rank = 0; rank < mpiSize; rank++) 437 { 438 if (nbSendElement[rank] > 0) 439 { 440 delete[] sendElement[rank]; 441 delete[] recvValue[rank]; 442 delete[] recvArea[rank]; 443 delete[] recvGivenArea[rank]; 444 if (order == 2) 445 { 446 delete[] recvGrad[rank]; 447 } 448 delete[] recvNeighIds[rank]; 449 } 450 if (nbRecvElement[rank] > 0) 451 { 452 delete[] recvElement[rank]; 453 delete[] sendValue[rank]; 454 delete[] sendArea[rank]; 455 delete[] sendGivenArea[rank]; 456 if (order == 2) 457 delete[] sendGrad[rank]; 458 delete[] sendNeighIds[rank]; 459 } 460 } 461 delete[] status; 462 delete[] sendRequest; 463 delete[] recvRequest; 464 delete[] elementList; 465 delete[] nbSendElement; 466 delete[] nbRecvElement; 467 delete[] sendElement; 468 delete[] recvElement; 469 delete[] sendValue; 470 delete[] recvValue; 471 delete[] sendGrad; 472 delete[] recvGrad; 473 delete[] sendNeighIds; 474 delete[] recvNeighIds; 475 return i; 414 i++; 415 } 416 } 417 418 /* free all memory allocated in this function */ 419 for (int rank = 0; rank < mpiSize; rank++) 420 { 421 if (nbSendElement[rank] > 0) 422 { 423 delete[] sendElement[rank]; 424 delete[] recvValue[rank]; 425 delete[] recvArea[rank]; 426 if (order == 2) 427 { 428 delete[] recvGrad[rank]; 429 } 430 delete[] recvNeighIds[rank]; 431 } 432 if (nbRecvElement[rank] > 0) 433 { 434 delete[] recvElement[rank]; 435 delete[] sendValue[rank]; 436 delete[] sendArea[rank]; 437 if (order == 2) 438 delete[] sendGrad[rank]; 439 delete[] sendNeighIds[rank]; 440 } 441 } 442 delete[] status; 443 delete[] sendRequest; 444 delete[] recvRequest; 445 delete[] elementList; 446 delete[] nbSendElement; 447 delete[] nbRecvElement; 448 delete[] sendElement; 449 delete[] recvElement; 450 delete[] sendValue; 451 delete[] recvValue; 452 delete[] sendGrad; 453 delete[] recvGrad; 454 delete[] sendNeighIds; 455 delete[] recvNeighIds; 456 return i; 476 457 } 477 458 478 459 void Mapper::computeGrads() 479 460 { 480 481 482 483 484 485 486 487 488 489 461 /* array of pointers to collect local elements and elements received from other cpu */ 462 vector<Elt*> globalElements(sstree.nbLocalElements + nbNeighbourElements); 463 int index = 0; 464 for (int i = 0; i < sstree.nbLocalElements; i++, index++) 465 globalElements[index] = &(sstree.localElements[i]); 466 for (int i = 0; i < nbNeighbourElements; i++, index++) 467 globalElements[index] = &neighbourElements[i]; 468 469 update_baryc(sstree.localElements, sstree.nbLocalElements); 470 computeGradients(&globalElements[0], sstree.nbLocalElements); 490 471 } 491 472 … … 494 475 void Mapper::buildMeshTopology() 495 476 { 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 477 int mpiSize, mpiRank; 478 MPI_Comm_size(communicator, &mpiSize); 479 MPI_Comm_rank(communicator, &mpiRank); 480 481 vector<Node> *routingList = new vector<Node>[mpiSize]; 482 vector<vector<int> > routes(sstree.localTree.leafs.size()); 483 484 sstree.routeIntersections(routes, sstree.localTree.leafs); 485 486 for (int i = 0; i < routes.size(); ++i) 487 for (int k = 0; k < routes[i].size(); ++k) 488 routingList[routes[i][k]].push_back(sstree.localTree.leafs[i]); 489 routingList[mpiRank].clear(); 490 491 492 CMPIRouting mpiRoute(communicator); 493 mpiRoute.init(routes); 494 int nRecv = mpiRoute.getTotalSourceElement(); 514 495 // cout << mpiRank << " NRECV " << nRecv << "(" << routes.size() << ")"<< endl; 515 496 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 497 int *nbSendNode = new int[mpiSize]; 498 int *nbRecvNode = new int[mpiSize]; 499 int *sendMessageSize = new int[mpiSize]; 500 int *recvMessageSize = new int[mpiSize]; 501 502 for (int rank = 0; rank < mpiSize; rank++) 503 { 504 nbSendNode[rank] = routingList[rank].size(); 505 sendMessageSize[rank] = 0; 506 for (size_t j = 0; j < routingList[rank].size(); j++) 507 { 508 Elt *elt = (Elt *) (routingList[rank][j].data); 509 sendMessageSize[rank] += packedPolygonSize(*elt); 510 } 511 } 512 513 MPI_Alltoall(nbSendNode, 1, MPI_INT, nbRecvNode, 1, MPI_INT, communicator); 514 MPI_Alltoall(sendMessageSize, 1, MPI_INT, recvMessageSize, 1, MPI_INT, communicator); 515 516 char **sendBuffer = new char*[mpiSize]; 517 char **recvBuffer = new char*[mpiSize]; 518 int *pos = new int[mpiSize]; 519 520 for (int rank = 0; rank < mpiSize; rank++) 521 { 522 if (nbSendNode[rank] > 0) sendBuffer[rank] = new char[sendMessageSize[rank]]; 523 if (nbRecvNode[rank] > 0) recvBuffer[rank] = new char[recvMessageSize[rank]]; 524 } 525 526 for (int rank = 0; rank < mpiSize; rank++) 527 { 528 pos[rank] = 0; 529 for (size_t j = 0; j < routingList[rank].size(); j++) 530 { 531 Elt *elt = (Elt *) (routingList[rank][j].data); 532 packPolygon(*elt, sendBuffer[rank], pos[rank]); 533 } 534 } 535 delete [] routingList; 536 537 538 int nbSendRequest = 0; 539 int nbRecvRequest = 0; 540 MPI_Request *sendRequest = new MPI_Request[mpiSize]; 541 MPI_Request *recvRequest = new MPI_Request[mpiSize]; 542 MPI_Status *status = new MPI_Status[mpiSize]; 543 544 for (int rank = 0; rank < mpiSize; rank++) 545 { 546 if (nbSendNode[rank] > 0) 547 { 548 MPI_Issend(sendBuffer[rank], sendMessageSize[rank], MPI_CHAR, rank, 0, communicator, &sendRequest[nbSendRequest]); 549 nbSendRequest++; 550 } 551 if (nbRecvNode[rank] > 0) 552 { 553 MPI_Irecv(recvBuffer[rank], recvMessageSize[rank], MPI_CHAR, rank, 0, communicator, &recvRequest[nbRecvRequest]); 554 nbRecvRequest++; 555 } 556 } 557 558 MPI_Waitall(nbRecvRequest, recvRequest, status); 559 MPI_Waitall(nbSendRequest, sendRequest, status); 560 561 for (int rank = 0; rank < mpiSize; rank++) 562 if (nbSendNode[rank] > 0) delete [] sendBuffer[rank]; 563 delete [] sendBuffer; 564 565 char **sendBuffer2 = new char*[mpiSize]; 566 char **recvBuffer2 = new char*[mpiSize]; 567 568 for (int rank = 0; rank < mpiSize; rank++) 569 { 570 nbSendNode[rank] = 0; 571 sendMessageSize[rank] = 0; 572 573 if (nbRecvNode[rank] > 0) 574 { 575 set<NodePtr> neighbourList; 576 pos[rank] = 0; 577 for (int j = 0; j < nbRecvNode[rank]; j++) 578 { 579 Elt elt; 580 unpackPolygon(elt, recvBuffer[rank], pos[rank]); 581 Node node(elt.x, cptRadius(elt), &elt); 582 findNeighbour(sstree.localTree.root, &node, neighbourList); 583 } 584 nbSendNode[rank] = neighbourList.size(); 585 for (set<NodePtr>::iterator it = neighbourList.begin(); it != neighbourList.end(); it++) 586 { 587 Elt *elt = (Elt *) ((*it)->data); 588 sendMessageSize[rank] += packedPolygonSize(*elt); 589 } 590 591 sendBuffer2[rank] = new char[sendMessageSize[rank]]; 592 pos[rank] = 0; 593 594 for (set<NodePtr>::iterator it = neighbourList.begin(); it != neighbourList.end(); it++) 595 { 596 Elt *elt = (Elt *) ((*it)->data); 597 packPolygon(*elt, sendBuffer2[rank], pos[rank]); 598 } 599 } 600 } 601 for (int rank = 0; rank < mpiSize; rank++) 602 if (nbRecvNode[rank] > 0) delete [] recvBuffer[rank]; 603 delete [] recvBuffer; 604 605 606 MPI_Barrier(communicator); 607 MPI_Alltoall(nbSendNode, 1, MPI_INT, nbRecvNode, 1, MPI_INT, communicator); 608 MPI_Alltoall(sendMessageSize, 1, MPI_INT, recvMessageSize, 1, MPI_INT, communicator); 609 610 for (int rank = 0; rank < mpiSize; rank++) 611 if (nbRecvNode[rank] > 0) recvBuffer2[rank] = new char[recvMessageSize[rank]]; 612 613 nbSendRequest = 0; 614 nbRecvRequest = 0; 615 616 for (int rank = 0; rank < mpiSize; rank++) 617 { 618 if (nbSendNode[rank] > 0) 619 { 620 MPI_Issend(sendBuffer2[rank], sendMessageSize[rank], MPI_CHAR, rank, 0, communicator, &sendRequest[nbSendRequest]); 621 nbSendRequest++; 622 } 623 if (nbRecvNode[rank] > 0) 624 { 625 MPI_Irecv(recvBuffer2[rank], recvMessageSize[rank], MPI_CHAR, rank, 0, communicator, &recvRequest[nbRecvRequest]); 626 nbRecvRequest++; 627 } 628 } 629 630 MPI_Waitall(nbRecvRequest, recvRequest, status); 631 MPI_Waitall(nbSendRequest, sendRequest, status); 632 633 int nbNeighbourNodes = 0; 634 for (int rank = 0; rank < mpiSize; rank++) 635 nbNeighbourNodes += nbRecvNode[rank]; 636 637 neighbourElements = new Elt[nbNeighbourNodes]; 638 nbNeighbourElements = nbNeighbourNodes; 639 640 int index = 0; 641 for (int rank = 0; rank < mpiSize; rank++) 642 { 643 pos[rank] = 0; 644 for (int j = 0; j < nbRecvNode[rank]; j++) 645 { 646 unpackPolygon(neighbourElements[index], recvBuffer2[rank], pos[rank]); 647 neighbourElements[index].id.ind = sstree.localTree.leafs.size() + index; 648 index++; 649 } 650 } 651 for (int rank = 0; rank < mpiSize; rank++) 652 { 653 if (nbRecvNode[rank] > 0) delete [] recvBuffer2[rank]; 654 if (nbSendNode[rank] > 0) delete [] sendBuffer2[rank]; 655 } 656 delete [] recvBuffer2; 657 delete [] sendBuffer2; 658 delete [] sendMessageSize; 659 delete [] recvMessageSize; 660 delete [] nbSendNode; 661 delete [] nbRecvNode; 662 delete [] sendRequest; 663 delete [] recvRequest; 664 delete [] status; 665 delete [] pos; 666 667 /* re-compute on received elements to avoid having to send this information */ 668 neighbourNodes.resize(nbNeighbourNodes); 669 setCirclesAndLinks(neighbourElements, neighbourNodes); 670 cptAllEltsGeom(neighbourElements, nbNeighbourNodes, srcGrid.pole); 671 672 /* the local SS tree must include nodes from other cpus if they are potential 692 673 intersector of a local node */ 693 694 695 674 sstree.localTree.insertNodes(neighbourNodes); 675 676 /* for every local element, 696 677 use the SS-tree to find all elements (including neighbourElements) 697 678 who are potential neighbours because their circles intersect, 698 699 700 701 702 703 704 705 706 707 708 709 710 711 679 then check all canditates for common edges to build up connectivity information 680 */ 681 for (int j = 0; j < sstree.localTree.leafs.size(); j++) 682 { 683 Node& node = sstree.localTree.leafs[j]; 684 685 /* find all leafs whoes circles that intersect node's circle and save into node->intersectors */ 686 node.search(sstree.localTree.root); 687 688 Elt *elt = (Elt *)(node.data); 689 690 for (int i = 0; i < elt->n; i++) elt->neighbour[i] = NOT_FOUND; 691 692 /* for element `elt` loop through all nodes in the SS-tree 712 693 whoes circles intersect with the circle around `elt` (the SS intersectors) 713 694 and check if they are neighbours in the sense that the two elements share an edge. 714 695 If they do, save this information for elt */ 715 716 717 718 719 696 for (list<NodePtr>::iterator it = (node.intersectors).begin(); it != (node.intersectors).end(); ++it) 697 { 698 Elt *elt2 = (Elt *)((*it)->data); 699 set_neighbour(*elt, *elt2); 700 } 720 701 721 702 /* 722 723 724 725 726 703 for (int i = 0; i < elt->n; i++) 704 { 705 if (elt->neighbour[i] == NOT_FOUND) 706 error_exit("neighbour not found"); 707 } 727 708 */ 728 709 } 729 710 } 730 711 … … 732 713 void Mapper::computeIntersection(Elt *elements, int nbElements) 733 714 { 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 // 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 715 int mpiSize, mpiRank; 716 MPI_Comm_size(communicator, &mpiSize); 717 MPI_Comm_rank(communicator, &mpiRank); 718 719 MPI_Barrier(communicator); 720 721 vector<Node> *routingList = new vector<Node>[mpiSize]; 722 723 vector<Node> routeNodes; routeNodes.reserve(nbElements); 724 for (int j = 0; j < nbElements; j++) 725 { 726 elements[j].id.ind = j; 727 elements[j].id.rank = mpiRank; 728 routeNodes.push_back(Node(elements[j].x, cptRadius(elements[j]), &elements[j])); 729 } 730 731 vector<vector<int> > routes(routeNodes.size()); 732 sstree.routeIntersections(routes, routeNodes); 733 for (int i = 0; i < routes.size(); ++i) 734 for (int k = 0; k < routes[i].size(); ++k) 735 routingList[routes[i][k]].push_back(routeNodes[i]); 736 737 if (verbose >= 2) 738 { 739 cout << " --> rank " << mpiRank << " nbElements " << nbElements << " : "; 740 for (int rank = 0; rank < mpiSize; rank++) 741 cout << routingList[rank].size() << " "; 742 cout << endl; 743 } 744 MPI_Barrier(communicator); 745 746 int *nbSendNode = new int[mpiSize]; 747 int *nbRecvNode = new int[mpiSize]; 748 int *sentMessageSize = new int[mpiSize]; 749 int *recvMessageSize = new int[mpiSize]; 750 751 for (int rank = 0; rank < mpiSize; rank++) 752 { 753 nbSendNode[rank] = routingList[rank].size(); 754 sentMessageSize[rank] = 0; 755 for (size_t j = 0; j < routingList[rank].size(); j++) 756 { 757 Elt *elt = (Elt *) (routingList[rank][j].data); 758 sentMessageSize[rank] += packedPolygonSize(*elt); 759 } 760 } 761 762 MPI_Alltoall(nbSendNode, 1, MPI_INT, nbRecvNode, 1, MPI_INT, communicator); 763 MPI_Alltoall(sentMessageSize, 1, MPI_INT, recvMessageSize, 1, MPI_INT, communicator); 764 765 int total = 0; 766 767 for (int rank = 0; rank < mpiSize; rank++) 768 { 769 total = total + nbRecvNode[rank]; 770 } 771 772 if (verbose >= 2) cout << "---> rank " << mpiRank << " : compute intersection : total received nodes " << total << endl; 773 char **sendBuffer = new char*[mpiSize]; 774 char **recvBuffer = new char*[mpiSize]; 775 int *pos = new int[mpiSize]; 776 777 for (int rank = 0; rank < mpiSize; rank++) 778 { 779 if (nbSendNode[rank] > 0) sendBuffer[rank] = new char[sentMessageSize[rank]]; 780 if (nbRecvNode[rank] > 0) recvBuffer[rank] = new char[recvMessageSize[rank]]; 781 } 782 783 for (int rank = 0; rank < mpiSize; rank++) 784 { 785 pos[rank] = 0; 786 for (size_t j = 0; j < routingList[rank].size(); j++) 787 { 788 Elt* elt = (Elt *) (routingList[rank][j].data); 789 packPolygon(*elt, sendBuffer[rank], pos[rank]); 790 } 791 } 792 delete [] routingList; 793 794 int nbSendRequest = 0; 795 int nbRecvRequest = 0; 796 MPI_Request *sendRequest = new MPI_Request[mpiSize]; 797 MPI_Request *recvRequest = new MPI_Request[mpiSize]; 798 MPI_Status *status = new MPI_Status[mpiSize]; 799 800 for (int rank = 0; rank < mpiSize; rank++) 801 { 802 if (nbSendNode[rank] > 0) 803 { 804 MPI_Issend(sendBuffer[rank], sentMessageSize[rank], MPI_CHAR, rank, 0, communicator, &sendRequest[nbSendRequest]); 805 nbSendRequest++; 806 } 807 if (nbRecvNode[rank] > 0) 808 { 809 MPI_Irecv(recvBuffer[rank], recvMessageSize[rank], MPI_CHAR, rank, 0, communicator, &recvRequest[nbRecvRequest]); 810 nbRecvRequest++; 811 } 812 } 813 814 MPI_Waitall(nbRecvRequest, recvRequest, status); 815 MPI_Waitall(nbSendRequest, sendRequest, status); 816 char **sendBuffer2 = new char*[mpiSize]; 817 char **recvBuffer2 = new char*[mpiSize]; 818 819 double tic = cputime(); 820 for (int rank = 0; rank < mpiSize; rank++) 821 { 822 sentMessageSize[rank] = 0; 823 824 if (nbRecvNode[rank] > 0) 825 { 826 Elt *recvElt = new Elt[nbRecvNode[rank]]; 827 pos[rank] = 0; 828 for (int j = 0; j < nbRecvNode[rank]; j++) 829 { 830 unpackPolygon(recvElt[j], recvBuffer[rank], pos[rank]); 831 cptEltGeom(recvElt[j], tgtGrid.pole); 832 Node recvNode(recvElt[j].x, cptRadius(recvElt[j]), &recvElt[j]); 833 recvNode.search(sstree.localTree.root); 834 /* for a node holding an element of the target, loop throught candidates for intersecting source */ 835 for (list<NodePtr>::iterator it = (recvNode.intersectors).begin(); it != (recvNode.intersectors).end(); ++it) 836 { 837 Elt *elt2 = (Elt *) ((*it)->data); 838 /* recvElt is target, elt2 is source */ 839 // intersect(&recvElt[j], elt2); 840 intersect_ym(&recvElt[j], elt2); 841 } 842 843 if (recvElt[j].is.size() > 0) sentMessageSize[rank] += packIntersectionSize(recvElt[j]); 844 845 // here recvNode goes out of scope 846 } 847 848 if (sentMessageSize[rank] > 0) 849 { 850 sentMessageSize[rank] += sizeof(int); 851 sendBuffer2[rank] = new char[sentMessageSize[rank]]; 852 *((int *) sendBuffer2[rank]) = 0; 853 pos[rank] = sizeof(int); 854 for (int j = 0; j < nbRecvNode[rank]; j++) 855 { 856 packIntersection(recvElt[j], sendBuffer2[rank], pos[rank]); 857 //FIXME should be deleted: recvElt[j].delete_intersections(); // intersection areas have been packed to buffer and won't be used any more 858 } 859 } 860 delete [] recvElt; 861 862 } 863 } 864 delete [] pos; 865 866 for (int rank = 0; rank < mpiSize; rank++) 867 { 868 if (nbSendNode[rank] > 0) delete [] sendBuffer[rank]; 869 if (nbRecvNode[rank] > 0) delete [] recvBuffer[rank]; 870 nbSendNode[rank] = 0; 871 } 872 873 if (verbose >= 2) cout << "Rank " << mpiRank << " Compute (internal) intersection " << cputime() - tic << " s" << endl; 874 MPI_Alltoall(sentMessageSize, 1, MPI_INT, recvMessageSize, 1, MPI_INT, communicator); 875 876 for (int rank = 0; rank < mpiSize; rank++) 877 if (recvMessageSize[rank] > 0) 878 recvBuffer2[rank] = new char[recvMessageSize[rank]]; 879 880 nbSendRequest = 0; 881 nbRecvRequest = 0; 882 883 for (int rank = 0; rank < mpiSize; rank++) 884 { 885 if (sentMessageSize[rank] > 0) 886 { 887 MPI_Issend(sendBuffer2[rank], sentMessageSize[rank], MPI_CHAR, rank, 0, communicator, &sendRequest[nbSendRequest]); 888 nbSendRequest++; 889 } 890 if (recvMessageSize[rank] > 0) 891 { 892 MPI_Irecv(recvBuffer2[rank], recvMessageSize[rank], MPI_CHAR, rank, 0, communicator, &recvRequest[nbRecvRequest]); 893 nbRecvRequest++; 894 } 895 } 896 897 MPI_Waitall(nbRecvRequest, recvRequest, status); 898 MPI_Waitall(nbSendRequest, sendRequest, status); 899 900 delete [] sendRequest; 901 delete [] recvRequest; 902 delete [] status; 903 for (int rank = 0; rank < mpiSize; rank++) 904 { 905 if (nbRecvNode[rank] > 0) 906 { 907 if (sentMessageSize[rank] > 0) 908 delete [] sendBuffer2[rank]; 909 } 910 911 if (recvMessageSize[rank] > 0) 912 { 913 unpackIntersection(elements, recvBuffer2[rank]); 914 delete [] recvBuffer2[rank]; 915 } 916 } 917 delete [] sendBuffer2; 918 delete [] recvBuffer2; 919 delete [] sendBuffer; 920 delete [] recvBuffer; 921 922 delete [] nbSendNode; 923 delete [] nbRecvNode; 924 delete [] sentMessageSize; 925 delete [] recvMessageSize; 945 926 } 946 927 947 928 Mapper::~Mapper() 948 929 { 949 950 951 952 953 954 } 955 956 } 930 delete [] remapMatrix; 931 delete [] srcAddress; 932 delete [] srcRank; 933 delete [] dstAddress; 934 if (neighbourElements) delete [] neighbourElements; 935 } 936 937 } -
XIOS/dev/dev_trunk_omp/extern/remap/src/mapper.hpp
r1619 r1630 23 23 void setVerbosity(verbosity v) {verbose=v ;} 24 24 25 void setSourceMesh(const double* boundsLon, const double* boundsLat, const double* area,int nVertex, int nbCells, const double* pole, const long int* globalId=NULL) ;26 void setTargetMesh(const double* boundsLon, const double* boundsLat, const double* area,int nVertex, int nbCells, const double* pole, const long int* globalId=NULL) ;25 void setSourceMesh(const double* boundsLon, const double* boundsLat, int nVertex, int nbCells, const double* pole, const long int* globalId=NULL) ; 26 void setTargetMesh(const double* boundsLon, const double* boundsLat, int nVertex, int nbCells, const double* pole, const long int* globalId=NULL) ; 27 27 void setSourceValue(const double* val) ; 28 28 void getTargetValue(double* val) ; -
XIOS/dev/dev_trunk_omp/extern/remap/src/meshutil.cpp
r1619 r1630 2 2 #include "elt.hpp" 3 3 #include "polyg.hpp" 4 #include "intersection_ym.hpp"5 #include "earcut.hpp"6 #include <vector>7 4 8 5 namespace sphereRemap { 9 6 10 7 using namespace std; 11 12 double computePolygoneArea(Elt& a, const Coord &pole)13 {14 using N = uint32_t;15 using Point = array<double, 2>;16 vector<Point> vect_points;17 vector< vector<Point> > polyline;18 19 vector<Coord> dstPolygon ;20 createGreatCirclePolygon(a, pole, dstPolygon) ;21 22 int na=dstPolygon.size() ;23 Coord *a_gno = new Coord[na];24 25 Coord OC=barycentre(a.vertex,a.n) ;26 Coord Oz=OC ;27 Coord Ox=crossprod(Coord(0,0,1),Oz) ;28 // choose Ox not too small to avoid rounding error29 if (norm(Ox)< 0.1) Ox=crossprod(Coord(0,1,0),Oz) ;30 Ox=Ox*(1./norm(Ox)) ;31 Coord Oy=crossprod(Oz,Ox) ;32 double cos_alpha;33 34 for(int n=0; n<na;n++)35 {36 cos_alpha=scalarprod(OC,dstPolygon[n]) ;37 a_gno[n].x=scalarprod(dstPolygon[n],Ox)/cos_alpha ;38 a_gno[n].y=scalarprod(dstPolygon[n],Oy)/cos_alpha ;39 a_gno[n].z=scalarprod(dstPolygon[n],Oz)/cos_alpha ; // must be equal to 140 41 vect_points.push_back( array<double, 2>() );42 vect_points[n][0] = a_gno[n].x;43 vect_points[n][1] = a_gno[n].y;44 45 }46 47 polyline.push_back(vect_points);48 vector<N> indices_a_gno = mapbox::earcut<N>(polyline);49 50 double area_a_gno=0 ;51 for(int i=0;i<indices_a_gno.size()/3;++i)52 {53 Coord x0 = Ox * polyline[0][indices_a_gno[3*i]][0] + Oy* polyline[0][indices_a_gno[3*i]][1] + Oz ;54 Coord x1 = Ox * polyline[0][indices_a_gno[3*i+1]][0] + Oy* polyline[0][indices_a_gno[3*i+1]][1] + Oz ;55 Coord x2 = Ox * polyline[0][indices_a_gno[3*i+2]][0] + Oy* polyline[0][indices_a_gno[3*i+2]][1] + Oz ;56 area_a_gno+=triarea(x0 * (1./norm(x0)),x1* (1./norm(x1)), x2* (1./norm(x2))) ;57 }58 59 vect_points.clear();60 polyline.clear();61 indices_a_gno.clear();62 return area_a_gno ;63 }64 65 8 66 9 void cptEltGeom(Elt& elt, const Coord &pole) … … 71 14 elt.area = airbar(elt.n, elt.vertex, elt.edge, elt.d, pole, gg); 72 15 elt.x = gg; 73 // overwrite area computation74 75 elt.area = computePolygoneArea(elt, pole) ;76 16 } 77 78 17 79 18 void cptAllEltsGeom(Elt *elt, int N, const Coord &pole) -
XIOS/dev/dev_trunk_omp/extern/remap/src/polyg.cpp
r1619 r1630 218 218 int packedPolygonSize(const Elt& e) 219 219 { 220 return sizeof(e.id) + sizeof(e.src_id) + sizeof(e.x) + sizeof(e.val) + sizeof(e.given_area)+220 return sizeof(e.id) + sizeof(e.src_id) + sizeof(e.x) + sizeof(e.val) + 221 221 sizeof(e.n) + e.n*(sizeof(double)+sizeof(Coord)); 222 222 } … … 235 235 pos += sizeof(e.val); 236 236 237 *((double*) &(buffer[pos])) = e.given_area;238 pos += sizeof(e.val);239 240 237 *((int *) & (buffer[pos])) = e.n; 241 238 pos += sizeof(e.n); … … 265 262 pos += sizeof(double); 266 263 267 e.given_area = *((double *) & (buffer[pos]));268 pos += sizeof(double);269 270 264 e.n = *((int *) & (buffer[pos])); 271 265 pos += sizeof(int); … … 297 291 *((double *) &(buffer[pos])) = e.area; 298 292 pos += sizeof(double); 299 300 293 301 294 *((GloId *) &(buffer[pos])) = (*it)->id; … … 329 322 pos += sizeof(double); 330 323 331 332 324 Polyg *polygon = new Polyg; 333 325 -
XIOS/dev/dev_trunk_omp/src/calendar.cpp
r1629 r1630 119 119 this->timestep = timestep; 120 120 } 121 /* 121 122 122 int CCalendar::getStep(void) const 123 123 { 124 124 return step; 125 125 } 126 */ 126 127 127 const CDate& CCalendar::update(int step) 128 128 { … … 153 153 //----------------------------------------------------------------- 154 154 155 //const CDuration& CCalendar::getTimeStep(void) const { return this->timestep; }156 //const CDate& CCalendar::getInitDate(void) const { return this->initDate; }157 //const CDate& CCalendar::getTimeOrigin(void) const { return this->timeOrigin; }158 //const CDate& CCalendar::getCurrentDate(void) const { return this->currentDate; }155 const CDuration& CCalendar::getTimeStep(void) const { return this->timestep; } 156 const CDate& CCalendar::getInitDate(void) const { return this->initDate; } 157 const CDate& CCalendar::getTimeOrigin(void) const { return this->timeOrigin; } 158 const CDate& CCalendar::getCurrentDate(void) const { return this->currentDate; } 159 159 160 160 //----------------------------------------------------------------- … … 169 169 StdString CCalendar::getType(void) const { return StdString(this->getId()); } 170 170 171 //int CCalendar::getYearTotalLength(const CDate& date) const { return (365 * 86400); }171 int CCalendar::getYearTotalLength(const CDate& date) const { return (365 * 86400); } 172 172 173 173 //int CCalendar::getYearLength (void) const { return 12; } … … 177 177 //int CCalendar::getDayLengthInSeconds(void) const { return getDayLength() * getHourLength() * getMinuteLength(); } 178 178 179 //bool CCalendar::hasLeapYear() const { return false; }180 181 /*StdString CCalendar::getMonthName(int monthId) const179 bool CCalendar::hasLeapYear() const { return false; } 180 181 StdString CCalendar::getMonthName(int monthId) const 182 182 { 183 183 static const StdString MonthNames[] = … … 185 185 "july", "august", "september", "october", "november", "december" }; 186 186 return MonthNames[monthId - 1]; 187 } */187 } 188 188 189 189 const StdString CCalendar::getMonthShortName(int monthId) const -
XIOS/dev/dev_trunk_omp/src/calendar.hpp
r1629 r1630 52 52 53 53 /// Mutateur /// 54 void setTimeStep(const CDuration& timestep) 54 void setTimeStep(const CDuration& timestep); 55 55 void setInitDate(const CDate& initDate); 56 56 void setTimeOrigin(const CDate& timeOrigin); … … 60 60 61 61 /// Accesseurs /// 62 const CDuration& getTimeStep(void) const { return this->timestep; };63 const CDate& getInitDate(void) const { return this->initDate; };64 const CDate& getTimeOrigin(void) const { return this->timeOrigin; };65 const CDate& getCurrentDate(void) const { return this->currentDate; };62 const CDuration& getTimeStep(void) const; 63 const CDate& getInitDate(void) const; 64 const CDate& getTimeOrigin(void) const; 65 const CDate& getCurrentDate(void) const; 66 66 67 67 public : … … 70 70 virtual StdString getType(void) const; 71 71 72 int getStep(void) const {return step;};72 int getStep(void) const; 73 73 74 74 inline int getMonthLength(const CDate& date) const … … 78 78 }; 79 79 80 //virtual int getYearTotalLength(const CDate& date) const; // Retourne la durée d'une année en seconde. 81 inline virtual int getYearTotalLength(const CDate& date) const { return (365 * 86400); } ; // Retourne la durée d'une année en seconde. 80 virtual int getYearTotalLength(const CDate& date) const; // Retourne la durée d'une année en seconde. 82 81 83 82 //virtual int getYearLength (void) const; // Retourne la durée d'une année en mois. 84 inline virtualint getYearLength (void) const { return 12; } ;85 inline virtualint getDayLength (void) const { return 24; } ; // Retourne la durée d'un jour en heures.86 inline virtualint getHourLength (void) const { return 60; } ; // Retourne la durée d'une heure en minute.87 inline virtualint getMinuteLength(void) const {return 60; } ; // Retourne la durée d'une minute en secondes.83 inline int getYearLength (void) const { return 12; } ; 84 inline int getDayLength (void) const { return 24; } ; // Retourne la durée d'un jour en heures. 85 inline int getHourLength (void) const { return 60; } ; // Retourne la durée d'une heure en minute. 86 inline int getMinuteLength(void) const {return 60; } ; // Retourne la durée d'une minute en secondes. 88 87 /*! Returns the day length expressed in seconds. */ 89 inline virtualint getDayLengthInSeconds(void) const { return 86400; } ;88 inline int getDayLengthInSeconds(void) const { return 86400; } ; 90 89 91 inline virtual StdString getMonthName(int monthId) const 92 { 93 static const StdString MonthNames[] = 94 { "january", "february", "march", "april" , "may", "june", 95 "july", "august", "september", "october", "november", "december" }; 96 return MonthNames[monthId - 1]; 97 }; 90 virtual StdString getMonthName(int monthId) const; 98 91 virtual const StdString getMonthShortName(int monthId) const; 99 92 100 93 /*! Test if the calendar can have leap year. */ 101 inline virtual bool hasLeapYear() const {return false;};94 virtual bool hasLeapYear() const; 102 95 103 96 void initializeDate(int yr, int mth, int d, int hr = 0, int min = 0, int sec = 0); -
XIOS/dev/dev_trunk_omp/src/calendar_util.cpp
r1629 r1630 1 1 #include "calendar_util.hpp" 2 #include "calendar.hpp" 2 3 3 4 namespace xios -
XIOS/dev/dev_trunk_omp/src/config/domain_attribute.conf
r1619 r1630 58 58 59 59 DECLARE_ARRAY(double, 2, area) 60 DECLARE_ATTRIBUTE(double, radius)61 60 62 61 DECLARE_ENUM4(type,rectilinear,curvilinear,unstructured, gaussian) -
XIOS/dev/dev_trunk_omp/src/config/interpolate_domain_attribute.conf
r1619 r1630 10 10 DECLARE_ATTRIBUTE(bool, write_weight) 11 11 DECLARE_ENUM2(read_write_convention, c, fortran) 12 DECLARE_ATTRIBUTE(bool, use_area) -
XIOS/dev/dev_trunk_omp/src/context_client.cpp
r1619 r1630 96 96 { 97 97 list<int> ranks = event.getRanks(); 98 info(100)<<"Event "<<timeLine<<" of context "<<context->getId()<<endl ; 98 99 99 if (CXios::checkEventSync) 100 100 { … … 124 124 { 125 125 event.send(timeLine, sizes, buffList); 126 info(100)<<"Event "<<timeLine<<" of context "<<context->getId()<<" sent"<<endl ;127 126 128 127 checkBuffers(ranks); … … 143 142 info(100)<<"DEBUG : temporaly event created : timeline "<<timeLine<<endl ; 144 143 event.send(timeLine, tmpBufferedEvent.sizes, tmpBufferedEvent.buffers); 145 info(100)<<"Event "<<timeLine<<" of context "<<context->getId()<<" sent"<<endl ;146 144 } 147 145 } -
XIOS/dev/dev_trunk_omp/src/date/allleap.cpp
r1629 r1630 32 32 33 33 ///-------------------------------------------------------------- 34 /* 34 35 35 int CAllLeapCalendar::getYearTotalLength(const CDate & date) const 36 36 { return (366 * 86400); } 37 */ 37 38 38 int CAllLeapCalendar::getMonthLength(const CDate & date) const 39 39 { … … 41 41 return (CCalendar::getMonthLength(date)); 42 42 } 43 /* 43 44 44 StdString CAllLeapCalendar::getType(void) const 45 45 { return (StdString("all_leap")); } 46 */ 46 47 47 ///-------------------------------------------------------------- 48 48 } // namespace xios -
XIOS/dev/dev_trunk_omp/src/date/allleap.hpp
r1629 r1630 26 26 27 27 /// Accesseurs /// 28 inline virtual int getYearTotalLength(const CDate & date) const { return (366 * 86400); };28 virtual int getYearTotalLength(const CDate & date) const; 29 29 virtual int getMonthLength(const CDate & date) const; 30 virtual StdString getType(void) const { return (StdString("all_leap")); };30 virtual StdString getType(void) const; 31 31 32 32 /// Destructeur /// 33 virtual ~CAllLeapCalendar(void) 33 virtual ~CAllLeapCalendar(void); 34 34 35 35 }; // class CAllLeapCalendar -
XIOS/dev/dev_trunk_omp/src/date/d360.cpp
r1629 r1630 33 33 ///-------------------------------------------------------------- 34 34 35 //int CD360Calendar::getYearTotalLength(const CDate & date) const36 //{ return (360 * 86400); }35 int CD360Calendar::getYearTotalLength(const CDate & date) const 36 { return (360 * 86400); } 37 37 38 //int CD360Calendar::getMonthLength(const CDate & date) const39 //{ return (30); }38 int CD360Calendar::getMonthLength(const CDate & date) const 39 { return (30); } 40 40 41 //StdString CD360Calendar::getType(void) const42 //{ return (StdString("360_day")); }41 StdString CD360Calendar::getType(void) const 42 { return (StdString("360_day")); } 43 43 44 44 ///-------------------------------------------------------------- -
XIOS/dev/dev_trunk_omp/src/date/d360.hpp
r1629 r1630 26 26 27 27 /// Accesseurs /// 28 inline virtual int getYearTotalLength(const CDate & date) const { return (360 * 86400); };29 inline virtual int getMonthLength(const CDate & date) const { return 30; };30 inline virtual StdString getType(void) const { return (StdString("360_day")); };28 virtual int getYearTotalLength(const CDate & date) const; 29 virtual int getMonthLength(const CDate & date) const; 30 virtual StdString getType(void) const; 31 31 32 32 /// Destructeur /// -
XIOS/dev/dev_trunk_omp/src/date/gregorian.cpp
r1629 r1630 55 55 } 56 56 57 //StdString CGregorianCalendar::getType(void) const58 //{ return (StdString("gregorian")); }57 StdString CGregorianCalendar::getType(void) const 58 { return (StdString("gregorian")); } 59 59 60 //bool CGregorianCalendar::hasLeapYear() const { return true; }60 bool CGregorianCalendar::hasLeapYear() const { return true; } 61 61 62 62 ///-------------------------------------------------------------- -
XIOS/dev/dev_trunk_omp/src/date/gregorian.hpp
r1629 r1630 28 28 virtual int getYearTotalLength(const CDate & date) const; 29 29 virtual int getMonthLength(const CDate & date) const; 30 inline virtual StdString getType(void) const { return (StdString("gregorian")); }; 31 inline virtual int getYearLength (void) const { return 12; } ; 30 virtual StdString getType(void) const; 32 31 33 inline virtual bool hasLeapYear() const { return true; };32 virtual bool hasLeapYear() const; 34 33 35 34 /// Destructeur /// -
XIOS/dev/dev_trunk_omp/src/io/onetcdf4_impl.hpp
r1619 r1630 73 73 } 74 74 char *PtrArrayStr ; 75 PtrArrayStr=new char[stringArrayLen*data.numElements()] ; 76 memset (PtrArrayStr,' ',stringArrayLen*data.numElements()); 77 size_t offset=0 ; 75 PtrArrayStr=new char[stringArrayLen] ; 78 76 Array<StdString,1>::const_iterator it, itb=data.begin(), ite=data.end() ; 79 for(it=itb;it!=ite;++it, offset+=stringArrayLen) 77 int lineNb = 0; 78 for(it=itb;it!=ite;++it) 80 79 { 81 it->copy(PtrArrayStr+offset,it->size()) ; 82 PtrArrayStr[offset+it->size()]='\0' ; 80 it->copy(PtrArrayStr,it->size()) ; 81 PtrArrayStr[it->size()]='\0' ; 82 sstart[0] = lineNb; 83 sstart[dimArrayLen] = 0; 84 scount[0] = 1; 85 scount[dimArrayLen] = it->size() + 1; 86 CTimer::get("CONetCDF4::writeData writeData_").resume(); 87 this->writeData_(grpid, varid, sstart, scount, PtrArrayStr); 88 CTimer::get("CONetCDF4::writeData writeData_").suspend(); 89 ++lineNb; 83 90 } 84 85 CTimer::get("CONetCDF4::writeData writeData_").resume();86 this->writeData_(grpid, varid, sstart, scount, PtrArrayStr);87 CTimer::get("CONetCDF4::writeData writeData_").suspend();88 89 91 delete [] PtrArrayStr; 90 92 } -
XIOS/dev/dev_trunk_omp/src/node/interpolate_domain.cpp
r1619 r1630 65 65 if (this->read_write_convention.isEmpty()) this->read_write_convention.setValue(read_write_convention_attr::fortran); 66 66 67 68 67 } 69 68 -
XIOS/dev/dev_trunk_omp/src/transformation/domain_algorithm_interpolate.cpp
r1619 r1630 305 305 CArray<double,2> boundsLonSrcUnmasked(nVertexSrc,nSrcLocalUnmasked); 306 306 CArray<double,2> boundsLatSrcUnmasked(nVertexSrc,nSrcLocalUnmasked); 307 CArray<double,1> areaSrcUnmasked(nSrcLocalUnmasked);308 309 307 long int * globalSrcUnmasked = new long int [nSrcLocalUnmasked]; 310 308 311 309 nSrcLocalUnmasked=0 ; 312 bool hasSrcArea=domainSrc_->hasArea && !domainSrc_->radius.isEmpty() && !interpDomain_->use_area.isEmpty() && interpDomain_->use_area==true ;313 double srcAreaFactor ;314 if (hasSrcArea) srcAreaFactor=1./(domainSrc_->radius*domainSrc_->radius) ;315 316 310 for (int idx=0 ; idx < nSrcLocal; idx++) 317 311 { … … 323 317 boundsLatSrcUnmasked(n,nSrcLocalUnmasked) = boundsLatSrc(n,idx) ; 324 318 } 325 if (hasSrcArea) areaSrcUnmasked(nSrcLocalUnmasked) = domainSrc_->areavalue(idx)*srcAreaFactor ;326 319 globalSrcUnmasked[nSrcLocalUnmasked]=globalSrc[idx] ; 327 320 ++nSrcLocalUnmasked ; 328 321 } 329 322 } 330 323 331 324 332 325 int nDstLocalUnmasked = 0 ; … … 335 328 CArray<double,2> boundsLonDestUnmasked(nVertexDest,nDstLocalUnmasked); 336 329 CArray<double,2> boundsLatDestUnmasked(nVertexDest,nDstLocalUnmasked); 337 CArray<double,1> areaDstUnmasked(nDstLocalUnmasked);338 339 330 long int * globalDstUnmasked = new long int [nDstLocalUnmasked]; 340 331 341 332 nDstLocalUnmasked=0 ; 342 bool hasDstArea=domainDest_->hasArea && !domainDest_->radius.isEmpty() && !interpDomain_->use_area.isEmpty() && interpDomain_->use_area==true ;343 double dstAreaFactor ;344 if (hasDstArea) dstAreaFactor=1./(domainDest_->radius*domainDest_->radius) ;345 333 for (int idx=0 ; idx < nDstLocal; idx++) 346 334 { … … 352 340 boundsLatDestUnmasked(n,nDstLocalUnmasked) = boundsLatDest(n,idx) ; 353 341 } 354 if (hasDstArea) areaDstUnmasked(nDstLocalUnmasked) = domainDest_->areavalue(idx)*dstAreaFactor ;355 342 globalDstUnmasked[nDstLocalUnmasked]=globalDst[idx] ; 356 343 ++nDstLocalUnmasked ; … … 358 345 } 359 346 360 double* ptAreaSrcUnmasked = NULL ; 361 if (hasSrcArea) ptAreaSrcUnmasked=areaSrcUnmasked.dataFirst() ; 362 363 double* ptAreaDstUnmasked = NULL ; 364 if (hasDstArea) ptAreaDstUnmasked=areaDstUnmasked.dataFirst() ; 365 366 mapper.setSourceMesh(boundsLonSrcUnmasked.dataFirst(), boundsLatSrcUnmasked.dataFirst(), ptAreaSrcUnmasked, nVertexSrc, nSrcLocalUnmasked, &srcPole[0], globalSrcUnmasked); 367 mapper.setTargetMesh(boundsLonDestUnmasked.dataFirst(), boundsLatDestUnmasked.dataFirst(), ptAreaDstUnmasked, nVertexDest, nDstLocalUnmasked, &dstPole[0], globalDstUnmasked); 347 mapper.setSourceMesh(boundsLonSrcUnmasked.dataFirst(), boundsLatSrcUnmasked.dataFirst(), nVertexSrc, nSrcLocalUnmasked, &srcPole[0], globalSrcUnmasked); 348 mapper.setTargetMesh(boundsLonDestUnmasked.dataFirst(), boundsLatDestUnmasked.dataFirst(), nVertexDest, nDstLocalUnmasked, &dstPole[0], globalDstUnmasked); 368 349 369 350 std::vector<double> timings = mapper.computeWeights(orderInterp,renormalize,quantity); -
XIOS/dev/dev_trunk_omp/src/transformation/domain_algorithm_zoom.cpp
r1611 r1630 93 93 domainDest_->ni.setValue(niDest); 94 94 domainDest_->nj.setValue(njDest); 95 if ( (niDest==0) || (njDest==0)) 96 { 97 domainDest_->ibegin.setValue(0); 98 domainDest_->jbegin.setValue(0); 99 } 100 else 101 { 102 domainDest_->ibegin.setValue(ibeginDest); 103 domainDest_->jbegin.setValue(jbeginDest); 104 } 95 domainDest_->ibegin.setValue(ibeginDest); 96 domainDest_->jbegin.setValue(jbeginDest); 105 97 domainDest_->i_index.resize(niDest*njDest); 106 98 domainDest_->j_index.resize(niDest*njDest);
Note: See TracChangeset
for help on using the changeset viewer.