Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
V_TetMetric.cpp File Reference
#include "moab/verdict.h"
#include "verdict_defines.hpp"
#include "VerdictVector.hpp"
#include "V_GaussIntegration.hpp"
#include <memory.h>
+ Include dependency graph for V_TetMetric.cpp:

Go to the source code of this file.

Macros

#define VERDICT_EXPORTS
 

Functions

C_FUNC_DEF void v_set_tet_size (double size)
 Sets average size (volume) of tet, needed for v_tet_relative_size(...) More...
 
int get_weight (VerdictVector &w1, VerdictVector &w2, VerdictVector &w3)
 
C_FUNC_DEF double v_tet_edge_ratio (int, double coordinates[][3])
 Calculates tet edge ratio metric. More...
 
C_FUNC_DEF double v_tet_scaled_jacobian (int, double coordinates[][3])
 Calculates tet scaled jacobian. More...
 
C_FUNC_DEF double v_tet_radius_ratio (int, double coordinates[][3])
 Calculates tet radius ratio metric. More...
 
C_FUNC_DEF double v_tet_aspect_beta (int, double coordinates[][3])
 Calculates the radius ratio metric of a positively oriented tet. More...
 
C_FUNC_DEF double v_tet_aspect_ratio (int, double coordinates[][3])
 Calculates tet aspect ratio metric. More...
 
C_FUNC_DEF double v_tet_aspect_gamma (int, double coordinates[][3])
 Calculates tet aspect gamma metric. More...
 
C_FUNC_DEF double v_tet_aspect_frobenius (int, double coordinates[][3])
 Calculates tet aspect frobenius metric. More...
 
C_FUNC_DEF double v_tet_minimum_angle (int, double coordinates[][3])
 Calculates tet minimum dihedral angle. More...
 
C_FUNC_DEF double v_tet_collapse_ratio (int, double coordinates[][3])
 Calculates tet collapse ratio metric. More...
 
C_FUNC_DEF double v_tet_volume (int, double coordinates[][3])
 Calculates tet volume. More...
 
C_FUNC_DEF double v_tet_condition (int, double coordinates[][3])
 Calculates tet condition metric. More...
 
C_FUNC_DEF double v_tet_jacobian (int, double coordinates[][3])
 Calculates tet jacobian. More...
 
C_FUNC_DEF double v_tet_shape (int, double coordinates[][3])
 Calculates tet shape metric. More...
 
C_FUNC_DEF double v_tet_relative_size_squared (int, double coordinates[][3])
 Calculates tet relative size metric. More...
 
C_FUNC_DEF double v_tet_shape_and_size (int num_nodes, double coordinates[][3])
 Calculates tet shape-size metric. More...
 
C_FUNC_DEF double v_tet_distortion (int num_nodes, double coordinates[][3])
 Calculates tet distortion metric. More...
 
C_FUNC_DEF void v_tet_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, TetMetricVals *metric_vals)
 Calculates quality metrics for tetrahedral elements. More...
 

Variables

double verdict_tet_size = 0
 the average volume of a tet More...
 

Macro Definition Documentation

◆ VERDICT_EXPORTS

#define VERDICT_EXPORTS

Definition at line 23 of file V_TetMetric.cpp.

Function Documentation

◆ get_weight()

int get_weight ( VerdictVector w1,
VerdictVector w2,
VerdictVector w3 
)

get the weights based on the average size of a tet

Definition at line 46 of file V_TetMetric.cpp.

47 {
48  static const double rt3 = sqrt( 3.0 );
49  static const double root_of_2 = sqrt( 2.0 );
50 
51  w1.set( 1, 0, 0 );
52  w2.set( 0.5, 0.5 * rt3, 0 );
53  w3.set( 0.5, rt3 / 6.0, root_of_2 / rt3 );
54 
55  double scale = pow( 6. * verdict_tet_size / determinant( w1, w2, w3 ), 0.3333333333333 );
56 
57  w1 *= scale;
58  w2 *= scale;
59  w3 *= scale;
60 
61  return 1;
62 }

References determinant(), VerdictVector::set(), and verdict_tet_size.

Referenced by v_tet_quality(), and v_tet_relative_size_squared().

◆ v_set_tet_size()

C_FUNC_DEF void v_set_tet_size ( double  size)

Sets average size (volume) of tet, needed for v_tet_relative_size(...)

set the average volume of a tet

Definition at line 37 of file V_TetMetric.cpp.

38 {
40 }

References size, and verdict_tet_size.

Referenced by moab::VerdictWrapper::set_size().

◆ v_tet_aspect_beta()

C_FUNC_DEF double v_tet_aspect_beta ( int  num_nodes,
double  coordinates[][3] 
)

Calculates the radius ratio metric of a positively oriented tet.

The radius ratio of a positively-oriented tet, a.k.a. "aspect beta"

NB (P. Pebay 04/16/07): CR / (3.0 * IR) where CR is the circumsphere radius and IR is the inscribed sphere radius if the element has positive orientation. Note that this metric is similar to the radius ratio of a tet, except that it returns VERDICT_DBL_MAX if the element has negative orientation.

Definition at line 265 of file V_TetMetric.cpp.

