Changeset 1542 for XIOS/trunk/src/node/mesh.cpp
- Timestamp:
- 06/13/18 16:48:53 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/mesh.cpp
r1507 r1542 6 6 7 7 #include "mesh.hpp" 8 #include <boost/functional/hash.hpp> 9 //#include <unordered_map> 8 10 9 11 namespace xios { … … 136 138 } 137 139 138 139 ///----------------------------------------------------------------140 /*!141 * \fn size_t CMesh::nodeIndex (double lon, double lat)142 * Returns its index if a node exists; otherwise adds the node and returns -1.143 * Precision check is implemented with two hash values for each dimension, longitude and latitude.144 * \param [in] lon Node longitude in degrees.145 * \param [in] lat Node latitude in degrees ranged from 0 to 360.146 * \return node index if a node exists; -1 otherwise147 */148 size_t CMesh::nodeIndex (double lon, double lat)149 {150 double minBoundLon = 0. ;151 double maxBoundLon = 360. ;152 double minBoundLat = -90 ;153 double maxBoundLat = 90 ;154 double prec=1e-11 ;155 double precLon=prec ;156 double precLat=prec ;157 158 size_t maxsize_t=numeric_limits<size_t>::max() ;159 if ( (maxBoundLon-minBoundLon)/maxsize_t > precLon) precLon=(maxBoundLon-minBoundLon)/maxsize_t ;160 if ( (maxBoundLat-minBoundLat)/maxsize_t > precLat) precLat=(maxBoundLat-minBoundLat)/maxsize_t ;161 162 size_t iMinLon=0 ;163 size_t iMaxLon=(maxBoundLon-minBoundLon)/precLon ;164 size_t iMinLat=0 ;165 size_t iMaxLat=(maxBoundLat-minBoundLat)/precLat ;166 167 size_t hash0,hash1,hash2,hash3 ;168 size_t lon0,lon1,lat0,lat1 ;169 170 lon0=(lon-minBoundLon)/precLon ;171 if ( ((lon0+1)*precLon + lon0*precLon)/2 > lon-minBoundLon)172 {173 if (lon0==iMinLon) lon1=iMaxLon ;174 else lon1=lon0-1 ;175 }176 else177 {178 if (lon0==iMaxLon) lon1=iMinLon ;179 else lon1=lon0+1 ;180 }181 182 lat0=(lat-minBoundLat)/precLat ;183 if ( ((lat0+1)*precLat + lat0*precLat)/2 > lat-minBoundLat)184 {185 if (lat0==iMinLat) lat1=lat0 ;186 else lat1=lat0-1 ;187 }188 else189 {190 if (lat0==iMaxLat) lat1=lat0 ;191 else lat1=lat0+1 ;192 }193 194 hash0=hashPair(lon0,lat0) ;195 hash1=hashPair(lon0,lat1) ;196 hash2=hashPair(lon1,lat0) ;197 hash3=hashPair(lon1,lat1) ;198 199 boost::unordered_map<size_t, size_t>::iterator end = hashed_map_nodes.end() ;200 size_t mapSize = hashed_map_nodes.size();201 if (hashed_map_nodes.find(hash0)==end && hashed_map_nodes.find(hash1)==end && hashed_map_nodes.find(hash2)==end && hashed_map_nodes.find(hash3)==end)202 {203 hashed_map_nodes[hash0] = mapSize ;204 hashed_map_nodes[hash1] = mapSize + 1;205 hashed_map_nodes[hash2] = mapSize + 2;206 hashed_map_nodes[hash3] = mapSize + 3;207 return -1;208 }209 else210 return ( (hashed_map_nodes[hash0]+1) / 4 );211 212 } // nodeIndex()213 214 140 ///---------------------------------------------------------------- 215 141 /*! … … 298 224 * \param [in] bounds_lat Array of boundary latitudes. Its size depends on the element type. 299 225 */ 300 void CMesh::createMesh(const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,301 const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)302 {303 int nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();304 305 if (nvertex == 1)306 {307 nbNodes_ = lonvalue.numElements();308 node_lon.resizeAndPreserve(nbNodes_);309 node_lat.resizeAndPreserve(nbNodes_);310 for (int nn = 0; nn < nbNodes_; ++nn)311 {312 if (map_nodes.find(make_pair (lonvalue(nn), latvalue(nn))) == map_nodes.end())313 {314 map_nodes[make_pair (lonvalue(nn), latvalue(nn))] = nn ;315 node_lon(nn) = lonvalue(nn);316 node_lat(nn) = latvalue(nn);317 }318 }319 }320 else if (nvertex == 2)321 {322 nbEdges_ = bounds_lon.shape()[1];323 324 // Create nodes and edge_node connectivity325 node_lon.resizeAndPreserve(nbEdges_*nvertex); // Max possible number of nodes326 node_lat.resizeAndPreserve(nbEdges_*nvertex);327 edge_nodes.resizeAndPreserve(nvertex, nbEdges_);328 329 for (int ne = 0; ne < nbEdges_; ++ne)330 {331 for (int nv = 0; nv < nvertex; ++nv)332 {333 if (map_nodes.find(make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))) == map_nodes.end())334 {335 map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv, ne))] = nbNodes_ ;336 edge_nodes(nv,ne) = nbNodes_ ;337 node_lon(nbNodes_) = bounds_lon(nv, ne);338 node_lat(nbNodes_) = bounds_lat(nv, ne);339 ++nbNodes_ ;340 }341 else342 edge_nodes(nv,ne) = map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))];343 }344 }345 node_lon.resizeAndPreserve(nbNodes_);346 node_lat.resizeAndPreserve(nbNodes_);347 348 // Create edges349 edge_lon.resizeAndPreserve(nbEdges_);350 edge_lat.resizeAndPreserve(nbEdges_);351 352 for (int ne = 0; ne < nbEdges_; ++ne)353 {354 if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end())355 {356 map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ;357 edge_lon(ne) = lonvalue(ne);358 edge_lat(ne) = latvalue(ne);359 }360 361 }362 edgesAreWritten = true;363 }364 else365 {366 nbFaces_ = bounds_lon.shape()[1];367 368 // Create nodes and face_node connectivity369 node_lon.resizeAndPreserve(nbFaces_*nvertex); // Max possible number of nodes370 node_lat.resizeAndPreserve(nbFaces_*nvertex);371 face_nodes.resize(nvertex, nbFaces_);372 373 for (int nf = 0; nf < nbFaces_; ++nf)374 {375 for (int nv = 0; nv < nvertex; ++nv)376 {377 if (map_nodes.find(make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))) == map_nodes.end())378 {379 map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv, nf))] = nbNodes_ ;380 face_nodes(nv,nf) = nbNodes_ ;381 node_lon(nbNodes_) = bounds_lon(nv, nf);382 node_lat(nbNodes_) = bounds_lat(nv ,nf);383 ++nbNodes_ ;384 }385 else386 {387 face_nodes(nv,nf) = map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))];388 }389 }390 }391 node_lon.resizeAndPreserve(nbNodes_);392 node_lat.resizeAndPreserve(nbNodes_);393 394 // Create edges and edge_nodes connectivity395 edge_lon.resizeAndPreserve(nbFaces_*nvertex); // Max possible number of edges396 edge_lat.resizeAndPreserve(nbFaces_*nvertex);397 edge_nodes.resizeAndPreserve(2, nbFaces_*nvertex);398 edge_faces.resize(2, nbFaces_*nvertex);399 face_edges.resize(nvertex, nbFaces_);400 face_faces.resize(nvertex, nbFaces_);401 402 vector<int> countEdges(nbFaces_*nvertex); // needed in case if edges have been already generated403 vector<int> countFaces(nbFaces_);404 countEdges.assign(nbFaces_*nvertex, 0);405 countFaces.assign(nbFaces_, 0);406 int edge;407 for (int nf = 0; nf < nbFaces_; ++nf)408 {409 for (int nv1 = 0; nv1 < nvertex; ++nv1)410 {411 int nv = 0;412 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation413 if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end())414 {415 map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges_ ;416 face_edges(nv1,nf) = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))];417 edge_faces(0,nbEdges_) = nf;418 edge_faces(1,nbEdges_) = -999;419 face_faces(nv1,nf) = 999999;420 edge_nodes(Range::all(),nbEdges_) = face_nodes(nv1,nf), face_nodes(nv2,nf);421 edge_lon(nbEdges_) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ?422 (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) :423 (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);424 edge_lat(nbEdges_) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5;425 ++nbEdges_;426 }427 else428 {429 edge = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))];430 face_edges(nv1,nf) = edge;431 if (edgesAreWritten)432 {433 edge_faces(countEdges[edge], edge) = nf;434 if (countEdges[edge]==0)435 {436 face_faces(nv1,nf) = 999999;437 }438 else439 {440 int face1 = nf; // = edge_faces(1,edge)441 int face2 = edge_faces(0,edge);442 face_faces(countFaces[face1], face1) = face2;443 face_faces(countFaces[face2], face2) = face1;444 ++(countFaces[face1]);445 ++(countFaces[face2]);446 }447 }448 else449 {450 edge_faces(1,edge) = nf;451 int face1 = nf; // = edge_faces(1,edge)452 int face2 = edge_faces(0,edge);453 face_faces(countFaces[face1], face1) = face2;454 face_faces(countFaces[face2], face2) = face1;455 ++(countFaces[face1]);456 ++(countFaces[face2]);457 }458 ++(countEdges[edge]);459 }460 }461 }462 edge_nodes.resizeAndPreserve(2, nbEdges_);463 edge_faces.resizeAndPreserve(2, nbEdges_);464 edge_lon.resizeAndPreserve(nbEdges_);465 edge_lat.resizeAndPreserve(nbEdges_);466 467 // Create faces468 face_lon.resize(nbFaces_);469 face_lat.resize(nbFaces_);470 face_lon = lonvalue;471 face_lat = latvalue;472 facesAreWritten = true;473 474 } // nvertex > 2475 476 } // createMesh()226 // void CMesh::createMesh(const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue, 227 // const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat) 228 // { 229 // int nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows(); 230 // 231 // if (nvertex == 1) 232 // { 233 // nbNodes_ = lonvalue.numElements(); 234 // node_lon.resizeAndPreserve(nbNodes_); 235 // node_lat.resizeAndPreserve(nbNodes_); 236 // for (int nn = 0; nn < nbNodes_; ++nn) 237 // { 238 // if (map_nodes.find(make_pair (lonvalue(nn), latvalue(nn))) == map_nodes.end()) 239 // { 240 // map_nodes[make_pair (lonvalue(nn), latvalue(nn))] = nn ; 241 // node_lon(nn) = lonvalue(nn); 242 // node_lat(nn) = latvalue(nn); 243 // } 244 // } 245 // } 246 // else if (nvertex == 2) 247 // { 248 // nbEdges_ = bounds_lon.shape()[1]; 249 // 250 // // Create nodes and edge_node connectivity 251 // node_lon.resizeAndPreserve(nbEdges_*nvertex); // Max possible number of nodes 252 // node_lat.resizeAndPreserve(nbEdges_*nvertex); 253 // edge_nodes.resizeAndPreserve(nvertex, nbEdges_); 254 // 255 // for (int ne = 0; ne < nbEdges_; ++ne) 256 // { 257 // for (int nv = 0; nv < nvertex; ++nv) 258 // { 259 // if (map_nodes.find(make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))) == map_nodes.end()) 260 // { 261 // map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv, ne))] = nbNodes_ ; 262 // edge_nodes(nv,ne) = nbNodes_ ; 263 // node_lon(nbNodes_) = bounds_lon(nv, ne); 264 // node_lat(nbNodes_) = bounds_lat(nv, ne); 265 // ++nbNodes_ ; 266 // } 267 // else 268 // edge_nodes(nv,ne) = map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))]; 269 // } 270 // } 271 // node_lon.resizeAndPreserve(nbNodes_); 272 // node_lat.resizeAndPreserve(nbNodes_); 273 // 274 // // Create edges 275 // edge_lon.resizeAndPreserve(nbEdges_); 276 // edge_lat.resizeAndPreserve(nbEdges_); 277 // 278 // for (int ne = 0; ne < nbEdges_; ++ne) 279 // { 280 // if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end()) 281 // { 282 // map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ; 283 // edge_lon(ne) = lonvalue(ne); 284 // edge_lat(ne) = latvalue(ne); 285 // } 286 // 287 // } 288 // edgesAreWritten = true; 289 // } 290 // else 291 // { 292 // nbFaces_ = bounds_lon.shape()[1]; 293 // 294 // // Create nodes and face_node connectivity 295 // node_lon.resizeAndPreserve(nbFaces_*nvertex); // Max possible number of nodes 296 // node_lat.resizeAndPreserve(nbFaces_*nvertex); 297 // face_nodes.resize(nvertex, nbFaces_); 298 // 299 // for (int nf = 0; nf < nbFaces_; ++nf) 300 // { 301 // for (int nv = 0; nv < nvertex; ++nv) 302 // { 303 // if (map_nodes.find(make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))) == map_nodes.end()) 304 // { 305 // map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv, nf))] = nbNodes_ ; 306 // face_nodes(nv,nf) = nbNodes_ ; 307 // node_lon(nbNodes_) = bounds_lon(nv, nf); 308 // node_lat(nbNodes_) = bounds_lat(nv ,nf); 309 // ++nbNodes_ ; 310 // } 311 // else 312 // { 313 // face_nodes(nv,nf) = map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))]; 314 // } 315 // } 316 // } 317 // node_lon.resizeAndPreserve(nbNodes_); 318 // node_lat.resizeAndPreserve(nbNodes_); 319 // 320 // // Create edges and edge_nodes connectivity 321 // edge_lon.resizeAndPreserve(nbFaces_*nvertex); // Max possible number of edges 322 // edge_lat.resizeAndPreserve(nbFaces_*nvertex); 323 // edge_nodes.resizeAndPreserve(2, nbFaces_*nvertex); 324 // edge_faces.resize(2, nbFaces_*nvertex); 325 // face_edges.resize(nvertex, nbFaces_); 326 // face_faces.resize(nvertex, nbFaces_); 327 // 328 // vector<int> countEdges(nbFaces_*nvertex); // needed in case if edges have been already generated 329 // vector<int> countFaces(nbFaces_); 330 // countEdges.assign(nbFaces_*nvertex, 0); 331 // countFaces.assign(nbFaces_, 0); 332 // int edge; 333 // for (int nf = 0; nf < nbFaces_; ++nf) 334 // { 335 // for (int nv1 = 0; nv1 < nvertex; ++nv1) 336 // { 337 // int nv = 0; 338 // int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 339 // if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end()) 340 // { 341 // map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges_ ; 342 // face_edges(nv1,nf) = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))]; 343 // edge_faces(0,nbEdges_) = nf; 344 // edge_faces(1,nbEdges_) = -999; 345 // face_faces(nv1,nf) = 999999; 346 // edge_nodes(Range::all(),nbEdges_) = face_nodes(nv1,nf), face_nodes(nv2,nf); 347 // edge_lon(nbEdges_) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ? 348 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) : 349 // (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.); 350 // edge_lat(nbEdges_) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5; 351 // ++nbEdges_; 352 // } 353 // else 354 // { 355 // edge = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))]; 356 // face_edges(nv1,nf) = edge; 357 // if (edgesAreWritten) 358 // { 359 // edge_faces(countEdges[edge], edge) = nf; 360 // if (countEdges[edge]==0) 361 // { 362 // face_faces(nv1,nf) = 999999; 363 // } 364 // else 365 // { 366 // int face1 = nf; // = edge_faces(1,edge) 367 // int face2 = edge_faces(0,edge); 368 // face_faces(countFaces[face1], face1) = face2; 369 // face_faces(countFaces[face2], face2) = face1; 370 // ++(countFaces[face1]); 371 // ++(countFaces[face2]); 372 // } 373 // } 374 // else 375 // { 376 // edge_faces(1,edge) = nf; 377 // int face1 = nf; // = edge_faces(1,edge) 378 // int face2 = edge_faces(0,edge); 379 // face_faces(countFaces[face1], face1) = face2; 380 // face_faces(countFaces[face2], face2) = face1; 381 // ++(countFaces[face1]); 382 // ++(countFaces[face2]); 383 // } 384 // ++(countEdges[edge]); 385 // } 386 // } 387 // } 388 // edge_nodes.resizeAndPreserve(2, nbEdges_); 389 // edge_faces.resizeAndPreserve(2, nbEdges_); 390 // edge_lon.resizeAndPreserve(nbEdges_); 391 // edge_lat.resizeAndPreserve(nbEdges_); 392 // 393 // // Create faces 394 // face_lon.resize(nbFaces_); 395 // face_lat.resize(nbFaces_); 396 // face_lon = lonvalue; 397 // face_lat = latvalue; 398 // facesAreWritten = true; 399 // 400 // } // nvertex > 2 401 // 402 // } // createMesh() 477 403 478 404 ///---------------------------------------------------------------- … … 2088 2014 2089 2015 // faceToFaces connectivity 2090 boost::unordered_map <int, int> mapFaces; // mapFaces = < hash(face1, face2), hash> (the mapped value is irrelevant)2016 std::unordered_map <int, int> mapFaces; // mapFaces = < hash(face1, face2), hash> (the mapped value is irrelevant) 2091 2017 int maxNb = 20; // some assumption on the max possible number of neighboring cells 2092 2018 faceToFaces.resize(maxNb, nbFaces); … … 2145 2071 CArray<double, 2> faceToNodes (nvertex, nbFaces); 2146 2072 2147 boost::unordered_map <pair<double,double>, int> mapNodes;2073 std::unordered_map <pairDouble, int, boost::hash<pairDouble> > mapNodes; 2148 2074 2149 2075 for (int nf = 0; nf < nbFaces; ++nf) … … 2161 2087 2162 2088 // faceToFaces connectivity 2163 boost::unordered_map <pair<int,int>, int> mapEdges;2089 std::unordered_map <pairInt, int, boost::hash<pairInt> > mapEdges; 2164 2090 faceToFaces.resize(nvertex, nbFaces); 2165 2091 CArray<int, 2> edgeToFaces(2, nbFaces*nvertex); // max possible
Note: See TracChangeset
for help on using the changeset viewer.