Changeset 1158 for XIOS/dev/dev_olga/extern/remap
- Timestamp:
- 06/06/17 17:58:16 (7 years ago)
- Location:
- XIOS/dev/dev_olga/extern/remap/src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_olga/extern/remap/src/elt.hpp
r923 r1158 105 105 } 106 106 107 void insert_vertex(int i, const Coord& v) 108 { 109 for(int j=n; j > i ; j--) 110 { 111 vertex[j]=vertex[j-1] ; 112 edge[j]=edge[j-1] ; 113 d[j]=d[j-1] ; 114 neighbour[j]=neighbour[j-1] ; 115 } 116 vertex[i+1]=v ; 117 n++ ; 118 } 119 107 120 int neighbour[NMAX]; 108 121 double d[NMAX]; /**< distance of centre of small circle to origin, zero if great circle */ -
XIOS/dev/dev_olga/extern/remap/src/intersect.cpp
r688 r1158 37 37 } 38 38 39 /** New methods to find an insert a neighbour in a cell of the source mesh. 40 * return true/false if cell b is a neighbour of a. if "insert" is true, then b will be inserted as a neighbour 41 * in cell a . This is needed for 2 order interpolation that need neighboround for gradient computing. 42 * A cell is a neighbour if : 43 * - it shares 2 countiguous vertex (ie an edge) with a 44 * - A vertex of b is located on one of an edge of a. 45 **/ 46 bool insertNeighbour( Elt& a, const Elt& b, bool insert ) 47 { 48 // for now suppose pole -> Oz 49 Coord pole(0,0,1) ; 50 Coord O, Oa1, Oa2,Ob1,Ob2,V1,V2 ; 51 double da,db,alpha,alpha1,alpha2,delta ; 52 53 54 for (int i = 0; i < a.n; i++) 55 { 56 for (int j = 0; j < b.n; j++) 57 { 58 // share a full edge ? be carefull at the orientation 59 assert(squaredist(a.vertex[ i ], b.vertex[ j ]) > 1e-10*1e-10 || 60 squaredist(a.vertex[(i+1)%a.n], b.vertex[(j+1)%b.n]) > 1e-10*1e-10); 61 if ( squaredist(a.vertex[ i ], b.vertex[ j ]) < 1e-10*1e-10 && 62 squaredist(a.vertex[(i+1)%a.n], b.vertex[(j+b.n-1)%b.n]) < 1e-10*1e-10) 63 { 64 if (insert) a.neighbour[i] = b.id.ind ; 65 return true; 66 } 67 68 69 // 1 or 2 vertices of b is located on an edge of a 70 da=a.d[i] ; 71 if (scalarprod(a.edge[i], pole) < 0) da=-da ; 72 db=b.d[(j+b.n-1)%b.n] ; 73 if (scalarprod(b.edge[(j+b.n-1)%b.n], pole) < 0) db=-db ; 74 75 if ( fabs(da-db)<1e-10 ) 76 { 77 O=pole*da ; 78 Oa1=a.vertex[i]-O ; 79 Oa2=a.vertex[(i+1)%a.n]-O ; 80 Ob1=b.vertex[j]-O ; 81 Ob2=b.vertex[(j+b.n-1)%b.n]-O ; 82 V1=crossprod(Oa1,Oa2) ; 83 V2=crossprod(Ob1,Ob2) ; 84 if (norm(crossprod(V1,V2))/(norm(V1)*norm(V2)) < 1e-10) 85 { 86 alpha = vectAngle(Oa1,Oa2,V1) ; 87 alpha1= vectAngle(Oa1,Ob1,V1) ; 88 alpha2= vectAngle(Oa1,Ob2,V1) ; 89 delta= alpha2-alpha1 ; 90 if (delta >= M_PI) delta=2*M_PI-delta ; 91 else if (delta <= -M_PI) delta=2*M_PI+delta ; 92 93 if (alpha >= 0) 94 { 95 if (alpha1 > 1e-10 && alpha1 < alpha-1e-10) 96 { 97 if (alpha2 > 1e-10 && alpha2 < alpha-1e-10) 98 { 99 assert(delta > 0) ; 100 if (insert) 101 { 102 // insert both 103 a.insert_vertex(i,b.vertex[(j+b.n-1)%b.n]); 104 a.insert_vertex(i,b.vertex[j]); 105 a.neighbour[i+1] = b.id.ind ; 106 } 107 return true ; 108 } 109 else 110 { 111 assert( delta > 0 ) ; 112 if (insert) 113 { 114 //insert alpha1 115 a.insert_vertex(i,b.vertex[j]); 116 a.neighbour[i+1] = b.id.ind ; 117 } 118 return true ; 119 } 120 } 121 else if (alpha2 > 1e-10 && alpha2 < alpha-1e-10) 122 { 123 assert( delta > 0 ) ; 124 if (insert) 125 { 126 // insert alpha2 127 a.insert_vertex(i,b.vertex[(j+b.n-1)%b.n]); 128 a.neighbour[i] = b.id.ind ; 129 } 130 return true ; 131 } 132 else 133 { 134 // nothing to do 135 } 136 137 } 138 else // alpha < 0 139 { 140 if (alpha1 < -1e-10 && alpha1 > alpha+1e-10) 141 { 142 if (alpha2 < -1e-10 && alpha2 > alpha+1e-10) 143 { 144 assert(delta < 0) ; 145 if (insert) 146 { 147 // insert both 148 a.insert_vertex(i,b.vertex[(j+b.n-1)%b.n]); 149 a.insert_vertex(i,b.vertex[j]); 150 a.neighbour[i+1] = b.id.ind ; 151 } 152 return true ; 153 } 154 else 155 { 156 assert(delta < 0) ; 157 if (insert) 158 { 159 //insert alpha1 160 a.insert_vertex(i,b.vertex[j]); 161 a.neighbour[i+1] = b.id.ind ; 162 } 163 return true ; 164 } 165 } 166 else if (alpha2 < -1e-10 && alpha2 > alpha+1e-10) 167 { 168 assert(delta < 0) ; 169 if (insert) 170 { 171 // insert alpha2 172 a.insert_vertex(i,b.vertex[(j+b.n-1)%b.n]); 173 a.neighbour[i] = b.id.ind ; 174 } 175 return true ; 176 } 177 else 178 { 179 // nothing to do 180 } 181 } 182 } 183 } 184 } 185 } 186 return false; 187 } 39 188 40 189 /** … … 44 193 void set_neighbour(Elt& a, const Elt& b) 45 194 { 46 if (b.id.ind == a.id.ind) return; 47 int idx = neighbour_idx(a, b); 48 if (idx != NOT_FOUND) 49 a.neighbour[idx] = b.id.ind; 195 if (b.id.ind == a.id.ind) return; 196 /* 197 int idx = neighbour_idx(a, b); 198 if (idx != NOT_FOUND) 199 a.neighbour[idx] = b.id.ind; 200 */ 201 insertNeighbour(a,b,true) ; 50 202 } 51 203 52 204 /** return true if `a` and `b` share an edge */ 53 bool isNeighbour(const Elt& a, const Elt& b) 54 { 55 return neighbour_idx(a, b) != NOT_FOUND; 205 bool isNeighbour(Elt& a, const Elt& b) 206 { 207 // return neighbour_idx(a, b) != NOT_FOUND; 208 return insertNeighbour(a,b,false) ; 56 209 } 57 210 -
XIOS/dev/dev_olga/extern/remap/src/intersect.hpp
r688 r1158 2 2 3 3 void set_neighbour(Elt& elt, const Elt& elt2); 4 bool isNeighbour( constElt& elt, const Elt& elt2);4 bool isNeighbour(Elt& elt, const Elt& elt2); 5 5 6 6 void intersect(Elt *a, Elt *b); -
XIOS/dev/dev_olga/extern/remap/src/mapper.cpp
r923 r1158 109 109 } 110 110 111 vector<double> Mapper::computeWeights(int interpOrder, bool renormalize )111 vector<double> Mapper::computeWeights(int interpOrder, bool renormalize, bool quantity) 112 112 { 113 113 vector<double> timings; … … 152 152 if (mpiRank == 0 && verbose) cout << "Remapping..." << endl; 153 153 tic = cputime(); 154 nWeights = remap(&targetElements[0], targetElements.size(), interpOrder, renormalize );154 nWeights = remap(&targetElements[0], targetElements.size(), interpOrder, renormalize, quantity); 155 155 timings.push_back(cputime() - tic); 156 156 … … 166 166 @param order is the order of interpolaton (must be 1 or 2). 167 167 */ 168 int Mapper::remap(Elt *elements, int nbElements, int order, bool renormalize )168 int Mapper::remap(Elt *elements, int nbElements, int order, bool renormalize, bool quantity) 169 169 { 170 170 int mpiSize, mpiRank; … … 184 184 int **sendElement = new int*[mpiSize]; /* indices of elements required from other rank */ 185 185 double **recvValue = new double*[mpiSize]; 186 double **recvArea = new double*[mpiSize]; 186 187 Coord **recvGrad = new Coord*[mpiSize]; 187 188 GloId **recvNeighIds = new GloId*[mpiSize]; /* ids of the of the source neighbours which also contribute through gradient */ … … 205 206 sendElement[rank] = new int[nbSendElement[rank]]; 206 207 recvValue[rank] = new double[nbSendElement[rank]]; 208 recvArea[rank] = new double[nbSendElement[rank]]; 207 209 if (order == 2) 208 210 { … … 234 236 int **recvElement = new int*[mpiSize]; 235 237 double **sendValue = new double*[mpiSize]; 238 double **sendArea = new double*[mpiSize]; 236 239 Coord **sendGrad = new Coord*[mpiSize]; 237 240 GloId **sendNeighIds = new GloId*[mpiSize]; 238 MPI_Request *sendRequest = new MPI_Request[ 3*mpiSize];239 MPI_Request *recvRequest = new MPI_Request[ 3*mpiSize];241 MPI_Request *sendRequest = new MPI_Request[4*mpiSize]; 242 MPI_Request *recvRequest = new MPI_Request[4*mpiSize]; 240 243 for (int rank = 0; rank < mpiSize; rank++) 241 244 { … … 250 253 recvElement[rank] = new int[nbRecvElement[rank]]; 251 254 sendValue[rank] = new double[nbRecvElement[rank]]; 255 sendArea[rank] = new double[nbRecvElement[rank]]; 252 256 if (order == 2) 253 257 { … … 263 267 } 264 268 } 265 MPI_Status *status = new MPI_Status[ 3*mpiSize];266 MPI_Waitall(nbRecvRequest, recvRequest, status);269 MPI_Status *status = new MPI_Status[4*mpiSize]; 270 267 271 MPI_Waitall(nbSendRequest, sendRequest, status); 272 MPI_Waitall(nbRecvRequest, recvRequest, status); 268 273 269 274 /* for all indices that have been received from requesting ranks: pack values and gradients, then send */ … … 278 283 { 279 284 sendValue[rank][j] = sstree.localElements[recvElement[rank][j]].val; 285 sendArea[rank][j] = sstree.localElements[recvElement[rank][j]].area; 280 286 if (order == 2) 281 287 { … … 297 303 MPI_Issend(sendValue[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 298 304 nbSendRequest++; 305 MPI_Issend(sendArea[rank], nbRecvElement[rank], MPI_DOUBLE, rank, 0, communicator, &sendRequest[nbSendRequest]); 306 nbSendRequest++; 299 307 if (order == 2) 300 308 { … … 317 325 MPI_Irecv(recvValue[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 318 326 nbRecvRequest++; 327 MPI_Irecv(recvArea[rank], nbSendElement[rank], MPI_DOUBLE, rank, 0, communicator, &recvRequest[nbRecvRequest]); 328 nbRecvRequest++; 319 329 if (order == 2) 320 330 { … … 334 344 } 335 345 } 346 347 MPI_Waitall(nbSendRequest, sendRequest, status); 336 348 MPI_Waitall(nbRecvRequest, recvRequest, status); 337 MPI_Waitall(nbSendRequest, sendRequest, status);349 338 350 339 351 /* now that all values and gradients are available use them to computed interpolated values on target … … 357 369 int rank = (*it)->id.rank; 358 370 double fk = recvValue[rank][n1]; 371 double srcArea = recvArea[rank][n1]; 359 372 double w = (*it)->area; 373 if (quantity) w/=srcArea ; 360 374 361 375 /* first order: src value times weight (weight = supermesh area), later divide by target area */ 362 376 int kk = (order == 2) ? n1 * (NMAX + 1) : n1; 363 377 GloId neighID = recvNeighIds[rank][kk]; 364 wgt_map[neighID] += (*it)->area;378 wgt_map[neighID] += w; 365 379 366 380 if (order == 2) … … 383 397 for (map<GloId,double>::iterator it = wgt_map.begin(); it != wgt_map.end(); it++) 384 398 { 385 this->remapMatrix[i] = (it->second / e.area) / renorm; 399 if (quantity) this->remapMatrix[i] = (it->second ) / renorm; 400 else this->remapMatrix[i] = (it->second / e.area) / renorm; 386 401 this->srcAddress[i] = it->first.ind; 387 402 this->srcRank[i] = it->first.rank; … … 400 415 delete[] sendElement[rank]; 401 416 delete[] recvValue[rank]; 417 delete[] recvArea[rank]; 402 418 if (order == 2) 403 419 { … … 410 426 delete[] recvElement[rank]; 411 427 delete[] sendValue[rank]; 428 delete[] sendArea[rank]; 412 429 if (order == 2) 413 430 delete[] sendGrad[rank]; -
XIOS/dev/dev_olga/extern/remap/src/mapper.hpp
r844 r1158 34 34 /** @param trgElts are the elements of the unstructured target grid 35 35 Returns the timings for substeps: */ 36 vector<double> computeWeights(int interpOrder, bool renormalize=false );36 vector<double> computeWeights(int interpOrder, bool renormalize=false, bool quantity=false); 37 37 int getNbWeights(void) { return nWeights ; } 38 38 /* … … 51 51 private: 52 52 /** @return number of weights (local to cpu) */ 53 int remap(Elt* elements, int nbElements, int order, bool renormalize=false );53 int remap(Elt* elements, int nbElements, int order, bool renormalize=false, bool quantity=false); 54 54 55 55 void buildMeshTopology(); -
XIOS/dev/dev_olga/extern/remap/src/tree.cpp
r951 r1158 142 142 root->parent = 0; 143 143 root->leafCount = 0; 144 root->centre = ORIGIN; 144 // initialize root node on the sphere 145 root->centre.x=1 ; root->centre.y=0 ; root->centre.z=0 ; 145 146 root->radius = 0.; 146 147 root->reinserted = false; -
XIOS/dev/dev_olga/extern/remap/src/triple.cpp
r849 r1158 124 124 } 125 125 126 // return oriented vector angle in range [-pi..pi], pole must be orthogonal to a and b 127 double vectAngle(const Coord &a, const Coord &b, const Coord &pole) 128 { 129 double nab = 1./(norm(a)*norm(b)) ; 130 131 Coord a_cross_b=crossprod(a, b)*nab ; 132 double sinVect ; 133 if (scalarprod(a_cross_b, pole) >= 0) sinVect=norm(a_cross_b) ; 134 else sinVect=-norm(a_cross_b) ; 135 double cosVect=scalarprod(a,b)*nab ; 136 137 return atan2(sinVect,cosVect) ; 126 138 } 139 140 } -
XIOS/dev/dev_olga/extern/remap/src/triple.hpp
r688 r1158 121 121 122 122 double angle(const Coord &a, const Coord &b, const Coord &pole); 123 124 // return oriented vector angle in range [-pi..pi], pole must be orthogonal to a and b 125 double vectAngle(const Coord &a, const Coord &b, const Coord &pole) ; 126 123 127 void print_Coord(Coord &p); 124 128
Note: See TracChangeset
for help on using the changeset viewer.