Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include "moab/verdict.h"
#include "verdict_defines.hpp"
#include "VerdictVector.hpp"
#include "V_GaussIntegration.hpp"
#include <memory.h>
Go to the source code of this file.
Defines | |
#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(...) | |
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. | |
C_FUNC_DEF double | v_tet_scaled_jacobian (int, double coordinates[][3]) |
Calculates tet scaled jacobian. | |
C_FUNC_DEF double | v_tet_radius_ratio (int, double coordinates[][3]) |
Calculates tet radius ratio metric. | |
C_FUNC_DEF double | v_tet_aspect_beta (int, double coordinates[][3]) |
Calculates the radius ratio metric of a positively oriented tet. | |
C_FUNC_DEF double | v_tet_aspect_ratio (int, double coordinates[][3]) |
Calculates tet aspect ratio metric. | |
C_FUNC_DEF double | v_tet_aspect_gamma (int, double coordinates[][3]) |
Calculates tet aspect gamma metric. | |
C_FUNC_DEF double | v_tet_aspect_frobenius (int, double coordinates[][3]) |
Calculates tet aspect frobenius metric. | |
C_FUNC_DEF double | v_tet_minimum_angle (int, double coordinates[][3]) |
Calculates tet minimum dihedral angle. | |
C_FUNC_DEF double | v_tet_collapse_ratio (int, double coordinates[][3]) |
Calculates tet collapse ratio metric. | |
C_FUNC_DEF double | v_tet_volume (int, double coordinates[][3]) |
Calculates tet volume. | |
C_FUNC_DEF double | v_tet_condition (int, double coordinates[][3]) |
Calculates tet condition metric. | |
C_FUNC_DEF double | v_tet_jacobian (int, double coordinates[][3]) |
Calculates tet jacobian. | |
C_FUNC_DEF double | v_tet_shape (int, double coordinates[][3]) |
Calculates tet shape metric. | |
C_FUNC_DEF double | v_tet_relative_size_squared (int, double coordinates[][3]) |
Calculates tet relative size metric. | |
C_FUNC_DEF double | v_tet_shape_and_size (int num_nodes, double coordinates[][3]) |
Calculates tet shape-size metric. | |
C_FUNC_DEF double | v_tet_distortion (int num_nodes, double coordinates[][3]) |
Calculates tet distortion metric. | |
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. | |
Variables | |
double | verdict_tet_size = 0 |
the average volume of a tet |
#define VERDICT_EXPORTS |
Definition at line 23 of file V_TetMetric.cpp.
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.
References determinant(), VerdictVector::set(), and verdict_tet_size.
{ static const double rt3 = sqrt( 3.0 ); static const double root_of_2 = sqrt( 2.0 ); w1.set( 1, 0, 0 ); w2.set( 0.5, 0.5 * rt3, 0 ); w3.set( 0.5, rt3 / 6.0, root_of_2 / rt3 ); double scale = pow( 6. * verdict_tet_size / determinant( w1, w2, w3 ), 0.3333333333333 ); w1 *= scale; w2 *= scale; w3 *= scale; return 1; }
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.
References size, and verdict_tet_size.
Referenced by moab::VerdictWrapper::set_size().
{ verdict_tet_size = size; }
C_FUNC_DEF double v_tet_aspect_beta | ( | int | , |
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.
References length(), VerdictVector::length(), length_squared(), VerdictVector::length_squared(), VerdictVector::set(), v_tet_volume(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
{ // Determine side vectors VerdictVector side[6]; side[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); side[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); side[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); side[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); VerdictVector numerator = side[3].length_squared() * ( side[2] * side[0] ) + side[2].length_squared() * ( side[3] * side[0] ) + side[0].length_squared() * ( side[3] * side[2] ); double area_sum; area_sum = ( ( side[2] * side[0] ).length() + ( side[3] * side[0] ).length() + ( side[4] * side[1] ).length() + ( side[3] * side[2] ).length() ) * 0.5; double volume = v_tet_volume( 4, coordinates ); if( volume < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; else { double radius_ratio; radius_ratio = numerator.length() * area_sum / ( 108 * volume * volume ); return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX ); } }
C_FUNC_DEF double v_tet_aspect_frobenius | ( | int | , |
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.
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().
{ static const double normal_exp = 1. / 3.; VerdictVector ab, ac, ad; ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); ac.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], coordinates[2][2] - coordinates[0][2] ); ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); double denominator = ab % ( ac * ad ); denominator *= denominator; denominator *= 2.; denominator = 3. * pow( denominator, normal_exp ); if( denominator < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; double u[3]; ab.get_xyz( u ); double v[3]; ac.get_xyz( v ); double w[3]; ad.get_xyz( w ); double numerator = u[0] * u[0] + u[1] * u[1] + u[2] * u[2]; numerator += v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; numerator += w[0] * w[0] + w[1] * w[1] + w[2] * w[2]; numerator *= 1.5; numerator -= v[0] * u[0] + v[1] * u[1] + v[2] * u[2]; numerator -= w[0] * u[0] + w[1] * u[1] + w[2] * u[2]; numerator -= w[0] * v[0] + w[1] * v[1] + w[2] * v[2]; double aspect_frobenius = numerator / denominator; if( aspect_frobenius > 0 ) return (double)VERDICT_MIN( aspect_frobenius, VERDICT_DBL_MAX ); return (double)VERDICT_MAX( aspect_frobenius, -VERDICT_DBL_MAX ); }
C_FUNC_DEF double v_tet_aspect_gamma | ( | int | , |
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.
References VerdictVector::length_squared(), VerdictVector::set(), v_tet_volume(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
{ // Determine side vectors VerdictVector side0, side1, side2, side3, side4, side5; side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); side4.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); side5.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); double volume = fabs( v_tet_volume( 4, coordinates ) ); if( volume < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; else { double srms = sqrt( ( side0.length_squared() + side1.length_squared() + side2.length_squared() + side3.length_squared() + side4.length_squared() + side5.length_squared() ) / 6.0 ); double aspect_ratio_gamma = pow( srms, 3 ) / ( 8.48528137423857 * volume ); return (double)aspect_ratio_gamma; } }
C_FUNC_DEF double v_tet_aspect_ratio | ( | int | , |
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.
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().
{ static const double normal_coeff = sqrt( 6. ) / 12.; // Determine side vectors VerdictVector ab, bc, ac, ad, bd, cd; ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); ac.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], coordinates[2][2] - coordinates[0][2] ); ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); double detTet = ab % ( ac * ad ); if( detTet < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; bc.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); bd.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); cd.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); double ab2 = ab.length_squared(); double bc2 = bc.length_squared(); double ac2 = ac.length_squared(); double ad2 = ad.length_squared(); double bd2 = bd.length_squared(); double cd2 = cd.length_squared(); double A = ab2 > bc2 ? ab2 : bc2; double B = ac2 > ad2 ? ac2 : ad2; double C = bd2 > cd2 ? bd2 : cd2; double D = A > B ? A : B; double hm = D > C ? sqrt( D ) : sqrt( C ); bd = ab * bc; A = bd.length(); bd = ab * ad; B = bd.length(); bd = ac * ad; C = bd.length(); bd = bc * cd; D = bd.length(); double aspect_ratio; aspect_ratio = normal_coeff * hm * ( A + B + C + D ) / fabs( detTet ); if( aspect_ratio > 0 ) return (double)VERDICT_MIN( aspect_ratio, VERDICT_DBL_MAX ); return (double)VERDICT_MAX( aspect_ratio, -VERDICT_DBL_MAX ); }
C_FUNC_DEF double v_tet_collapse_ratio | ( | int | , |
double | coordinates[][3] | ||
) |
Calculates tet collapse ratio metric.
The collapse ratio of a tet
Definition at line 526 of file V_TetMetric.cpp.
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().
{ // Determine side vectors VerdictVector e01, e02, e03, e12, e13, e23; e01.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); e02.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], coordinates[2][2] - coordinates[0][2] ); e03.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); e12.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); e13.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); e23.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); double l[6]; l[0] = e01.length(); l[1] = e02.length(); l[2] = e03.length(); l[3] = e12.length(); l[4] = e13.length(); l[5] = e23.length(); // Find longest edge for each bounding triangle of tetrahedron double l012 = l[4] > l[0] ? l[4] : l[0]; l012 = l[1] > l012 ? l[1] : l012; double l031 = l[0] > l[2] ? l[0] : l[2]; l031 = l[3] > l031 ? l[3] : l031; double l023 = l[2] > l[1] ? l[2] : l[1]; l023 = l[5] > l023 ? l[5] : l023; double l132 = l[4] > l[3] ? l[4] : l[3]; l132 = l[5] > l132 ? l[5] : l132; // Compute collapse ratio for each vertex/triangle pair VerdictVector N; double h, magN; double cr; double crMin; N = e01 * e02; magN = N.length(); h = ( e03 % N ) / magN; // height of vertex 3 above 0-1-2 crMin = h / l012; // ratio of height to longest edge of 0-1-2 N = e03 * e01; magN = N.length(); h = ( e02 % N ) / magN; // height of vertex 2 above 0-3-1 cr = h / l031; // ratio of height to longest edge of 0-3-1 if( cr < crMin ) crMin = cr; N = e02 * e03; magN = N.length(); h = ( e01 % N ) / magN; // height of vertex 1 above 0-2-3 cr = h / l023; // ratio of height to longest edge of 0-2-3 if( cr < crMin ) crMin = cr; N = e12 * e13; magN = N.length(); h = ( e01 % N ) / magN; // height of vertex 0 above 1-3-2 cr = h / l132; // ratio of height to longest edge of 1-3-2 if( cr < crMin ) crMin = cr; if( crMin < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; if( crMin > 0 ) return (double)VERDICT_MIN( crMin, VERDICT_DBL_MAX ); return (double)VERDICT_MAX( crMin, -VERDICT_DBL_MAX ); }
C_FUNC_DEF double v_tet_condition | ( | int | , |
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.
References VerdictVector::set(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
{ double condition, term1, term2, det; double rt3 = sqrt( 3.0 ); double rt6 = sqrt( 6.0 ); VerdictVector side0, side2, side3; side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); VerdictVector c_1, c_2, c_3; c_1 = side0; c_2 = ( -2 * side2 - side0 ) / rt3; c_3 = ( 3 * side3 + side2 - side0 ) / rt6; term1 = c_1 % c_1 + c_2 % c_2 + c_3 % c_3; 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 ); det = c_1 % ( c_2 * c_3 ); if( det <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX; else condition = sqrt( term1 * term2 ) / ( 3.0 * det ); return (double)condition; }
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.
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().
{ double distortion = VERDICT_DBL_MAX; int number_of_gauss_points = 0; if( num_nodes == 4 ) // for linear tet, the distortion is always 1 because // straight edge tets are the target shape for tet return 1.0; else if( num_nodes == 10 ) // use four integration points for quadratic tet number_of_gauss_points = 4; int number_dims = 3; int total_number_of_gauss_points = number_of_gauss_points; // use is_tri=1 to indicate this is for tet in 3D int is_tri = 1; double shape_function[maxTotalNumberGaussPoints][maxNumberNodes]; double dndy1[maxTotalNumberGaussPoints][maxNumberNodes]; double dndy2[maxTotalNumberGaussPoints][maxNumberNodes]; double dndy3[maxTotalNumberGaussPoints][maxNumberNodes]; double weight[maxTotalNumberGaussPoints]; // create an object of GaussIntegration for tet GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dims, is_tri ); GaussIntegration::calculate_shape_function_3d_tet(); GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], dndy3[0], weight ); // vector xxi is the derivative vector of coordinates w.r.t local xi coordinate in the // computation space // vector xet is the derivative vector of coordinates w.r.t local et coordinate in the // computation space // vector xze is the derivative vector of coordinates w.r.t local ze coordinate in the // computation space VerdictVector xxi, xet, xze, xin; double jacobian, minimum_jacobian; double element_volume = 0.0; minimum_jacobian = VERDICT_DBL_MAX; // calculate element volume int ife, ja; for( ife = 0; ife < total_number_of_gauss_points; ife++ ) { xxi.set( 0.0, 0.0, 0.0 ); xet.set( 0.0, 0.0, 0.0 ); xze.set( 0.0, 0.0, 0.0 ); for( ja = 0; ja < num_nodes; ja++ ) { xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); xxi += dndy1[ife][ja] * xin; xet += dndy2[ife][ja] * xin; xze += dndy3[ife][ja] * xin; } // determinant jacobian = xxi % ( xet * xze ); if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian; element_volume += weight[ife] * jacobian; } // element_volume is 6 times the actual volume // loop through all nodes double dndy1_at_node[maxNumberNodes][maxNumberNodes]; double dndy2_at_node[maxNumberNodes][maxNumberNodes]; double dndy3_at_node[maxNumberNodes][maxNumberNodes]; GaussIntegration::calculate_derivative_at_nodes_3d_tet( dndy1_at_node, dndy2_at_node, dndy3_at_node ); int node_id; for( node_id = 0; node_id < num_nodes; node_id++ ) { xxi.set( 0.0, 0.0, 0.0 ); xet.set( 0.0, 0.0, 0.0 ); xze.set( 0.0, 0.0, 0.0 ); for( ja = 0; ja < num_nodes; ja++ ) { xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); xxi += dndy1_at_node[node_id][ja] * xin; xet += dndy2_at_node[node_id][ja] * xin; xze += dndy3_at_node[node_id][ja] * xin; } jacobian = xxi % ( xet * xze ); if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian; } distortion = minimum_jacobian / element_volume; return (double)distortion; }
C_FUNC_DEF double v_tet_edge_ratio | ( | int | , |
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.
References VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
{ VerdictVector a, b, c, d, e, f; a.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); b.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); c.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); d.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); e.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); f.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); double a2 = a.length_squared(); double b2 = b.length_squared(); double c2 = c.length_squared(); double d2 = d.length_squared(); double e2 = e.length_squared(); double f2 = f.length_squared(); double m2, M2, mab, mcd, mef, Mab, Mcd, Mef; if( a2 < b2 ) { mab = a2; Mab = b2; } else // b2 <= a2 { mab = b2; Mab = a2; } if( c2 < d2 ) { mcd = c2; Mcd = d2; } else // d2 <= c2 { mcd = d2; Mcd = c2; } if( e2 < f2 ) { mef = e2; Mef = f2; } else // f2 <= e2 { mef = f2; Mef = e2; } m2 = mab < mcd ? mab : mcd; m2 = m2 < mef ? m2 : mef; if( m2 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; M2 = Mab > Mcd ? Mab : Mcd; M2 = M2 > Mef ? M2 : Mef; double edge_ratio = sqrt( M2 / m2 ); if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX ); return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX ); }
C_FUNC_DEF double v_tet_jacobian | ( | int | , |
double | coordinates[][3] | ||
) |
Calculates tet jacobian.
the jacobian of a tet
TODO
Definition at line 670 of file V_TetMetric.cpp.
References VerdictVector::set().
Referenced by moab::VerdictWrapper::quality_measure().
{ VerdictVector side0, side2, side3; side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); return (double)( side3 % ( side2 * side0 ) ); }
C_FUNC_DEF double v_tet_minimum_angle | ( | int | , |
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.
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().
{ static const double normal_coeff = 180. * .3183098861837906715377675267450287; // Determine side vectors VerdictVector ab, bc, ad, cd; ab.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); ad.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); bc.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); cd.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); VerdictVector abc = ab * bc; double nabc = abc.length(); VerdictVector abd = ab * ad; double nabd = abd.length(); VerdictVector acd = ad * cd; double nacd = acd.length(); VerdictVector bcd = bc * cd; double nbcd = bcd.length(); double alpha = acos( ( abc % abd ) / ( nabc * nabd ) ); double beta = acos( ( abc % acd ) / ( nabc * nacd ) ); double gamma = acos( ( abc % bcd ) / ( nabc * nbcd ) ); double delta = acos( ( abd % acd ) / ( nabd * nacd ) ); double epsilon = acos( ( abd % bcd ) / ( nabd * nbcd ) ); double zeta = acos( ( acd % bcd ) / ( nacd * nbcd ) ); alpha = alpha < beta ? alpha : beta; alpha = alpha < gamma ? alpha : gamma; alpha = alpha < delta ? alpha : delta; alpha = alpha < epsilon ? alpha : epsilon; alpha = alpha < zeta ? alpha : zeta; alpha *= normal_coeff; if( alpha < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; if( alpha > 0 ) return (double)VERDICT_MIN( alpha, VERDICT_DBL_MAX ); return (double)VERDICT_MAX( alpha, -VERDICT_DBL_MAX ); }
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.
References TetMetricVals::aspect_beta, TetMetricVals::aspect_frobenius, TetMetricVals::aspect_gamma, TetMetricVals::aspect_ratio, TetMetricVals::collapse_ratio, TetMetricVals::condition, TetMetricVals::distortion, get_weight(), TetMetricVals::jacobian, length(), VerdictVector::length(), length_squared(), VerdictVector::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().
{ memset( metric_vals, 0, sizeof( TetMetricVals ) ); /* node numbers and edge numbers below 3 + edge 0 is node 0 to 1 +|+ edge 1 is node 1 to 2 3/ | \5 edge 2 is node 0 to 2 / 4| \ edge 3 is node 0 to 3 0 - -|- + 2 edge 4 is node 1 to 3 \ | + edge 5 is node 2 to 3 0\ | /1 +|/ edge 2 is behind edge 4 1 */ // lets start with making the vectors VerdictVector edges[6]; edges[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); edges[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); edges[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); edges[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); edges[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); edges[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); // common numbers static const double root_of_2 = sqrt( 2.0 ); // calculate the jacobian static const int do_jacobian = V_TET_JACOBIAN | V_TET_VOLUME | V_TET_ASPECT_BETA | V_TET_ASPECT_GAMMA | V_TET_SHAPE | V_TET_RELATIVE_SIZE_SQUARED | V_TET_SHAPE_AND_SIZE | V_TET_SCALED_JACOBIAN | V_TET_CONDITION; if( metrics_request_flag & do_jacobian ) { metric_vals->jacobian = (double)( edges[3] % ( edges[2] * edges[0] ) ); } // calculate the volume if( metrics_request_flag & V_TET_VOLUME ) { metric_vals->volume = (double)( metric_vals->jacobian / 6.0 ); } // calculate aspect ratio if( metrics_request_flag & V_TET_ASPECT_BETA ) { double surface_area = ( ( edges[2] * edges[0] ).length() + ( edges[3] * edges[0] ).length() + ( edges[4] * edges[1] ).length() + ( edges[3] * edges[2] ).length() ) * 0.5; VerdictVector numerator = edges[3].length_squared() * ( edges[2] * edges[0] ) + edges[2].length_squared() * ( edges[3] * edges[0] ) + edges[0].length_squared() * ( edges[3] * edges[2] ); double volume = metric_vals->jacobian / 6.0; if( volume < VERDICT_DBL_MIN ) metric_vals->aspect_beta = (double)( VERDICT_DBL_MAX ); else metric_vals->aspect_beta = (double)( numerator.length() * surface_area / ( 108 * volume * volume ) ); } // calculate the aspect gamma if( metrics_request_flag & V_TET_ASPECT_GAMMA ) { double volume = fabs( metric_vals->jacobian / 6.0 ); if( fabs( volume ) < VERDICT_DBL_MIN ) metric_vals->aspect_gamma = VERDICT_DBL_MAX; else { double srms = sqrt( ( edges[0].length_squared() + edges[1].length_squared() + edges[2].length_squared() + edges[3].length_squared() + edges[4].length_squared() + edges[5].length_squared() ) / 6.0 ); // cube the srms srms *= ( srms * srms ); metric_vals->aspect_gamma = (double)( srms / ( 8.48528137423857 * volume ) ); } } // calculate the shape of the tet if( metrics_request_flag & ( V_TET_SHAPE | V_TET_SHAPE_AND_SIZE ) ) { // if the jacobian is non-positive, the shape is 0 if( metric_vals->jacobian < VERDICT_DBL_MIN ) { metric_vals->shape = (double)0.0; } else { static const double two_thirds = 2.0 / 3.0; double num = 3.0 * pow( root_of_2 * metric_vals->jacobian, two_thirds ); double den = 1.5 * ( edges[0] % edges[0] + edges[2] % edges[2] + edges[3] % edges[3] ) - ( edges[0] % -edges[2] + -edges[2] % edges[3] + edges[3] % edges[0] ); if( den < VERDICT_DBL_MIN ) metric_vals->shape = (double)0.0; else metric_vals->shape = (double)VERDICT_MAX( num / den, 0 ); } } // calculate the relative size of the tet if( metrics_request_flag & ( V_TET_RELATIVE_SIZE_SQUARED | V_TET_SHAPE_AND_SIZE ) ) { VerdictVector w1, w2, w3; get_weight( w1, w2, w3 ); double avg_vol = ( w1 % ( w2 * w3 ) ) / 6; if( avg_vol < VERDICT_DBL_MIN ) metric_vals->relative_size_squared = 0.0; else { double tmp = metric_vals->jacobian / ( 6 * avg_vol ); if( tmp < VERDICT_DBL_MIN ) metric_vals->relative_size_squared = 0.0; else { tmp *= tmp; metric_vals->relative_size_squared = (double)VERDICT_MIN( tmp, 1 / tmp ); } } } // calculate the shape and size if( metrics_request_flag & V_TET_SHAPE_AND_SIZE ) { metric_vals->shape_and_size = (double)( metric_vals->shape * metric_vals->relative_size_squared ); } // calculate the scaled jacobian if( metrics_request_flag & V_TET_SCALED_JACOBIAN ) { // find out which node the normalized jacobian can be calculated at // and it will be the smaller than at other nodes double length_squared[4] = { edges[0].length_squared() * edges[2].length_squared() * edges[3].length_squared(), edges[0].length_squared() * edges[1].length_squared() * edges[4].length_squared(), edges[1].length_squared() * edges[2].length_squared() * edges[5].length_squared(), edges[3].length_squared() * edges[4].length_squared() * edges[5].length_squared() }; int which_node = 0; if( length_squared[1] > length_squared[which_node] ) which_node = 1; if( length_squared[2] > length_squared[which_node] ) which_node = 2; if( length_squared[3] > length_squared[which_node] ) which_node = 3; // find the scaled jacobian at this node double length_product = sqrt( length_squared[which_node] ); if( length_product < fabs( metric_vals->jacobian ) ) length_product = fabs( metric_vals->jacobian ); if( length_product < VERDICT_DBL_MIN ) metric_vals->scaled_jacobian = (double)VERDICT_DBL_MAX; else metric_vals->scaled_jacobian = (double)( root_of_2 * metric_vals->jacobian / length_product ); } // calculate the condition number if( metrics_request_flag & V_TET_CONDITION ) { static const double root_of_3 = sqrt( 3.0 ); static const double root_of_6 = sqrt( 6.0 ); VerdictVector c_1, c_2, c_3; c_1 = edges[0]; c_2 = ( -2 * edges[2] - edges[0] ) / root_of_3; c_3 = ( 3 * edges[3] + edges[2] - edges[0] ) / root_of_6; double term1 = c_1 % c_1 + c_2 % c_2 + c_3 % c_3; 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 ); double det = c_1 % ( c_2 * c_3 ); if( det <= VERDICT_DBL_MIN ) metric_vals->condition = (double)VERDICT_DBL_MAX; else metric_vals->condition = (double)( sqrt( term1 * term2 ) / ( 3.0 * det ) ); } // calculate the distortion if( metrics_request_flag & V_TET_DISTORTION ) { metric_vals->distortion = v_tet_distortion( num_nodes, coordinates ); } // check for overflow if( metrics_request_flag & V_TET_ASPECT_BETA ) { if( metric_vals->aspect_beta > 0 ) metric_vals->aspect_beta = (double)VERDICT_MIN( metric_vals->aspect_beta, VERDICT_DBL_MAX ); metric_vals->aspect_beta = (double)VERDICT_MAX( metric_vals->aspect_beta, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_ASPECT_GAMMA ) { if( metric_vals->aspect_gamma > 0 ) metric_vals->aspect_gamma = (double)VERDICT_MIN( metric_vals->aspect_gamma, VERDICT_DBL_MAX ); metric_vals->aspect_gamma = (double)VERDICT_MAX( metric_vals->aspect_gamma, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_VOLUME ) { if( metric_vals->volume > 0 ) metric_vals->volume = (double)VERDICT_MIN( metric_vals->volume, VERDICT_DBL_MAX ); metric_vals->volume = (double)VERDICT_MAX( metric_vals->volume, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_CONDITION ) { if( metric_vals->condition > 0 ) metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX ); metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_JACOBIAN ) { if( metric_vals->jacobian > 0 ) metric_vals->jacobian = (double)VERDICT_MIN( metric_vals->jacobian, VERDICT_DBL_MAX ); metric_vals->jacobian = (double)VERDICT_MAX( metric_vals->jacobian, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_SCALED_JACOBIAN ) { if( metric_vals->scaled_jacobian > 0 ) metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX ); metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_SHAPE ) { if( metric_vals->shape > 0 ) metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX ); metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_RELATIVE_SIZE_SQUARED ) { if( metric_vals->relative_size_squared > 0 ) metric_vals->relative_size_squared = (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX ); metric_vals->relative_size_squared = (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_SHAPE_AND_SIZE ) { if( metric_vals->shape_and_size > 0 ) metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX ); metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_DISTORTION ) { if( metric_vals->distortion > 0 ) metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX ); metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX ); } if( metrics_request_flag & V_TET_ASPECT_RATIO ) metric_vals->aspect_ratio = v_tet_aspect_ratio( 4, coordinates ); if( metrics_request_flag & V_TET_ASPECT_FROBENIUS ) metric_vals->aspect_frobenius = v_tet_aspect_frobenius( 4, coordinates ); if( metrics_request_flag & V_TET_MINIMUM_ANGLE ) metric_vals->minimum_angle = v_tet_minimum_angle( 4, coordinates ); if( metrics_request_flag & V_TET_COLLAPSE_RATIO ) metric_vals->collapse_ratio = v_tet_collapse_ratio( 4, coordinates ); if( metrics_request_flag & V_TET_RADIUS_RATIO ) metric_vals->radius_ratio = v_tet_radius_ratio( 4, coordinates ); }
C_FUNC_DEF double v_tet_radius_ratio | ( | int | , |
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.
References length(), VerdictVector::length(), length_squared(), VerdictVector::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().
{ // Determine side vectors VerdictVector side[6]; side[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); side[2].set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side[3].set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); side[4].set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); side[5].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); VerdictVector numerator = side[3].length_squared() * ( side[2] * side[0] ) + side[2].length_squared() * ( side[3] * side[0] ) + side[0].length_squared() * ( side[3] * side[2] ); double area_sum; area_sum = ( ( side[2] * side[0] ).length() + ( side[3] * side[0] ).length() + ( side[4] * side[1] ).length() + ( side[3] * side[2] ).length() ) * 0.5; double volume = v_tet_volume( 4, coordinates ); if( fabs( volume ) < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; else { double radius_ratio; radius_ratio = numerator.length() * area_sum / ( 108 * volume * volume ); return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX ); } }
C_FUNC_DEF double v_tet_relative_size_squared | ( | int | , |
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.
References get_weight(), size, v_tet_volume(), and VERDICT_DBL_MIN.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_shape_and_size().
{ double size; VerdictVector w1, w2, w3; get_weight( w1, w2, w3 ); double avg_volume = ( w1 % ( w2 * w3 ) ) / 6.0; double volume = v_tet_volume( 4, coordinates ); if( avg_volume < VERDICT_DBL_MIN ) return 0.0; else { size = volume / avg_volume; if( size <= VERDICT_DBL_MIN ) return 0.0; if( size > 1 ) size = (double)( 1 ) / size; } return (double)( size * size ); }
C_FUNC_DEF double v_tet_scaled_jacobian | ( | int | , |
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.
References length_squared(), VerdictVector::length_squared(), VerdictVector::set(), VERDICT_DBL_MAX, and VERDICT_DBL_MIN.
Referenced by moab::VerdictWrapper::quality_measure().
{ VerdictVector side0, side1, side2, side3, side4, side5; side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], coordinates[2][2] - coordinates[1][2] ); side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); side4.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], coordinates[3][2] - coordinates[1][2] ); side5.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], coordinates[3][2] - coordinates[2][2] ); double jacobi; jacobi = side3 % ( side2 * side0 ); // products of lengths squared of each edge attached to a node. double length_squared[4] = { side0.length_squared() * side2.length_squared() * side3.length_squared(), side0.length_squared() * side1.length_squared() * side4.length_squared(), side1.length_squared() * side2.length_squared() * side5.length_squared(), side3.length_squared() * side4.length_squared() * side5.length_squared() }; int which_node = 0; if( length_squared[1] > length_squared[which_node] ) which_node = 1; if( length_squared[2] > length_squared[which_node] ) which_node = 2; if( length_squared[3] > length_squared[which_node] ) which_node = 3; double length_product = sqrt( length_squared[which_node] ); if( length_product < fabs( jacobi ) ) length_product = fabs( jacobi ); if( length_product < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; static const double root_of_2 = sqrt( 2.0 ); return (double)( root_of_2 * jacobi / length_product ); }
C_FUNC_DEF double v_tet_shape | ( | int | , |
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.
References VerdictVector::set(), VERDICT_DBL_MIN, and VERDICT_MAX.
Referenced by moab::VerdictWrapper::quality_measure(), and v_tet_shape_and_size().
{ static const double two_thirds = 2.0 / 3.0; static const double root_of_2 = sqrt( 2.0 ); VerdictVector edge0, edge2, edge3; edge0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); edge2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); edge3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); double jacobian = edge3 % ( edge2 * edge0 ); if( jacobian < VERDICT_DBL_MIN ) { return (double)0.0; } double num = 3 * pow( root_of_2 * jacobian, two_thirds ); double den = 1.5 * ( edge0 % edge0 + edge2 % edge2 + edge3 % edge3 ) - ( edge0 % -edge2 + -edge2 % edge3 + edge3 % edge0 ); if( den < VERDICT_DBL_MIN ) return (double)0.0; return (double)VERDICT_MAX( num / den, 0 ); }
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.
References size, v_tet_relative_size_squared(), and v_tet_shape().
Referenced by moab::VerdictWrapper::quality_measure().
{ double shape, size; shape = v_tet_shape( num_nodes, coordinates ); size = v_tet_relative_size_squared( num_nodes, coordinates ); return (double)( shape * size ); }
C_FUNC_DEF double v_tet_volume | ( | int | , |
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.
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().
{ // Determine side vectors VerdictVector side0, side2, side3; side0.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], coordinates[1][2] - coordinates[0][2] ); side2.set( coordinates[0][0] - coordinates[2][0], coordinates[0][1] - coordinates[2][1], coordinates[0][2] - coordinates[2][2] ); side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], coordinates[3][2] - coordinates[0][2] ); return (double)( ( side3 % ( side2 * side0 ) ) / 6.0 ); }
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().