Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::IntxRllCssphere Class Reference

#include <IntxRllCssphere.hpp>

+ Inheritance diagram for moab::IntxRllCssphere:
+ Collaboration diagram for moab::IntxRllCssphere:

Public Member Functions

 IntxRllCssphere (Interface *mbimpl)
 
virtual ~IntxRllCssphere ()
 
void set_radius (double radius)
 
double setup_tgt_cell (EntityHandle tgt, int &nsTgt)
 
ErrorCode computeIntersectionBetweenTgtAndSrc (EntityHandle tgt, EntityHandle src, double *P, int &nP, double &area, int markb[MAXEDGES], int markr[MAXEDGES], int &nsSrc, int &nsTgt, bool check_boxes_first=false)
 
ErrorCode findNodes (EntityHandle tgt, int nsTgt, EntityHandle src, int nsSrc, double *iP, int nP)
 
- Public Member Functions inherited from moab::Intx2Mesh
 Intx2Mesh (Interface *mbimpl)
 
virtual ~Intx2Mesh ()
 
ErrorCode intersect_meshes (EntityHandle mbs1, EntityHandle mbs2, EntityHandle &outputSet)
 
ErrorCode intersect_meshes_kdtree (EntityHandle mbset1, EntityHandle mbset2, EntityHandle &outputSet)
 
virtual ErrorCode FindMaxEdgesInSet (EntityHandle eset, int &max_edges)
 
virtual ErrorCode FindMaxEdges (EntityHandle set1, EntityHandle set2)
 
virtual ErrorCode createTags ()
 
virtual ErrorCode filterByMask (Range &cells)
 
ErrorCode DetermineOrderedNeighbors (EntityHandle inputSet, int max_edges, Tag &neighTag)
 
void set_error_tolerance (double eps)
 
void clean ()
 
void set_box_error (double berror)
 
ErrorCode create_departure_mesh_2nd_alg (EntityHandle &euler_set, EntityHandle &covering_lagr_set)
 
ErrorCode create_departure_mesh_3rd_alg (EntityHandle &lagr_set, EntityHandle &covering_set)
 
void correct_polygon (EntityHandle *foundIds, int &nP)
 

Private Attributes

double R
 
int plane
 
int srcEdgeType [4]
 

Additional Inherited Members

- Protected Attributes inherited from moab::Intx2Mesh
Interfacemb
 
EntityHandle mbs1
 
EntityHandle mbs2
 
Range rs1
 
Range rs2
 
EntityHandle outSet
 
Tag gid
 
Tag TgtFlagTag
 
Range TgtEdges
 
Tag tgtParentTag
 
Tag srcParentTag
 
Tag countTag
 
Tag srcNeighTag
 
Tag tgtNeighTag
 
Tag neighTgtEdgeTag
 
Tag orgSendProcTag
 
Tag imaskTag
 for coverage mesh, will store the original sender More...
 
const EntityHandletgtConn
 
const EntityHandlesrcConn
 
CartVect tgtCoords [MAXEDGES]
 
CartVect srcCoords [MAXEDGES]
 
double tgtCoords2D [MAXEDGES2]
 
double srcCoords2D [MAXEDGES2]
 
std::vector< std::vector< EntityHandle > * > extraNodesVec
 
double epsilon_1
 
double epsilon_area
 
std::vector< double > allBoxes
 
double box_error
 
EntityHandle localRoot
 
Range localEnts
 
unsigned int my_rank
 
int max_edges_1
 
int max_edges_2
 
int counting
 

Detailed Description

Definition at line 14 of file IntxRllCssphere.hpp.

Constructor & Destructor Documentation

◆ IntxRllCssphere()

moab::IntxRllCssphere::IntxRllCssphere ( Interface mbimpl)

Definition at line 15 of file IntxRllCssphere.cpp.

15 : Intx2Mesh( mbimpl ), R( 0.0 ), plane( 0 ) {}

◆ ~IntxRllCssphere()

moab::IntxRllCssphere::~IntxRllCssphere ( )
virtual

Definition at line 17 of file IntxRllCssphere.cpp.

17 {}

Member Function Documentation

