23 #define VERDICT_EXPORTS
48 static const double rt3 = sqrt( 3.0 );
49 static const double root_of_2 = sqrt( 2.0 );
52 w2.
set( 0.5, 0.5 * rt3, 0 );
53 w3.
set( 0.5, rt3 / 6.0, root_of_2 / rt3 );
75 a.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
76 coordinates[1][2] - coordinates[0][2] );
78 b.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
79 coordinates[2][2] - coordinates[1][2] );
81 c.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
82 coordinates[0][2] - coordinates[2][2] );
84 d.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
85 coordinates[3][2] - coordinates[0][2] );
87 e.
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
88 coordinates[3][2] - coordinates[1][2] );
90 f.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
91 coordinates[3][2] - coordinates[2][2] );
100 double m2, M2, mab, mcd, mef, Mab, Mcd, Mef;
133 m2 = mab < mcd ? mab : mcd;
134 m2 = m2 < mef ? m2 : mef;
138 M2 = Mab > Mcd ? Mab : Mcd;
139 M2 = M2 > Mef ? M2 : Mef;
141 double edge_ratio = sqrt( M2 / m2 );
158 side0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
159 coordinates[1][2] - coordinates[0][2] );
161 side1.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
162 coordinates[2][2] - coordinates[1][2] );
164 side2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
165 coordinates[0][2] - coordinates[2][2] );
167 side3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
168 coordinates[3][2] - coordinates[0][2] );
170 side4.
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
171 coordinates[3][2] - coordinates[1][2] );
173 side5.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
174 coordinates[3][2] - coordinates[2][2] );
178 jacobi = side3 % ( side2 * side0 );
191 if( length_product < fabs( jacobi ) ) length_product = fabs( jacobi );
195 static const double root_of_2 = sqrt( 2.0 );
197 return (
double)( root_of_2 * jacobi / length_product );
215 side[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
216 coordinates[1][2] - coordinates[0][2] );
218 side[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
219 coordinates[2][2] - coordinates[1][2] );
221 side[2].
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
222 coordinates[0][2] - coordinates[2][2] );
224 side[3].
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
225 coordinates[3][2] - coordinates[0][2] );
227 side[4].
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
228 coordinates[3][2] - coordinates[1][2] );
230 side[5].
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
231 coordinates[3][2] - coordinates[2][2] );
238 area_sum = ( ( side[2] * side[0] ).
length() + ( side[3] * side[0] ).
length() + ( side[4] * side[1] ).
length() +
239 ( side[3] * side[2] ).
length() ) *
249 radius_ratio = numerator.
length() * area_sum / ( 108 * volume * volume );
271 side[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
272 coordinates[1][2] - coordinates[0][2] );
274 side[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
275 coordinates[2][2] - coordinates[1][2] );
277 side[2].
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
278 coordinates[0][2] - coordinates[2][2] );
280 side[3].
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
281 coordinates[3][2] - coordinates[0][2] );
283 side[4].
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
284 coordinates[3][2] - coordinates[1][2] );
286 side[5].
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
287 coordinates[3][2] - coordinates[2][2] );
294 area_sum = ( ( side[2] * side[0] ).
length() + ( side[3] * side[0] ).
length() + ( side[4] * side[1] ).
length() +
295 ( side[3] * side[2] ).
length() ) *
305 radius_ratio = numerator.
length() * area_sum / ( 108 * volume * volume );
320 static const double normal_coeff = sqrt( 6. ) / 12.;
325 ab.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
326 coordinates[1][2] - coordinates[0][2] );
328 ac.
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
329 coordinates[2][2] - coordinates[0][2] );
331 ad.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
332 coordinates[3][2] - coordinates[0][2] );
334 double detTet = ab % ( ac * ad );
338 bc.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
339 coordinates[2][2] - coordinates[1][2] );
341 bd.
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
342 coordinates[3][2] - coordinates[1][2] );
344 cd.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
345 coordinates[3][2] - coordinates[2][2] );
354 double A = ab2 > bc2 ? ab2 : bc2;
355 double B = ac2 > ad2 ? ac2 : ad2;
356 double C = bd2 > cd2 ? bd2 : cd2;
357 double D = A > B ? A : B;
358 double hm = D > C ? sqrt( D ) : sqrt( C );
370 aspect_ratio = normal_coeff * hm * ( A + B + C + D ) / fabs( detTet );
387 side0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
388 coordinates[1][2] - coordinates[0][2] );
390 side1.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
391 coordinates[2][2] - coordinates[1][2] );
393 side2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
394 coordinates[0][2] - coordinates[2][2] );
396 side3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
397 coordinates[3][2] - coordinates[0][2] );
399 side4.
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
400 coordinates[3][2] - coordinates[1][2] );
402 side5.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
403 coordinates[3][2] - coordinates[2][2] );
415 double aspect_ratio_gamma = pow( srms, 3 ) / ( 8.48528137423857 * volume );
416 return (
double)aspect_ratio_gamma;
428 static const double normal_exp = 1. / 3.;
432 ab.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
433 coordinates[1][2] - coordinates[0][2] );
435 ac.
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
436 coordinates[2][2] - coordinates[0][2] );
438 ad.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
439 coordinates[3][2] - coordinates[0][2] );
441 double denominator = ab % ( ac * ad );
442 denominator *= denominator;
444 denominator = 3. * pow( denominator, normal_exp );
455 double numerator = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
456 numerator += v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
457 numerator += w[0] * w[0] + w[1] * w[1] + w[2] * w[2];
459 numerator -= v[0] * u[0] + v[1] * u[1] + v[2] * u[2];
460 numerator -= w[0] * u[0] + w[1] * u[1] + w[2] * u[2];
461 numerator -= w[0] * v[0] + w[1] * v[1] + w[2] * v[2];
463 double aspect_frobenius = numerator / denominator;
477 static const double normal_coeff = 180. * .3183098861837906715377675267450287;
482 ab.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
483 coordinates[1][2] - coordinates[0][2] );
485 ad.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
486 coordinates[3][2] - coordinates[0][2] );
488 bc.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
489 coordinates[2][2] - coordinates[1][2] );
491 cd.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
492 coordinates[3][2] - coordinates[2][2] );
495 double nabc = abc.
length();
497 double nabd = abd.
length();
499 double nacd = acd.
length();
501 double nbcd = bcd.
length();
503 double alpha = acos( ( abc % abd ) / ( nabc * nabd ) );
504 double beta = acos( ( abc % acd ) / ( nabc * nacd ) );
505 double gamma = acos( ( abc % bcd ) / ( nabc * nbcd ) );
506 double delta = acos( ( abd % acd ) / ( nabd * nacd ) );
507 double epsilon = acos( ( abd % bcd ) / ( nabd * nbcd ) );
508 double zeta = acos( ( acd % bcd ) / ( nacd * nbcd ) );
510 alpha = alpha < beta ? alpha : beta;
511 alpha = alpha < gamma ? alpha : gamma;
512 alpha = alpha < delta ? alpha : delta;
513 alpha = alpha < epsilon ? alpha : epsilon;
514 alpha = alpha < zeta ? alpha : zeta;
515 alpha *= normal_coeff;
531 e01.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
532 coordinates[1][2] - coordinates[0][2] );
534 e02.
set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
535 coordinates[2][2] - coordinates[0][2] );
537 e03.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
538 coordinates[3][2] - coordinates[0][2] );
540 e12.
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
541 coordinates[2][2] - coordinates[1][2] );
543 e13.
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
544 coordinates[3][2] - coordinates[1][2] );
546 e23.
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
547 coordinates[3][2] - coordinates[2][2] );
558 double l012 = l[4] > l[0] ? l[4] : l[0];
559 l012 = l[1] > l012 ? l[1] : l012;
560 double l031 = l[0] > l[2] ? l[0] : l[2];
561 l031 = l[3] > l031 ? l[3] : l031;
562 double l023 = l[2] > l[1] ? l[2] : l[1];
563 l023 = l[5] > l023 ? l[5] : l023;
564 double l132 = l[4] > l[3] ? l[4] : l[3];
565 l132 = l[5] > l132 ? l[5] : l132;
575 h = ( e03 % N ) / magN;
580 h = ( e02 % N ) / magN;
582 if( cr < crMin ) crMin = cr;
586 h = ( e01 % N ) / magN;
588 if( cr < crMin ) crMin = cr;
592 h = ( e01 % N ) / magN;
594 if( cr < crMin ) crMin = cr;
612 side0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
613 coordinates[1][2] - coordinates[0][2] );
615 side2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
616 coordinates[0][2] - coordinates[2][2] );
618 side3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
619 coordinates[3][2] - coordinates[0][2] );
621 return (
double)( ( side3 % ( side2 * side0 ) ) / 6.0 );
632 double condition, term1, term2, det;
633 double rt3 = sqrt( 3.0 );
634 double rt6 = sqrt( 6.0 );
638 side0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
639 coordinates[1][2] - coordinates[0][2] );
641 side2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
642 coordinates[0][2] - coordinates[2][2] );
644 side3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
645 coordinates[3][2] - coordinates[0][2] );
650 c_2 = ( -2 * side2 - side0 ) / rt3;
651 c_3 = ( 3 * side3 + side2 - side0 ) / rt6;
653 term1 = c_1 % c_1 + c_2 % c_2 + c_3 % c_3;
654 term2 = ( c_1 * c_2 ) % ( c_1 * c_2 ) + ( c_2 * c_3 ) % ( c_2 * c_3 ) + ( c_1 * c_3 ) % ( c_1 * c_3 );
655 det = c_1 % ( c_2 * c_3 );
660 condition = sqrt( term1 * term2 ) / ( 3.0 * det );
662 return (
double)condition;
674 side0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
675 coordinates[1][2] - coordinates[0][2] );
677 side2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
678 coordinates[0][2] - coordinates[2][2] );
680 side3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
681 coordinates[3][2] - coordinates[0][2] );
683 return (
double)( side3 % ( side2 * side0 ) );
694 static const double two_thirds = 2.0 / 3.0;
695 static const double root_of_2 = sqrt( 2.0 );
699 edge0.
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
700 coordinates[1][2] - coordinates[0][2] );
702 edge2.
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
703 coordinates[0][2] - coordinates[2][2] );
705 edge3.
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
706 coordinates[3][2] - coordinates[0][2] );
708 double jacobian = edge3 % ( edge2 * edge0 );
713 double num = 3 * pow( root_of_2 * jacobian, two_thirds );
715 1.5 * ( edge0 % edge0 + edge2 % edge2 + edge3 % edge3 ) - ( edge0 % -edge2 + -edge2 % edge3 + edge3 % edge0 );
732 double avg_volume = ( w1 % ( w2 * w3 ) ) / 6.0;
740 size = volume / avg_volume;
759 return (
double)( shape *
size );
769 int number_of_gauss_points = 0;
775 else if( num_nodes == 10 )
777 number_of_gauss_points = 4;
780 int total_number_of_gauss_points = number_of_gauss_points;
803 double jacobian, minimum_jacobian;
804 double element_volume = 0.0;
809 for( ife = 0; ife < total_number_of_gauss_points; ife++ )
811 xxi.
set( 0.0, 0.0, 0.0 );
812 xet.
set( 0.0, 0.0, 0.0 );
813 xze.
set( 0.0, 0.0, 0.0 );
815 for( ja = 0; ja < num_nodes; ja++ )
817 xin.
set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
818 xxi += dndy1[ife][ja] * xin;
819 xet += dndy2[ife][ja] * xin;
820 xze += dndy3[ife][ja] * xin;
824 jacobian = xxi % ( xet * xze );
825 if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
827 element_volume += weight[ife] * jacobian;
837 for( node_id = 0; node_id < num_nodes; node_id++ )
839 xxi.
set( 0.0, 0.0, 0.0 );
840 xet.
set( 0.0, 0.0, 0.0 );
841 xze.
set( 0.0, 0.0, 0.0 );
843 for( ja = 0; ja < num_nodes; ja++ )
845 xin.
set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
846 xxi += dndy1_at_node[node_id][ja] * xin;
847 xet += dndy2_at_node[node_id][ja] * xin;
848 xze += dndy3_at_node[node_id][ja] * xin;
851 jacobian = xxi % ( xet * xze );
852 if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
854 distortion = minimum_jacobian / element_volume;
856 return (
double)distortion;
863 double coordinates[][3],
864 unsigned int metrics_request_flag,
892 edges[0].
set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
893 coordinates[1][2] - coordinates[0][2] );
895 edges[1].
set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
896 coordinates[2][2] - coordinates[1][2] );
898 edges[2].
set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
899 coordinates[0][2] - coordinates[2][2] );
901 edges[3].
set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
902 coordinates[3][2] - coordinates[0][2] );
904 edges[4].
set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
905 coordinates[3][2] - coordinates[1][2] );
907 edges[5].
set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
908 coordinates[3][2] - coordinates[2][2] );
911 static const double root_of_2 = sqrt( 2.0 );
917 if( metrics_request_flag & do_jacobian )
919 metric_vals->
jacobian = (double)( edges[3] % ( edges[2] * edges[0] ) );
931 double surface_area = ( ( edges[2] * edges[0] ).
length() + ( edges[3] * edges[0] ).
length() +
932 ( edges[4] * edges[1] ).
length() + ( edges[3] * edges[2] ).
length() ) *
939 double volume = metric_vals->
jacobian / 6.0;
944 metric_vals->
aspect_beta = (double)( numerator.
length() * surface_area / ( 108 * volume * volume ) );
950 double volume = fabs( metric_vals->
jacobian / 6.0 );
960 srms *= ( srms * srms );
961 metric_vals->
aspect_gamma = (double)( srms / ( 8.48528137423857 * volume ) );
971 metric_vals->
shape = (double)0.0;
975 static const double two_thirds = 2.0 / 3.0;
976 double num = 3.0 * pow( root_of_2 * metric_vals->
jacobian, two_thirds );
977 double den = 1.5 * ( edges[0] % edges[0] + edges[2] % edges[2] + edges[3] % edges[3] ) -
978 ( edges[0] % -edges[2] + -edges[2] % edges[3] + edges[3] % edges[0] );
981 metric_vals->
shape = (double)0.0;
992 double avg_vol = ( w1 % ( w2 * w3 ) ) / 6;
998 double tmp = metric_vals->
jacobian / ( 6 * avg_vol );
1033 if( length_product < fabs( metric_vals->
jacobian ) ) length_product = fabs( metric_vals->
jacobian );
1044 static const double root_of_3 = sqrt( 3.0 );
1045 static const double root_of_6 = sqrt( 6.0 );
1049 c_2 = ( -2 * edges[2] - edges[0] ) / root_of_3;
1050 c_3 = ( 3 * edges[3] + edges[2] - edges[0] ) / root_of_6;
1052 double term1 = c_1 % c_1 + c_2 % c_2 + c_3 % c_3;
1053 double term2 = ( c_1 * c_2 ) % ( c_1 * c_2 ) + ( c_2 * c_3 ) % ( c_2 * c_3 ) + ( c_3 * c_1 ) % ( c_3 * c_1 );
1055 double det = c_1 % ( c_2 * c_3 );
1060 metric_vals->
condition = (double)( sqrt( term1 * term2 ) / ( 3.0 * det ) );