source: XIOS/trunk/src/node/mesh.cpp @ 900

Last change on this file since 900 was 900, checked in by oabramkina, 8 years ago

Sequential version of new functionalities for mesh connectivity:

edge_faces
face_edges
face_face.

File size: 26.2 KB
Line 
1/*!
2  \file mesh.cpp
3  \author Olga Abramkina
4  \brief Definition of class CMesh.
5*/
6
7#include "mesh.hpp"
8
9namespace xios {
10
11/// ////////////////////// Définitions ////////////////////// ///
12
13  CMesh::CMesh(void) :  nbFaces{0}, nbNodes{0}, nbEdges{0}
14            ,   nvertex{0}
15            ,  nodesAreWritten{false}, edgesAreWritten{false}, facesAreWritten{false}
16            ,  node_lon(), node_lat()
17            ,  edge_lon(), edge_lat(), edge_nodes()
18            ,  face_lon(), face_lat()
19            ,  face_nodes()
20  {
21  }
22
23
24  CMesh::~CMesh(void)
25  {
26  }
27
28  std::map <StdString, CMesh> CMesh::meshList = std::map <StdString, CMesh>();
29  //CMesh* CMesh::getMesh;
30
31///---------------------------------------------------------------
32/*!
33 * \fn bool CMesh::getMesh (StdString meshName)
34 * Returns a pointer to a mesh. If a mesh has not been created, creates it and adds its name to the list of meshes meshList.
35 * \param [in] meshName  The name of a mesh ("name" attribute of a domain).
36 */
37  CMesh* CMesh::getMesh (StdString meshName)
38  {
39    if ( CMesh::meshList.begin() != CMesh::meshList.end() )
40    {
41      for (std::map<StdString, CMesh>::iterator it=CMesh::meshList.begin(); it!=CMesh::meshList.end(); ++it)
42      {
43        if (it->first == meshName)
44          return &meshList[meshName];
45        else
46        {
47          CMesh newMesh;
48          CMesh::meshList.insert( make_pair(meshName, newMesh) );
49          return &meshList[meshName];
50        }
51      }
52    }
53    else
54    {
55      CMesh newMesh;
56      CMesh::meshList.insert( make_pair(meshName, newMesh) );
57      return &meshList[meshName];
58    }
59  }
60
61///----------------------------------------------------------------
62  int hashPair(int first, int second)
63  {
64    int seed = first + 0x9e3779b9 ;
65    seed ^= second + 0x9e3779b9 + (seed << 6) + (seed >> 2);
66    return seed ;
67  }
68
69///----------------------------------------------------------------
70/*!
71 * \fn size_t CMesh::nodeIndex (double lon, double lat)
72 * Returns its index if a node exists; otherwise adds the node and returns -1.
73 * Precision check is implemented with two hash values for each dimension, longitude and latitude.
74 * \param [in] lon Node longitude in degrees.
75 * \param [in] lat Node latitude in degrees ranged from 0 to 360.
76 * \return node index if a node exists; -1 otherwise
77 */
78  size_t CMesh::nodeIndex (double lon, double lat)
79  {
80    double minBoundLon = 0. ;
81    double maxBoundLon = 360. ;
82    double minBoundLat = -90 ;
83    double maxBoundLat = 90 ;
84    double prec=1e-11 ;
85    double precLon=prec ;
86    double precLat=prec ;
87
88    size_t maxsize_t=numeric_limits<size_t>::max() ;
89    if ( (maxBoundLon-minBoundLon)/maxsize_t > precLon) precLon=(maxBoundLon-minBoundLon)/maxsize_t ;
90    if ( (maxBoundLat-minBoundLat)/maxsize_t > precLat) precLat=(maxBoundLat-minBoundLat)/maxsize_t ;
91
92    size_t iMinLon=0 ;
93    size_t iMaxLon=(maxBoundLon-minBoundLon)/precLon ;
94    size_t iMinLat=0 ;
95    size_t iMaxLat=(maxBoundLat-minBoundLat)/precLat ;
96
97    size_t hash0,hash1,hash2,hash3 ;
98    size_t lon0,lon1,lat0,lat1 ;
99
100    lon0=(lon-minBoundLon)/precLon ;
101    if ( ((lon0+1)*precLon + lon0*precLon)/2 > lon-minBoundLon)
102    {
103      if (lon0==iMinLon) lon1=iMaxLon ;
104      else lon1=lon0-1 ;
105    }
106    else
107    {
108      if (lon0==iMaxLon) lon1=iMinLon ;
109      else lon1=lon0+1 ;
110    }
111
112    lat0=(lat-minBoundLat)/precLat ;
113    if ( ((lat0+1)*precLat + lat0*precLat)/2 > lat-minBoundLat)
114    {
115      if (lat0==iMinLat) lat1=lat0 ;
116      else lat1=lat0-1 ;
117    }
118    else
119    {
120      if (lat0==iMaxLat) lat1=lat0 ;
121      else lat1=lat0+1 ;
122    }
123
124    hash0=hashPair(lon0,lat0) ;
125    hash1=hashPair(lon0,lat1) ;
126    hash2=hashPair(lon1,lat0) ;
127    hash3=hashPair(lon1,lat1) ;
128
129    boost::unordered_map<size_t, size_t>::iterator end = hashed_map_nodes.end() ;
130    size_t mapSize = hashed_map_nodes.size();
131    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)
132    {
133      hashed_map_nodes[hash0] = mapSize ;
134      hashed_map_nodes[hash1] = mapSize + 1;
135      hashed_map_nodes[hash2] = mapSize + 2;
136      hashed_map_nodes[hash3] = mapSize + 3;
137      return -1;
138    }
139    else
140      return ( (hashed_map_nodes[hash0]+1) / 4 );
141
142  } // nodeIndex()
143
144///----------------------------------------------------------------
145/*!
146 * \fn CArray<size_t,1>& CMesh::createHashes (double lon, double lat)
147 * Creates two hash values for each dimension, longitude and latitude.
148 * \param [in] lon Node longitude in degrees.
149 * \param [in] lat Node latitude in degrees ranged from 0 to 360.
150 */
151
152  vector<size_t> CMesh::createHashes (double lon, double lat)
153  {
154    double minBoundLon = 0. ;
155    double maxBoundLon = 360. ;
156    double minBoundLat = -90 ;
157    double maxBoundLat = 90 ;
158    double prec=1e-11 ;
159    double precLon=prec ;
160    double precLat=prec ;
161
162    size_t maxsize_t=numeric_limits<size_t>::max() ;
163    if ( (maxBoundLon-minBoundLon)/maxsize_t > precLon) precLon=(maxBoundLon-minBoundLon)/maxsize_t ;
164    if ( (maxBoundLat-minBoundLat)/maxsize_t > precLat) precLat=(maxBoundLat-minBoundLat)/maxsize_t ;
165
166    size_t iMinLon=0 ;
167    size_t iMaxLon=(maxBoundLon-minBoundLon)/precLon ;
168    size_t iMinLat=0 ;
169    size_t iMaxLat=(maxBoundLat-minBoundLat)/precLat ;
170
171    vector<size_t> hash(4);
172    size_t lon0,lon1,lat0,lat1 ;
173
174    lon0=(lon-minBoundLon)/precLon ;
175    if ( ((lon0+1)*precLon + lon0*precLon)/2 > lon-minBoundLon)
176    {
177      if (lon0==iMinLon) lon1=iMaxLon ;
178      else lon1=lon0-1 ;
179    }
180    else
181    {
182      if (lon0==iMaxLon) lon1=iMinLon ;
183      else lon1=lon0+1 ;
184    }
185
186    lat0=(lat-minBoundLat)/precLat ;
187    if ( ((lat0+1)*precLat + lat0*precLat)/2 > lat-minBoundLat)
188    {
189      if (lat0==iMinLat) lat1=lat0 ;
190      else lat1=lat0-1 ;
191    }
192    else
193    {
194      if (lat0==iMaxLat) lat1=lat0 ;
195      else lat1=lat0+1 ;
196    }
197
198    hash[0] = hashPair(lon0,lat0) ;
199    hash[1] = hashPair(lon0,lat1) ;
200    hash[2] = hashPair(lon1,lat0) ;
201    hash[3] = hashPair(lon1,lat1) ;
202
203    return hash;
204
205  } // createHashes
206
207///----------------------------------------------------------------
208  std::pair<int,int> make_ordered_pair(int a, int b)
209  {
210    if ( a < b )
211      return std::pair<int,int>(a,b);
212    else
213      return std::pair<int,int>(b,a);
214  }
215
216///----------------------------------------------------------------
217//#include <random>
218//  size_t randNum()
219//  {
220//    typedef mt19937 rng;
221//    size_t max = numeric_limits<size_t>::max();
222//    uniform_int_distribution<> distr(0, max);
223//    return distr(rng);
224//  }
225
226///----------------------------------------------------------------
227/*!
228 * \fn void CMesh::createMesh(const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,
229            const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)
230 * Creates or updates a mesh for the three types of mesh elements: nodes, edges, and faces.
231 * \param [in] lonvalue  Array of longitudes.
232 * \param [in] latvalue  Array of latitudes.
233 * \param [in] bounds_lon Array of boundary longitudes. Its size depends on the element type.
234 * \param [in] bounds_lat Array of boundary latitudes. Its size depends on the element type.
235 */
236  void CMesh::createMesh(const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,
237            const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)
238  {
239    nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();
240
241    if (nvertex == 1)
242    {
243      nbNodes = lonvalue.numElements();
244      node_lon.resizeAndPreserve(nbNodes);
245      node_lat.resizeAndPreserve(nbNodes);
246      for (int nn = 0; nn < nbNodes; ++nn)
247      {
248        if (map_nodes.find(make_pair (lonvalue(nn), latvalue(nn))) == map_nodes.end())
249        {
250          map_nodes[make_pair (lonvalue(nn), latvalue(nn))] = nn ;
251          node_lon(nn) = lonvalue(nn);
252          node_lat(nn) = latvalue(nn);
253        }
254      }
255    }
256    else if (nvertex == 2)
257    {
258      nbEdges = bounds_lon.shape()[1];
259
260      // Create nodes and edge_node connectivity
261      node_lon.resizeAndPreserve(nbEdges*nvertex); // Max possible number of nodes
262      node_lat.resizeAndPreserve(nbEdges*nvertex);
263      edge_nodes.resizeAndPreserve(nvertex, nbEdges);
264
265      for (int ne = 0; ne < nbEdges; ++ne)
266      {
267        for (int nv = 0; nv < nvertex; ++nv)
268        {
269          if (map_nodes.find(make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))) == map_nodes.end())
270          {
271            map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv, ne))] = nbNodes ;
272            edge_nodes(nv,ne) = nbNodes ;
273            node_lon(nbNodes) = bounds_lon(nv, ne);
274            node_lat(nbNodes) = bounds_lat(nv, ne);
275            ++nbNodes ;
276          }
277          else
278            edge_nodes(nv,ne) = map_nodes[make_pair (bounds_lon(nv, ne), bounds_lat(nv ,ne))];
279        }
280      }
281      node_lon.resizeAndPreserve(nbNodes);
282      node_lat.resizeAndPreserve(nbNodes);
283
284      // Create edges
285      edge_lon.resizeAndPreserve(nbEdges);
286      edge_lat.resizeAndPreserve(nbEdges);
287
288      for (int ne = 0; ne < nbEdges; ++ne)
289      {
290        if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end())
291        {
292          map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ;
293          edge_lon(ne) = lonvalue(ne);
294          edge_lat(ne) = latvalue(ne);
295        }
296
297      }
298      edgesAreWritten = true;
299    }
300    else
301    {
302      nbFaces = bounds_lon.shape()[1];
303 
304      // Create nodes and face_node connectivity
305      node_lon.resizeAndPreserve(nbFaces*nvertex);  // Max possible number of nodes
306      node_lat.resizeAndPreserve(nbFaces*nvertex);
307      face_nodes.resize(nvertex, nbFaces);
308 
309      for (int nf = 0; nf < nbFaces; ++nf)
310      {
311        for (int nv = 0; nv < nvertex; ++nv)
312        {
313          if (map_nodes.find(make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))) == map_nodes.end())
314          {
315            map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv, nf))] = nbNodes ;
316            face_nodes(nv,nf) = nbNodes ;
317            node_lon(nbNodes) = bounds_lon(nv, nf);
318            node_lat(nbNodes) = bounds_lat(nv ,nf);
319            ++nbNodes ;
320          }
321          else
322          {
323            face_nodes(nv,nf) = map_nodes[make_pair (bounds_lon(nv, nf), bounds_lat(nv ,nf))];
324          }
325        }
326      }
327      node_lon.resizeAndPreserve(nbNodes);
328      node_lat.resizeAndPreserve(nbNodes);
329 
330      // Create edges and edge_nodes connectivity
331      edge_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of edges
332      edge_lat.resizeAndPreserve(nbFaces*nvertex);
333      edge_nodes.resizeAndPreserve(2, nbFaces*nvertex);
334      edge_faces.resize(2, nbFaces*nvertex);
335      face_edges.resize(nvertex, nbFaces);
336      face_faces.resize(nvertex, nbFaces);
337
338      vector<int> countEdges(nbFaces*nvertex);   // needed in case if edges have been already generated
339      vector<int> countFaces(nbFaces);
340      countEdges.assign(nbFaces*nvertex, 0);
341      countFaces.assign(nbFaces, 0);
342      int edge;
343      for (int nf = 0; nf < nbFaces; ++nf)
344      {
345        for (int nv1 = 0; nv1 < nvertex; ++nv1)
346        {
347          int nv = 0;
348          int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation
349          if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end())
350          {
351            map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges ;
352            face_edges(nv1,nf) = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))];
353            edge_faces(0,nbEdges) = nf;
354            edge_faces(1,nbEdges) = -999;
355            face_faces(nv1,nf) = -1;
356            edge_nodes(Range::all(),nbEdges) = face_nodes(nv1,nf), face_nodes(nv2,nf);
357            edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ?
358                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) :
359                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);;
360            edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5;
361            ++nbEdges;
362          }
363          else
364          {
365            edge = map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))];
366            face_edges(nv1,nf) = edge;
367            if (edgesAreWritten)
368            {
369              edge_faces(countEdges[edge], edge) = nf;
370              if (countEdges[edge]==0)
371              {
372                face_faces(nv1,nf) = -1;
373              }
374              else
375              {
376                int face1 = nf; // = edge_faces(1,edge)
377                int face2 = edge_faces(0,edge);
378                face_faces(countFaces[face1], face1) =  face2;
379                face_faces(countFaces[face2], face2) =  face1;
380                ++(countFaces[face1]);
381                ++(countFaces[face2]);
382              }
383            }
384            else
385            {
386              edge_faces(1,edge) = nf;
387              int face1 = nf; // = edge_faces(1,edge)
388              int face2 = edge_faces(0,edge);
389              face_faces(countFaces[face1], face1) =  face2;
390              face_faces(countFaces[face2], face2) =  face1;
391              ++(countFaces[face1]);
392              ++(countFaces[face2]);
393            }
394            ++(countEdges[edge]);
395          }
396        }
397      }
398      edge_nodes.resizeAndPreserve(2, nbEdges);
399      edge_faces.resizeAndPreserve(2, nbEdges);
400      edge_lon.resizeAndPreserve(nbEdges);
401      edge_lat.resizeAndPreserve(nbEdges);
402
403      // Create faces
404      face_lon.resize(nbFaces);
405      face_lat.resize(nbFaces);
406      face_lon = lonvalue;
407      face_lat = latvalue;
408      facesAreWritten = true;
409
410    } // nvertex > 2
411   
412  } // createMesh()
413
414///----------------------------------------------------------------
415/*!
416 * \fn void CMesh::createMeshEpsilon(const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,
417            const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)
418 * Creates or updates a mesh for the three types of mesh elements: nodes, edges, and faces.
419 * Precision check is implemented with two hash values for each dimension, longitude and latitude.
420 * \param [in] lonvalue  Array of longitudes.
421 * \param [in] latvalue  Array of latitudes.
422 * \param [in] bounds_lon Array of boundary longitudes. Its size depends on the element type.
423 * \param [in] bounds_lat Array of boundary latitudes. Its size depends on the element type.
424 */
425  void CMesh::createMeshEpsilon(const MPI_Comm& comm, const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,
426            const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)
427  {
428
429    nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();
430
431    if (nvertex == 1)
432    {
433      nbNodes = lonvalue.numElements();
434
435      CClientClientDHTSizet::Index2VectorInfoTypeMap hash2Idx;      // map <hash, idx>
436      vector<size_t> hashValues(4);                                 // temporary vector for storing hashes for each node
437      vector<size_t> globalIndexes(nbNodes);                        // Probably a map ?
438      CArray<size_t,1> hashList(nbNodes*4);                         // Do I need it?
439      CArray<size_t,1> idxList(nbNodes);
440
441      // Assign a unique index for each node represented by four hashes
442      // The first hash will serve as the unique index
443      size_t randomIdx;
444      int rank, size;
445      MPI_Comm_rank(comm, &rank);
446      MPI_Comm_size(comm, &size);
447      srand((unsigned)time(NULL)+rank*size);
448
449      for (size_t nn = 0; nn < nbNodes; ++nn)
450      {
451        hashValues = CMesh::createHashes(lonvalue(nn), latvalue(nn));
452        idxList(nn) = hashValues[nn];
453//        randomIdx = rand() % numeric_limits<size_t>::max();
454//        idxList(nn) = randomIdx;
455//        for (size_t nh = 0; nh < 4; ++nh)
456//        {
457//          hash2Idx[hashValues[nh]].push_back(randomIdx);
458//          hashList(nn*4 + nh) = hashValues[nh];
459//        }
460      }
461
462
463//      CClientClientDHTSizet dhtSizet(hash2Idx, comm);
464//      dhtSizet.computeIndexInfoMapping(hashList);
465 //     CClientClientDHTSizet::Index2VectorInfoTypeMap& hashIdxList = dhtSizet.getInfoIndexMap();
466
467//      // (2.1) Create a list of indexes for each hush
468//      CClientClientDHTSizet dhtSizet(hash2Idx, comm);
469//      dhtSizet.computeIndexInfoMapping(hashList);
470//      CClientClientDHTSizet::Index2VectorInfoTypeMap& hashIdxList = dhtSizet.getInfoIndexMap();
471//
472//      // (2.2) If more than one index assigned to a hush, set the larger value to be equal to the smaller
473//      int iidx = 0;
474//      for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = hashIdxList.begin(); it != hashIdxList.end(); ++it, ++iidx)
475//      {
476//        vector<size_t> tmp = it->second;
477//        size_t idxMinValue = it->second[0];
478//        for (int i = 1; i < it->second.size(); ++i)
479//        {
480//          if (it->second[i] < idxMinValue )
481//              idxMinValue = it->second[i];
482//        }
483//        if ( (iidx % 4) == 0 )
484//          idxList(iidx/4) = idxMinValue;
485//      }
486
487      // Unique global indexing
488      CDHTAutoIndexing dhtSizetIdx = CDHTAutoIndexing(idxList, comm);
489      CClientClientDHTSizet* pDhtSizet = &dhtSizetIdx;
490      pDhtSizet->computeIndexInfoMapping(idxList);
491
492      //globalIndexes = dhtSizetIdx.getGlobalIndex();
493
494      node_lon.resize(nbNodes);
495      node_lat.resize(nbNodes);
496      node_lon = lonvalue;
497      node_lat = latvalue;
498
499      nodesAreWritten = true;
500
501    }
502
503    else if (nvertex == 2)
504    {
505      nbEdges = bounds_lon.shape()[1];
506
507      vector<size_t> hashValues(4);
508      for (int ne = 0; ne < nbEdges; ++ne)
509      {
510        for (int nv = 0; nv < nvertex; ++nv)
511        {
512          hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne));
513//          for (size_t nh = 0; nh < 4; ++nh)
514//          {
515//            hash2Idx[hashValues[nh]].push_back(randomIdx);
516//            hashList(nn*4 + nh) = hashValues[nh];
517//          }
518
519
520        }
521      }
522      // Create nodes and edge_node connectivity
523
524      node_lon.resizeAndPreserve(nbEdges*nvertex); // Max possible number of nodes
525      node_lat.resizeAndPreserve(nbEdges*nvertex);
526      edge_nodes.resizeAndPreserve(nvertex, nbEdges);
527
528//      for (int ne = 0; ne < nbEdges; ++ne)
529//      {
530//        for (int nv = 0; nv < nvertex; ++nv)
531//        {
532//          if ( nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne)) == -1)
533//          {
534//            edge_nodes(nv,ne) = nbNodes ;
535//            node_lon(nbNodes) = bounds_lon(nv, ne);
536//            node_lat(nbNodes) = bounds_lat(nv, ne);
537//            ++nbNodes ;
538//          }
539//          else
540//            edge_nodes(nv,ne) = nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne));
541//        }
542//      }
543//      node_lon.resizeAndPreserve(nbNodes);
544//      node_lat.resizeAndPreserve(nbNodes);
545
546      // Create edges
547      edge_lon.resizeAndPreserve(nbEdges);
548      edge_lat.resizeAndPreserve(nbEdges);
549
550      for (int ne = 0; ne < nbEdges; ++ne)
551      {
552        if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end())
553        {
554          map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ;
555          edge_lon(ne) = lonvalue(ne);
556          edge_lat(ne) = latvalue(ne);
557        }
558      }
559      edgesAreWritten = true;
560    } // nvertex = 2
561    else
562    {
563      nbFaces = bounds_lon.shape()[1];
564
565      // Create nodes and face_node connectivity
566      node_lon.resizeAndPreserve(nbFaces*nvertex);  // Max possible number of nodes
567      node_lat.resizeAndPreserve(nbFaces*nvertex);
568      face_nodes.resize(nvertex, nbFaces);
569
570      /*for (int nf = 0; nf < nbFaces; ++nf)
571      {
572        for (int nv = 0; nv < nvertex; ++nv)
573        {
574          if ( nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf)) == -1)
575          {
576            face_nodes(nv,nf) = nbNodes ;
577            node_lon(nbNodes) = bounds_lon(nv, nf);
578            node_lat(nbNodes) = bounds_lat(nv ,nf);
579            ++nbNodes ;
580          }
581          else
582          {
583            face_nodes(nv,nf) = nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf));
584          }
585        }
586      }
587      node_lon.resizeAndPreserve(nbNodes);
588      node_lat.resizeAndPreserve(nbNodes);*/
589
590
591      // Create edges and edge_nodes connectivity
592//      edge_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of edges
593//      edge_lat.resizeAndPreserve(nbFaces*nvertex);
594//      edge_nodes.resizeAndPreserve(2, nbFaces*nvertex);
595//      for (int nf = 0; nf < nbFaces; ++nf)
596//      {
597//        for (int nv1 = 0; nv1 < nvertex; ++nv1)
598//        {
599//          int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation
600//          if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end())
601//          {
602//            map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges ;
603//            edge_nodes(Range::all(),nbEdges) = face_nodes(nv1,nf), face_nodes(nv2,nf);
604//            edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ?
605//                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) :
606//                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);;
607//            edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5;
608//            ++nbEdges;
609//          }
610//        }
611//      }
612//      edge_nodes.resizeAndPreserve(2, nbEdges);
613//      edge_lon.resizeAndPreserve(nbEdges);
614//      edge_lat.resizeAndPreserve(nbEdges);
615
616      // Create faces
617//      face_lon.resize(nbFaces);
618//      face_lat.resize(nbFaces);
619//      face_lon = lonvalue;
620//      face_lat = latvalue;
621//      facesAreWritten = true;
622
623    } // nvertex >= 3
624
625  } // createMeshEpsilon
626
627} // namespace xios
628
629//  void CMesh::createMeshEpsilon(const MPI_Comm& comm, const CArray<double, 1>& lonvalue, const CArray<double, 1>& latvalue,
630//            const CArray<double, 2>& bounds_lon, const CArray<double, 2>& bounds_lat)
631//  {
632//
633//    nvertex = (bounds_lon.numElements() == 0) ? 1 : bounds_lon.rows();
634//
635//    if (nvertex == 1)
636//    {
637//      nbNodes = lonvalue.numElements();
638//      node_lon.resizeAndPreserve(nbNodes);
639//      node_lat.resizeAndPreserve(nbNodes);
640//      for (int nn = 0; nn < nbNodes; ++nn)
641//      {
642//        if ( nodeIndex(lonvalue(nn), latvalue(nn)) == -1 )
643//        {
644//          node_lon(nn) = lonvalue(nn);
645//          node_lat(nn) = latvalue(nn);
646//        }
647//      }
648//
649//      nodesAreWritten = true;
650//    }
651//    else if (nvertex == 2)
652//    {
653//      nbEdges = bounds_lon.shape()[1];
654//
655//      // Create nodes and edge_node connectivity
656//      node_lon.resizeAndPreserve(nbEdges*nvertex); // Max possible number of nodes
657//      node_lat.resizeAndPreserve(nbEdges*nvertex);
658//      edge_nodes.resizeAndPreserve(nvertex, nbEdges);
659//
660//      for (int ne = 0; ne < nbEdges; ++ne)
661//      {
662//        for (int nv = 0; nv < nvertex; ++nv)
663//        {
664//          if ( nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne)) == -1)
665//          {
666//            edge_nodes(nv,ne) = nbNodes ;
667//            node_lon(nbNodes) = bounds_lon(nv, ne);
668//            node_lat(nbNodes) = bounds_lat(nv, ne);
669//            ++nbNodes ;
670//          }
671//          else
672//            edge_nodes(nv,ne) = nodeIndex(bounds_lon(nv, ne), bounds_lat(nv ,ne));
673//        }
674//      }
675//      node_lon.resizeAndPreserve(nbNodes);
676//      node_lat.resizeAndPreserve(nbNodes);
677//
678//      // Create edges
679//      edge_lon.resizeAndPreserve(nbEdges);
680//      edge_lat.resizeAndPreserve(nbEdges);
681//
682//      for (int ne = 0; ne < nbEdges; ++ne)
683//      {
684//        if (map_edges.find(make_ordered_pair (edge_nodes(0,ne), edge_nodes(1,ne))) == map_edges.end())
685//        {
686//          map_edges[make_ordered_pair ( edge_nodes(0,ne), edge_nodes(1,ne) )] = ne ;
687//          edge_lon(ne) = lonvalue(ne);
688//          edge_lat(ne) = latvalue(ne);
689//        }
690//      }
691//      edgesAreWritten = true;
692//    } // nvertex = 2
693//    else
694//    {
695//      nbFaces = bounds_lon.shape()[1];
696//
697//      // Create nodes and face_node connectivity
698//      node_lon.resizeAndPreserve(nbFaces*nvertex);  // Max possible number of nodes
699//      node_lat.resizeAndPreserve(nbFaces*nvertex);
700//      face_nodes.resize(nvertex, nbFaces);
701//
702//      for (int nf = 0; nf < nbFaces; ++nf)
703//      {
704//        for (int nv = 0; nv < nvertex; ++nv)
705//        {
706//          if ( nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf)) == -1)
707//          {
708//            face_nodes(nv,nf) = nbNodes ;
709//            node_lon(nbNodes) = bounds_lon(nv, nf);
710//            node_lat(nbNodes) = bounds_lat(nv ,nf);
711//            ++nbNodes ;
712//          }
713//          else
714//          {
715//            face_nodes(nv,nf) = nodeIndex(bounds_lon(nv, nf), bounds_lat(nv ,nf));
716//          }
717//        }
718//      }
719//      node_lon.resizeAndPreserve(nbNodes);
720//      node_lat.resizeAndPreserve(nbNodes);
721//
722//      // Create edges and edge_nodes connectivity
723//      edge_lon.resizeAndPreserve(nbFaces*nvertex); // Max possible number of edges
724//      edge_lat.resizeAndPreserve(nbFaces*nvertex);
725//      edge_nodes.resizeAndPreserve(2, nbFaces*nvertex);
726//      for (int nf = 0; nf < nbFaces; ++nf)
727//      {
728//        for (int nv1 = 0; nv1 < nvertex; ++nv1)
729//        {
730//          int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation
731//          if (map_edges.find(make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))) == map_edges.end())
732//          {
733//            map_edges[make_ordered_pair (face_nodes(nv1,nf), face_nodes(nv2,nf))] = nbEdges ;
734//            edge_nodes(Range::all(),nbEdges) = face_nodes(nv1,nf), face_nodes(nv2,nf);
735//            edge_lon(nbEdges) = ( abs( node_lon(face_nodes(nv1,nf)) - node_lon(face_nodes(nv2,nf))) < 180.) ?
736//                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5) :
737//                        (( node_lon(face_nodes(nv1,nf)) + node_lon(face_nodes(nv2,nf))) * 0.5 -180.);;
738//            edge_lat(nbEdges) = ( node_lat(face_nodes(nv1,nf)) + node_lat(face_nodes(nv2,nf)) ) * 0.5;
739//            ++nbEdges;
740//          }
741//        }
742//      }
743//      edge_nodes.resizeAndPreserve(2, nbEdges);
744//      edge_lon.resizeAndPreserve(nbEdges);
745//      edge_lat.resizeAndPreserve(nbEdges);
746//
747//      // Create faces
748//      face_lon.resize(nbFaces);
749//      face_lat.resize(nbFaces);
750//      face_lon = lonvalue;
751//      face_lat = latvalue;
752//      facesAreWritten = true;
753//    } // nvertex >= 3
754//
755//  } // createMeshEpsilon
Note: See TracBrowser for help on using the repository browser.