◆ computeIntersectionBetweenTgtAndSrc()

ErrorCode moab::IntxRllCssphere::computeIntersectionBetweenTgtAndSrc ( EntityHandle  tgt,
EntityHandle  src,
double *  P,
int &  nP,
double &  area,
int  markb[MAXEDGES],
int  markr[MAXEDGES],
int &  nsSrc,
int &  nsTgt,
bool  check_boxes_first = false 
)
virtual

Implements moab::Intx2Mesh.

Definition at line 61 of file IntxRllCssphere.cpp.

71 {
72  // the area will be used from now on, to see how well we fill the tgt cell with polygons
73  // the points will be at most 40; they will describe a convex patch, after the points will be
74  // ordered and collapsed (eliminate doubles)
75 
76  // CartVect srccoords[4];
77  int num_nodes = 0;
78  MB_CHK_ERR( mb->get_connectivity( src, srcConn, num_nodes ) );
79 
80  nsSrc = num_nodes;
81  MB_CHK_ERR( mb->get_coords( srcConn, nsSrc, &( srcCoords[0][0] ) ) );
82 
83  // determine the type of edge: const lat or not?
84  // just look at the consecutive z coordinates for the edge
85  for( int i = 0; i < nsSrc; i++ )
86  {
87  int nexti = ( i + 1 ) % nsSrc;
88  if( fabs( srcCoords[i][2] - srcCoords[nexti][2] ) < 1.e-6 )
89  srcEdgeType[i] = 1;
90  else
91  srcEdgeType[i] = 0;
92  }
93  area = 0.;
94  nP = 0; // number of intersection points we are marking the boundary of src!
95  if( check_boxes_first )
96  {
97  // look at the boxes formed with vertices; if they are far away, return false early
98  // make sure the tgt is setup already
99  setup_tgt_cell( tgt, nsTgt ); // we do not need area here
101  return MB_SUCCESS; // no error, but no intersection, decide early to get out
102  }
103 #ifdef ENABLE_DEBUG
104  if( dbg_1 )
105  {
106  std::cout << "tgt " << mb->id_from_handle( tgt ) << "\n";
107  for( int j = 0; j < nsTgt; j++ )
108  {
109  std::cout << tgtCoords[j] << "\n";
110  }
111  std::cout << "src " << mb->id_from_handle( src ) << "\n";
112  for( int j = 0; j < nsSrc; j++ )
113  {
114  std::cout << srcCoords[j] << "\n";
115  }
116  mb->list_entities( &tgt, 1 );
117  mb->list_entities( &src, 1 );
118  }
119 #endif
120  for( int j = 0; j < nsSrc; j++ )
121  {
122  MB_CHK_ERR(
124  }
125 #ifdef ENABLE_DEBUG
126  if( dbg_1 )
127  {
128  std::cout << "gnomonic plane: " << plane << "\n";
129  std::cout << " tgt src\n";
130  for( int j = 0; j < nsTgt; j++ )
131  {
132  std::cout << tgtCoords2D[2 * j] << " " << tgtCoords2D[2 * j + 1] << "\n";
133  }
134  for( int j = 0; j < nsSrc; j++ )
135  {
136  std::cout << srcCoords2D[2 * j] << " " << srcCoords2D[2 * j + 1] << "\n";
137  }
138  }
139 #endif
141  markb, markr, plane, R, P, nP ) );
142 
143  int side[MAXEDGES] = { 0 }; // this refers to what side? src or tgt?// more tolerant here with epsilon_area
144  int extraPoints = IntxUtils::borderPointsOfXinY2( srcCoords2D, nsSrc, tgtCoords2D, nsTgt, &( P[2 * nP] ), side,
145  2 * epsilon_area );
146  if( extraPoints >= 1 )
147  {
148  for( int k = 0; k < nsSrc; k++ )
149  {
150  if( side[k] )
151  {
152  // this means that vertex k of src is inside convex tgt; mark edges k-1 and k in
153  // src,
154  // as being "intersected" by tgt; (even though they might not be intersected by
155  // other edges, the fact that their apex is inside, is good enough)
156  markb[k] = 1;
157  markb[( k + nsSrc - 1 ) % nsSrc] =
158  1; // it is the previous edge, actually, but instead of doing -1, it is
159  // better to do modulo +3 (modulo 4)
160  // null side b for next call
161  side[k] = 0;
162  }
163  }
164  }
165  nP += extraPoints;
166 
167  extraPoints =
169  side,
170  100 * epsilon_area ); // we need to compare with 0 a volume from 3 vector
171  // product; // lots of round off errors at stake
172  if( extraPoints >= 1 )
173  {
174  for( int k = 0; k < nsTgt; k++ )
175  {
176  if( side[k] )
177  {
178  // this is to mark that tgt edges k-1 and k are intersecting src
179  markr[k] = 1;
180  markr[( k + nsTgt - 1 ) % nsTgt] =
181  1; // it is the previous edge, actually, but instead of doing -1, it is
182  // better to do modulo +3 (modulo 4)
183  // null side b for next call
184  }
185  }
186  }
187  nP += extraPoints;
188 
189  // now sort and orient the points in P, such that they are forming a convex polygon
190  // this will be the foundation of our new mesh
191  // this works if the polygons are convex
192  IntxUtils::SortAndRemoveDoubles2( P, nP, epsilon_1 ); // nP should be at most 8 in the end ?
193  // if there are more than 3 points, some area will be positive
194 
195  if( nP >= 3 )
196  {
197  for( int k = 1; k < nP - 1; k++ )
198  area += IntxUtils::area2D( P, &P[2 * k], &P[2 * k + 2] );
199  }
200 
201  return MB_SUCCESS; // no error
202 }

