Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
Intx2Mesh.hpp
Go to the documentation of this file.
1 /*
2  * Intx2Mesh.hpp
3  *
4  * Created on: Oct 2, 2012
5  *
6  */
7 
8 #ifndef INTX2MESH_HPP_
9 #define INTX2MESH_HPP_
10 
11 #include <iostream>
12 #include <sstream>
13 #include <fstream>
14 #include <map>
15 #include <ctime>
16 #include <cstdlib>
17 #include <cstdio>
18 #include <cstring>
19 #include "moab/Core.hpp"
20 #include "moab/Interface.hpp"
21 #include "moab/Range.hpp"
22 #include "moab/CartVect.hpp"
24 
25 // #define ENABLE_DEBUG
26 
27 // maximum number of edges on each convex polygon of interest
28 #define MAXEDGES 10
29 #define MAXEDGES2 20 // used for coordinates in plane
30 #define CORRTAGNAME "__correspondent"
31 
32 namespace moab
33 {
34 
35 #define ERRORR( rval, str ) \
36  if( MB_SUCCESS != ( rval ) ) \
37  { \
38  std::cout << ( str ) << "\n"; \
39  return rval; \
40  }
41 
42 #define ERRORV( rval, str ) \
43  if( MB_SUCCESS != ( rval ) ) \
44  { \
45  std::cout << ( str ) << "\n"; \
46  return; \
47  }
48 
49 #ifdef MOAB_HAVE_MPI
50 // forward declarations
51 class ParallelComm;
52 class TupleList;
53 #endif
54 
55 class Intx2Mesh
56 {
57  public:
58  Intx2Mesh( Interface* mbimpl );
59 
60  virtual ~Intx2Mesh();
61 
62  /*
63  * computes intersection between 2 sets;
64  * set 2 (mbs2) should be completely covered by set mbs1, as all elements
65  * from set 2 will be decomposed in polygons ; an area verification is done, and
66  * will signal elements from set 2 that are not "recovered"
67  *
68  * the resulting polygons are inserted in output set; total area from output set should be
69  * equal to total area of elements in set 2 (check that!)
70  */
72 
73  /*
74  * slower intx, use kd tree only, no adjacency, no adv front
75  */
77 
78  // mark could be (3 or 4, depending on type: ) no, it could go to 10
79  // no, it will be MAXEDGES = 10
80  // this is pure abstract, this needs to be implemented by
81  // all derivations
82  // the max number of intersection points could be 2*MAXEDGES
83  // so P must be dimensioned to 4*MAXEDGES (2*2*MAXEDGES)
84  // so, if you intersect 2 convex polygons with MAXEDGES , you will get a convex polygon
85  // with 2*MAXEDGES, at most
86  // will also return the number of nodes of tgt and src elements
88  EntityHandle src,
89  double* P,
90  int& nP,
91  double& area,
92  int markb[MAXEDGES],
93  int markr[MAXEDGES],
94  int& nsidesSrc,
95  int& nsidesTgt,
96  bool check_boxes_first = false ) = 0;
97 
98  // this is also abstract
99  virtual ErrorCode findNodes( EntityHandle tgt, int nsTgt, EntityHandle src, int nsSrc, double* iP, int nP ) = 0;
100 
101  // this is also computing the area of the tgt cell in plane (gnomonic plane for sphere)
102  // setting the local variables:
103  // this will be done once per tgt cell, and once per localQueue for src cells
104  // const EntityHandle * tgtConn;
105  // CartVect redCoords[MAXEDGES];
106  // double redCoords2D[MAXEDGES2]; // these are in plane
107 
108  virtual double setup_tgt_cell( EntityHandle tgt, int& nsTgt ) = 0;
109 
110  virtual ErrorCode FindMaxEdgesInSet( EntityHandle eset, int& max_edges );
111  virtual ErrorCode FindMaxEdges( EntityHandle set1,
112  EntityHandle set2 ); // this needs to be called before any
113  // covering communication in parallel
114 
115  virtual ErrorCode createTags();
116 
117  virtual ErrorCode filterByMask(Range & cells);
118 
119  ErrorCode DetermineOrderedNeighbors( EntityHandle inputSet, int max_edges, Tag& neighTag );
120 
121  void set_error_tolerance( double eps )
122  {
123  epsilon_1 = eps;
124  epsilon_area = eps * sqrt( eps );
125  }
126 
127 #ifdef MOAB_HAVE_MPI
128  void set_parallel_comm( moab::ParallelComm* pcomm )
129  {
130  parcomm = pcomm;
131  }
132 #endif
133  // void SetEntityType (EntityType tp) { type=tp;}
134 
135  // clean some memory allocated
136  void clean();
137 
138  void set_box_error( double berror )
139  {
140  box_error = berror;
141  }
142 
144 
145  // in this method, used in parallel, each departure elements are already created, and at their
146  // positions the covering_set is output, will contain the departure cells that cover the euler
147  // set; some of these departure cells might come from different processors so the covering_set
148  // contains some elements from lagr_set and some elements that come from other procs we need to
149  // keep track of what processors "sent" the elements so we know were to send back the info about
150  // the tracers masses
151 
153 
154  /* in this method, used in parallel, each cell from first mesh need to be sent to the
155  * tasks whose second mesh bounding boxes intersects bounding box of the cell
156  * this method assumes that the bounding boxes for the second mesh were computed already in a
157  * previous method (called build_processor_euler_boxes)
158  *
159  * the covering_set is output, will cover the second mesh (set) from the task;
160  * Some of the cells in the first mesh will be sent to multiple processors; we keep track of
161  * them using the global id of the vertices and global ids of the cells (we do not want to
162  * create multiple vertices with the same ids). The global id of the cells are needed just for
163  * debugging, the cells cannot come from 2 different tasks, but the vertices can
164  *
165  * Right now, we use crystal router, but an improvement might be to use direct communication
166  * (send_entities) on parallel comm
167  *
168  * param initial_distributed_set (IN) : the initial distribution of the first mesh (set)
169  *
170  * param (OUT) : the covering set in first mesh , which completely covers the second mesh set
171  */
172 #ifdef MOAB_HAVE_MPI
173 
174  virtual ErrorCode build_processor_euler_boxes( EntityHandle euler_set, Range& local_verts, bool gnomonic = true );
175 #endif
176  void correct_polygon( EntityHandle* foundIds, int& nP );
177 #ifdef MOAB_HAVE_MPI
178  // share vertices between the intersection target domains
179  ErrorCode resolve_intersection_sharing();
180 #endif
181 #ifdef ENABLE_DEBUG
182  void enable_debug()
183  {
184  dbg_1 = 1;
185  }
186  void disable_debug()
187  {
188  dbg_1 = 0;
189  }
190 #endif
191 
192 #ifdef MOAB_HAVE_TEMPESTREMAP
193  friend class TempestRemapper;
194 #endif
195 
196  protected: // so it can be accessed in derived classes, InPlane and OnSphere
198 
201  Range rs1; // range set 1 (departure set, lagrange set, src set, manufactured set, target mesh)
202  Range rs2; // range set 2 (arrival set, euler set, tgt set, initial set, source mesh)
203 
204  EntityHandle outSet; // will contain intersection
205  Tag gid; // global id tag will be used to set the parents of the intersection cell
206 
207  // tags used in computation, advancing front
208  Tag TgtFlagTag; // to mark tgt quads already considered
209 
211 
212  // tgt parent and src parent tags
213  // these will be on the out mesh
217 
218  Tag srcNeighTag; // will store neighbors for navigating easily in advancing front, for first
219  // mesh (src, target, lagrange)
220  Tag tgtNeighTag; // will store neighbors for navigating easily in advancing front, for second
221  // mesh (tgt, source, euler)
222 
223  Tag neighTgtEdgeTag; // will store edge borders for each tgt cell
224 
225  Tag orgSendProcTag; /// for coverage mesh, will store the original sender
226  Tag imaskTag; // if it exists, use it for filtering the source or target cells
227 
228  // EntityType type; // this will be tri, quad or MBPOLYGON...
229 
234  double tgtCoords2D[MAXEDGES2]; // these are in plane
235  double srcCoords2D[MAXEDGES2]; // these are in plane
236 
237 #ifdef ENABLE_DEBUG
238  static int dbg_1;
239  std::ofstream mout_1[6]; // some debug files
240 #endif
241  // for each tgt edge, we keep a vector of extra nodes, coming from intersections
242  // use the index in TgtEdges range
243  // so the extra nodes on each tgt edge are kept track of
244  // only entity handles are in the vector, not the actual coordinates;
245  // actual coordinates are retrieved every time, which could be expensive
246  // maybe we should store the coordinates too, along with entity handles (more memory used,
247  // faster to retrieve)
248  std::vector< std::vector< EntityHandle >* > extraNodesVec;
249 
250  double epsilon_1;
251  double epsilon_area;
252 
253  std::vector< double > allBoxes;
254  double box_error;
255  /* \brief Local root of the kdtree */
257  Range localEnts; // this range is for local elements of interest, euler cells, or "first mesh"
258  unsigned int my_rank;
259 
260 #ifdef MOAB_HAVE_MPI
261  ParallelComm* parcomm;
262  TupleList* remote_cells; // not used anymore for communication, just a container
263  TupleList* remote_cells_with_tracers; // these will be used now to update tracers on remote procs
264  std::map< int, EntityHandle > globalID_to_eh; // needed for parallel, mostly
265 #endif
266  int max_edges_1; // maximum number of edges in the lagrange set (first set, src)
267  int max_edges_2; // maximum number of edges in the euler set (second set, tgt)
268  int counting;
269 };
270 
271 } /* namespace moab */
272 #endif /* INTX2MESH_HPP_ */