Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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" 23 #include "moab/IntxMesh/IntxUtils.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  */ 71  ErrorCode intersect_meshes( EntityHandle mbs1, EntityHandle mbs2, EntityHandle& outputSet ); 72  73  /* 74  * slower intx, use kd tree only, no adjacency, no adv front 75  */ 76  ErrorCode intersect_meshes_kdtree( EntityHandle mbset1, EntityHandle mbset2, EntityHandle& outputSet ); 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 87  virtual ErrorCode computeIntersectionBetweenTgtAndSrc( EntityHandle tgt, 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  143  ErrorCode create_departure_mesh_2nd_alg( EntityHandle& euler_set, EntityHandle& covering_lagr_set ); 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  152  ErrorCode create_departure_mesh_3rd_alg( EntityHandle& lagr_set, EntityHandle& covering_set ); 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 197  Interface* mb; 198  199  EntityHandle mbs1; 200  EntityHandle mbs2; 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  210  Range TgtEdges; // 211  212  // tgt parent and src parent tags 213  // these will be on the out mesh 214  Tag tgtParentTag; 215  Tag srcParentTag; 216  Tag countTag; 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  230  const EntityHandle* tgtConn; 231  const EntityHandle* srcConn; 232  CartVect tgtCoords[MAXEDGES]; 233  CartVect srcCoords[MAXEDGES]; 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 */ 256  EntityHandle localRoot; 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_ */