References moab::IntxUtils::area2D(), moab::IntxUtils::borderPointsOfCSinRLL(), moab::IntxUtils::borderPointsOfXinY2(), moab::GeomUtil::bounding_boxes_overlap(), moab::Intx2Mesh::box_error, moab::IntxUtils::EdgeIntxRllCs(), moab::Intx2Mesh::epsilon_1, moab::Intx2Mesh::epsilon_area, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::IntxUtils::gnomonic_projection(), moab::Interface::id_from_handle(), moab::Interface::list_entities(), MAXEDGES, moab::Intx2Mesh::mb, MB_CHK_ERR, MB_SUCCESS, plane, R, setup_tgt_cell(), moab::IntxUtils::SortAndRemoveDoubles2(), moab::Intx2Mesh::srcConn, moab::Intx2Mesh::srcCoords, moab::Intx2Mesh::srcCoords2D, srcEdgeType, moab::Intx2Mesh::tgtCoords, and moab::Intx2Mesh::tgtCoords2D.

◆ findNodes()

ErrorCode moab::IntxRllCssphere::findNodes ( EntityHandle  tgt,
int  nsTgt,
EntityHandle  src,
int  nsSrc,
double *  iP,
int  nP 
)
virtual

Implements moab::Intx2Mesh.

Definition at line 209 of file IntxRllCssphere.cpp.

