23 #define VERDICT_EXPORTS
42 static const double rootOf3 = sqrt( 3.0 );
80 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
81 coordinates[1][2] - coordinates[0][2] );
83 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
84 coordinates[2][2] - coordinates[1][2] );
86 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
87 coordinates[0][2] - coordinates[2][2] );
142 edge_ratio = sqrt( M2 / m2 );
162 static const double normal_coeff = sqrt( 3. ) / 6.;
165 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
166 coordinates[1][2] - coordinates[0][2] );
168 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
169 coordinates[2][2] - coordinates[1][2] );
171 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
172 coordinates[0][2] - coordinates[2][2] );
178 double hm = a1 > b1 ? a1 : b1;
179 hm = hm > c1 ? hm : c1;
182 double denominator = ab.
length();
189 aspect_ratio = normal_coeff * hm * ( a1 + b1 + c1 ) / denominator;
210 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
211 coordinates[1][2] - coordinates[0][2] );
213 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
214 coordinates[2][2] - coordinates[1][2] );
216 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
217 coordinates[0][2] - coordinates[2][2] );
229 radius_ratio = .25 * a2 * b2 * c2 * ( a2 + b2 + c2 ) / denominator;
248 static const double two_times_root_of_3 = 2 * sqrt( 3.0 );
251 VerdictVector side1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
252 coordinates[1][2] - coordinates[0][2] );
254 VerdictVector side2( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
255 coordinates[2][2] - coordinates[1][2] );
257 VerdictVector side3( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
258 coordinates[0][2] - coordinates[2][2] );
264 double areaX2 = ( ( side1 * ( -side3 ) ).length() );
268 double aspect = (double)( srms / ( two_times_root_of_3 * ( areaX2 ) ) );
281 VerdictVector side1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
282 coordinates[1][2] - coordinates[0][2] );
284 VerdictVector side3( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
285 coordinates[2][2] - coordinates[0][2] );
292 double area = 0.5 * tmp.
length();
308 sides[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
309 coordinates[1][2] - coordinates[0][2] );
310 sides[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
311 coordinates[2][2] - coordinates[1][2] );
312 sides[2].
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
313 coordinates[2][2] - coordinates[0][2] );
317 sides[3] = -sides[1];
320 double sides_lengths[3];
325 if( sides_lengths[0] == 0.0 || sides_lengths[1] == 0.0 || sides_lengths[2] == 0.0 )
return 0.0;
332 if( sides_lengths[1] < sides_lengths[0] ) short_side = 1;
333 if( sides_lengths[2] < sides_lengths[short_side] ) short_side = 2;
338 if( short_side == 0 )
342 else if( short_side == 1 )
366 sides[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
367 coordinates[1][2] - coordinates[0][2] );
368 sides[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
369 coordinates[2][2] - coordinates[1][2] );
370 sides[2].
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
371 coordinates[2][2] - coordinates[0][2] );
375 sides[3] = -sides[1];
378 double sides_lengths[3];
383 if( sides_lengths[0] == 0.0 || sides_lengths[1] == 0.0 || sides_lengths[2] == 0.0 )
393 if( sides_lengths[1] > sides_lengths[0] ) short_side = 1;
394 if( sides_lengths[2] > sides_lengths[short_side] ) short_side = 2;
399 if( short_side == 0 )
403 else if( short_side == 1 )
423 static const double rt3 = sqrt( 3.0 );
425 VerdictVector v1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
426 coordinates[1][2] - coordinates[0][2] );
428 VerdictVector v2( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
429 coordinates[2][2] - coordinates[0][2] );
432 double areax2 = tri_normal.
length();
436 double condition = (double)( ( ( v1 % v1 ) + ( v2 % v2 ) - ( v1 % v2 ) ) / ( areax2 * rt3 ) );
442 double point[3], surf_normal[3];
443 point[0] = ( coordinates[0][0] + coordinates[1][0] + coordinates[2][0] ) / 3;
444 point[1] = ( coordinates[0][1] + coordinates[1][1] + coordinates[2][1] ) / 3;
445 point[2] = ( coordinates[0][2] + coordinates[1][2] + coordinates[2][2] ) / 3;
449 if( ( tri_normal.
x() * surf_normal[0] + tri_normal.
y() * surf_normal[1] + tri_normal.
z() * surf_normal[2] ) <
463 static const double detw = 2. / sqrt( 3.0 );
468 edge[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
469 coordinates[1][2] - coordinates[0][2] );
471 edge[1].set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
472 coordinates[2][2] - coordinates[0][2] );
474 edge[2].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
475 coordinates[2][2] - coordinates[1][2] );
480 jacobian =
cross.length();
482 double max_edge_length_product;
483 max_edge_length_product =
490 jacobian /= max_edge_length_product;
495 double point[3], surf_normal[3];
496 point[0] = ( coordinates[0][0] + coordinates[1][0] + coordinates[2][0] ) / 3;
497 point[1] = ( coordinates[0][1] + coordinates[1][1] + coordinates[2][1] ) / 3;
498 point[2] = ( coordinates[0][2] + coordinates[1][2] + coordinates[2][2] ) / 3;
502 if( (
cross.x() * surf_normal[0] +
cross.y() * surf_normal[1] +
cross.z() * surf_normal[2] ) < 0 )
523 shape = ( 1 / condition );
536 double w11, w21, w12, w22;
544 if( detw == 0.0 )
return 0.0;
546 xxi.
set( coordinates[0][0] - coordinates[1][0], coordinates[0][1] - coordinates[1][1],
547 coordinates[0][2] - coordinates[1][2] );
549 xet.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
550 coordinates[0][2] - coordinates[2][2] );
552 tri_normal = xxi * xet;
554 double deta = tri_normal.
length();
555 if( deta == 0.0 || detw == 0.0 )
return 0.0;
557 double size = pow( deta / detw, 2 );
577 double shape_and_size =
size * shape;
592 int total_number_of_gauss_points = 0;
594 double element_area = 0.;
596 aa.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
597 coordinates[1][2] - coordinates[0][2] );
599 bb.
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
600 coordinates[2][2] - coordinates[0][2] );
604 int number_of_gauss_points = 0;
608 return (
double)distortion;
611 else if( num_nodes == 6 )
613 total_number_of_gauss_points = 6;
614 number_of_gauss_points = 6;
632 for( ife = 0; ife < total_number_of_gauss_points; ife++ )
634 aa.
set( 0.0, 0.0, 0.0 );
635 bb.
set( 0.0, 0.0, 0.0 );
637 for( ja = 0; ja < num_nodes; ja++ )
639 xin.
set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
640 aa += dndy1[ife][ja] * xin;
641 bb += dndy2[ife][ja] * xin;
643 normal_at_point = aa * bb;
644 double jacobian = normal_at_point.
length();
645 element_area += weight[ife] * jacobian;
648 element_area *= 0.8660254;
658 for( ja = 0; ja < num_nodes; ja++ )
660 aa.
set( 0.0, 0.0, 0.0 );
661 bb.
set( 0.0, 0.0, 0.0 );
662 for( jai = 0; jai < num_nodes; jai++ )
664 xin.
set( coordinates[jai][0], coordinates[jai][1], coordinates[jai][2] );
665 aa += dndy1_at_node[ja][jai] * xin;
666 bb += dndy2_at_node[ja][jai] * xin;
668 normal_at_nodes[ja] = aa * bb;
673 bool flat_element =
true;
676 for( ja = 0; ja < num_nodes; ja++ )
678 dot_product = normal_at_nodes[0] % normal_at_nodes[ja];
681 flat_element =
false;
687 double thickness, thickness_gauss;
690 thickness = 0.001 * sqrt( element_area );
693 double zl = 0.5773502691896;
694 if( flat_element ) zl = 0.0;
696 int no_gauss_pts_z = ( flat_element ) ? 1 : 2;
701 for( ife = 0; ife < total_number_of_gauss_points; ife++ )
704 for( igz = 0; igz < no_gauss_pts_z; igz++ )
707 thickness_z = zl * thickness / 2.0;
709 aa.
set( 0.0, 0.0, 0.0 );
710 bb.
set( 0.0, 0.0, 0.0 );
711 cc.
set( 0.0, 0.0, 0.0 );
713 for( ja = 0; ja < num_nodes; ja++ )
715 xin.
set( coordinates[jai][0], coordinates[jai][1], coordinates[jai][2] );
716 xin += thickness_z * normal_at_nodes[ja];
717 aa += dndy1[ife][ja] * xin;
718 bb += dndy2[ife][ja] * xin;
719 thickness_gauss = shape_function[ife][ja] * thickness / 2.0;
720 cc += thickness_gauss * normal_at_nodes[ja];
723 normal_at_point = aa * bb;
724 distrt = cc % normal_at_point;
725 if( distrt < distortion ) distortion = distrt;
730 for( ja = 0; ja < num_nodes; ja++ )
732 for( igz = 0; igz < no_gauss_pts_z; igz++ )
735 thickness_z = zl * thickness / 2.0;
737 aa.
set( 0.0, 0.0, 0.0 );
738 bb.
set( 0.0, 0.0, 0.0 );
739 cc.
set( 0.0, 0.0, 0.0 );
741 for( jai = 0; jai < num_nodes; jai++ )
743 xin.
set( coordinates[jai][0], coordinates[jai][1], coordinates[jai][2] );
744 xin += thickness_z * normal_at_nodes[ja];
745 aa += dndy1_at_node[ja][jai] * xin;
746 bb += dndy2_at_node[ja][jai] * xin;
748 thickness_gauss = thickness / 2.0;
750 thickness_gauss = 0.;
751 cc += thickness_gauss * normal_at_nodes[jai];
755 normal_at_point = aa * bb;
756 double sign_jacobian = ( tri_normal % normal_at_point ) > 0 ? 1. : -1.;
757 distrt = sign_jacobian * ( cc % normal_at_point );
759 if( distrt < distortion ) distortion = distrt;
761 if( element_area * thickness != 0 )
762 distortion *= 1. / ( element_area * thickness );
778 double coordinates[][3],
779 unsigned int metrics_request_flag,
801 sides[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
802 coordinates[1][2] - coordinates[0][2] );
803 sides[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
804 coordinates[2][2] - coordinates[1][2] );
805 sides[2].
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
806 coordinates[2][2] - coordinates[0][2] );
813 bool is_inverted =
false;
817 double point[3], surf_normal[3];
818 point[0] = ( coordinates[0][0] + coordinates[1][0] + coordinates[2][0] ) / 3;
819 point[1] = ( coordinates[0][1] + coordinates[1][1] + coordinates[2][1] ) / 3;
820 point[2] = ( coordinates[0][2] + coordinates[1][2] + coordinates[2][2] ) / 3;
823 if( ( tri_normal.
x() * surf_normal[0] + tri_normal.
y() * surf_normal[1] + tri_normal.
z() * surf_normal[2] ) <
829 double sides_lengths_squared[3];
838 int short_side = 0, long_side = 0;
840 if( sides_lengths_squared[1] < sides_lengths_squared[0] ) short_side = 1;
841 if( sides_lengths_squared[2] < sides_lengths_squared[short_side] ) short_side = 2;
843 if( sides_lengths_squared[1] > sides_lengths_squared[0] ) long_side = 1;
844 if( sides_lengths_squared[2] > sides_lengths_squared[long_side] ) long_side = 2;
849 if( sides_lengths_squared[0] == 0.0 || sides_lengths_squared[1] == 0.0 || sides_lengths_squared[2] == 0.0 )
853 else if( short_side == 0 )
855 else if( short_side == 1 )
864 if( sides_lengths_squared[0] == 0.0 || sides_lengths_squared[1] == 0.0 || sides_lengths_squared[2] == 0.0 )
868 else if( long_side == 0 )
870 else if( long_side == 1 )
879 if( metrics_request_flag &
882 metric_vals->
area = (double)( ( sides[0] * sides[2] ).length() * 0.5 );
889 double srms = sides_lengths_squared[0] + sides_lengths_squared[1] + sides_lengths_squared[2];
892 static const double twoTimesRootOf3 = 2 * sqrt( 3.0 );
894 double div = ( twoTimesRootOf3 * ( ( sides[0] * sides[2] ).
length() ) );
906 static const double twoOverRootOf3 = 2 / sqrt( 3.0 );
909 double tmp = tri_normal.
length() * twoOverRootOf3;
913 double temp_scaled_jac;
914 for(
int i = 0; i < 3; i++ )
916 if( sides_lengths_squared[i % 3] == 0.0 || sides_lengths_squared[( i + 2 ) % 3] == 0.0 )
917 temp_scaled_jac = 0.0;
920 tmp / sqrt( sides_lengths_squared[i % 3] ) / sqrt( sides_lengths_squared[( i + 2 ) % 3] );
921 if( temp_scaled_jac < min_scaled_jac ) min_scaled_jac = temp_scaled_jac;
926 min_scaled_jac *= -1;
935 static const double rootOf3 = sqrt( 3.0 );
943 double area2x = ( sides[0] * sides[2] ).
length();
947 metric_vals->
condition = (double)( ( sides[0] % sides[0] + sides[2] % sides[2] - sides[0] % sides[2] ) /
948 ( area2x * rootOf3 ) );
959 metric_vals->
shape = 0.0;
964 static const double rootOf3 = sqrt( 3.0 );
966 double area2x = metric_vals->
area * 2;
968 double dots[3] = { sides[0] % sides[0], sides[2] % sides[2], sides[0] % sides[2] };
971 double sum_dots = dots[0] + dots[1] - dots[2];
974 if( sum_dots == 0.0 )
975 metric_vals->
shape = 0.0;
977 metric_vals->
shape = (double)( rootOf3 * area2x / sum_dots );
985 double w11, w21, w12, w22;
990 if( metric_vals->
area == 0.0 || detw == 0.0 )
994 double size = metric_vals->
area * 2.0 / detw;
1017 if( metric_vals->
area > 0 )
1037 if( metric_vals->
shape > 0 )