6 #if defined( _MSC_VER ) || defined( WIN32 )
7 #define _USE_MATH_DEFINES
36 #ifdef MOAB_HAVE_TEMPESTREMAP
37 #include "GridElements.h"
40 #ifdef MOAB_HAVE_EIGEN3
41 #define EIGEN_NO_DEBUG
42 #include "Eigen/Dense"
77 for(
int i = 0; i < nX; i++ )
83 double* A = X + 2 * i;
86 for(
int j = 0; j < nY; j++ )
88 const double* B = Y + 2 * j;
89 int j1 = ( j + 1 ) % nY;
90 const double* C = Y + 2 * j1;
92 double area2 = ( B[0] - A[0] ) * ( C[1] - A[1] ) - ( C[0] - A[0] ) * ( B[1] - A[1] );
93 if( area2 < -epsilon_area )
103 P[extraPoint * 2] = A[0];
104 P[extraPoint * 2 + 1] = A[1];
135 if( nP < 2 )
return 0;
138 double c[2] = { 0., 0. };
140 for( k = 0; k < nP; k++ )
143 c[1] += P[2 * k + 1];
152 for( k = 0; k < nP; k++ )
154 double x = P[2 * k] - c[0], y = P[2 * k + 1] - c[1];
155 if( x != 0. || y != 0. )
157 pairAngleIndex[k].
angle = atan2( y, x );
161 pairAngleIndex[k].
angle = 0;
164 pairAngleIndex[k].
index = k;
168 std::sort( pairAngleIndex, pairAngleIndex + nP,
angleCompare );
172 for( k = 0; k < nP; k++ )
174 int ck = pairAngleIndex[k].
index;
175 PCopy[2 * k] = P[2 * ck];
176 PCopy[2 * k + 1] = P[2 * ck + 1];
179 std::copy( PCopy, PCopy + 2 * nP, P );
189 double d2 =
dist2( &P[2 * i], &P[2 * j] );
194 P[2 * i + 1] = P[2 * j + 1];
201 double d2 =
dist2( P, &P[2 * i] );
208 if( nP == 0 ) nP = 1;
247 markb[i] = markr[i] = 0;
250 for(
int i = 0; i < nsBlue; i++ )
252 for(
int j = 0; j < nsRed; j++ )
256 int iPlus1 = ( i + 1 ) % nsBlue;
257 int jPlus1 = ( j + 1 ) % nsRed;
258 for(
int k = 0; k < 2; k++ )
260 b[k] = red[2 * j + k] - blue[2 * i + k];
262 a[k][0] = blue[2 * iPlus1 + k] - blue[2 * i + k];
263 a[k][1] = red[2 * j + k] - red[2 * jPlus1 + k];
265 double delta = a[0][0] * a[1][1] - a[0][1] * a[1][0];
266 if( fabs( delta ) > 1.e-14 )
269 double alfa = ( b[0] * a[1][1] - a[0][1] * b[1] ) / delta;
270 double beta = ( -b[0] * a[1][0] + b[1] * a[0][0] ) / delta;
271 if( 0 <= alfa && alfa <= 1. && 0 <= beta && beta <= 1. )
274 for(
int k = 0; k < 2; k++ )
276 points[2 * nPoints + k] = blue[2 * i + k] + alfa * ( blue[2 * iPlus1 + k] - blue[2 * i + k] );
325 for(
int i = 0; i < 4; i++ )
327 markb[i] = markr[i] = 0;
330 for(
int i = 0; i < nsBlue; i++ )
332 int iPlus1 = ( i + 1 ) % nsBlue;
333 if( blueEdgeType[i] == 0 )
335 for(
int j = 0; j < nsRed; j++ )
340 int jPlus1 = ( j + 1 ) % nsRed;
341 for(
int k = 0; k < 2; k++ )
343 b[k] = red[2 * j + k] - blue[2 * i + k];
345 a[k][0] = blue[2 * iPlus1 + k] - blue[2 * i + k];
346 a[k][1] = red[2 * j + k] - red[2 * jPlus1 + k];
348 double delta = a[0][0] * a[1][1] - a[0][1] * a[1][0];
349 if( fabs( delta ) > 1.e-14 )
352 double alfa = ( b[0] * a[1][1] - a[0][1] * b[1] ) / delta;
353 double beta = ( -b[0] * a[1][0] + b[1] * a[0][0] ) / delta;
354 if( 0 <= alfa && alfa <= 1. && 0 <= beta && beta <= 1. )
357 for(
int k = 0; k < 2; k++ )
359 points[2 * nPoints + k] =
360 blue[2 * i + k] + alfa * ( blue[2 * iPlus1 + k] - blue[2 * i + k] );
373 for(
int j = 0; j < nsRed; j++ )
375 int jPlus1 = ( j + 1 ) % nsRed;
381 if( np == 0 )
continue;
384 std::cout <<
"intersection with 2 points :" << A << B << C << D <<
"\n";
386 for(
int k = 0; k < np; k++ )
389 points[2 * nPoints + 1] );
417 if( fabs( pos[0] ) < fabs( pos[1] ) )
419 if( fabs( pos[2] ) < fabs( pos[1] ) )
438 if( fabs( pos[2] ) < fabs( pos[0] ) )
470 if( x == 0.0 && y == 0.0 )
484 if( x == 0.0 && z == 0.0 )
498 if( z == 0.0 && y == 0.0 )
551 double ang =
angle( pos, axis[0] );
555 double alpha = axis[0] % axis[0] / ( pos % axis[0] );
556 CartVect planeVect = alpha * pos - axis[0];
557 c1 = planeVect % axis[1];
558 c2 = planeVect % axis[2];
627 double len = sqrt( c1 * c1 + c2 * c2 +
R *
R );
628 double beta =
R / len;
725 std::string parTagName(
"PARALLEL_PARTITION" );
727 Tag gidTag =
mb->globalId_tag();
728 Tag targetParentTag, sourceParentTag;
729 mb->tag_get_handle(
"TargetParent", targetParentTag );
730 mb->tag_get_handle(
"SourceParent", sourceParentTag );
731 bool intxMesh =
false;
732 if( targetParentTag !=
nullptr && sourceParentTag !=
nullptr )
735 ErrorCode rval =
mb->tag_get_handle( parTagName.c_str(), part_tag );
744 rval =
mb->get_entities_by_dimension( inSet, 1, inputRange );
MB_CHK_ERR( rval );
745 rval =
mb->get_entities_by_dimension( inSet, 2, inputRange );
MB_CHK_ERR( rval );
747 std::map< EntityHandle, int > partsAssign;
748 std::map< int, EntityHandle > newPartSets;
749 if( !partSets.
empty() )
756 rval =
mb->get_entities_by_handle( pSet, ents );
MB_CHK_ERR( rval );
758 rval =
mb->tag_get_data( part_tag, &pSet, 1, &val );
MB_CHK_ERR( rval );
762 rval =
mb->tag_set_data( part_tag, &newPartSet, 1, &val );
MB_CHK_ERR( rval );
763 newPartSets[val] = newPartSet;
764 rval =
mb->add_entities( outSet, &newPartSet, 1 );
MB_CHK_ERR( rval );
767 partsAssign[*it] = val;
779 rval =
mb->get_connectivity( inputRange, verts );
MB_CHK_ERR( rval );
780 std::map< EntityHandle, EntityHandle > corr;
795 rval =
mb->tag_get_data( gidTag, &v, 1, &vID );
MB_CHK_SET_ERR( rval,
"can't get id tag on vertex" );
807 rval =
mb->get_connectivity( eh, conn, num_nodes );
MB_CHK_ERR( rval );
809 for(
int j = 0; j < num_nodes; j++ )
810 new_conn[j] = corr[conn[j]];
811 EntityType type =
mb->type_from_handle( eh );
813 rval =
mb->create_element( type, new_conn, num_nodes, newCell );
MB_CHK_ERR( rval );
814 rval =
mb->add_entities( outSet, &newCell, 1 );
MB_CHK_ERR( rval );
818 rval =
mb->tag_get_data( gidTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get id tag on entity handle" );
820 rval =
mb->tag_set_data( gidTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set id tag on new cell" );
827 rval =
mb->tag_get_data( targetParentTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get parent tag on entity handle" );
828 rval =
mb->tag_set_data( targetParentTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set parent tag on entity handle" );
829 rval =
mb->tag_get_data( sourceParentTag, &eh, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't get parent tag on entity handle" );
830 rval =
mb->tag_set_data( sourceParentTag, &newCell, 1, &eID );
MB_CHK_SET_ERR( rval,
"can't set parent tag on entity handle" );
833 std::map< EntityHandle, int >::iterator mit = partsAssign.find( eh );
834 if( mit != partsAssign.end() )
836 int val = mit->second;
837 rval =
mb->add_entities( newPartSets[val], &newCell, 1 );
MB_CHK_ERR( rval );
850 std::string parTagName(
"PARALLEL_PARTITION" );
852 Tag gidTag =
mb->globalId_tag();
853 Tag targetParentTag, sourceParentTag;
854 mb->tag_get_handle(
"TargetParent", targetParentTag );
855 mb->tag_get_handle(
"SourceParent", sourceParentTag );
856 bool intxMesh =
false;
857 if( targetParentTag !=
nullptr && sourceParentTag !=
nullptr )
860 ErrorCode rval =
mb->tag_get_handle( parTagName.c_str(), part_tag );
869 MB_CHK_ERR(
mb->get_entities_by_dimension( inSet, 1, inputRange ) );
870 MB_CHK_ERR(
mb->get_entities_by_dimension( inSet, 2, inputRange ) );
872 std::map< EntityHandle, int > partsAssign;
873 std::map< int, EntityHandle > newPartSets;
874 if( !partSets.
empty() )
883 MB_CHK_ERR(
mb->tag_get_data( part_tag, &pSet, 1, &val ) );
887 MB_CHK_ERR(
mb->tag_set_data( part_tag, &newPartSet, 1, &val ) );
888 newPartSets[val] = newPartSet;
889 MB_CHK_ERR(
mb->add_entities( outSet, &newPartSet, 1 ) );
892 partsAssign[*it] = val;
907 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &cell, 1, &globalID ),
"can't get id tag on cell" );
939 subranges[plane - 1].
insert( cell );
941 for(
int i = 1; i <= 6; i++ )
944 MB_CHK_ERR(
mb->get_connectivity( subranges[i - 1], verts ) );
945 std::map< EntityHandle, EntityHandle > corr;
961 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &v, 1, &vID ),
"can't get id tag on vertex" );
968 for(
Range::iterator eit = subranges[i - 1].begin(); eit != subranges[i - 1].
end(); ++eit )
973 MB_CHK_ERR(
mb->get_connectivity( eh, conn, num_nodes ) );
976 for(
int j = 0; j < num_nodes; j++ )
977 new_conn[j] = corr[conn[j]];
979 EntityType type =
mb->type_from_handle( eh );
981 MB_CHK_ERR(
mb->create_element( type, new_conn, num_nodes, newCell ) );
987 MB_CHK_SET_ERR(
mb->tag_get_data( gidTag, &eh, 1, &eID ),
"can't get id tag on entity handle" );
989 MB_CHK_SET_ERR(
mb->tag_set_data( gidTag, &newCell, 1, &eID ),
"can't set id tag on new cell" );
997 "can't get parent tag on entity handle" );
999 "can't set parent tag on entity handle" );
1001 "can't get parent tag on entity handle" );
1003 "can't set parent tag on entity handle" );
1007 std::map< EntityHandle, int >::iterator mit = partsAssign.find( eh );
1008 if( mit != partsAssign.end() )
1010 int val = mit->second;
1011 MB_CHK_ERR(
mb->add_entities( newPartSets[val], &newCell, 1 ) );
1022 if( projection_type == 1 )
1025 avg_position[0] * avg_position[0] + avg_position[1] * avg_position[1] + avg_position[2] * avg_position[2];
1027 double lat = asin( avg_position[2] /
R );
1028 double lon = atan2( avg_position[1], avg_position[0] );
1029 avg_position[0] = lon;
1030 avg_position[1] = lat;
1031 avg_position[2] =
R;
1033 else if( projection_type == 2 )
1040 avg_position[2] = 0;
1085 res.
lat = asin( cart3d[2] / res.
R );
1086 res.
lon = atan2( cart3d[1], cart3d[0] );
1087 if( res.
lon < 0 ) res.
lon += 2 * M_PI;
1115 res[0] = sc.
R * cos( sc.
lat ) * cos( sc.
lon );
1116 res[1] = sc.
R * cos( sc.
lat ) * sin( sc.
lon );
1117 res[2] = sc.
R * sin( sc.
lat );
1133 rval =
mb->get_coords( &nd, 1, pos.
array() );
1135 double len = pos.
length();
1136 if( len == 0. )
return MB_FAILURE;
1137 pos =
R / len * pos;
1138 rval =
mb->set_coords( &nd, 1, pos.
array() );
1152 if( fabs( err1 ) > 0.0001 )
1154 std::cout <<
" error in input " << a <<
" radius: " << Radius <<
" error:" << err1 <<
"\n";
1158 return angle( normalOAB, normalOCB );
1170 CartVect orient = ( c - b ) * ( a - b );
1171 double ang =
angle( normalOAB, normalOCB );
1175 std::cout << a <<
" " << b <<
" " << c <<
"\n";
1176 std::cout << ang <<
"\n";
1178 if( orient % b < 0 )
return ( 2 * M_PI - ang );
1189 #ifdef MOAB_HAVE_TEMPESTREMAP
1191 return area_spherical_triangle_GQ( A, B, C );
1207 #ifdef MOAB_HAVE_TEMPESTREMAP
1209 return area_spherical_polygon_GQ( A, N ) * Radius * Radius;
1221 std::string lname( name );
1222 std::transform( lname.begin(), lname.end(), lname.begin(), ::tolower );
1224 if( lname ==
"lhuiller" || lname ==
"lhuilier" )
1226 else if( lname ==
"girard" )
1228 else if( lname ==
"gquad" || lname ==
"gaussquadrature" )
1230 else if( lname ==
"vos" || lname ==
"vanoosterom" )
1270 CartVect ua( A ), ub( B ), uc( C );
1279 const double numerator = ua % ( ub * uc );
1280 const double denominator = 1.0 + ( ua % ub ) + ( ub % uc ) + ( uc % ua );
1284 const double excess = 2.0 * atan2( numerator, denominator );
1286 return excess * Radius * Radius;
1295 for(
int i = 1; i < N - 1; i++ )
1300 if( sign ) *sign = ( area < 0.0 ? -1 : ( area > 0.0 ? 1 : 0 ) );
1309 double area = Radius * Radius * correction;
1312 CartVect abc = ( b - a ) * ( c - a );
1324 if( N <= 2 )
return 0.;
1325 double sum_angles = 0.;
1326 for(
int i = 0; i < N; i++ )
1328 int i1 = ( i + 1 ) % N;
1329 int i2 = ( i + 2 ) % N;
1332 double correction = sum_angles - ( N - 2 ) * M_PI;
1333 return Radius * Radius * correction;
1342 if( N <= 2 )
return 0.;
1346 for(
int i = 1; i < N - 1; i++ )
1350 if( areaTriangle < 0 ) lsign = -1;
1352 area += areaTriangle;
1354 if( sign ) *sign = lsign;
1359 #ifdef MOAB_HAVE_TEMPESTREMAP
1361 double IntxAreaUtils::area_spherical_polygon_GQ(
const double* A,
int N )
1367 if( N <= 2 )
return 0.;
1371 for(
int i = 1; i < N - 1; i++ )
1373 area += area_spherical_triangle_GQ( A, A + 3 * i, A + 3 * ( i + 1 ) );
1378 template <
typename Derived >
1379 Eigen::Array< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > shift(
1380 const Eigen::ArrayBase< Derived >& array,
1383 Eigen::Array< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime > result = array;
1386 result.segment( positions, array.size() - positions ) = array.head( array.size() - positions );
1387 result.head( positions ).setZero();
1389 else if( positions < 0 )
1391 result.head( array.size() + positions ) = array.tail( array.size() + positions );
1392 result.tail( -positions ).setZero();
1397 double IntxAreaUtils::area_spherical_triangle_GQ(
const double* inode1,
const double* inode2,
const double* inode3 )
1399 #if defined( MOAB_HAVE_EIGEN3 )
1400 typedef Eigen::Map< const Eigen::Vector3d > V3d;
1401 const V3d node1( inode1 );
1402 const V3d node2( inode2 );
1403 const V3d node3( inode3 );
1404 const int nOrder = 6;
1407 const double dG[6] = { 0.03376524289842397, 0.1693953067668678, 0.3806904069584016,
1408 0.6193095930415985, 0.8306046932331322, 0.966234757101576 };
1409 const double dW[6] = { 0.08566224618958521, 0.1803807865240693, 0.2339569672863455,
1410 0.2339569672863455, 0.1803807865240693, 0.08566224618958521 };
1412 double dFaceArea = 0.0;
1413 Eigen::Vector3d dF, dF2, dDaF, dDbF, dDaG, dDbG;
1414 double nodeCross[3];
1417 for(
int p = 0; p < nOrder; p++ )
1419 for(
int q = 0; q < nOrder; q++ )
1422 const double dA = dG[p];
1423 const double dB = dG[q];
1426 dF = ( ( ( 1.0 - dB ) * ( 1.0 - dA ) ) * node1 ) + ( ( ( 1.0 - dB ) * dA ) * node2 ) + ( dB * node3 );
1427 dF2 = dF.array().square();
1429 dDaF = ( node1 - node2 );
1432 dDbF = ( node3 - node1 ) + dA * dDaF;
1433 dDaF *= ( dB - 1.0 );
1435 const double dDenomTerm = std::pow( dF.norm(), -3.0 );
1453 dDaG( 0 ) = dDaF( 0 ) * ( dF2( 1 ) + dF2( 2 ) ) - dF( 0 ) * ( dDaF( 1 ) * dF( 1 ) + dDaF( 2 ) * dF( 2 ) );
1454 dDaG( 1 ) = dDaF( 1 ) * ( dF2( 0 ) + dF2( 2 ) ) - dF( 1 ) * ( dDaF( 0 ) * dF( 0 ) + dDaF( 2 ) * dF( 2 ) );
1455 dDaG( 2 ) = dDaF( 2 ) * ( dF2( 0 ) + dF2( 1 ) ) - dF( 2 ) * ( dDaF( 0 ) * dF( 0 ) + dDaF( 1 ) * dF( 1 ) );
1458 dDbG( 0 ) = dDbF( 0 ) * ( dF2( 1 ) + dF2( 2 ) ) - dF( 0 ) * ( dDbF( 1 ) * dF( 1 ) + dDbF( 2 ) * dF( 2 ) );
1459 dDbG( 1 ) = dDbF( 1 ) * ( dF2( 0 ) + dF2( 2 ) ) - dF( 1 ) * ( dDbF( 0 ) * dF( 0 ) + dDbF( 2 ) * dF( 2 ) );
1460 dDbG( 2 ) = dDbF( 2 ) * ( dF2( 0 ) + dF2( 1 ) ) - dF( 2 ) * ( dDbF( 0 ) * dF( 0 ) + dDbF( 1 ) * dF( 1 ) );
1467 nodeCross[0] = dDaG( 1 ) * dDbG( 2 ) - dDaG( 2 ) * dDbG( 1 );
1468 nodeCross[1] = dDaG( 2 ) * dDbG( 0 ) - dDaG( 0 ) * dDbG( 2 );
1469 nodeCross[2] = dDaG( 0 ) * dDbG( 1 ) - dDaG( 1 ) * dDbG( 0 );
1471 const double dJacobian =
1472 std::sqrt( nodeCross[0] * nodeCross[0] + nodeCross[1] * nodeCross[1] + nodeCross[2] * nodeCross[2] );
1475 dFaceArea += dW[p] * dW[q] * dJacobian;
1483 NodeVector nodes( 3 );
1484 nodes[0] = Node( inode1[0], inode1[1], inode1[2] );
1485 nodes[1] = Node( inode2[0], inode2[1], inode2[2] );
1486 nodes[2] = Node( inode3[0], inode3[1], inode3[2] );
1487 face.SetNode( 0, 0 );
1488 face.SetNode( 1, 1 );
1489 face.SetNode( 2, 2 );
1490 return CalculateFaceArea(
face, nodes );
1529 CartVect vA( ptA ), vB( ptB ), vC( ptC );
1535 if( ( vA * vB ) % vC < 0 ) sign = -1;
1536 double s = ( a + b + c ) / 2;
1537 double a1 = ( s - a ) / 2;
1538 double b1 = ( s - b ) / 2;
1539 double c1 = ( s - c ) / 2;
1540 #ifdef MOAB_HAVE_TEMPESTREMAP
1541 if( fabs( a1 ) < 1.e-14 || fabs( b1 ) < 1.e-14 || fabs( c1 ) < 1.e-14 )
1543 double area = area_spherical_triangle_GQ( ptA, ptB, ptC ) * sign;
1545 std::cout <<
" very obtuse angle, use TR to compute area "
1546 <<
" a1:" << a1 <<
" b1:" << b1 <<
" c1:" << c1 <<
"\n";
1547 std::cout <<
" area with TR: " << area <<
"\n";
1552 double tmp = tan( s / 2 ) * tan( a1 ) * tan( b1 ) * tan( c1 );
1553 if( tmp < 0. ) tmp = 0.;
1555 double E = 4 * atan( sqrt( tmp ) );
1556 if(
E !=
E ) std::cout <<
" NaN at spherical triangle area \n";
1558 double area = sign *
E * Radius * Radius;
1577 std::vector< int > ownerinfo( inputRange.
size(), -1 );
1579 rval =
mb->tag_get_handle(
"ORIG_PROC", intxOwnerTag );
1582 rval =
mb->tag_get_data( intxOwnerTag, inputRange, &ownerinfo[0] );
MB_CHK_ERR_RET_VAL( rval, -1.0 );
1587 double total_area = 0.;
1592 if( ownerinfo[ie++] >= 0 )
continue;
1598 if( elem_area <= 0 )
1600 std::cout <<
"Area of element " <<
mb->id_from_handle( eh ) <<
" is = " << elem_area <<
"\n";
1601 mb->list_entity( eh );
1603 assert( elem_area > 0 );
1606 total_area += elem_area;
1621 while( verts[nsides - 2] == verts[nsides - 1] && nsides > 3 )
1625 std::vector< double > coords( 3 * nsides );
1643 const std::streamsize oldprec = std::cout.precision();
1644 std::cout <<
"negative area: " << std::setprecision( 15 ) << area <<
" for element "
1645 <<
mb->id_from_handle( elem ) <<
" with " << nsides <<
" vertices\n";
1646 for(
int iv = 0; iv < nsides; iv++ )
1648 std::cout <<
" v" << iv <<
": " << coords[3 * iv] <<
" " << coords[3 * iv + 1] <<
" "
1649 << coords[3 * iv + 2] <<
"\n";
1651 std::cout.precision( oldprec );
1663 acos( sin( sph1.
lon ) * sin( sph2.
lon ) + cos( sph1.
lat ) * cos( sph2.
lat ) * cos( sph2.
lon - sph2.
lon ) );
1682 MB_CHK_ERR(
mb->get_entities_by_dimension( lset, 2, inputRange ) );
1684 Tag corrTag =
nullptr;
1689 Tag gidTag =
mb->globalId_tag();
1691 std::vector< double > coords;
1695 std::queue< EntityHandle > newPolys;
1696 int brokenPolys = 0;
1698 while( eit != inputRange.
end() || !newPolys.empty() )
1701 if( eit != inputRange.
end() )
1708 eh = newPolys.front();
1714 MB_CHK_ERR(
mb->get_connectivity( eh, verts, num_nodes ) );
1715 int nsides = num_nodes;
1717 while( verts[nsides - 2] == verts[nsides - 1] && nsides > 3 )
1722 MB_CHK_ERR(
mb->tag_get_data( corrTag, &eh, 1, &corrHandle ) );
1725 MB_CHK_ERR(
mb->tag_get_data( gidTag, &eh, 1, &gid ) );
1726 coords.resize( 3 * nsides );
1727 if( nsides < 4 )
continue;
1729 MB_CHK_ERR(
mb->get_coords( verts, nsides, &coords[0] ) );
1731 bool alreadyBroken =
false;
1733 for(
int i = 0; i < nsides; i++ )
1735 double* A = &coords[3 * i];
1736 double* B = &coords[3 * ( ( i + 1 ) % nsides )];
1737 double* C = &coords[3 * ( ( i + 2 ) % nsides )];
1739 if(
angle - M_PI > 0. )
1743 mb->list_entities( &eh, 1 );
1744 mb->list_entities( verts, nsides );
1745 double* D = &coords[3 * ( ( i + 3 ) % nsides )];
1746 std::cout <<
"ABC: " <<
angle <<
" \n";
1750 std::cout <<
" this cell has at least 2 angles > 180, it has serious issues\n";
1761 EntityHandle conn3[3] = { verts[( i + 1 ) % nsides], verts[( i + 2 ) % nsides],
1762 verts[( i + 3 ) % nsides] };
1765 std::vector< EntityHandle > conn( nsides - 1 );
1766 for(
int j = 1; j < nsides; j++ )
1768 conn[j - 1] = verts[( i + j + 2 ) % nsides];
1773 MB_CHK_ERR(
mb->add_entities( lset, &newElement, 1 ) );
1776 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &corrHandle ) );
1778 MB_CHK_ERR(
mb->tag_set_data( gidTag, &newElement, 1, &gid ) );
1788 newPolys.push( newElement );
1791 MB_CHK_ERR(
mb->add_entities( lset, &newElement, 1 ) );
1794 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &corrHandle ) );
1796 MB_CHK_ERR(
mb->tag_set_data( gidTag, &newElement, 1, &gid ) );
1799 alreadyBroken =
true;
1803 if( brokenPolys > 0 )
1805 std::cout <<
"on local process " << my_rank <<
", " << brokenPolys
1806 <<
" concave polygons were decomposed in convex ones \n";
1808 std::stringstream fff;
1809 fff <<
"file_set" <<
mb->id_from_handle( lset ) <<
"rk_" << my_rank <<
".h5m";
1810 MB_CHK_ERR(
mb->write_file( fff.str().c_str(), 0, 0, &lset, 1 ) );
1811 std::cout <<
"wrote new file set: " << fff.str() <<
"\n";
1824 Tag gid =
mb->globalId_tag();
1830 MB_CHK_ERR(
mb->get_connectivity( quad, conn4, num_nodes ) );
1831 for(
int i = 0; i < num_nodes; i++ )
1833 int next_node_index = ( i + 1 ) % num_nodes;
1834 if( conn4[i] == conn4[next_node_index] )
1839 MB_CHK_ERR(
mb->tag_get_data( gid, &quad, 1, &global_id ) );
1840 int i2 = ( i + 2 ) % num_nodes;
1841 int i3 = ( i + 3 ) % num_nodes;
1842 EntityHandle conn3[3] = { conn4[i], conn4[i2], conn4[i3] };
1848 MB_CHK_ERR(
mb->tag_set_data( gid, &tri, 1, &global_id ) );
1858 MB_CHK_ERR(
mb->get_entities_by_dimension( set, 2, cells2d ) );
1864 size_t nNonconvex = 0;
1865 double maxNonconvexMagnitude = 0.0;
1872 MB_CHK_ERR(
mb->get_connectivity( cell, conn, num_nodes ) );
1873 if( num_nodes < 3 )
return MB_FAILURE;
1885 for(
int i = 0; i < num_nodes && nprobe < 3; i++ )
1887 bool duplicate =
false;
1888 for(
int j = 0; j < nprobe; j++ )
1889 if( probe[j] == conn[i] ) duplicate =
true;
1890 if( !duplicate ) probe[nprobe++] = conn[i];
1894 if( nprobe < 3 )
continue;
1915 std::vector< double > coords2( 3 * num_nodes );
1917 MB_CHK_ERR(
mb->get_coords( conn, num_nodes, &coords2[0] ) );
1922 std::vector< EntityHandle > newconn( num_nodes );
1923 for(
int i = 0; i < num_nodes; i++ )
1925 newconn[num_nodes - 1 - i] = conn[i];
1927 MB_CHK_ERR(
mb->set_connectivity( cell, &newconn[0], num_nodes ) );
1943 maxNonconvexMagnitude = std::max( maxNonconvexMagnitude, -area );
1944 #ifdef CHECKNEGATIVEAREA
1945 std::cout <<
" nonconvex problem first area:" << area <<
" total area: " << totArea << std::endl;
1955 if( nNonconvex > 0 )
1956 std::cout <<
"positive_orientation: " << nNonconvex
1957 <<
" element(s) had non-convex overlap sub-cells (orientation corrected), "
1958 "max |probe area| = "
1959 << maxNonconvexMagnitude
1968 return acos( sin( te1 ) * sin( te2 ) + cos( te1 ) * cos( te2 ) * cos( la1 - la2 ) );
1979 const double Tolerance = 1.e-12 * R2;
1981 CartVect a( A ), b( B ), c( C ), d( D );
1983 if( fabs( a.length_squared() - R2 ) + fabs( b.length_squared() - R2 ) + fabs( c.length_squared() - R2 ) +
1999 if( n1 % n4 >= -Tolerance && n1 % n5 >= -Tolerance )
2004 if( n2 % n4 >= -Tolerance && n2 % n5 >= -Tolerance )
2017 n4 = a * n3, n5 = n3 * b;
2018 if( n1 % n4 >= -Tolerance && n1 % n5 >= -Tolerance )
2023 if( n2 % n4 >= -Tolerance && n2 % n5 >= -Tolerance )
2049 if( n1 % n2 < 0 || n1 % n3 < 0 )
return false;
2052 c[2] = d[2] = s[2] = 0.;
2057 if( n1 % n2 < 0 || n1 % n3 < 0 )
return false;
2070 const double distTol =
R * 1.e-6;
2071 const double Tolerance =
R *
R * 1.e-12;
2073 CartVect a( A ), b( B ), c( C ), d( D );
2076 if( fabs( a.length_squared() - R2 ) + fabs( b.length_squared() - R2 ) + fabs( c.length_squared() - R2 ) +
2086 if( fabs( C[2] - D[2] ) > distTol )
2089 if( fabs(
R - C[2] ) < distTol || fabs(
R + C[2] ) < distTol )
return MB_FAILURE;
2101 if( fabs( n1[0] ) + fabs( n1[1] ) < 2 * Tolerance )
2104 if( fabs( C[2] ) > distTol )
2119 bool agtc = ( ca % cd >= -Tolerance );
2120 bool dgta = ( ad % cd >= -Tolerance );
2121 bool bgtc = ( cb % cd >= -Tolerance );
2122 bool dgtb = ( bd % cd >= -Tolerance );
2229 if( fabs( n1[0] ) <= fabs( n1[1] ) )
2236 double u = -n1[2] / n1[1] * z, v = -n1[0] / n1[1];
2237 double a1 = v * v + 1, b1 = 2 * u * v, c1 = u * u + z * z - R2;
2238 double delta = b1 * b1 - 4 * a1 * c1;
2239 if( delta < -Tolerance )
return MB_FAILURE;
2240 if( delta > Tolerance )
2242 double x1 = ( -b1 + sqrt( delta ) ) / 2 / a1;
2243 double x2 = ( -b1 - sqrt( delta ) ) / 2 / a1;
2244 double y1 = u + v * x1;
2245 double y2 = u + v * x2;
2246 if(
verify( a, b, c, d, x1, y1, z ) )
2253 if(
verify( a, b, c, d, x2, y2, z ) )
2264 double x1 = -b1 / 2 / a1;
2265 double y1 = u + v * x1;
2266 if(
verify( a, b, c, d, x1, y1, z ) )
2283 double u = -n1[2] / n1[0] * z, v = -n1[1] / n1[0];
2284 double a1 = v * v + 1, b1 = 2 * u * v, c1 = u * u + z * z - R2;
2285 double delta = b1 * b1 - 4 * a1 * c1;
2286 if( delta < -Tolerance )
return MB_FAILURE;
2287 if( delta > Tolerance )
2289 double y1 = ( -b1 + sqrt( delta ) ) / 2 / a1;
2290 double y2 = ( -b1 - sqrt( delta ) ) / 2 / a1;
2291 double x1 = u + v * y1;
2292 double x2 = u + v * y2;
2293 if(
verify( a, b, c, d, x1, y1, z ) )
2300 if(
verify( a, b, c, d, x2, y2, z ) )
2311 double y1 = -b1 / 2 / a1;
2312 double x1 = u + v * y1;
2313 if(
verify( a, b, c, d, x1, y1, z ) )
2324 if( np <= 0 )
return MB_FAILURE;
2348 int type_constant_lat=1;
2361 if (fabs( coords[2]-coords[5] )< 1.e-6 )
2385 int extraPoints = 0;
2387 CartVect A( 0. ), B( 0. ), C( 0. ), D( 0. );
2388 for(
int i = 0; i < nsBlue; i++ )
2390 if( blueEdgeType[i] == 0 )
2392 int iP1 = ( i + 1 ) % nsBlue;
2393 if( bluec[i][2] > bluec[iP1][2] )
2397 C = bluec[( i + 2 ) % nsBlue];
2398 D = bluec[( i + 3 ) % nsBlue];
2403 if( nsBlue == 3 && B[2] < 0 )
2412 for(
int i = 0; i < nsRed; i++ )
2415 if( X[2] > A[2] || X[2] < B[2] )
continue;
2417 if( ( ( A * B ) % X >= -epsil ) && ( ( C * D ) % X >= -epsil ) )
2422 P[extraPoints * 2] = red2dc[2 * i];
2423 P[extraPoints * 2 + 1] = red2dc[2 * i + 1];
2441 Tag gid =
mb->globalId_tag();
2447 MB_CHK_ERR(
mb->get_connectivity( quads, connecVerts ) );
2449 std::map< EntityHandle, EntityHandle > newNodes;
2451 std::vector< double* > coords;
2453 int num_verts = connecVerts.
size();
2462 MB_CHK_ERR(
mb->get_coords( &oldV, 1, &( posi[0] ) ) );
2465 MB_CHK_ERR(
mb->tag_get_data( gid, &oldV, 1, &global_id ) );
2468 coords[0][i] = posi[0];
2469 coords[1][i] = posi[1];
2470 coords[2][i] = posi[2];
2472 newNodes[oldV] = new_vert;
2474 MB_CHK_ERR(
mb->tag_set_data( corrTag, &oldV, 1, &new_vert ) );
2479 MB_CHK_ERR(
mb->tag_set_data( corrTag, &new_vert, 1, &oldV ) );
2481 MB_CHK_ERR(
mb->tag_set_data( gid, &new_vert, 1, &global_id ) );
2495 MB_CHK_ERR(
mb->tag_get_data( gid, &q, 1, &global_id ) );
2497 for(
int ii = 0; ii < nnodes; ii++ )
2500 connect[4 * ie + ii] = newNodes[v1];
2505 MB_CHK_ERR(
mb->tag_set_data( corrTag, &q, 1, &newElement ) );
2506 MB_CHK_ERR(
mb->tag_set_data( corrTag, &newElement, 1, &q ) );
2509 MB_CHK_ERR(
mb->tag_set_data( gid, &newElement, 1, &global_id ) );
2511 MB_CHK_ERR(
mb->add_entities( dest_set, &newElement, 1 ) );
2522 std::vector< Tag >& tagList )
2525 MB_CHK_ERR(
mb->get_entities_by_dimension( file_set, 0, verts ) );
2544 MB_CHK_ERR(
mb->get_entities_by_dimension( file_set, 2, cells ) );
2549 Range modifiedCells;
2557 MB_CHK_SET_ERR(
mb->get_connectivity( cell, connec, num_verts ),
"Failed to get connectivity" );
2559 std::vector< EntityHandle > newConnec;
2560 newConnec.push_back( connec[0] );
2563 while(
index < num_verts - 2 )
2565 int next_index = (
index + 1 );
2566 if( connec[next_index] != newConnec[new_size - 1] )
2568 newConnec.push_back( connec[next_index] );
2574 if( ( connec[num_verts - 1] != connec[num_verts - 2] ) && ( connec[num_verts - 1] != connec[0] ) )
2576 newConnec.push_back( connec[num_verts - 1] );
2579 if( new_size < num_verts && new_size >= 3 )
2582 modifiedCells.
insert( cell );
2584 EntityType type =
MBTRI;
2587 else if( new_size == 4 )
2589 else if( new_size > 4 )
2594 MB_CHK_SET_ERR(
mb->create_element( type, &newConnec[0], new_size, newCell ),
"Failed to create new cell" );
2596 newCells.
insert( newCell );
2598 for(
size_t i = 0; i < tagList.size(); i++ )
2601 "Failed to get tag value" );
2603 "Failed to set tag value on new cell" );
2611 MB_CHK_SET_ERR(
mb->remove_entities( file_set, modifiedCells ),
"Failed to remove old cells from file set" );
2612 MB_CHK_SET_ERR(
mb->delete_entities( modifiedCells ),
"Failed to delete old cells" );
2613 MB_CHK_SET_ERR(
mb->add_entities( file_set, newCells ),
"Failed to add new cells to file set" );
2614 MB_CHK_SET_ERR(
mb->add_entities( file_set, verts ),
"Failed to add verts to the file set" );
2622 std::vector< CartVect > coords( max_edges );
2623 for(
auto it = cells.
begin(); it != cells.
end(); ++it )
2629 MB_CHK_SET_ERR(
mb->get_connectivity( cell, connec, num_verts ),
"Failed to get connectivity" );
2630 MB_CHK_SET_ERR(
mb->get_coords( connec, num_verts, &( coords[0][0] ) ),
"Failed to get coordinates" );
2632 for(
int i = 0; i < num_verts - 1; i++ )
2634 for(
int j = i + 1; j < num_verts; j++ )
2637 if( len_sq > diagonal ) diagonal = len_sq;
2643 diagonal = std::sqrt( diagonal );