210 {
211  // first of all, check against tgt and src vertices
212  //
213 #ifdef ENABLE_DEBUG
214  if( dbg_1 )
215  {
216  std::cout << "tgt, src, nP, P " << mb->id_from_handle( tgt ) << " " << mb->id_from_handle( src ) << " " << nP
217  << "\n";
218  for( int n = 0; n < nP; n++ )
219  std::cout << " \t" << iP[2 * n] << "\t" << iP[2 * n + 1] << "\n";
220  }
221 #endif
222 
223  // get the edges for the tgt triangle; the extra points will be on those edges, saved as
224  // lists (unordered)
225 
226  // first get the list of edges adjacent to the tgt cell
227  // use the neighTgtEdgeTag
228  EntityHandle adjTgtEdges[MAXEDGES];
229  MB_CHK_SET_ERR( mb->tag_get_data( neighTgtEdgeTag, &tgt, 1, &( adjTgtEdges[0] ) ), "can't get edge tgt tag" );
230  // we know that we have only nsTgt edges here; [nsTgt, MAXEDGES) are ignored, but it is small
231  // potatoes
232 
233  // these will be in the new mesh, mbOut
234  // some of them will be handles to the initial vertices from src or tgt meshes (lagr or euler)
235 
236  EntityHandle* foundIds = new EntityHandle[nP];
237  for( int i = 0; i < nP; i++ )
238  {
239  double* pp = &iP[2 * i]; // iP+2*i
240  // project the point back on the sphere
241  CartVect pos;
242  IntxUtils::reverse_gnomonic_projection( pp[0], pp[1], R, plane, pos );
243  int found = 0;
244  // first, are they on vertices from tgt or src?
245  // priority is the tgt mesh (mb2?)
246  int j = 0;
247  EntityHandle outNode = (EntityHandle)0;
248  for( j = 0; j < nsTgt && !found; j++ )
249  {
250  // int node = tgtTri.v[j];
251  double d2 = IntxUtils::dist2( pp, &tgtCoords2D[2 * j] );
252  if( d2 < epsilon_1 )
253  {
254 
255  foundIds[i] = tgtConn[j]; // no new node
256  found = 1;
257 #ifdef ENABLE_DEBUG
258  if( dbg_1 )
259  std::cout << " tgt node j:" << j << " id:" << mb->id_from_handle( tgtConn[j] )
260  << " 2d coords:" << tgtCoords2D[2 * j] << " " << tgtCoords2D[2 * j + 1] << " d2: " << d2
261  << " \n";
262 #endif
263  }
264  }
265 
266  for( j = 0; j < nsSrc && !found; j++ )
267  {
268  // int node = srcTri.v[j];
269  double d2 = IntxUtils::dist2( pp, &srcCoords2D[2 * j] );
270  if( d2 < epsilon_1 )
271  {
272  // suspect is srcConn[j] corresponding in mbOut
273 
274  foundIds[i] = srcConn[j]; // no new node
275  found = 1;
276 #ifdef ENABLE_DEBUG
277  if( dbg_1 )
278  std::cout << " src node " << j << " " << mb->id_from_handle( srcConn[j] ) << " d2:" << d2 << " \n";
279 #endif
280  }
281  }
282  if( !found )
283  {
284  // find the edge it belongs, first, on the tgt element
285  //
286  for( j = 0; j < nsTgt; j++ )
287  {
288  int j1 = ( j + 1 ) % nsTgt;
289  double area = IntxUtils::area2D( &tgtCoords2D[2 * j], &tgtCoords2D[2 * j1], pp );
290 #ifdef ENABLE_DEBUG
291  if( dbg_1 )
292  std::cout << " edge " << j << ": " << mb->id_from_handle( adjTgtEdges[j] ) << " " << tgtConn[j]
293  << " " << tgtConn[j1] << " area : " << area << "\n";
294 #endif
295  if( fabs( area ) < epsilon_1 / 2 )
296  {
297  // found the edge; now find if there is a point in the list here
298  // std::vector<EntityHandle> * expts = extraNodesMap[tgtEdges[j]];
299  int indx = TgtEdges.index( adjTgtEdges[j] );
300  // CID 181167 (#1 of 1): Argument cannot be negative (NEGATIVE_RETURNS)
301  if( indx < 0 )
302  {
303  std::cerr << " error in adjacent tgt edge: " << mb->id_from_handle( adjTgtEdges[j] ) << "\n";
304  delete[] foundIds;
305  return MB_FAILURE;
306  }
307  std::vector< EntityHandle >* expts = extraNodesVec[indx];
308  // if the points pp is between extra points, then just give that id
309  // if not, create a new point, (check the id)
310  // get the coordinates of the extra points so far
311  int nbExtraNodesSoFar = expts->size();
312  if( nbExtraNodesSoFar > 0 )
313  {
314  CartVect* coords1 = new CartVect[nbExtraNodesSoFar];
315  mb->get_coords( &( *expts )[0], nbExtraNodesSoFar, &( coords1[0][0] ) );
316  // std::list<int>::iterator it;
317  for( int k = 0; k < nbExtraNodesSoFar && !found; k++ )
318  {
319  // int pnt = *it;
320  double d2 = ( pos - coords1[k] ).length_squared();
321  if( d2 < epsilon_1 )
322  {
323  found = 1;
324  foundIds[i] = ( *expts )[k];
325 #ifdef ENABLE_DEBUG
326  if( dbg_1 ) std::cout << " found node:" << foundIds[i] << std::endl;
327 #endif
328  }
329  }
330  delete[] coords1;
331  }
332  if( !found )
333  {
334  // create a new point in 2d (at the intersection)
335  // foundIds[i] = m_num2dPoints;
336  // expts.push_back(m_num2dPoints);
337  // need to create a new node in mbOut
338  // this will be on the edge, and it will be added to the local list
339  mb->create_vertex( pos.array(), outNode );
340  ( *expts ).push_back( outNode );
341  foundIds[i] = outNode;
342  found = 1;
343 #ifdef ENABLE_DEBUG
344  if( dbg_1 ) std::cout << " new node: " << outNode << std::endl;
345 #endif
346  }
347  }
348  }
349  }
350  if( !found )
351  {
352  std::cout << " tgt quad: ";
353  for( int j1 = 0; j1 < nsTgt; j1++ )
354  {
355  std::cout << tgtCoords2D[2 * j1] << " " << tgtCoords2D[2 * j1 + 1] << "\n";
356  }
357  std::cout << " a point pp is not on a tgt quad " << *pp << " " << pp[1] << " tgt quad "
358  << mb->id_from_handle( tgt ) << " \n";
359  delete[] foundIds;
360  return MB_FAILURE;
361  }
362  }
363 #ifdef ENABLE_DEBUG
364  if( dbg_1 )
365  {
366  std::cout << " candidate polygon: nP" << nP << " plane: " << plane << "\n";
367  for( int i1 = 0; i1 < nP; i1++ )
368  std::cout << iP[2 * i1] << " " << iP[2 * i1 + 1] << " " << foundIds[i1] << "\n";
369  }
370 #endif
371  // first, find out if we have nodes collapsed; shrink them
372  // we may have to reduce nP
373  // it is possible that some nodes are collapsed after intersection only
374  // nodes will always be in order (convex intersection)
375  correct_polygon( foundIds, nP );
376  // now we can build the triangles, from P array, with foundIds
377  // we will put them in the out set
378  if( nP >= 3 )
379  {
380  EntityHandle polyNew;
381  mb->create_element( MBPOLYGON, foundIds, nP, polyNew );
382  mb->add_entities( outSet, &polyNew, 1 );
383 
384  // tag it with the index ids from tgt and src sets
385  int id = rs1.index( src ); // index starts from 0
386  mb->tag_set_data( srcParentTag, &polyNew, 1, &id );
387  id = rs2.index( tgt );
388  mb->tag_set_data( tgtParentTag, &polyNew, 1, &id );
389 
390  counting++;
391  mb->tag_set_data( countTag, &polyNew, 1, &counting );
392 
393 #ifdef ENABLE_DEBUG
394  if( dbg_1 )
395  {
396 
397  std::cout << "Counting: " << counting << "\n";
398  std::cout << " polygon " << mb->id_from_handle( polyNew ) << " nodes: " << nP << " :";
399  for( int i1 = 0; i1 < nP; i1++ )
400  std::cout << " " << mb->id_from_handle( foundIds[i1] );
401  std::cout << " plane: " << plane << "\n";
402  std::vector< CartVect > posi( nP );
403  mb->get_coords( foundIds, nP, &( posi[0][0] ) );
404  for( int i1 = 0; i1 < nP; i1++ )
405  std::cout << foundIds[i1] << " " << posi[i1] << "\n";
406 
407  std::stringstream fff;
408  fff << "file0" << counting << ".vtk";
409  mb->write_mesh( fff.str().c_str(), &outSet, 1 );
410  }
411 #endif
412  }
413  // disable_debug();
414  delete[] foundIds;
415  foundIds = nullptr;
416  return MB_SUCCESS;
417 }

