#include "moab/verdict.h"
#include "verdict_defines.hpp"
#include "V_GaussIntegration.hpp"
#include "VerdictVector.hpp"
#include <memory.h>
#include <cstddef>
Go to the source code of this file.
Macros | |
#define | VERDICT_EXPORTS |
Functions | |
static int | v_tri_get_weight (double &m11, double &m21, double &m12, double &m22) |
C_FUNC_DEF void | v_set_tri_size (double size) |
Sets average size (area) of tri, needed for v_tri_relative_size(...) More... | |
C_FUNC_DEF void | v_set_tri_normal_func (ComputeNormal func) |
Sets fuction pointer to calculate tri normal wrt surface. More... | |
C_FUNC_DEF double | v_tri_edge_ratio (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_aspect_ratio (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_radius_ratio (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_aspect_frobenius (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_area (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_minimum_angle (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_maximum_angle (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_condition (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_scaled_jacobian (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_shape (int num_nodes, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_relative_size_squared (int, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_shape_and_size (int num_nodes, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF double | v_tri_distortion (int num_nodes, double coordinates[][3]) |
Calculates tri metric. More... | |
C_FUNC_DEF void | v_tri_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, TriMetricVals *metric_vals) |
Calculates quality metrics for triangle elements. More... | |
Variables | |
static double | verdict_tri_size = 0 |
static ComputeNormal | compute_normal = NULL |
#define VERDICT_EXPORTS |
Definition at line 23 of file V_TriMetric.cpp.
C_FUNC_DEF void v_set_tri_normal_func | ( | ComputeNormal | func | ) |
Sets fuction pointer to calculate tri normal wrt surface.
Definition at line 63 of file V_TriMetric.cpp.
64 { 65 compute_normal = func; 66 }
References compute_normal.
C_FUNC_DEF void v_set_tri_size | ( | double | size | ) |
Sets average size (area) of tri, needed for v_tri_relative_size(...)
sets the average area of a tri
Definition at line 58 of file V_TriMetric.cpp.
59 {
60 verdict_tri_size = size;
61 }
References size, and verdict_tri_size.
Referenced by moab::VerdictWrapper::set_size().
C_FUNC_DEF double v_tri_area | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The area of a tri
0.5 * jacobian at a node
Definition at line 278 of file V_TriMetric.cpp.
279 {
280 // two vectors for two sides
281 VerdictVector side1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
282 coordinates[1][2] - coordinates[0][2] );
283
284 VerdictVector side3( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
285 coordinates[2][2] - coordinates[0][2] );
286
287 // the cross product of the two vectors representing two sides of the
288 // triangle
289 VerdictVector tmp = side1 * side3;
290
291 // return the magnitude of the vector divided by two
292 double area = 0.5 * tmp.length();
293 if( area > 0 ) return (double)VERDICT_MIN( area, VERDICT_DBL_MAX );
294 return (double)VERDICT_MAX( area, -VERDICT_DBL_MAX );
295 }
References VerdictVector::length(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), v_quad_jacobian(), and v_quad_quality().
C_FUNC_DEF double v_tri_aspect_frobenius | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
the Frobenius aspect of a tri
srms^2/(2 * sqrt(3.0) * area) where srms^2 is sum of the lengths squared
NB (P. Pebay 01/14/07): this method was called "aspect ratio" in earlier incarnations of VERDICT
Definition at line 246 of file V_TriMetric.cpp.
247 {
248 static const double two_times_root_of_3 = 2 * sqrt( 3.0 );
249
250 // three vectors for each side
251 VerdictVector side1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
252 coordinates[1][2] - coordinates[0][2] );
253
254 VerdictVector side2( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
255 coordinates[2][2] - coordinates[1][2] );
256
257 VerdictVector side3( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
258 coordinates[0][2] - coordinates[2][2] );
259
260 // sum the lengths squared of each side
261 double srms = ( side1.length_squared() + side2.length_squared() + side3.length_squared() );
262
263 // find two times the area of the triangle by cross product
264 double areaX2 = ( ( side1 * ( -side3 ) ).length() );
265
266 if( areaX2 == 0.0 ) return (double)VERDICT_DBL_MAX;
267
268 double aspect = (double)( srms / ( two_times_root_of_3 * ( areaX2 ) ) );
269 if( aspect > 0 ) return (double)VERDICT_MIN( aspect, VERDICT_DBL_MAX );
270 return (double)VERDICT_MAX( aspect, -VERDICT_DBL_MAX );
271 }
References VerdictVector::length_squared(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
C_FUNC_DEF double v_tri_aspect_ratio | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
the aspect ratio of a triangle
NB (P. Pebay 01/14/07): Hmax / ( 2.0 * sqrt(3.0) * IR) where Hmax is the maximum edge length and IR is the inradius
note that previous incarnations of verdict used "v_tri_aspect_ratio" to denote what is now called "v_tri_aspect_frobenius"
Definition at line 160 of file V_TriMetric.cpp.
161 {
162 static const double normal_coeff = sqrt( 3. ) / 6.;
163
164 // three vectors for each side
165 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
166 coordinates[1][2] - coordinates[0][2] );
167
168 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
169 coordinates[2][2] - coordinates[1][2] );
170
171 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
172 coordinates[0][2] - coordinates[2][2] );
173
174 double a1 = a.length();
175 double b1 = b.length();
176 double c1 = c.length();
177
178 double hm = a1 > b1 ? a1 : b1;
179 hm = hm > c1 ? hm : c1;
180
181 VerdictVector ab = a * b;
182 double denominator = ab.length();
183
184 if( denominator < VERDICT_DBL_MIN )
185 return (double)VERDICT_DBL_MAX;
186 else
187 {
188 double aspect_ratio;
189 aspect_ratio = normal_coeff * hm * ( a1 + b1 + c1 ) / denominator;
190
191 if( aspect_ratio > 0 ) return (double)VERDICT_MIN( aspect_ratio, VERDICT_DBL_MAX );
192 return (double)VERDICT_MAX( aspect_ratio, -VERDICT_DBL_MAX );
193 }
194 }
References VerdictVector::length(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
C_FUNC_DEF double v_tri_condition | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The condition of a tri
Condition number of the jacobian matrix at any corner
Definition at line 421 of file V_TriMetric.cpp.
422 {
423 static const double rt3 = sqrt( 3.0 );
424
425 VerdictVector v1( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
426 coordinates[1][2] - coordinates[0][2] );
427
428 VerdictVector v2( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
429 coordinates[2][2] - coordinates[0][2] );
430
431 VerdictVector tri_normal = v1 * v2;
432 double areax2 = tri_normal.length();
433
434 if( areax2 == 0.0 ) return (double)VERDICT_DBL_MAX;
435
436 double condition = (double)( ( ( v1 % v1 ) + ( v2 % v2 ) - ( v1 % v2 ) ) / ( areax2 * rt3 ) );
437
438 // check for inverted if we have access to the normal
439 if( compute_normal )
440 {
441 // center of tri
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;
446
447 // dot product
448 compute_normal( point, surf_normal );
449 if( ( tri_normal.x() * surf_normal[0] + tri_normal.y() * surf_normal[1] + tri_normal.z() * surf_normal[2] ) <
450 0 )
451 return (double)VERDICT_DBL_MAX;
452 }
453 return (double)VERDICT_MIN( condition, VERDICT_DBL_MAX );
454 }
References compute_normal, VerdictVector::length(), VERDICT_DBL_MAX, VERDICT_MIN, VerdictVector::x(), VerdictVector::y(), and VerdictVector::z().
Referenced by moab::VerdictWrapper::quality_measure(), v_quad_condition(), and v_tri_shape().
C_FUNC_DEF double v_tri_distortion | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The distortion of a tri
TODO: make a short definition of the distortion and comment below
Definition at line 588 of file V_TriMetric.cpp.
589 {
590
591 double distortion;
592 int total_number_of_gauss_points = 0;
593 VerdictVector aa, bb, cc, normal_at_point, xin;
594 double element_area = 0.;
595
596 aa.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
597 coordinates[1][2] - coordinates[0][2] );
598
599 bb.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
600 coordinates[2][2] - coordinates[0][2] );
601
602 VerdictVector tri_normal = aa * bb;
603
604 int number_of_gauss_points = 0;
605 if( num_nodes == 3 )
606 {
607 distortion = 1.0;
608 return (double)distortion;
609 }
610
611 else if( num_nodes == 6 )
612 {
613 total_number_of_gauss_points = 6;
614 number_of_gauss_points = 6;
615 }
616
617 distortion = VERDICT_DBL_MAX;
618 double shape_function[maxTotalNumberGaussPoints][maxNumberNodes];
619 double dndy1[maxTotalNumberGaussPoints][maxNumberNodes];
620 double dndy2[maxTotalNumberGaussPoints][maxNumberNodes];
621 double weight[maxTotalNumberGaussPoints];
622
623 // create an object of GaussIntegration
624 int number_dims = 2;
625 int is_tri = 1;
626 GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dims, is_tri );
627 GaussIntegration::calculate_shape_function_2d_tri();
628 GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], weight );
629
630 // calculate element area
631 int ife, ja;
632 for( ife = 0; ife < total_number_of_gauss_points; ife++ )
633 {
634 aa.set( 0.0, 0.0, 0.0 );
635 bb.set( 0.0, 0.0, 0.0 );
636
637 for( ja = 0; ja < num_nodes; ja++ )
638 {
639 xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
640 aa += dndy1[ife][ja] * xin;
641 bb += dndy2[ife][ja] * xin;
642 }
643 normal_at_point = aa * bb;
644 double jacobian = normal_at_point.length();
645 element_area += weight[ife] * jacobian;
646 }
647
648 element_area *= 0.8660254;
649 double dndy1_at_node[maxNumberNodes][maxNumberNodes];
650 double dndy2_at_node[maxNumberNodes][maxNumberNodes];
651
652 GaussIntegration::calculate_derivative_at_nodes_2d_tri( dndy1_at_node, dndy2_at_node );
653
654 VerdictVector normal_at_nodes[7];
655
656 // evaluate normal at nodes and distortion values at nodes
657 int jai = 0;
658 for( ja = 0; ja < num_nodes; ja++ )
659 {
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++ )
663 {
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;
667 }
668 normal_at_nodes[ja] = aa * bb;
669 normal_at_nodes[ja].normalize();
670 }
671
672 // determine if element is flat
673 bool flat_element = true;
674 double dot_product;
675
676 for( ja = 0; ja < num_nodes; ja++ )
677 {
678 dot_product = normal_at_nodes[0] % normal_at_nodes[ja];
679 if( fabs( dot_product ) < 0.99 )
680 {
681 flat_element = false;
682 break;
683 }
684 }
685
686 // take into consideration of the thickness of the element
687 double thickness, thickness_gauss;
688 double distrt;
689 // get_tri_thickness(tri, element_area, thickness );
690 thickness = 0.001 * sqrt( element_area );
691
692 // set thickness gauss point location
693 double zl = 0.5773502691896;
694 if( flat_element ) zl = 0.0;
695
696 int no_gauss_pts_z = ( flat_element ) ? 1 : 2;
697 double thickness_z;
698
699 // loop on integration points
700 int igz;
701 for( ife = 0; ife < total_number_of_gauss_points; ife++ )
702 {
703 // loop on the thickness direction gauss points
704 for( igz = 0; igz < no_gauss_pts_z; igz++ )
705 {
706 zl = -zl;
707 thickness_z = zl * thickness / 2.0;
708
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 );
712
713 for( ja = 0; ja < num_nodes; ja++ )
714 {
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];
721 }
722
723 normal_at_point = aa * bb;
724 distrt = cc % normal_at_point;
725 if( distrt < distortion ) distortion = distrt;
726 }
727 }
728
729 // loop through nodal points
730 for( ja = 0; ja < num_nodes; ja++ )
731 {
732 for( igz = 0; igz < no_gauss_pts_z; igz++ )
733 {
734 zl = -zl;
735 thickness_z = zl * thickness / 2.0;
736
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 );
740
741 for( jai = 0; jai < num_nodes; jai++ )
742 {
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;
747 if( jai == ja )
748 thickness_gauss = thickness / 2.0;
749 else
750 thickness_gauss = 0.;
751 cc += thickness_gauss * normal_at_nodes[jai];
752 }
753 }
754
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 );
758
759 if( distrt < distortion ) distortion = distrt;
760 }
761 if( element_area * thickness != 0 )
762 distortion *= 1. / ( element_area * thickness );
763 else
764 distortion *= 1.;
765
766 if( distortion > 0 ) return (double)VERDICT_MIN( distortion, VERDICT_DBL_MAX );
767 return (double)VERDICT_MAX( distortion, -VERDICT_DBL_MAX );
768 }
References GaussIntegration::calculate_derivative_at_nodes_2d_tri(), GaussIntegration::calculate_shape_function_2d_tri(), dot_product(), GaussIntegration::get_shape_func(), GaussIntegration::initialize(), VerdictVector::length(), maxNumberNodes, maxTotalNumberGaussPoints, VerdictVector::normalize(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tri_quality().
C_FUNC_DEF double v_tri_edge_ratio | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
the edge ratio of a triangle
NB (P. Pebay 01/14/07): Hmax / Hmin where Hmax and Hmin are respectively the maximum and the minimum edge lengths
Definition at line 76 of file V_TriMetric.cpp.
77 {
78
79 // three vectors for each side
80 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
81 coordinates[1][2] - coordinates[0][2] );
82
83 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
84 coordinates[2][2] - coordinates[1][2] );
85
86 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
87 coordinates[0][2] - coordinates[2][2] );
88
89 double a2 = a.length_squared();
90 double b2 = b.length_squared();
91 double c2 = c.length_squared();
92
93 double m2, M2;
94 if( a2 < b2 )
95 {
96 if( b2 < c2 )
97 {
98 m2 = a2;
99 M2 = c2;
100 }
101 else // b2 <= a2
102 {
103 if( a2 < c2 )
104 {
105 m2 = a2;
106 M2 = b2;
107 }
108 else // c2 <= a2
109 {
110 m2 = c2;
111 M2 = b2;
112 }
113 }
114 }
115 else // b2 <= a2
116 {
117 if( a2 < c2 )
118 {
119 m2 = b2;
120 M2 = c2;
121 }
122 else // c2 <= a2
123 {
124 if( b2 < c2 )
125 {
126 m2 = b2;
127 M2 = a2;
128 }
129 else // c2 <= b2
130 {
131 m2 = c2;
132 M2 = a2;
133 }
134 }
135 }
136
137 if( m2 < VERDICT_DBL_MIN )
138 return (double)VERDICT_DBL_MAX;
139 else
140 {
141 double edge_ratio;
142 edge_ratio = sqrt( M2 / m2 );
143
144 if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX );
145 return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX );
146 }
147 }
References VerdictVector::length_squared(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tri_quality().
|
static |
get weights based on the average area of a set of tris
Definition at line 40 of file V_TriMetric.cpp.
41 {
42 static const double rootOf3 = sqrt( 3.0 );
43 m11 = 1;
44 m21 = 0;
45 m12 = 0.5;
46 m22 = 0.5 * rootOf3;
47 double scale = sqrt( 2.0 * verdict_tri_size / ( m11 * m22 - m21 * m12 ) );
48
49 m11 *= scale;
50 m21 *= scale;
51 m12 *= scale;
52 m22 *= scale;
53
54 return 1;
55 }
References verdict_tri_size.
Referenced by v_tri_quality(), and v_tri_relative_size_squared().
C_FUNC_DEF double v_tri_maximum_angle | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The maximum angle of a tri
The maximum angle of a tri is the maximum angle between two adjacents sides out of all three corners of the triangle.
Definition at line 361 of file V_TriMetric.cpp.
362 {
363
364 // vectors for all the sides
365 VerdictVector sides[4];
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] );
372
373 // in case we need to find the interior angle
374 // between sides 0 and 1
375 sides[3] = -sides[1];
376
377 // calculate the lengths squared of the sides
378 double sides_lengths[3];
379 sides_lengths[0] = sides[0].length_squared();
380 sides_lengths[1] = sides[1].length_squared();
381 sides_lengths[2] = sides[2].length_squared();
382
383 if( sides_lengths[0] == 0.0 || sides_lengths[1] == 0.0 || sides_lengths[2] == 0.0 )
384 {
385 return 0.0;
386 }
387
388 // using the law of sines, we know that the maximum
389 // angle is opposite of the longest side
390
391 // find the longest side
392 int short_side = 0;
393 if( sides_lengths[1] > sides_lengths[0] ) short_side = 1;
394 if( sides_lengths[2] > sides_lengths[short_side] ) short_side = 2;
395
396 // from the longest side, calculate the angle of the
397 // opposite angle
398 double max_angle;
399 if( short_side == 0 )
400 {
401 max_angle = sides[2].interior_angle( sides[1] );
402 }
403 else if( short_side == 1 )
404 {
405 max_angle = sides[0].interior_angle( sides[2] );
406 }
407 else
408 {
409 max_angle = sides[0].interior_angle( sides[3] );
410 }
411
412 if( max_angle > 0 ) return (double)VERDICT_MIN( max_angle, VERDICT_DBL_MAX );
413 return (double)VERDICT_MAX( max_angle, -VERDICT_DBL_MAX );
414 }
References VerdictVector::interior_angle(), VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), v_quad_maximum_angle(), and v_quad_quality().
C_FUNC_DEF double v_tri_minimum_angle | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The minimum angle of a tri
The minimum angle of a tri is the minimum angle between two adjacents sides out of all three corners of the triangle.
Definition at line 303 of file V_TriMetric.cpp.
304 {
305
306 // vectors for all the sides
307 VerdictVector sides[4];
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] );
314
315 // in case we need to find the interior angle
316 // between sides 0 and 1
317 sides[3] = -sides[1];
318
319 // calculate the lengths squared of the sides
320 double sides_lengths[3];
321 sides_lengths[0] = sides[0].length_squared();
322 sides_lengths[1] = sides[1].length_squared();
323 sides_lengths[2] = sides[2].length_squared();
324
325 if( sides_lengths[0] == 0.0 || sides_lengths[1] == 0.0 || sides_lengths[2] == 0.0 ) return 0.0;
326
327 // using the law of sines, we know that the minimum
328 // angle is opposite of the shortest side
329
330 // find the shortest side
331 int short_side = 0;
332 if( sides_lengths[1] < sides_lengths[0] ) short_side = 1;
333 if( sides_lengths[2] < sides_lengths[short_side] ) short_side = 2;
334
335 // from the shortest side, calculate the angle of the
336 // opposite angle
337 double min_angle;
338 if( short_side == 0 )
339 {
340 min_angle = sides[2].interior_angle( sides[1] );
341 }
342 else if( short_side == 1 )
343 {
344 min_angle = sides[0].interior_angle( sides[2] );
345 }
346 else
347 {
348 min_angle = sides[0].interior_angle( sides[3] );
349 }
350
351 if( min_angle > 0 ) return (double)VERDICT_MIN( min_angle, VERDICT_DBL_MAX );
352 return (double)VERDICT_MAX( min_angle, -VERDICT_DBL_MAX );
353 }
References VerdictVector::interior_angle(), VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), v_quad_minimum_angle(), and v_quad_quality().
C_FUNC_DEF void v_tri_quality | ( | int | num_nodes, |
double | coordinates[][3], | ||
unsigned int | metrics_request_flag, | ||
TriMetricVals * | metric_vals | ||
) |
Calculates quality metrics for triangle elements.
tri_quality for calculating multiple tri metrics at once
using this method is generally faster than using the individual method multiple times.
Definition at line 777 of file V_TriMetric.cpp.
781 {
782
783 memset( metric_vals, 0, sizeof( TriMetricVals ) );
784
785 // for starts, lets set up some basic and common information
786
787 /* node numbers and side numbers used below
788
789 2
790 ++
791 / \
792 2 / \ 1
793 / \
794 / \
795 0 ---------+ 1
796 0
797 */
798
799 // vectors for each side
800 VerdictVector sides[3];
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] );
807 VerdictVector tri_normal = sides[0] * sides[2];
808 // if we have access to normal information, check to see if the
809 // element is inverted. If we don't have the normal information
810 // that we need for this, assume the element is not inverted.
811 // This flag will be used for condition number, jacobian, shape,
812 // and size and shape.
813 bool is_inverted = false;
814 if( compute_normal )
815 {
816 // center of tri
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;
821 // dot product
822 compute_normal( point, surf_normal );
823 if( ( tri_normal.x() * surf_normal[0] + tri_normal.y() * surf_normal[1] + tri_normal.z() * surf_normal[2] ) <
824 0 )
825 is_inverted = true;
826 }
827
828 // lengths squared of each side
829 double sides_lengths_squared[3];
830 sides_lengths_squared[0] = sides[0].length_squared();
831 sides_lengths_squared[1] = sides[1].length_squared();
832 sides_lengths_squared[2] = sides[2].length_squared();
833
834 // if we are doing angle calcuations
835 if( metrics_request_flag & ( V_TRI_MINIMUM_ANGLE | V_TRI_MAXIMUM_ANGLE ) )
836 {
837 // which is short and long side
838 int short_side = 0, long_side = 0;
839
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;
842
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;
845
846 // calculate the minimum angle of the tri
847 if( metrics_request_flag & V_TRI_MINIMUM_ANGLE )
848 {
849 if( sides_lengths_squared[0] == 0.0 || sides_lengths_squared[1] == 0.0 || sides_lengths_squared[2] == 0.0 )
850 {
851 metric_vals->minimum_angle = 0.0;
852 }
853 else if( short_side == 0 )
854 metric_vals->minimum_angle = (double)sides[2].interior_angle( sides[1] );
855 else if( short_side == 1 )
856 metric_vals->minimum_angle = (double)sides[0].interior_angle( sides[2] );
857 else
858 metric_vals->minimum_angle = (double)sides[0].interior_angle( -sides[1] );
859 }
860
861 // calculate the maximum angle of the tri
862 if( metrics_request_flag & V_TRI_MAXIMUM_ANGLE )
863 {
864 if( sides_lengths_squared[0] == 0.0 || sides_lengths_squared[1] == 0.0 || sides_lengths_squared[2] == 0.0 )
865 {
866 metric_vals->maximum_angle = 0.0;
867 }
868 else if( long_side == 0 )
869 metric_vals->maximum_angle = (double)sides[2].interior_angle( sides[1] );
870 else if( long_side == 1 )
871 metric_vals->maximum_angle = (double)sides[0].interior_angle( sides[2] );
872 else
873 metric_vals->maximum_angle = (double)sides[0].interior_angle( -sides[1] );
874 }
875 }
876
877 // calculate the area of the tri
878 // the following metrics depend on area
879 if( metrics_request_flag &
880 ( V_TRI_AREA | V_TRI_SCALED_JACOBIAN | V_TRI_SHAPE | V_TRI_RELATIVE_SIZE_SQUARED | V_TRI_SHAPE_AND_SIZE ) )
881 {
882 metric_vals->area = (double)( ( sides[0] * sides[2] ).length() * 0.5 );
883 }
884
885 // calculate the aspect ratio
886 if( metrics_request_flag & V_TRI_ASPECT_FROBENIUS )
887 {
888 // sum the lengths squared
889 double srms = sides_lengths_squared[0] + sides_lengths_squared[1] + sides_lengths_squared[2];
890
891 // calculate once and reuse
892 static const double twoTimesRootOf3 = 2 * sqrt( 3.0 );
893
894 double div = ( twoTimesRootOf3 * ( ( sides[0] * sides[2] ).length() ) );
895
896 if( div == 0.0 )
897 metric_vals->aspect_frobenius = (double)VERDICT_DBL_MAX;
898 else
899 metric_vals->aspect_frobenius = (double)( srms / div );
900 }
901
902 // calculate the scaled jacobian
903 if( metrics_request_flag & V_TRI_SCALED_JACOBIAN )
904 {
905 // calculate once and reuse
906 static const double twoOverRootOf3 = 2 / sqrt( 3.0 );
907 // use the area from above
908
909 double tmp = tri_normal.length() * twoOverRootOf3;
910
911 // now scale it by the lengths of the sides
912 double min_scaled_jac = VERDICT_DBL_MAX;
913 double temp_scaled_jac;
914 for( int i = 0; i < 3; i++ )
915 {
916 if( sides_lengths_squared[i % 3] == 0.0 || sides_lengths_squared[( i + 2 ) % 3] == 0.0 )
917 temp_scaled_jac = 0.0;
918 else
919 temp_scaled_jac =
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;
922 }
923 // multiply by -1 if the normals are in opposite directions
924 if( is_inverted )
925 {
926 min_scaled_jac *= -1;
927 }
928 metric_vals->scaled_jacobian = (double)min_scaled_jac;
929 }
930
931 // calculate the condition number
932 if( metrics_request_flag & V_TRI_CONDITION )
933 {
934 // calculate once and reuse
935 static const double rootOf3 = sqrt( 3.0 );
936 // if it is inverted, the condition number is considered to be infinity.
937 if( is_inverted )
938 {
939 metric_vals->condition = VERDICT_DBL_MAX;
940 }
941 else
942 {
943 double area2x = ( sides[0] * sides[2] ).length();
944 if( area2x == 0.0 )
945 metric_vals->condition = (double)( VERDICT_DBL_MAX );
946 else
947 metric_vals->condition = (double)( ( sides[0] % sides[0] + sides[2] % sides[2] - sides[0] % sides[2] ) /
948 ( area2x * rootOf3 ) );
949 }
950 }
951
952 // calculate the shape
953 if( metrics_request_flag & V_TRI_SHAPE || metrics_request_flag & V_TRI_SHAPE_AND_SIZE )
954 {
955 // if element is inverted, shape is zero. We don't need to
956 // calculate anything.
957 if( is_inverted )
958 {
959 metric_vals->shape = 0.0;
960 }
961 else
962 { // otherwise, we calculate the shape
963 // calculate once and reuse
964 static const double rootOf3 = sqrt( 3.0 );
965 // reuse area from before
966 double area2x = metric_vals->area * 2;
967 // dot products
968 double dots[3] = { sides[0] % sides[0], sides[2] % sides[2], sides[0] % sides[2] };
969
970 // add the dots
971 double sum_dots = dots[0] + dots[1] - dots[2];
972
973 // then the finale
974 if( sum_dots == 0.0 )
975 metric_vals->shape = 0.0;
976 else
977 metric_vals->shape = (double)( rootOf3 * area2x / sum_dots );
978 }
979 }
980
981 // calculate relative size squared
982 if( metrics_request_flag & V_TRI_RELATIVE_SIZE_SQUARED || metrics_request_flag & V_TRI_SHAPE_AND_SIZE )
983 {
984 // get weights
985 double w11, w21, w12, w22;
986 v_tri_get_weight( w11, w21, w12, w22 );
987 // get the determinant
988 double detw = determinant( w11, w21, w12, w22 );
989 // use the area from above and divide with the determinant
990 if( metric_vals->area == 0.0 || detw == 0.0 )
991 metric_vals->relative_size_squared = 0.0;
992 else
993 {
994 double size = metric_vals->area * 2.0 / detw;
995 // square the size
996 size *= size;
997 // value ranges between 0 to 1
998 metric_vals->relative_size_squared = (double)VERDICT_MIN( size, 1.0 / size );
999 }
1000 }
1001
1002 // calculate shape and size
1003 if( metrics_request_flag & V_TRI_SHAPE_AND_SIZE )
1004 {
1005 metric_vals->shape_and_size = metric_vals->relative_size_squared * metric_vals->shape;
1006 }
1007
1008 // calculate distortion
1009 if( metrics_request_flag & V_TRI_DISTORTION ) metric_vals->distortion = v_tri_distortion( num_nodes, coordinates );
1010
1011 // take care of any over-flow problems
1012 if( metric_vals->aspect_frobenius > 0 )
1013 metric_vals->aspect_frobenius = (double)VERDICT_MIN( metric_vals->aspect_frobenius, VERDICT_DBL_MAX );
1014 else
1015 metric_vals->aspect_frobenius = (double)VERDICT_MAX( metric_vals->aspect_frobenius, -VERDICT_DBL_MAX );
1016
1017 if( metric_vals->area > 0 )
1018 metric_vals->area = (double)VERDICT_MIN( metric_vals->area, VERDICT_DBL_MAX );
1019 else
1020 metric_vals->area = (double)VERDICT_MAX( metric_vals->area, -VERDICT_DBL_MAX );
1021
1022 if( metric_vals->minimum_angle > 0 )
1023 metric_vals->minimum_angle = (double)VERDICT_MIN( metric_vals->minimum_angle, VERDICT_DBL_MAX );
1024 else
1025 metric_vals->minimum_angle = (double)VERDICT_MAX( metric_vals->minimum_angle, -VERDICT_DBL_MAX );
1026
1027 if( metric_vals->maximum_angle > 0 )
1028 metric_vals->maximum_angle = (double)VERDICT_MIN( metric_vals->maximum_angle, VERDICT_DBL_MAX );
1029 else
1030 metric_vals->maximum_angle = (double)VERDICT_MAX( metric_vals->maximum_angle, -VERDICT_DBL_MAX );
1031
1032 if( metric_vals->condition > 0 )
1033 metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX );
1034 else
1035 metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX );
1036
1037 if( metric_vals->shape > 0 )
1038 metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX );
1039 else
1040 metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX );
1041
1042 if( metric_vals->scaled_jacobian > 0 )
1043 metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX );
1044 else
1045 metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX );
1046
1047 if( metric_vals->relative_size_squared > 0 )
1048 metric_vals->relative_size_squared = (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX );
1049 else
1050 metric_vals->relative_size_squared =
1051 (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX );
1052
1053 if( metric_vals->shape_and_size > 0 )
1054 metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX );
1055 else
1056 metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX );
1057
1058 if( metric_vals->distortion > 0 )
1059 metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX );
1060 else
1061 metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX );
1062
1063 if( metrics_request_flag & V_TRI_EDGE_RATIO )
1064 {
1065 metric_vals->edge_ratio = v_tri_edge_ratio( 3, coordinates );
1066 }
1067 if( metrics_request_flag & V_TRI_RADIUS_RATIO )
1068 {
1069 metric_vals->radius_ratio = v_tri_radius_ratio( 3, coordinates );
1070 }
1071 if( metrics_request_flag & V_TRI_ASPECT_FROBENIUS ) // there is no V_TRI_ASPECT_RATIO !
1072 {
1073 metric_vals->aspect_ratio = v_tri_radius_ratio( 3, coordinates );
1074 }
1075 }
References TriMetricVals::area, TriMetricVals::aspect_frobenius, TriMetricVals::aspect_ratio, compute_normal, TriMetricVals::condition, determinant(), TriMetricVals::distortion, TriMetricVals::edge_ratio, interior_angle(), VerdictVector::length(), length(), VerdictVector::length_squared(), TriMetricVals::maximum_angle, TriMetricVals::minimum_angle, TriMetricVals::radius_ratio, TriMetricVals::relative_size_squared, TriMetricVals::scaled_jacobian, VerdictVector::set(), TriMetricVals::shape, TriMetricVals::shape_and_size, size, V_TRI_AREA, V_TRI_ASPECT_FROBENIUS, V_TRI_CONDITION, V_TRI_DISTORTION, v_tri_distortion(), V_TRI_EDGE_RATIO, v_tri_edge_ratio(), v_tri_get_weight(), V_TRI_MAXIMUM_ANGLE, V_TRI_MINIMUM_ANGLE, V_TRI_RADIUS_RATIO, v_tri_radius_ratio(), V_TRI_RELATIVE_SIZE_SQUARED, V_TRI_SCALED_JACOBIAN, V_TRI_SHAPE, V_TRI_SHAPE_AND_SIZE, VERDICT_DBL_MAX, VERDICT_MAX, VERDICT_MIN, VerdictVector::x(), VerdictVector::y(), and VerdictVector::z().
Referenced by moab::VerdictWrapper::all_quality_measures().
C_FUNC_DEF double v_tri_radius_ratio | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
the radius ratio of a triangle
NB (P. Pebay 01/13/07): CR / (3.0*IR) where CR is the circumradius and IR is the inradius
this quality metric is also known to VERDICT, for tetrahedral elements only, a the "aspect beta"
Definition at line 206 of file V_TriMetric.cpp.
207 {
208
209 // three vectors for each side
210 VerdictVector a( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
211 coordinates[1][2] - coordinates[0][2] );
212
213 VerdictVector b( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
214 coordinates[2][2] - coordinates[1][2] );
215
216 VerdictVector c( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
217 coordinates[0][2] - coordinates[2][2] );
218
219 double a2 = a.length_squared();
220 double b2 = b.length_squared();
221 double c2 = c.length_squared();
222
223 VerdictVector ab = a * b;
224 double denominator = ab.length_squared();
225
226 if( denominator < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
227
228 double radius_ratio;
229 radius_ratio = .25 * a2 * b2 * c2 * ( a2 + b2 + c2 ) / denominator;
230
231 if( radius_ratio > 0 ) return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX );
232 return (double)VERDICT_MAX( radius_ratio, -VERDICT_DBL_MAX );
233 }
References VerdictVector::length_squared(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tri_quality().
C_FUNC_DEF double v_tri_relative_size_squared | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The relative size of a tri
Min(J,1/J) where J is the determinant of the weighted jacobian matrix.
Definition at line 534 of file V_TriMetric.cpp.
535 {
536 double w11, w21, w12, w22;
537
538 VerdictVector xxi, xet, tri_normal;
539
540 v_tri_get_weight( w11, w21, w12, w22 );
541
542 double detw = determinant( w11, w21, w12, w22 );
543
544 if( detw == 0.0 ) return 0.0;
545
546 xxi.set( coordinates[0][0] - coordinates[1][0], coordinates[0][1] - coordinates[1][1],
547 coordinates[0][2] - coordinates[1][2] );
548
549 xet.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
550 coordinates[0][2] - coordinates[2][2] );
551
552 tri_normal = xxi * xet;
553
554 double deta = tri_normal.length();
555 if( deta == 0.0 || detw == 0.0 ) return 0.0;
556
557 double size = pow( deta / detw, 2 );
558
559 double rel_size = VERDICT_MIN( size, 1.0 / size );
560
561 if( rel_size > 0 ) return (double)VERDICT_MIN( rel_size, VERDICT_DBL_MAX );
562 return (double)VERDICT_MAX( rel_size, -VERDICT_DBL_MAX );
563 }
References determinant(), VerdictVector::length(), VerdictVector::set(), size, v_tri_get_weight(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tri_shape_and_size().
C_FUNC_DEF double v_tri_scaled_jacobian | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The scaled jacobian of a tri
minimum of the jacobian divided by the lengths of 2 edge vectors
Definition at line 461 of file V_TriMetric.cpp.
462 {
463 static const double detw = 2. / sqrt( 3.0 );
464 VerdictVector first, second;
465 double jacobian;
466
467 VerdictVector edge[3];
468 edge[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
469 coordinates[1][2] - coordinates[0][2] );
470
471 edge[1].set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
472 coordinates[2][2] - coordinates[0][2] );
473
474 edge[2].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
475 coordinates[2][2] - coordinates[1][2] );
476 first = edge[1] - edge[0];
477 second = edge[2] - edge[0];
478
479 VerdictVector cross = first * second;
480 jacobian = cross.length();
481
482 double max_edge_length_product;
483 max_edge_length_product =
484 VERDICT_MAX( edge[0].length() * edge[1].length(),
485 VERDICT_MAX( edge[1].length() * edge[2].length(), edge[0].length() * edge[2].length() ) );
486
487 if( max_edge_length_product < VERDICT_DBL_MIN ) return (double)0.0;
488
489 jacobian *= detw;
490 jacobian /= max_edge_length_product;
491
492 if( compute_normal )
493 {
494 // center of tri
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;
499
500 // dot product
501 compute_normal( point, surf_normal );
502 if( ( cross.x() * surf_normal[0] + cross.y() * surf_normal[1] + cross.z() * surf_normal[2] ) < 0 )
503 jacobian *= -1;
504 }
505
506 if( jacobian > 0 ) return (double)VERDICT_MIN( jacobian, VERDICT_DBL_MAX );
507 return (double)VERDICT_MAX( jacobian, -VERDICT_DBL_MAX );
508 }
References compute_normal, moab::cross(), moab::GeomUtil::first(), length(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), v_quad_quality(), and v_quad_scaled_jacobian().
C_FUNC_DEF double v_tri_shape | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The shape of a tri
2 / condition number of weighted jacobian matrix
Definition at line 515 of file V_TriMetric.cpp.
516 {
517 double condition = v_tri_condition( num_nodes, coordinates );
518
519 double shape;
520 if( condition <= VERDICT_DBL_MIN )
521 shape = VERDICT_DBL_MAX;
522 else
523 shape = ( 1 / condition );
524
525 if( shape > 0 ) return (double)VERDICT_MIN( shape, VERDICT_DBL_MAX );
526 return (double)VERDICT_MAX( shape, -VERDICT_DBL_MAX );
527 }
References v_tri_condition(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tri_shape_and_size().
C_FUNC_DEF double v_tri_shape_and_size | ( | int | num_nodes, |
double | coordinates[][3] | ||
) |
Calculates tri metric.
The shape and size of a tri
Product of the Shape and Relative Size
Definition at line 570 of file V_TriMetric.cpp.
571 {
572 double size, shape;
573
574 size = v_tri_relative_size_squared( num_nodes, coordinates );
575 shape = v_tri_shape( num_nodes, coordinates );
576
577 double shape_and_size = size * shape;
578
579 if( shape_and_size > 0 ) return (double)VERDICT_MIN( shape_and_size, VERDICT_DBL_MAX );
580 return (double)VERDICT_MAX( shape_and_size, -VERDICT_DBL_MAX );
581 }
References size, v_tri_relative_size_squared(), v_tri_shape(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
|
static |
Definition at line 34 of file V_TriMetric.cpp.
Referenced by v_set_tri_normal_func(), v_tri_condition(), v_tri_quality(), and v_tri_scaled_jacobian().
|
static |
Definition at line 33 of file V_TriMetric.cpp.
Referenced by v_set_tri_size(), and v_tri_get_weight().