6 #if defined( _MSC_VER ) || defined( WIN32 )
7 #define _USE_MATH_DEFINES
21 #define CHECKNEGATIVEAREA
22 #ifdef CHECKNEGATIVEAREA
28 #ifdef MOAB_HAVE_TEMPESTREMAP
29 #include "GridElements.h"
32 #ifdef MOAB_HAVE_EIGEN3
33 #define EIGEN_NO_DEBUG
34 #define EIGEN_MAX_CPP_VER 11
35 #include "Eigen/Dense"
51 #define CORRTAGNAME "__correspondent"
73 for(
int i = 0; i < nX; i++ )
79 double* A = X + 2 * i;
82 for(
int j = 0; j < nY; j++ )
84 double* B = Y + 2 * j;
85 int j1 = ( j + 1 ) % nY;
86 double* C = Y + 2 * j1;
88 double area2 = ( B[0] - A[0] ) * ( C[1] - A[1] ) - ( C[0] - A[0] ) * ( B[1] - A[1] );
89 if( area2 < -epsilon_area )
99 P[extraPoint * 2] = A[0];
100 P[extraPoint * 2 + 1] = A[1];
131 if( nP < 2 )
return 0;
134 double c[2] = { 0., 0. };
136 for( k = 0; k < nP; k++ )
139 c[1] += P[2 * k + 1];
148 for( k = 0; k < nP; k++ )
150 double x = P[2 * k] - c[0], y = P[2 * k + 1] - c[1];
151 if( x != 0. || y != 0. )
153 pairAngleIndex[k].
angle = atan2( y, x );
157 pairAngleIndex[k].
angle = 0;
160 pairAngleIndex[k].
index = k;
164 std::sort( pairAngleIndex, pairAngleIndex + nP,
angleCompare );
168 for( k = 0; k < nP; k++ )
170 int ck = pairAngleIndex[k].
index;
171 PCopy[2 * k] = P[2 * ck];
172 PCopy[2 * k + 1] = P[2 * ck + 1];
175 std::copy( PCopy, PCopy + 2 * nP, P );
185 double d2 =
dist2( &P[2 * i], &P[2 * j] );
190 P[2 * i + 1] = P[2 * j + 1];
197 double d2 =
dist2( P, &P[2 * i] );
204 if( nP == 0 ) nP = 1;
243 markb[i] = markr[i] = 0;
246 for(
int i = 0; i < nsBlue; i++ )
248 for(
int j = 0; j < nsRed; j++ )
252 int iPlus1 = ( i + 1 ) % nsBlue;
253 int jPlus1 = ( j + 1 ) % nsRed;
254 for(
int k = 0; k < 2; k++ )
256 b[k] = red[2 * j + k] - blue[2 * i + k];
258 a[k][0] = blue[2 * iPlus1 + k] - blue[2 * i + k];
259 a[k][1] = red[2 * j + k] - red[2 * jPlus1 + k];
261 double delta = a[0][0] * a[1][1] - a[0][1] * a[1][0];
262 if( fabs( delta ) > 1.e-14 )
265 double alfa = ( b[0] * a[1][1] - a[0][1] * b[1] ) / delta;
266 double beta = ( -b[0] * a[1][0] + b[1] * a[0][0] ) / delta;
267 if( 0 <= alfa && alfa <= 1. && 0 <= beta && beta <= 1. )
270 for(
int k = 0; k < 2; k++ )
272 points[2 * nPoints + k] = blue[2 * i + k] + alfa * ( blue[2 * iPlus1 + k] - blue[2 * i + k] );
321 for(
int i = 0; i < 4; i++ )
323 markb[i] = markr[i] = 0;
326 for(
int i = 0; i < nsBlue; i++ )
328 int iPlus1 = ( i + 1 ) % nsBlue;
329 if( blueEdgeType[i] == 0 )
331 for(
int j = 0; j < nsRed; j++ )
336 int jPlus1 = ( j + 1 ) % nsRed;
337 for(
int k = 0; k < 2; k++ )
339 b[k] = red[2 * j + k] - blue[2 * i + k];
341 a[k][0] = blue[2 * iPlus1 + k] - blue[2 * i + k];
342 a[k][1] = red[2 * j + k] - red[2 * jPlus1 + k];
344 double delta = a[0][0] * a[1][1] - a[0][1] * a[1][0];
345 if( fabs( delta ) > 1.e-14 )
348 double alfa = ( b[0] * a[1][1] - a[0][1] * b[1] ) / delta;
349 double beta = ( -b[0] * a[1][0] + b[1] * a[0][0] ) / delta;
350 if( 0 <= alfa && alfa <= 1. && 0 <= beta && beta <= 1. )
353 for(
int k = 0; k < 2; k++ )
355 points[2 * nPoints + k] =
356 blue[2 * i + k] + alfa * ( blue[2 * iPlus1 + k] - blue[2 * i + k] );
369 for(
int j = 0; j < nsRed; j++ )
371 int jPlus1 = ( j + 1 ) % nsRed;
377 if( np == 0 )
continue;
380 std::cout <<
"intersection with 2 points :" << A << B << C << D <<
"\n";
382 for(
int k = 0; k < np; k++ )
385 points[2 * nPoints + 1] );
413 if( fabs( pos[0] ) < fabs( pos[1] ) )
415 if( fabs( pos[2] ) < fabs( pos[1] ) )
434 if( fabs( pos[2] ) < fabs( pos[0] ) )
466 if( x == 0.0 && y == 0.0 )
480 if( x == 0.0 && z == 0.0 )
494 if( z == 0.0 && y == 0.0 )
547 double ang =
angle( pos, axis[0] );
551 double alpha = axis[0] % axis[0] / ( pos % axis[0] );
552 CartVect planeVect = alpha * pos - axis[0];
553 c1 = planeVect % axis[1];
554 c2 = planeVect % axis[2];
623 double len = sqrt( c1 * c1 + c2 * c2 +
R *
R );
624 double beta =
R / len;
721 std::string parTagName(
"PARALLEL_PARTITION" );
723 Tag gidTag =
mb->globalId_tag();
724 Tag targetParentTag, sourceParentTag;
725 mb->tag_get_handle(
"TargetParent", targetParentTag );
726 mb->tag_get_handle(
"SourceParent", sourceParentTag );
727 bool intxMesh =
false;
728 if( targetParentTag !=
nullptr && sourceParentTag !=
nullptr )
731 ErrorCode rval =
mb->tag_get_handle( parTagName.c_str(), part_tag );
740 rval =
mb->get_entities_by_dimension( inSet, 1, inputRange );
MB_CHK_ERR( rval );
741 rval =
mb->get_entities_by_dimension( inSet, 2, inputRange );
MB_CHK_ERR( rval );
743 std::map< EntityHandle, int > partsAssign;
744 std::map< int, EntityHandle > newPartSets;
745 if( !partSets.
empty() )
752 rval =
mb->get_entities_by_handle( pSet, ents );
MB_CHK_ERR( rval );
754 rval =
mb->tag_get_data( part_tag, &pSet, 1, &val );
MB_CHK_ERR( rval );
758 rval =
mb->tag_set_data( part_tag, &newPartSet, 1, &val );
MB_CHK_ERR( rval );
759 newPartSets[val] = newPartSet;
760 rval =
mb->add_entities( outSet, &newPartSet, 1 );
MB_CHK_ERR( rval );
763 partsAssign[*it] = val;
775 rval =
mb->get_connectivity( inputRange, verts );
MB_CHK_ERR( rval );
776 std::map< EntityHandle, EntityHandle > corr;
791 rval =
mb->tag_get_data( gidTag, &v, 1, &vID );
MB_CHK_SET_ERR( rval,
"can't get id tag on vertex" );
803 rval =
mb->get_connectivity( eh, conn, num_nodes );
MB_CHK_ERR( rval );
805 for(
int j = 0; j < num_nodes; j++ )
806 new_conn[j] = corr[conn[j]];
807 EntityType type =
mb->type_from_handle( eh );
809 rval =
mb->create_element( type, new_conn, num_nodes, newCell );
MB_CHK_ERR( rval );
810 rval =
mb->add_entities( outSet, &newCell, 1 );
MB_CHK_ERR( rval );
814 rval =
mb->tag_get_data( gidTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get id tag on entity handle" );
816 rval =
mb->tag_set_data( gidTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set id tag on new cell" );
823 rval =
mb->tag_get_data( targetParentTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get parent tag on entity handle" );
824 rval =
mb->tag_set_data( targetParentTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set parent tag on entity handle" );
825 rval =
mb->tag_get_data( sourceParentTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get parent tag on entity handle" );
826 rval =
mb->tag_set_data( sourceParentTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set parent tag on entity handle" );
829 std::map< EntityHandle, int >::iterator mit = partsAssign.find( eh );
830 if( mit != partsAssign.end() )
832 int val = mit->second;
833 rval =
mb->add_entities( newPartSets[val], &newCell, 1 );
MB_CHK_ERR( rval );
846 std::string parTagName(
"PARALLEL_PARTITION" );
848 Tag gidTag =
mb->globalId_tag();
849 Tag targetParentTag, sourceParentTag;
850 mb->tag_get_handle(
"TargetParent", targetParentTag );
851 mb->tag_get_handle(
"SourceParent", sourceParentTag );
852 bool intxMesh =
false;
853 if( targetParentTag !=
nullptr && sourceParentTag !=
nullptr )
856 ErrorCode rval =
mb->tag_get_handle( parTagName.c_str(), part_tag );
865 MB_CHK_ERR(
mb->get_entities_by_dimension( inSet, 1, inputRange ) );
866 MB_CHK_ERR(
mb->get_entities_by_dimension( inSet, 2, inputRange ) );
868 std::map< EntityHandle, int > partsAssign;
869 std::map< int, EntityHandle > newPartSets;
870 if( !partSets.
empty() )
879 MB_CHK_ERR(
mb->tag_get_data( part_tag, &pSet, 1, &val ) );
883 MB_CHK_ERR(
mb->tag_set_data( part_tag, &newPartSet, 1, &val ) );
884 newPartSets[val] = newPartSet;
885 MB_CHK_ERR(
mb->add_entities( outSet, &newPartSet, 1 ) );
888 partsAssign[*it] = val;
903 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &cell, 1, &globalID ),
"can't get id tag on cell" );
935 subranges[plane - 1].
insert( cell );
937 for(
int i = 1; i <= 6; i++ )
940 MB_CHK_ERR(
mb->get_connectivity( subranges[i - 1], verts ) );
941 std::map< EntityHandle, EntityHandle > corr;
957 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &v, 1, &vID ),
"can't get id tag on vertex" );
964 for(
Range::iterator eit = subranges[i - 1].begin(); eit != subranges[i - 1].
end(); ++eit )
969 MB_CHK_ERR(
mb->get_connectivity( eh, conn, num_nodes ) );
972 for(
int j = 0; j < num_nodes; j++ )
973 new_conn[j] = corr[conn[j]];
975 EntityType type =
mb->type_from_handle( eh );
977 MB_CHK_ERR(
mb->create_element( type, new_conn, num_nodes, newCell ) );
983 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &eh, 1, &eID ),
"can't get id tag on entity handle" );
985 MB_CHK_SET_ERR(
mb->tag_set_data( gidTag, &newCell, 1, &eID ),
"can't set id tag on new cell" );
993 "can't get parent tag on entity handle" );
995 "can't set parent tag on entity handle" );
997 "can't get parent tag on entity handle" );
999 "can't set parent tag on entity handle" );
1003 std::map< EntityHandle, int >::iterator mit = partsAssign.find( eh );
1004 if( mit != partsAssign.end() )
1006 int val = mit->second;
1007 MB_CHK_ERR(
mb->add_entities( newPartSets[val], &newCell, 1 ) );
1018 if( projection_type == 1 )
1021 avg_position[0] * avg_position[0] + avg_position[1] * avg_position[1] + avg_position[2] * avg_position[2];
1023 double lat = asin( avg_position[2] /
R );
1024 double lon = atan2( avg_position[1], avg_position[0] );
1025 avg_position[0] = lon;
1026 avg_position[1] = lat;
1027 avg_position[2] =
R;
1029 else if( projection_type == 2 )
1036 avg_position[2] = 0;
1081 res.
lat = asin( cart3d[2] / res.
R );
1082 res.
lon = atan2( cart3d[1], cart3d[0] );
1083 if( res.
lon < 0 ) res.
lon += 2 * M_PI;
1111 res[0] = sc.
R * cos( sc.
lat ) * cos( sc.
lon );
1112 res[1] = sc.
R * cos( sc.
lat ) * sin( sc.
lon );
1113 res[2] = sc.
R * sin( sc.
lat );
1129 rval =
mb->get_coords( &nd, 1, (
double*)&( pos[0] ) );
1131 double len = pos.
length();
1132 if( len == 0. )
return MB_FAILURE;
1133 pos =
R / len * pos;
1134 rval =
mb->set_coords( &nd, 1, (
double*)&( pos[0] ) );
1148 if( fabs( err1 ) > 0.0001 )
1150 std::cout <<
" error in input " << a <<
" radius: " << Radius <<
" error:" << err1 <<
"\n";
1154 return angle( normalOAB, normalOCB );
1166 CartVect orient = ( c - b ) * ( a - b );
1167 double ang =
angle( normalOAB, normalOCB );
1171 std::cout << a <<
" " << b <<
" " << c <<
"\n";
1172 std::cout << ang <<
"\n";
1174 if( orient % b < 0 )
return ( 2 * M_PI - ang );
1185 #ifdef MOAB_HAVE_TEMPESTREMAP
1187 return area_spherical_triangle_GQ( A, B, C );
1201 #ifdef MOAB_HAVE_TEMPESTREMAP
1203 return area_spherical_polygon_GQ( A, N ) * Radius * Radius;
1215 double area = Radius * Radius * correction;
1218 CartVect abc = ( b - a ) * ( c - a );
1230 if( N <= 2 )
return 0.;
1231 double sum_angles = 0.;
1232 for(
int i = 0; i < N; i++ )
1234 int i1 = ( i + 1 ) % N;
1235 int i2 = ( i + 2 ) % N;
1238 double correction = sum_angles - ( N - 2 ) * M_PI;
1239 return Radius * Radius * correction;
1248 if( N <= 2 )
return 0.;
1252 for(
int i = 1; i < N - 1; i++ )
1256 if( areaTriangle < 0 ) lsign = -1;
1258 area += areaTriangle;
1260 if( sign ) *sign = lsign;
1265 #ifdef MOAB_HAVE_TEMPESTREMAP
1267 double IntxAreaUtils::area_spherical_polygon_GQ(
const double* A,
int N )
1273 if( N <= 2 )
return 0.;
1277 for(
int i = 1; i < N - 1; i++ )
1279 area += area_spherical_triangle_GQ( A, A + 3 * i, A + 3 * ( i + 1 ) );
1284 template <
typename Derived >
1285 Eigen::Array< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > shift(
1286 const Eigen::ArrayBase< Derived >& array,
1289 Eigen::Array< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > result = array;
1292 result.segment( positions, array.size() - positions ) = array.head( array.size() - positions );
1293 result.head( positions ).setZero();
1295 else if( positions < 0 )
1297 result.head( array.size() + positions ) = array.tail( array.size() + positions );
1298 result.tail( -positions ).setZero();
1303 double IntxAreaUtils::area_spherical_triangle_GQ(
const double* inode1,
const double* inode2,
const double* inode3 )
1305 #if defined( MOAB_HAVE_EIGEN3 )
1306 typedef Eigen::Map< const Eigen::Vector3d > V3d;
1307 const V3d node1( inode1 );
1308 const V3d node2( inode2 );
1309 const V3d node3( inode3 );
1310 const int nOrder = 6;
1313 const double dG[6] = { 0.03376524289842397, 0.1693953067668678, 0.3806904069584016,
1314 0.6193095930415985, 0.8306046932331322, 0.966234757101576 };
1315 const double dW[6] = { 0.08566224618958521, 0.1803807865240693, 0.2339569672863455,
1316 0.2339569672863455, 0.1803807865240693, 0.08566224618958521 };
1318 double dFaceArea = 0.0;
1319 Eigen::Vector3d dF, dF2, dDaF, dDbF, dDaG, dDbG;
1320 double nodeCross[3];
1323 for(
int p = 0; p < nOrder; p++ )
1325 for(
int q = 0; q < nOrder; q++ )
1328 const double dA = dG[p];
1329 const double dB = dG[q];
1332 dF = ( ( ( 1.0 - dB ) * ( 1.0 - dA ) ) * node1 ) + ( ( ( 1.0 - dB ) * dA ) * node2 ) + ( dB * node3 );
1333 dF2 = dF.array().square();
1335 dDaF = ( node1 - node2 );
1338 dDbF = ( node3 - node1 ) + dA * dDaF;
1339 dDaF *= ( dB - 1.0 );
1341 const double dDenomTerm = std::pow( dF.norm(), -3.0 );
1359 dDaG( 0 ) = dDaF( 0 ) * ( dF2( 1 ) + dF2( 2 ) ) - dF( 0 ) * ( dDaF( 1 ) * dF( 1 ) + dDaF( 2 ) * dF( 2 ) );
1360 dDaG( 1 ) = dDaF( 1 ) * ( dF2( 0 ) + dF2( 2 ) ) - dF( 1 ) * ( dDaF( 0 ) * dF( 0 ) + dDaF( 2 ) * dF( 2 ) );
1361 dDaG( 2 ) = dDaF( 2 ) * ( dF2( 0 ) + dF2( 1 ) ) - dF( 2 ) * ( dDaF( 0 ) * dF( 0 ) + dDaF( 1 ) * dF( 1 ) );
1364 dDbG( 0 ) = dDbF( 0 ) * ( dF2( 1 ) + dF2( 2 ) ) - dF( 0 ) * ( dDbF( 1 ) * dF( 1 ) + dDbF( 2 ) * dF( 2 ) );
1365 dDbG( 1 ) = dDbF( 1 ) * ( dF2( 0 ) + dF2( 2 ) ) - dF( 1 ) * ( dDbF( 0 ) * dF( 0 ) + dDbF( 2 ) * dF( 2 ) );
1366 dDbG( 2 ) = dDbF( 2 ) * ( dF2( 0 ) + dF2( 1 ) ) - dF( 2 ) * ( dDbF( 0 ) * dF( 0 ) + dDbF( 1 ) * dF( 1 ) );
1373 nodeCross[0] = dDaG( 1 ) * dDbG( 2 ) - dDaG( 2 ) * dDbG( 1 );
1374 nodeCross[1] = dDaG( 2 ) * dDbG( 0 ) - dDaG( 0 ) * dDbG( 2 );
1375 nodeCross[2] = dDaG( 0 ) * dDbG( 1 ) - dDaG( 1 ) * dDbG( 0 );
1377 const double dJacobian =
1378 std::sqrt( nodeCross[0] * nodeCross[0] + nodeCross[1] * nodeCross[1] + nodeCross[2] * nodeCross[2] );
1381 dFaceArea += dW[p] * dW[q] * dJacobian;
1389 NodeVector nodes( 3 );
1390 nodes[0] = Node( inode1[0], inode1[1], inode1[2] );
1391 nodes[1] = Node( inode2[0], inode2[1], inode2[2] );
1392 nodes[2] = Node( inode3[0], inode3[1], inode3[2] );
1393 face.SetNode( 0, 0 );
1394 face.SetNode( 1, 1 );
1395 face.SetNode( 2, 2 );
1396 return CalculateFaceArea(
face, nodes );
1435 CartVect vA( ptA ), vB( ptB ), vC( ptC );
1441 if( ( vA * vB ) % vC < 0 ) sign = -1;
1442 double s = ( a + b + c ) / 2;
1443 double a1 = ( s - a ) / 2;
1444 double b1 = ( s - b ) / 2;
1445 double c1 = ( s - c ) / 2;
1446 #ifdef MOAB_HAVE_TEMPESTREMAP
1447 if( fabs( a1 ) < 1.e-14 || fabs( b1 ) < 1.e-14 || fabs( c1 ) < 1.e-14 )
1449 double area = area_spherical_triangle_GQ( ptA, ptB, ptC ) * sign;
1451 std::cout <<
" very obtuse angle, use TR to compute area "
1452 <<
" a1:" << a1 <<
" b1:" << b1 <<
" c1:" << c1 <<
"\n";
1453 std::cout <<
" area with TR: " << area <<
"\n";
1458 double tmp = tan( s / 2 ) * tan( a1 ) * tan( b1 ) * tan( c1 );
1459 if( tmp < 0. ) tmp = 0.;
1461 double E = 4 * atan( sqrt( tmp ) );
1462 if(
E !=
E ) std::cout <<
" NaN at spherical triangle area \n";
1464 double area = sign *
E * Radius * Radius;
1466 #ifdef CHECKNEGATIVEAREA
1469 std::cout <<
"negative area: " << area <<
"\n";
1470 std::cout << std::setprecision( 15 );
1471 std::cout <<
"vA: " << vA <<
"\n";
1472 std::cout <<
"vB: " << vB <<
"\n";
1473 std::cout <<
"vC: " << vC <<
"\n";
1474 std::cout <<
"sign: " << sign <<
"\n";
1475 std::cout <<
" a: " << a <<
"\n";
1476 std::cout <<
" b: " << b <<
"\n";
1477 std::cout <<
" c: " << c <<
"\n";
1491 std::vector< int > ownerinfo( inputRange.
size(), -1 );
1493 rval =
mb->tag_get_handle(
"ORIG_PROC", intxOwnerTag );
1496 rval =
mb->tag_get_data( intxOwnerTag, inputRange, &ownerinfo[0] );
MB_CHK_ERR_RET_VAL( rval, -1.0 );
1501 double total_area = 0.;
1506 if( ownerinfo[ie++] >= 0 )
continue;
1512 if( elem_area <= 0 )
1514 std::cout <<
"Area of element " <<
mb->id_from_handle( eh ) <<
" is = " << elem_area <<
"\n";
1515 mb->list_entity( eh );
1517 assert( elem_area > 0 );
1520 total_area += elem_area;
1535 while( verts[nsides - 2] == verts[nsides - 1] && nsides > 3 )
1539 std::vector< double > coords( 3 * nsides );
1552 acos( sin( sph1.
lon ) * sin( sph2.
lon ) + cos( sph1.
lat ) * cos( sph2.
lat ) * cos( sph2.
lon - sph2.
lon ) );
1571 MB_CHK_ERR(
mb->get_entities_by_dimension( lset, 2, inputRange ) );
1573 Tag corrTag =
nullptr;
1578 Tag gidTag =
mb->globalId_tag();
1580 std::vector< double > coords;
1584 std::queue< EntityHandle > newPolys;
1585 int brokenPolys = 0;
1587 while( eit != inputRange.
end() || !newPolys.empty() )
1590 if( eit != inputRange.
end() )
1597 eh = newPolys.front();
1603 MB_CHK_ERR(
mb->get_connectivity( eh, verts, num_nodes ) );
1604 int nsides = num_nodes;
1606 while( verts[nsides - 2] == verts[nsides - 1] && nsides > 3 )
1611 MB_CHK_ERR(
mb->tag_get_data( corrTag, &eh, 1, &corrHandle ) );
1614 MB_CHK_ERR(
mb->tag_get_data( gidTag, &eh, 1, &gid ) );
1615 coords.resize( 3 * nsides );
1616 if( nsides < 4 )
continue;
1618 MB_CHK_ERR(
mb->get_coords( verts, nsides, &coords[0] ) );
1620 bool alreadyBroken =
false;
1622 for(
int i = 0; i < nsides; i++ )
1624 double* A = &coords[3 * i];
1625 double* B = &coords[3 * ( ( i + 1 ) % nsides )];
1626 double* C = &coords[3 * ( ( i + 2 ) % nsides )];
1628 if(
angle - M_PI > 0. )
1632 mb->list_entities( &eh, 1 );
1633 mb->list_entities( verts, nsides );
1634 double* D = &coords[3 * ( ( i + 3 ) % nsides )];
1635 std::cout <<
"ABC: " <<
angle <<
" \n";
1639 std::cout <<
" this cell has at least 2 angles > 180, it has serious issues\n";
1650 EntityHandle conn3[3] = { verts[( i + 1 ) % nsides], verts[( i + 2 ) % nsides],
1651 verts[( i + 3 ) % nsides] };
1654 std::vector< EntityHandle > conn( nsides - 1 );
1655 for(
int j = 1; j < nsides; j++ )
1657 conn[j - 1] = verts[( i + j + 2 ) % nsides];
1662 MB_CHK_ERR(
mb->add_entities( lset, &newElement, 1 ) );
1665 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &corrHandle ) );
1667 MB_CHK_ERR(
mb->tag_set_data( gidTag, &newElement, 1, &gid ) );
1677 newPolys.push( newElement );
1680 MB_CHK_ERR(
mb->add_entities( lset, &newElement, 1 ) );
1683 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &corrHandle ) );
1685 MB_CHK_ERR(
mb->tag_set_data( gidTag, &newElement, 1, &gid ) );
1688 alreadyBroken =
true;
1692 if( brokenPolys > 0 )
1694 std::cout <<
"on local process " << my_rank <<
", " << brokenPolys
1695 <<
" concave polygons were decomposed in convex ones \n";
1697 std::stringstream fff;
1698 fff <<
"file_set" <<
mb->id_from_handle( lset ) <<
"rk_" << my_rank <<
".h5m";
1699 MB_CHK_ERR(
mb->write_file( fff.str().c_str(), 0, 0, &lset, 1 ) );
1700 std::cout <<
"wrote new file set: " << fff.str() <<
"\n";
1713 Tag gid =
mb->globalId_tag();
1719 MB_CHK_ERR(
mb->get_connectivity( quad, conn4, num_nodes ) );
1720 for(
int i = 0; i < num_nodes; i++ )
1722 int next_node_index = ( i + 1 ) % num_nodes;
1723 if( conn4[i] == conn4[next_node_index] )
1728 MB_CHK_ERR(
mb->tag_get_data( gid, &quad, 1, &global_id ) );
1729 int i2 = ( i + 2 ) % num_nodes;
1730 int i3 = ( i + 3 ) % num_nodes;
1731 EntityHandle conn3[3] = { conn4[i], conn4[i2], conn4[i3] };
1737 MB_CHK_ERR(
mb->tag_set_data( gid, &tri, 1, &global_id ) );
1747 MB_CHK_ERR(
mb->get_entities_by_dimension( set, 2, cells2d ) );
1753 MB_CHK_ERR(
mb->get_connectivity( cell, conn, num_nodes ) );
1754 if( num_nodes < 3 )
return MB_FAILURE;
1767 std::vector< double > coords2( 3 * num_nodes );
1769 MB_CHK_ERR(
mb->get_coords( conn, num_nodes, &coords2[0] ) );
1773 std::vector< EntityHandle > newconn( num_nodes );
1774 for(
int i = 0; i < num_nodes; i++ )
1776 newconn[num_nodes - 1 - i] = conn[i];
1778 MB_CHK_ERR(
mb->set_connectivity( cell, &newconn[0], num_nodes ) );
1782 std::cout <<
" nonconvex problem first area:" << area <<
" total area: " << totArea << std::endl;
1793 return acos( sin( te1 ) * sin( te2 ) + cos( te1 ) * cos( te2 ) * cos( la1 - la2 ) );
1804 const double Tolerance = 1.e-12 * R2;
1806 CartVect a( A ), b( B ), c( C ), d( D );
1808 if( fabs( a.length_squared() - R2 ) + fabs( b.length_squared() - R2 ) + fabs( c.length_squared() - R2 ) +
1824 if( n1 % n4 >= -Tolerance && n1 % n5 >= -Tolerance )
1829 if( n2 % n4 >= -Tolerance && n2 % n5 >= -Tolerance )
1842 n4 = a * n3, n5 = n3 * b;
1843 if( n1 % n4 >= -Tolerance && n1 % n5 >= -Tolerance )
1848 if( n2 % n4 >= -Tolerance && n2 % n5 >= -Tolerance )
1874 if( n1 % n2 < 0 || n1 % n3 < 0 )
return false;
1877 c[2] = d[2] = s[2] = 0.;
1882 if( n1 % n2 < 0 || n1 % n3 < 0 )
return false;
1895 const double distTol =
R * 1.e-6;
1896 const double Tolerance =
R *
R * 1.e-12;
1898 CartVect a( A ), b( B ), c( C ), d( D );
1901 if( fabs( a.length_squared() - R2 ) + fabs( b.length_squared() - R2 ) + fabs( c.length_squared() - R2 ) +
1911 if( fabs( C[2] - D[2] ) > distTol )
1914 if( fabs(
R - C[2] ) < distTol || fabs(
R + C[2] ) < distTol )
return MB_FAILURE;
1926 if( fabs( n1[0] ) + fabs( n1[1] ) < 2 * Tolerance )
1929 if( fabs( C[2] ) > distTol )
1944 bool agtc = ( ca % cd >= -Tolerance );
1945 bool dgta = ( ad % cd >= -Tolerance );
1946 bool bgtc = ( cb % cd >= -Tolerance );
1947 bool dgtb = ( bd % cd >= -Tolerance );
2054 if( fabs( n1[0] ) <= fabs( n1[1] ) )
2061 double u = -n1[2] / n1[1] * z, v = -n1[0] / n1[1];
2062 double a1 = v * v + 1, b1 = 2 * u * v, c1 = u * u + z * z - R2;
2063 double delta = b1 * b1 - 4 * a1 * c1;
2064 if( delta < -Tolerance )
return MB_FAILURE;
2065 if( delta > Tolerance )
2067 double x1 = ( -b1 + sqrt( delta ) ) / 2 / a1;
2068 double x2 = ( -b1 - sqrt( delta ) ) / 2 / a1;
2069 double y1 = u + v * x1;
2070 double y2 = u + v * x2;
2071 if(
verify( a, b, c, d, x1, y1, z ) )
2078 if(
verify( a, b, c, d, x2, y2, z ) )
2089 double x1 = -b1 / 2 / a1;
2090 double y1 = u + v * x1;
2091 if(
verify( a, b, c, d, x1, y1, z ) )
2108 double u = -n1[2] / n1[0] * z, v = -n1[1] / n1[0];
2109 double a1 = v * v + 1, b1 = 2 * u * v, c1 = u * u + z * z - R2;
2110 double delta = b1 * b1 - 4 * a1 * c1;
2111 if( delta < -Tolerance )
return MB_FAILURE;
2112 if( delta > Tolerance )
2114 double y1 = ( -b1 + sqrt( delta ) ) / 2 / a1;
2115 double y2 = ( -b1 - sqrt( delta ) ) / 2 / a1;
2116 double x1 = u + v * y1;
2117 double x2 = u + v * y2;
2118 if(
verify( a, b, c, d, x1, y1, z ) )
2125 if(
verify( a, b, c, d, x2, y2, z ) )
2136 double y1 = -b1 / 2 / a1;
2137 double x1 = u + v * y1;
2138 if(
verify( a, b, c, d, x1, y1, z ) )
2149 if( np <= 0 )
return MB_FAILURE;
2173 int type_constant_lat=1;
2186 if (fabs( coords[2]-coords[5] )< 1.e-6 )
2210 int extraPoints = 0;
2212 CartVect A( 0. ), B( 0. ), C( 0. ), D( 0. );
2213 for(
int i = 0; i < nsBlue; i++ )
2215 if( blueEdgeType[i] == 0 )
2217 int iP1 = ( i + 1 ) % nsBlue;
2218 if( bluec[i][2] > bluec[iP1][2] )
2222 C = bluec[( i + 2 ) % nsBlue];
2223 D = bluec[( i + 3 ) % nsBlue];
2228 if( nsBlue == 3 && B[2] < 0 )
2237 for(
int i = 0; i < nsRed; i++ )
2240 if( X[2] > A[2] || X[2] < B[2] )
continue;
2242 if( ( ( A * B ) % X >= -epsil ) && ( ( C * D ) % X >= -epsil ) )
2247 P[extraPoints * 2] = red2dc[2 * i];
2248 P[extraPoints * 2 + 1] = red2dc[2 * i + 1];
2266 Tag gid =
mb->globalId_tag();
2272 MB_CHK_ERR(
mb->get_connectivity( quads, connecVerts ) );
2274 std::map< EntityHandle, EntityHandle > newNodes;
2276 std::vector< double* > coords;
2278 int num_verts = connecVerts.
size();
2287 MB_CHK_ERR(
mb->get_coords( &oldV, 1, &( posi[0] ) ) );
2290 MB_CHK_ERR(
mb->tag_get_data( gid, &oldV, 1, &global_id ) );
2293 coords[0][i] = posi[0];
2294 coords[1][i] = posi[1];
2295 coords[2][i] = posi[2];
2297 newNodes[oldV] = new_vert;
2299 MB_CHK_ERR(
mb->tag_set_data( corrTag, &oldV, 1, &new_vert ) );
2304 MB_CHK_ERR(
mb->tag_set_data( corrTag, &new_vert, 1, &oldV ) );
2306 MB_CHK_ERR(
mb->tag_set_data( gid, &new_vert, 1, &global_id ) );
2320 MB_CHK_ERR(
mb->tag_get_data( gid, &q, 1, &global_id ) );
2322 for(
int ii = 0; ii < nnodes; ii++ )
2325 connect[4 * ie + ii] = newNodes[v1];
2330 MB_CHK_ERR(
mb->tag_set_data( corrTag, &q, 1, &newElement ) );
2331 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &q ) );
2334 MB_CHK_ERR(
mb->tag_set_data( gid, &newElement, 1, &global_id ) );
2336 MB_CHK_ERR(
mb->add_entities( dest_set, &newElement, 1 ) );
2347 std::vector< Tag >& tagList )
2350 MB_CHK_ERR(
mb->get_entities_by_dimension( file_set, 0, verts ) );
2369 MB_CHK_ERR(
mb->get_entities_by_dimension( file_set, 2, cells ) );
2374 Range modifiedCells;
2382 MB_CHK_SET_ERR(
mb->get_connectivity( cell, connec, num_verts ),
"Failed to get connectivity" );
2384 std::vector< EntityHandle > newConnec;
2385 newConnec.push_back( connec[0] );
2388 while(
index < num_verts - 2 )
2390 int next_index = (
index + 1 );
2391 if( connec[next_index] != newConnec[new_size - 1] )
2393 newConnec.push_back( connec[next_index] );
2399 if( ( connec[num_verts - 1] != connec[num_verts - 2] ) && ( connec[num_verts - 1] != connec[0] ) )
2401 newConnec.push_back( connec[num_verts - 1] );
2404 if( new_size < num_verts )
2407 modifiedCells.
insert( cell );
2409 EntityType type =
MBTRI;
2412 else if( new_size == 4 )
2414 else if( new_size > 4 )
2419 MB_CHK_SET_ERR(
mb->create_element( type, &newConnec[0], new_size, newCell ),
"Failed to create new cell" );
2421 newCells.
insert( newCell );
2423 for(
size_t i = 0; i < tagList.size(); i++ )
2425 MB_CHK_SET_ERR(
mb->tag_get_data( tagList[i], &cell, 1, (
void*)( &value ) ),
2426 "Failed to get tag value" );
2427 MB_CHK_SET_ERR(
mb->tag_set_data( tagList[i], &newCell, 1, (
void*)( &value ) ),
2428 "Failed to set tag value on new cell" );
2433 MB_CHK_SET_ERR(
mb->remove_entities( file_set, modifiedCells ),
"Failed to remove old cells from file set" );
2434 MB_CHK_SET_ERR(
mb->delete_entities( modifiedCells ),
"Failed to delete old cells" );
2435 MB_CHK_SET_ERR(
mb->add_entities( file_set, newCells ),
"Failed to add new cells to file set" );
2436 MB_CHK_SET_ERR(
mb->add_entities( file_set, verts ),
"Failed to add verts to the file set" );
2444 std::vector< CartVect > coords( max_edges );
2445 for(
auto it = cells.
begin(); it != cells.
end(); ++it )
2451 MB_CHK_SET_ERR(
mb->get_connectivity( cell, connec, num_verts ),
"Failed to get connectivity" );
2452 MB_CHK_SET_ERR(
mb->get_coords( connec, num_verts, &( coords[0][0] ) ),
"Failed to get coordinates" );
2454 for(
int i = 0; i < num_verts - 1; i++ )
2456 for(
int j = i + 1; j < num_verts; j++ )
2459 if( len_sq > diagonal ) diagonal = len_sq;
2465 diagonal = std::sqrt( diagonal );