References moab::Interface::add_entities(), moab::IntxUtils::area2D(), moab::CartVect::array(), moab::Intx2Mesh::correct_polygon(), moab::Intx2Mesh::counting, moab::Intx2Mesh::countTag, moab::Interface::create_element(), moab::Interface::create_vertex(), moab::IntxUtils::dist2(), moab::Intx2Mesh::epsilon_1, moab::Intx2Mesh::extraNodesVec, moab::Interface::get_coords(), moab::Interface::id_from_handle(), moab::Range::index(), length_squared(), MAXEDGES, moab::Intx2Mesh::mb, MB_CHK_SET_ERR, MB_SUCCESS, MBPOLYGON, moab::Intx2Mesh::neighTgtEdgeTag, moab::Intx2Mesh::outSet, plane, R, moab::IntxUtils::reverse_gnomonic_projection(), moab::Intx2Mesh::rs1, moab::Intx2Mesh::rs2, moab::Intx2Mesh::srcConn, moab::Intx2Mesh::srcCoords2D, moab::Intx2Mesh::srcParentTag, moab::Interface::tag_get_data(), moab::Interface::tag_set_data(), moab::Intx2Mesh::tgtConn, moab::Intx2Mesh::tgtCoords2D, moab::Intx2Mesh::TgtEdges, moab::Intx2Mesh::tgtParentTag, and moab::Interface::write_mesh().