266 {
267 
268  // Determine side vectors
269  VerdictVector side[6];
270 
271  side[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
272  coordinates[1][2] - coordinates[0][2] );
273 
274  side[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
275  coordinates[2][2] - coordinates[1][2] );
276 
277  side[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
278  coordinates[0][2] - coordinates[2][2] );
279 
280  side[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
281  coordinates[3][2] - coordinates[0][2] );
282 
283  side[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
284  coordinates[3][2] - coordinates[1][2] );
285 
286  side[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
287  coordinates[3][2] - coordinates[2][2] );
288 
289  VerdictVector numerator = side[3].length_squared() * ( side[2] * side[0] ) +
290  side[2].length_squared() * ( side[3] * side[0] ) +
291  side[0].length_squared() * ( side[3] * side[2] );
292 
293  double area_sum;
294  area_sum = ( ( side[2] * side[0] ).length() + ( side[3] * side[0] ).length() + ( side[4] * side[1] ).length() +
295  ( side[3] * side[2] ).length() ) *
296  0.5;
297 
298  double volume = v_tet_volume( 4, coordinates );
299 
300  if( volume < VERDICT_DBL_MIN )
301  return (double)VERDICT_DBL_MAX;
302  else
303  {
304  double radius_ratio;
305  radius_ratio = numerator.length() * area_sum / ( 108 * volume * volume );
306 
307  return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX );
308  }
309 }

References VerdictVector::length(), length(), VerdictVector::length_squared(), length_squared(), VerdictVector::set(), v_tet_volume(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_aspect_frobenius()

C_FUNC_DEF double v_tet_aspect_frobenius ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet aspect frobenius metric.

The aspect frobenius of a tet

NB (P. Pebay 01/22/07): Frobenius condition number when the reference element is regular

Definition at line 426 of file V_TetMetric.cpp.

427 {
428  static const double normal_exp = 1. / 3.;
429 
430  VerdictVector ab, ac, ad;
431 
432  ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
433  coordinates[1][2] - coordinates[0][2] );
434 
435  ac.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
436  coordinates[2][2] - coordinates[0][2] );
437 
438  ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
439  coordinates[3][2] - coordinates[0][2] );
440 
441  double denominator = ab % ( ac * ad );
442  denominator *= denominator;
443  denominator *= 2.;
444  denominator = 3. * pow( denominator, normal_exp );
445 
446  if( denominator < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
447 
448  double u[3];
449  ab.get_xyz( u );
450  double v[3];
451  ac.get_xyz( v );
452  double w[3];
453  ad.get_xyz( w );
454 
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];
458  numerator *= 1.5;
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];
462 
463  double aspect_frobenius = numerator / denominator;
464 
465  if( aspect_frobenius > 0 ) return (double)VERDICT_MIN( aspect_frobenius, VERDICT_DBL_MAX );
466  return (double)VERDICT_MAX( aspect_frobenius, -VERDICT_DBL_MAX );
467 }

References VerdictVector::get_xyz(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_aspect_gamma()

C_FUNC_DEF double v_tet_aspect_gamma ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet aspect gamma metric.

the aspect gamma of a tet

srms^3 / (8.48528137423857*V) where srms = sqrt(sum(Si^2)/6), where Si is the edge length

Definition at line 381 of file V_TetMetric.cpp.

382 {
383 
384  // Determine side vectors
385  VerdictVector side0, side1, side2, side3, side4, side5;
386 
387  side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
388  coordinates[1][2] - coordinates[0][2] );
389 
390  side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
391  coordinates[2][2] - coordinates[1][2] );
392 
393  side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
394  coordinates[0][2] - coordinates[2][2] );
395 
396  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
397  coordinates[3][2] - coordinates[0][2] );
398 
399  side4.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
400  coordinates[3][2] - coordinates[1][2] );
401 
402  side5.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
403  coordinates[3][2] - coordinates[2][2] );
404 
405  double volume = fabs( v_tet_volume( 4, coordinates ) );
406 
407  if( volume < VERDICT_DBL_MIN )
408  return (double)VERDICT_DBL_MAX;
409  else
410  {
411  double srms = sqrt( ( side0.length_squared() + side1.length_squared() + side2.length_squared() +
412  side3.length_squared() + side4.length_squared() + side5.length_squared() ) /
413  6.0 );
414 
415  double aspect_ratio_gamma = pow( srms, 3 ) / ( 8.48528137423857 * volume );
416  return (double)aspect_ratio_gamma;
417  }
418 }

References VerdictVector::length_squared(), VerdictVector::set(), v_tet_volume(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_aspect_ratio()

C_FUNC_DEF double v_tet_aspect_ratio ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet aspect ratio metric.

The aspect ratio of a tet

NB (P. Pebay 01/22/07): Hmax / (2 sqrt(6) r) where Hmax and r respectively denote the greatest edge length and the inradius of the tetrahedron

Definition at line 318 of file V_TetMetric.cpp.

319 {
320  static const double normal_coeff = sqrt( 6. ) / 12.;
321 
322  // Determine side vectors
323  VerdictVector ab, bc, ac, ad, bd, cd;
324 
325  ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
326  coordinates[1][2] - coordinates[0][2] );
327 
328  ac.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
329  coordinates[2][2] - coordinates[0][2] );
330 
331  ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
332  coordinates[3][2] - coordinates[0][2] );
333 
334  double detTet = ab % ( ac * ad );
335 
336  if( detTet < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
337 
338  bc.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
339  coordinates[2][2] - coordinates[1][2] );
340 
341  bd.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
342  coordinates[3][2] - coordinates[1][2] );
343 
344  cd.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
345  coordinates[3][2] - coordinates[2][2] );
346 
347  double ab2 = ab.length_squared();
348  double bc2 = bc.length_squared();
349  double ac2 = ac.length_squared();
350  double ad2 = ad.length_squared();
351  double bd2 = bd.length_squared();
352  double cd2 = cd.length_squared();
353 
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 );
359 
360  bd = ab * bc;
361  A = bd.length();
362  bd = ab * ad;
363  B = bd.length();
364  bd = ac * ad;
365  C = bd.length();
366  bd = bc * cd;
367  D = bd.length();
368 
369  double aspect_ratio;
370  aspect_ratio = normal_coeff * hm * ( A + B + C + D ) / fabs( detTet );
371 
372  if( aspect_ratio > 0 ) return (double)VERDICT_MIN( aspect_ratio, VERDICT_DBL_MAX );
373  return (double)VERDICT_MAX( aspect_ratio, -VERDICT_DBL_MAX );
374 }

References VerdictVector::length(), VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_collapse_ratio()

C_FUNC_DEF double v_tet_collapse_ratio ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet collapse ratio metric.

The collapse ratio of a tet

Definition at line 526 of file V_TetMetric.cpp.

527 {
528  // Determine side vectors
529  VerdictVector e01, e02, e03, e12, e13, e23;
530 
531  e01.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
532  coordinates[1][2] - coordinates[0][2] );
533 
534  e02.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1],
535  coordinates[2][2] - coordinates[0][2] );
536 
537  e03.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
538  coordinates[3][2] - coordinates[0][2] );
539 
540  e12.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
541  coordinates[2][2] - coordinates[1][2] );
542 
543  e13.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
544  coordinates[3][2] - coordinates[1][2] );
545 
546  e23.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
547  coordinates[3][2] - coordinates[2][2] );
548 
549  double l[6];
550  l[0] = e01.length();
551  l[1] = e02.length();
552  l[2] = e03.length();
553  l[3] = e12.length();
554  l[4] = e13.length();
555  l[5] = e23.length();
556 
557  // Find longest edge for each bounding triangle of tetrahedron
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;
566 
567  // Compute collapse ratio for each vertex/triangle pair
568  VerdictVector N;
569  double h, magN;
570  double cr;
571  double crMin;
572 
573  N = e01 * e02;
574  magN = N.length();
575  h = ( e03 % N ) / magN; // height of vertex 3 above 0-1-2
576  crMin = h / l012; // ratio of height to longest edge of 0-1-2
577 
578  N = e03 * e01;
579  magN = N.length();
580  h = ( e02 % N ) / magN; // height of vertex 2 above 0-3-1
581  cr = h / l031; // ratio of height to longest edge of 0-3-1
582  if( cr < crMin ) crMin = cr;
583 
584  N = e02 * e03;
585  magN = N.length();
586  h = ( e01 % N ) / magN; // height of vertex 1 above 0-2-3
587  cr = h / l023; // ratio of height to longest edge of 0-2-3
588  if( cr < crMin ) crMin = cr;
589 
590  N = e12 * e13;
591  magN = N.length();
592  h = ( e01 % N ) / magN; // height of vertex 0 above 1-3-2
593  cr = h / l132; // ratio of height to longest edge of 1-3-2
594  if( cr < crMin ) crMin = cr;
595 
596  if( crMin < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
597  if( crMin > 0 ) return (double)VERDICT_MIN( crMin, VERDICT_DBL_MAX );
598  return (double)VERDICT_MAX( crMin, -VERDICT_DBL_MAX );
599 }

References VerdictVector::length(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_condition()

C_FUNC_DEF double v_tet_condition ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet condition metric.

the condition of a tet

condition number of the jacobian matrix at any corner

Definition at line 629 of file V_TetMetric.cpp.

630 {
631 
632  double condition, term1, term2, det;
633  double rt3 = sqrt( 3.0 );
634  double rt6 = sqrt( 6.0 );
635 
636  VerdictVector side0, side2, side3;
637 
638  side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
639  coordinates[1][2] - coordinates[0][2] );
640 
641  side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
642  coordinates[0][2] - coordinates[2][2] );
643 
644  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
645  coordinates[3][2] - coordinates[0][2] );
646 
647  VerdictVector c_1, c_2, c_3;
648 
649  c_1 = side0;
650  c_2 = ( -2 * side2 - side0 ) / rt3;
651  c_3 = ( 3 * side3 + side2 - side0 ) / rt6;
652 
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 );
656 
657  if( det <= VERDICT_DBL_MIN )
658  return VERDICT_DBL_MAX;
659  else
660  condition = sqrt( term1 * term2 ) / ( 3.0 * det );
661 
662  return (double)condition;
663 }

References VerdictVector::set(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_distortion()

C_FUNC_DEF double v_tet_distortion ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet distortion metric.

the distortion of a tet

Definition at line 765 of file V_TetMetric.cpp.

766 {
767 
768  double distortion = VERDICT_DBL_MAX;
769  int number_of_gauss_points = 0;
770  if( num_nodes == 4 )
771  // for linear tet, the distortion is always 1 because
772  // straight edge tets are the target shape for tet
773  return 1.0;
774 
775  else if( num_nodes == 10 )
776  // use four integration points for quadratic tet
777  number_of_gauss_points = 4;
778 
779  int number_dims = 3;
780  int total_number_of_gauss_points = number_of_gauss_points;
781  // use is_tri=1 to indicate this is for tet in 3D
782  int is_tri = 1;
783 
784  double shape_function[maxTotalNumberGaussPoints][maxNumberNodes];
788  double weight[maxTotalNumberGaussPoints];
789 
790  // create an object of GaussIntegration for tet
791  GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dims, is_tri );
793  GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], dndy3[0], weight );
794 
795  // vector xxi is the derivative vector of coordinates w.r.t local xi coordinate in the
796  // computation space
797  // vector xet is the derivative vector of coordinates w.r.t local et coordinate in the
798  // computation space
799  // vector xze is the derivative vector of coordinates w.r.t local ze coordinate in the
800  // computation space
801  VerdictVector xxi, xet, xze, xin;
802 
803  double jacobian, minimum_jacobian;
804  double element_volume = 0.0;
805  minimum_jacobian = VERDICT_DBL_MAX;
806 
807  // calculate element volume
808  int ife, ja;
809  for( ife = 0; ife < total_number_of_gauss_points; ife++ )
810  {
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 );
814 
815  for( ja = 0; ja < num_nodes; ja++ )
816  {
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;
821  }
822 
823  // determinant
824  jacobian = xxi % ( xet * xze );
825  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
826 
827  element_volume += weight[ife] * jacobian;
828  } // element_volume is 6 times the actual volume
829 
830  // loop through all nodes
831  double dndy1_at_node[maxNumberNodes][maxNumberNodes];
832  double dndy2_at_node[maxNumberNodes][maxNumberNodes];
833  double dndy3_at_node[maxNumberNodes][maxNumberNodes];
834 
835  GaussIntegration::calculate_derivative_at_nodes_3d_tet( dndy1_at_node, dndy2_at_node, dndy3_at_node );
836  int node_id;
837  for( node_id = 0; node_id < num_nodes; node_id++ )
838  {
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 );
842 
843  for( ja = 0; ja < num_nodes; ja++ )
844  {
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;
849  }
850 
851  jacobian = xxi % ( xet * xze );
852  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
853  }
854  distortion = minimum_jacobian / element_volume;
855 
856  return (double)distortion;
857 }

References GaussIntegration::calculate_derivative_at_nodes_3d_tet(), GaussIntegration::calculate_shape_function_3d_tet(), GaussIntegration::get_shape_func(), GaussIntegration::initialize(), maxNumberNodes, maxTotalNumberGaussPoints, VerdictVector::set(), and VERDICT_DBL_MAX.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_edge_ratio()

C_FUNC_DEF double v_tet_edge_ratio ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet edge ratio metric.

the edge ratio of a tet

NB (P. Pebay 01/22/07): Hmax / Hmin where Hmax and Hmin are respectively the maximum and the minimum edge lengths

Definition at line 71 of file V_TetMetric.cpp.

72 {
73  VerdictVector a, b, c, d, e, f;
74 
75  a.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
76  coordinates[1][2] - coordinates[0][2] );
77 
78  b.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
79  coordinates[2][2] - coordinates[1][2] );
80 
81  c.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
82  coordinates[0][2] - coordinates[2][2] );
83 
84  d.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
85  coordinates[3][2] - coordinates[0][2] );
86 
87  e.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
88  coordinates[3][2] - coordinates[1][2] );
89 
90  f.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
91  coordinates[3][2] - coordinates[2][2] );
92 
93  double a2 = a.length_squared();
94  double b2 = b.length_squared();
95  double c2 = c.length_squared();
96  double d2 = d.length_squared();
97  double e2 = e.length_squared();
98  double f2 = f.length_squared();
99 
100  double m2, M2, mab, mcd, mef, Mab, Mcd, Mef;
101 
102  if( a2 < b2 )
103  {
104  mab = a2;
105  Mab = b2;
106  }
107  else // b2 <= a2
108  {
109  mab = b2;
110  Mab = a2;
111  }
112  if( c2 < d2 )
113  {
114  mcd = c2;
115  Mcd = d2;
116  }
117  else // d2 <= c2
118  {
119  mcd = d2;
120  Mcd = c2;
121  }
122  if( e2 < f2 )
123  {
124  mef = e2;
125  Mef = f2;
126  }
127  else // f2 <= e2
128  {
129  mef = f2;
130  Mef = e2;
131  }
132 
133  m2 = mab < mcd ? mab : mcd;
134  m2 = m2 < mef ? m2 : mef;
135 
136  if( m2 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
137 
138  M2 = Mab > Mcd ? Mab : Mcd;
139  M2 = M2 > Mef ? M2 : Mef;
140 
141  double edge_ratio = sqrt( M2 / m2 );
142 
143  if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX );
144  return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX );
145 }

References VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_jacobian()

C_FUNC_DEF double v_tet_jacobian ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet jacobian.

the jacobian of a tet

TODO

Definition at line 670 of file V_TetMetric.cpp.

671 {
672  VerdictVector side0, side2, side3;
673 
674  side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
675  coordinates[1][2] - coordinates[0][2] );
676 
677  side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
678  coordinates[0][2] - coordinates[2][2] );
679 
680  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
681  coordinates[3][2] - coordinates[0][2] );
682 
683  return (double)( side3 % ( side2 * side0 ) );
684 }

References VerdictVector::set().

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_minimum_angle()

C_FUNC_DEF double v_tet_minimum_angle ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet minimum dihedral angle.

The minimum angle of a tet

NB (P. Pebay 01/22/07): minimum nonoriented dihedral angle

Definition at line 475 of file V_TetMetric.cpp.

476 {
477  static const double normal_coeff = 180. * .3183098861837906715377675267450287;
478 
479  // Determine side vectors
480  VerdictVector ab, bc, ad, cd;
481 
482  ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
483  coordinates[1][2] - coordinates[0][2] );
484 
485  ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
486  coordinates[3][2] - coordinates[0][2] );
487 
488  bc.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
489  coordinates[2][2] - coordinates[1][2] );
490 
491  cd.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
492  coordinates[3][2] - coordinates[2][2] );
493 
494  VerdictVector abc = ab * bc;
495  double nabc = abc.length();
496  VerdictVector abd = ab * ad;
497  double nabd = abd.length();
498  VerdictVector acd = ad * cd;
499  double nacd = acd.length();
500  VerdictVector bcd = bc * cd;
501  double nbcd = bcd.length();
502 
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 ) );
509 
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;
516 
517  if( alpha < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
518 
519  if( alpha > 0 ) return (double)VERDICT_MIN( alpha, VERDICT_DBL_MAX );
520  return (double)VERDICT_MAX( alpha, -VERDICT_DBL_MAX );
521 }

References VerdictVector::length(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_quality()

C_FUNC_DEF void v_tet_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
TetMetricVals metric_vals 
)

Calculates quality metrics for tetrahedral elements.

the quality metrics of a tet

Definition at line 862 of file V_TetMetric.cpp.

866 {
867 
868  memset( metric_vals, 0, sizeof( TetMetricVals ) );
869 
870  /*
871 
872  node numbers and edge numbers below
873 
874 
875 
876  3
877  + edge 0 is node 0 to 1
878  +|+ edge 1 is node 1 to 2
879  3/ | \5 edge 2 is node 0 to 2
880  / 4| \ edge 3 is node 0 to 3
881  0 - -|- + 2 edge 4 is node 1 to 3
882  \ | + edge 5 is node 2 to 3
883  0\ | /1
884  +|/ edge 2 is behind edge 4
885  1
886 
887 
888  */
889 
890  // lets start with making the vectors
891  VerdictVector edges[6];
892  edges[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
893  coordinates[1][2] - coordinates[0][2] );
894 
895  edges[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
896  coordinates[2][2] - coordinates[1][2] );
897 
898  edges[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
899  coordinates[0][2] - coordinates[2][2] );
900 
901  edges[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
902  coordinates[3][2] - coordinates[0][2] );
903 
904  edges[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
905  coordinates[3][2] - coordinates[1][2] );
906 
907  edges[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
908  coordinates[3][2] - coordinates[2][2] );
909 
910  // common numbers
911  static const double root_of_2 = sqrt( 2.0 );
912 
913  // calculate the jacobian
914  static const int do_jacobian = V_TET_JACOBIAN | V_TET_VOLUME | V_TET_ASPECT_BETA | V_TET_ASPECT_GAMMA |
917  if( metrics_request_flag & do_jacobian )
918  {
919  metric_vals->jacobian = (double)( edges[3] % ( edges[2] * edges[0] ) );
920  }
921 
922  // calculate the volume
923  if( metrics_request_flag & V_TET_VOLUME )
924  {
925  metric_vals->volume = (double)( metric_vals->jacobian / 6.0 );
926  }
927 
928  // calculate aspect ratio
929  if( metrics_request_flag & V_TET_ASPECT_BETA )
930  {
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() ) *
933  0.5;
934 
935  VerdictVector numerator = edges[3].length_squared() * ( edges[2] * edges[0] ) +
936  edges[2].length_squared() * ( edges[3] * edges[0] ) +
937  edges[0].length_squared() * ( edges[3] * edges[2] );
938 
939  double volume = metric_vals->jacobian / 6.0;
940 
941  if( volume < VERDICT_DBL_MIN )
942  metric_vals->aspect_beta = (double)( VERDICT_DBL_MAX );
943  else
944  metric_vals->aspect_beta = (double)( numerator.length() * surface_area / ( 108 * volume * volume ) );
945  }
946 
947  // calculate the aspect gamma
948  if( metrics_request_flag & V_TET_ASPECT_GAMMA )
949  {
950  double volume = fabs( metric_vals->jacobian / 6.0 );
951  if( fabs( volume ) < VERDICT_DBL_MIN )
952  metric_vals->aspect_gamma = VERDICT_DBL_MAX;
953  else
954  {
955  double srms = sqrt( ( edges[0].length_squared() + edges[1].length_squared() + edges[2].length_squared() +
956  edges[3].length_squared() + edges[4].length_squared() + edges[5].length_squared() ) /
957  6.0 );
958 
959  // cube the srms
960  srms *= ( srms * srms );
961  metric_vals->aspect_gamma = (double)( srms / ( 8.48528137423857 * volume ) );
962  }
963  }
964 
965  // calculate the shape of the tet
966  if( metrics_request_flag & ( V_TET_SHAPE | V_TET_SHAPE_AND_SIZE ) )
967  {
968  // if the jacobian is non-positive, the shape is 0
969  if( metric_vals->jacobian < VERDICT_DBL_MIN )
970  {
971  metric_vals->shape = (double)0.0;
972  }
973  else
974  {
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] );
979 
980  if( den < VERDICT_DBL_MIN )
981  metric_vals->shape = (double)0.0;
982  else
983  metric_vals->shape = (double)VERDICT_MAX( num / den, 0 );
984  }
985  }
986 
987  // calculate the relative size of the tet
988  if( metrics_request_flag & ( V_TET_RELATIVE_SIZE_SQUARED | V_TET_SHAPE_AND_SIZE ) )
989  {
990  VerdictVector w1, w2, w3;
991  get_weight( w1, w2, w3 );
992  double avg_vol = ( w1 % ( w2 * w3 ) ) / 6;
993 
994  if( avg_vol < VERDICT_DBL_MIN )
995  metric_vals->relative_size_squared = 0.0;
996  else
997  {
998  double tmp = metric_vals->jacobian / ( 6 * avg_vol );
999  if( tmp < VERDICT_DBL_MIN )
1000  metric_vals->relative_size_squared = 0.0;
1001  else
1002  {
1003  tmp *= tmp;
1004  metric_vals->relative_size_squared = (double)VERDICT_MIN( tmp, 1 / tmp );
1005  }
1006  }
1007  }
1008 
1009  // calculate the shape and size
1010  if( metrics_request_flag & V_TET_SHAPE_AND_SIZE )
1011  {
1012  metric_vals->shape_and_size = (double)( metric_vals->shape * metric_vals->relative_size_squared );
1013  }
1014 
1015  // calculate the scaled jacobian
1016  if( metrics_request_flag & V_TET_SCALED_JACOBIAN )
1017  {
1018  // find out which node the normalized jacobian can be calculated at
1019  // and it will be the smaller than at other nodes
1020  double length_squared[4] = { edges[0].length_squared() * edges[2].length_squared() * edges[3].length_squared(),
1021  edges[0].length_squared() * edges[1].length_squared() * edges[4].length_squared(),
1022  edges[1].length_squared() * edges[2].length_squared() * edges[5].length_squared(),
1023  edges[3].length_squared() * edges[4].length_squared() *
1024  edges[5].length_squared() };
1025 
1026  int which_node = 0;
1027  if( length_squared[1] > length_squared[which_node] ) which_node = 1;
1028  if( length_squared[2] > length_squared[which_node] ) which_node = 2;
1029  if( length_squared[3] > length_squared[which_node] ) which_node = 3;
1030 
1031  // find the scaled jacobian at this node
1032  double length_product = sqrt( length_squared[which_node] );
1033  if( length_product < fabs( metric_vals->jacobian ) ) length_product = fabs( metric_vals->jacobian );
1034 
1035  if( length_product < VERDICT_DBL_MIN )
1036  metric_vals->scaled_jacobian = (double)VERDICT_DBL_MAX;
1037  else
1038  metric_vals->scaled_jacobian = (double)( root_of_2 * metric_vals->jacobian / length_product );
1039  }
1040 
1041  // calculate the condition number
1042  if( metrics_request_flag & V_TET_CONDITION )
1043  {
1044  static const double root_of_3 = sqrt( 3.0 );
1045  static const double root_of_6 = sqrt( 6.0 );
1046 
1047  VerdictVector c_1, c_2, c_3;
1048  c_1 = edges[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;
1051 
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 );
1054 
1055  double det = c_1 % ( c_2 * c_3 );
1056 
1057  if( det <= VERDICT_DBL_MIN )
1058  metric_vals->condition = (double)VERDICT_DBL_MAX;
1059  else
1060  metric_vals->condition = (double)( sqrt( term1 * term2 ) / ( 3.0 * det ) );
1061  }
1062 
1063  // calculate the distortion
1064  if( metrics_request_flag & V_TET_DISTORTION )
1065  {
1066  metric_vals->distortion = v_tet_distortion( num_nodes, coordinates );
1067  }
1068 
1069  // check for overflow
1070  if( metrics_request_flag & V_TET_ASPECT_BETA )
1071  {
1072  if( metric_vals->aspect_beta > 0 )
1073  metric_vals->aspect_beta = (double)VERDICT_MIN( metric_vals->aspect_beta, VERDICT_DBL_MAX );
1074  metric_vals->aspect_beta = (double)VERDICT_MAX( metric_vals->aspect_beta, -VERDICT_DBL_MAX );
1075  }
1076 
1077  if( metrics_request_flag & V_TET_ASPECT_GAMMA )
1078  {
1079  if( metric_vals->aspect_gamma > 0 )
1080  metric_vals->aspect_gamma = (double)VERDICT_MIN( metric_vals->aspect_gamma, VERDICT_DBL_MAX );
1081  metric_vals->aspect_gamma = (double)VERDICT_MAX( metric_vals->aspect_gamma, -VERDICT_DBL_MAX );
1082  }
1083 
1084  if( metrics_request_flag & V_TET_VOLUME )
1085  {
1086  if( metric_vals->volume > 0 ) metric_vals->volume = (double)VERDICT_MIN( metric_vals->volume, VERDICT_DBL_MAX );
1087  metric_vals->volume = (double)VERDICT_MAX( metric_vals->volume, -VERDICT_DBL_MAX );
1088  }
1089 
1090  if( metrics_request_flag & V_TET_CONDITION )
1091  {
1092  if( metric_vals->condition > 0 )
1093  metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX );
1094  metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX );
1095  }
1096 
1097  if( metrics_request_flag & V_TET_JACOBIAN )
1098  {
1099  if( metric_vals->jacobian > 0 )
1100  metric_vals->jacobian = (double)VERDICT_MIN( metric_vals->jacobian, VERDICT_DBL_MAX );
1101  metric_vals->jacobian = (double)VERDICT_MAX( metric_vals->jacobian, -VERDICT_DBL_MAX );
1102  }
1103 
1104  if( metrics_request_flag & V_TET_SCALED_JACOBIAN )
1105  {
1106  if( metric_vals->scaled_jacobian > 0 )
1107  metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX );
1108  metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX );
1109  }
1110 
1111  if( metrics_request_flag & V_TET_SHAPE )
1112  {
1113  if( metric_vals->shape > 0 ) metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX );
1114  metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX );
1115  }
1116 
1117  if( metrics_request_flag & V_TET_RELATIVE_SIZE_SQUARED )
1118  {
1119  if( metric_vals->relative_size_squared > 0 )
1120  metric_vals->relative_size_squared =
1121  (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX );
1122  metric_vals->relative_size_squared =
1123  (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX );
1124  }
1125 
1126  if( metrics_request_flag & V_TET_SHAPE_AND_SIZE )
1127  {
1128  if( metric_vals->shape_and_size > 0 )
1129  metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX );
1130  metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX );
1131  }
1132 
1133  if( metrics_request_flag & V_TET_DISTORTION )
1134  {
1135  if( metric_vals->distortion > 0 )
1136  metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX );
1137  metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX );
1138  }
1139 
1140  if( metrics_request_flag & V_TET_ASPECT_RATIO ) metric_vals->aspect_ratio = v_tet_aspect_ratio( 4, coordinates );
1141 
1142  if( metrics_request_flag & V_TET_ASPECT_FROBENIUS )
1143  metric_vals->aspect_frobenius = v_tet_aspect_frobenius( 4, coordinates );
1144 
1145  if( metrics_request_flag & V_TET_MINIMUM_ANGLE ) metric_vals->minimum_angle = v_tet_minimum_angle( 4, coordinates );
1146 
1147  if( metrics_request_flag & V_TET_COLLAPSE_RATIO )
1148  metric_vals->collapse_ratio = v_tet_collapse_ratio( 4, coordinates );
1149 
1150  if( metrics_request_flag & V_TET_RADIUS_RATIO ) metric_vals->radius_ratio = v_tet_radius_ratio( 4, coordinates );
1151 }

References TetMetricVals::aspect_beta, TetMetricVals::aspect_frobenius, TetMetricVals::aspect_gamma, TetMetricVals::aspect_ratio, TetMetricVals::collapse_ratio, TetMetricVals::condition, TetMetricVals::distortion, get_weight(), TetMetricVals::jacobian, VerdictVector::length(), length(), VerdictVector::length_squared(), length_squared(), TetMetricVals::minimum_angle, TetMetricVals::radius_ratio, TetMetricVals::relative_size_squared, TetMetricVals::scaled_jacobian, VerdictVector::set(), TetMetricVals::shape, TetMetricVals::shape_and_size, V_TET_ASPECT_BETA, V_TET_ASPECT_FROBENIUS, v_tet_aspect_frobenius(), V_TET_ASPECT_GAMMA, V_TET_ASPECT_RATIO, v_tet_aspect_ratio(), V_TET_COLLAPSE_RATIO, v_tet_collapse_ratio(), V_TET_CONDITION, V_TET_DISTORTION, v_tet_distortion(), V_TET_JACOBIAN, V_TET_MINIMUM_ANGLE, v_tet_minimum_angle(), V_TET_RADIUS_RATIO, v_tet_radius_ratio(), V_TET_RELATIVE_SIZE_SQUARED, V_TET_SCALED_JACOBIAN, V_TET_SHAPE, V_TET_SHAPE_AND_SIZE, V_TET_VOLUME, VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, VERDICT_MIN, and TetMetricVals::volume.

Referenced by moab::VerdictWrapper::all_quality_measures().

◆ v_tet_radius_ratio()

C_FUNC_DEF double v_tet_radius_ratio ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet radius ratio metric.

The radius ratio of a tet

NB (P. Pebay 04/16/07): CR / (3.0 * IR) where CR is the circumsphere radius and IR is the inscribed sphere radius. Note that this metric is similar to the aspect beta of a tet, except that it does not return VERDICT_DBL_MAX if the element has negative orientation.

Definition at line 209 of file V_TetMetric.cpp.

210 {
211 
212  // Determine side vectors
213  VerdictVector side[6];
214 
215  side[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
216  coordinates[1][2] - coordinates[0][2] );
217 
218  side[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
219  coordinates[2][2] - coordinates[1][2] );
220 
221  side[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
222  coordinates[0][2] - coordinates[2][2] );
223 
224  side[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
225  coordinates[3][2] - coordinates[0][2] );
226 
227  side[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
228  coordinates[3][2] - coordinates[1][2] );
229 
230  side[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
231  coordinates[3][2] - coordinates[2][2] );
232 
233  VerdictVector numerator = side[3].length_squared() * ( side[2] * side[0] ) +
234  side[2].length_squared() * ( side[3] * side[0] ) +
235  side[0].length_squared() * ( side[3] * side[2] );
236 
237  double area_sum;
238  area_sum = ( ( side[2] * side[0] ).length() + ( side[3] * side[0] ).length() + ( side[4] * side[1] ).length() +
239  ( side[3] * side[2] ).length() ) *
240  0.5;
241 
242  double volume = v_tet_volume( 4, coordinates );
243 
244  if( fabs( volume ) < VERDICT_DBL_MIN )
245  return (double)VERDICT_DBL_MAX;
246  else
247  {
248  double radius_ratio;
249  radius_ratio = numerator.length() * area_sum / ( 108 * volume * volume );
250 
251  return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX );
252  }
253 }

References VerdictVector::length(), length(), VerdictVector::length_squared(), length_squared(), VerdictVector::set(), v_tet_volume(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_quality().

◆ v_tet_relative_size_squared()

C_FUNC_DEF double v_tet_relative_size_squared ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet relative size metric.

the relative size of a tet

Min(J,1/J), where J is the determinant of the weighted Jacobian matrix

Definition at line 727 of file V_TetMetric.cpp.

728 {
729  double size;
730  VerdictVector w1, w2, w3;
731  get_weight( w1, w2, w3 );
732  double avg_volume = ( w1 % ( w2 * w3 ) ) / 6.0;
733 
734  double volume = v_tet_volume( 4, coordinates );
735 
736  if( avg_volume < VERDICT_DBL_MIN )
737  return 0.0;
738  else
739  {
740  size = volume / avg_volume;
741  if( size <= VERDICT_DBL_MIN ) return 0.0;
742  if( size > 1 ) size = (double)( 1 ) / size;
743  }
744  return (double)( size * size );
745 }

References get_weight(), size, v_tet_volume(), and VERDICT_DBL_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_shape_and_size().

◆ v_tet_scaled_jacobian()

C_FUNC_DEF double v_tet_scaled_jacobian ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet scaled jacobian.

the scaled jacobian of a tet

minimum of the jacobian divided by the lengths of 3 edge vectors

Definition at line 153 of file V_TetMetric.cpp.

154 {
155 
156  VerdictVector side0, side1, side2, side3, side4, side5;
157 
158  side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
159  coordinates[1][2] - coordinates[0][2] );
160 
161  side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
162  coordinates[2][2] - coordinates[1][2] );
163 
164  side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
165  coordinates[0][2] - coordinates[2][2] );
166 
167  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
168  coordinates[3][2] - coordinates[0][2] );
169 
170  side4.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
171  coordinates[3][2] - coordinates[1][2] );
172 
173  side5.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
174  coordinates[3][2] - coordinates[2][2] );
175 
176  double jacobi;
177 
178  jacobi = side3 % ( side2 * side0 );
179 
180  // products of lengths squared of each edge attached to a node.
181  double length_squared[4] = { side0.length_squared() * side2.length_squared() * side3.length_squared(),
182  side0.length_squared() * side1.length_squared() * side4.length_squared(),
183  side1.length_squared() * side2.length_squared() * side5.length_squared(),
184  side3.length_squared() * side4.length_squared() * side5.length_squared() };
185  int which_node = 0;
186  if( length_squared[1] > length_squared[which_node] ) which_node = 1;
187  if( length_squared[2] > length_squared[which_node] ) which_node = 2;
188  if( length_squared[3] > length_squared[which_node] ) which_node = 3;
189 
190  double length_product = sqrt( length_squared[which_node] );
191  if( length_product < fabs( jacobi ) ) length_product = fabs( jacobi );
192 
193  if( length_product < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
194 
195  static const double root_of_2 = sqrt( 2.0 );
196 
197  return (double)( root_of_2 * jacobi / length_product );
198 }

References VerdictVector::length_squared(), length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_shape()

C_FUNC_DEF double v_tet_shape ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet shape metric.

the shape of a tet

3/ condition number of weighted jacobian matrix

Definition at line 691 of file V_TetMetric.cpp.

692 {
693 
694  static const double two_thirds = 2.0 / 3.0;
695  static const double root_of_2 = sqrt( 2.0 );
696 
697  VerdictVector edge0, edge2, edge3;
698 
699  edge0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
700  coordinates[1][2] - coordinates[0][2] );
701 
702  edge2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
703  coordinates[0][2] - coordinates[2][2] );
704 
705  edge3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
706  coordinates[3][2] - coordinates[0][2] );
707 
708  double jacobian = edge3 % ( edge2 * edge0 );
709  if( jacobian < VERDICT_DBL_MIN )
710  {
711  return (double)0.0;
712  }
713  double num = 3 * pow( root_of_2 * jacobian, two_thirds );
714  double den =
715  1.5 * ( edge0 % edge0 + edge2 % edge2 + edge3 % edge3 ) - ( edge0 % -edge2 + -edge2 % edge3 + edge3 % edge0 );
716 
717  if( den < VERDICT_DBL_MIN ) return (double)0.0;
718 
719  return (double)VERDICT_MAX( num / den, 0 );
720 }

References VerdictVector::set(), VERDICT_DBL_MIN, and VERDICT_MAX.

Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_shape_and_size().

◆ v_tet_shape_and_size()

C_FUNC_DEF double v_tet_shape_and_size ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet shape-size metric.

the shape and size of a tet

Product of the shape and relative size

Definition at line 752 of file V_TetMetric.cpp.

753 {
754 
755  double shape, size;
756  shape = v_tet_shape( num_nodes, coordinates );
757  size = v_tet_relative_size_squared( num_nodes, coordinates );
758 
759  return (double)( shape * size );
760 }

References size, v_tet_relative_size_squared(), and v_tet_shape().

Referenced by moab::VerdictWrapper::quality_measure().

◆ v_tet_volume()

C_FUNC_DEF double v_tet_volume ( int  num_nodes,
double  coordinates[][3] 
)

Calculates tet volume.

the volume of a tet

1/6 * jacobian at a corner node

Definition at line 606 of file V_TetMetric.cpp.

607 {
608 
609  // Determine side vectors
610  VerdictVector side0, side2, side3;
611 
612  side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
613  coordinates[1][2] - coordinates[0][2] );
614 
615  side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1],
616  coordinates[0][2] - coordinates[2][2] );
617 
618  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
619  coordinates[3][2] - coordinates[0][2] );
620 
621  return (double)( ( side3 % ( side2 * side0 ) ) / 6.0 );
622 }

References VerdictVector::set().

Referenced by moab::VerdictWrapper::quality_measure(), v_tet_aspect_beta(), v_tet_aspect_gamma(), v_tet_radius_ratio(), and v_tet_relative_size_squared().

Variable Documentation

◆ verdict_tet_size

double verdict_tet_size = 0

the average volume of a tet

Definition at line 32 of file V_TetMetric.cpp.

Referenced by get_weight(), and v_set_tet_size().