◆ set_radius()

void moab::IntxRllCssphere::set_radius ( double  radius)
inline

Definition at line 21 of file IntxRllCssphere.hpp.

22  {
23  R = radius;
24  }

References R, and radius.

◆ setup_tgt_cell()

double moab::IntxRllCssphere::setup_tgt_cell ( EntityHandle  tgt,
int &  nsTgt 
)
virtual

Implements moab::Intx2Mesh.

Definition at line 22 of file IntxRllCssphere.cpp.

23 {
24  // get coordinates of the tgt quad, to decide the gnomonic plane
25  double cellArea = 0;
26 
27  int num_nodes;
28  ErrorCode rval = mb->get_connectivity( tgt, tgtConn, num_nodes );
29 
30  if( MB_SUCCESS != rval ) return 1;
31  nsTgt = num_nodes;
32  // these edges will never be polygons, only quads or triangles
33 
34  // CartVect coords[4];
35  rval = mb->get_coords( tgtConn, nsTgt, &( tgtCoords[0][0] ) );
36  if( MB_SUCCESS != rval ) return 1;
37  CartVect middle = tgtCoords[0];
38  for( int i = 1; i < nsTgt; i++ )
39  middle += tgtCoords[i];
40  middle = 1. / nsTgt * middle;
41 
42  IntxUtils::decide_gnomonic_plane( middle, plane ); // output the plane
43  for( int j = 0; j < nsTgt; j++ )
44  {
45  // populate coords in the plane for intersection
46  // they should be oriented correctly, positively
47  int rc = IntxUtils::gnomonic_projection( tgtCoords[j], R, plane, tgtCoords2D[2 * j], tgtCoords2D[2 * j + 1] );
48  if( rc != 0 ) return 1;
49  }
50 
51  for( int j = 1; j < nsTgt - 1; j++ )
52  cellArea += IntxUtils::area2D( &tgtCoords2D[0], &tgtCoords2D[2 * j], &tgtCoords2D[2 * j + 2] );
53 
54  // take tgt coords in order and compute area in plane
55  return cellArea;
56 }

References moab::IntxUtils::area2D(), moab::IntxUtils::decide_gnomonic_plane(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::IntxUtils::gnomonic_projection(), moab::Intx2Mesh::mb, MB_SUCCESS, plane, R, moab::Intx2Mesh::tgtConn, moab::Intx2Mesh::tgtCoords, and moab::Intx2Mesh::tgtCoords2D.

Referenced by computeIntersectionBetweenTgtAndSrc().

Member Data Documentation

◆ plane

int moab::IntxRllCssphere::plane
private

◆ R

double moab::IntxRllCssphere::R
private

◆ srcEdgeType

int moab::IntxRllCssphere::srcEdgeType[4]
private

Definition at line 50 of file IntxRllCssphere.hpp.

Referenced by computeIntersectionBetweenTgtAndSrc().


The documentation for this class was generated from the following files: