Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
verdict.h File Reference

Header file for verdict library that calculates metrics for finite elements. Also see: Main Page. More...

+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  HexMetricVals
 
struct  EdgeMetricVals
 
struct  KnifeMetricVals
 
struct  QuadMetricVals
 
struct  PyramidMetricVals
 
struct  WedgeMetricVals
 
struct  TetMetricVals
 
struct  TriMetricVals
 

Macros

#define VERDICT_VERSION   120
 
#define VERDICT_DBL_MIN   1.0E-30
 
#define VERDICT_DBL_MAX   1.0E+30
 
#define VERDICT_PI   3.1415926535897932384626
 
#define C_FUNC_DEF
 
Hex bit fields
#define V_HEX_MAX_EDGE_RATIO
 
#define V_HEX_SKEW
 
#define V_HEX_TAPER
 
#define V_HEX_VOLUME
 
#define V_HEX_STRETCH
 
#define V_HEX_DIAGONAL
 
#define V_HEX_DIMENSION
 
#define V_HEX_ODDY
 
#define V_HEX_MAX_ASPECT_FROBENIUS
 
#define V_HEX_CONDITION
 
#define V_HEX_JACOBIAN
 
#define V_HEX_SCALED_JACOBIAN
 
#define V_HEX_SHEAR
 
#define V_HEX_SHAPE
 
#define V_HEX_RELATIVE_SIZE_SQUARED
 
#define V_HEX_SHAPE_AND_SIZE
 
#define V_HEX_SHEAR_AND_SIZE
 
#define V_HEX_DISTORTION
 
#define V_HEX_EDGE_RATIO
 
#define V_HEX_MED_ASPECT_FROBENIUS
 
#define V_HEX_ALL
 
#define V_HEX_TRADITIONAL
 
#define V_HEX_DIAGNOSTIC
 
#define V_HEX_ALGEBRAIC
 
#define V_HEX_ROBINSON   ( V_HEX_SKEW + V_HEX_TAPER )
 
Tet bit fields
#define V_TET_RADIUS_RATIO
 
#define V_TET_ASPECT_BETA
 
#define V_TET_ASPECT_GAMMA
 
#define V_TET_VOLUME
 
#define V_TET_CONDITION
 
#define V_TET_JACOBIAN
 
#define V_TET_SCALED_JACOBIAN
 
#define V_TET_SHAPE
 
#define V_TET_RELATIVE_SIZE_SQUARED
 
#define V_TET_SHAPE_AND_SIZE
 
#define V_TET_DISTORTION
 
#define V_TET_EDGE_RATIO
 
#define V_TET_ASPECT_RATIO
 
#define V_TET_ASPECT_FROBENIUS
 
#define V_TET_MINIMUM_ANGLE
 
#define V_TET_COLLAPSE_RATIO
 
#define V_TET_ALL
 
#define V_TET_TRADITIONAL
 
#define V_TET_DIAGNOSTIC
 
#define V_TET_ALGEBRAIC   ( V_TET_SHAPE + V_TET_RELATIVE_SIZE_SQUARED + V_TET_SHAPE_AND_SIZE )
 
Pyramid bit fields
#define V_PYRAMID_VOLUME
 
Wedge bit fields
#define V_WEDGE_VOLUME
 
Knife bit fields
#define V_KNIFE_VOLUME
 
Quad bit fields
#define V_QUAD_MAX_EDGE_RATIO
 
#define V_QUAD_SKEW
 
#define V_QUAD_TAPER
 
#define V_QUAD_WARPAGE
 
#define V_QUAD_AREA
 
#define V_QUAD_STRETCH
 
#define V_QUAD_MINIMUM_ANGLE
 
#define V_QUAD_MAXIMUM_ANGLE
 
#define V_QUAD_ODDY
 
#define V_QUAD_CONDITION
 
#define V_QUAD_JACOBIAN
 
#define V_QUAD_SCALED_JACOBIAN
 
#define V_QUAD_SHEAR
 
#define V_QUAD_SHAPE
 
#define V_QUAD_RELATIVE_SIZE_SQUARED
 
#define V_QUAD_SHAPE_AND_SIZE
 
#define V_QUAD_SHEAR_AND_SIZE
 
#define V_QUAD_DISTORTION
 
#define V_QUAD_EDGE_RATIO
 
#define V_QUAD_ASPECT_RATIO
 
#define V_QUAD_RADIUS_RATIO
 
#define V_QUAD_MED_ASPECT_FROBENIUS
 
#define V_QUAD_MAX_ASPECT_FROBENIUS
 
#define V_QUAD_ALL
 
#define V_QUAD_TRADITIONAL
 
#define V_QUAD_DIAGNOSTIC
 
#define V_QUAD_ALGEBRAIC
 
#define V_QUAD_ROBINSON   ( V_QUAD_MAX_EDGE_RATIO + V_QUAD_SKEW + V_QUAD_TAPER )
 

Typedefs

typedef double(* VerdictFunction) (int, double[][3])
 
typedef int(* ComputeNormal) (double point[3], double normal[3])
 

Tri bit fields

#define V_TRI_ASPECT_FROBENIUS
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_AREA
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_MINIMUM_ANGLE
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_MAXIMUM_ANGLE
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_CONDITION
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_SCALED_JACOBIAN
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_SHAPE
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_RELATIVE_SIZE_SQUARED
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_SHAPE_AND_SIZE
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_DISTORTION
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_RADIUS_RATIO
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_EDGE_RATIO
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_ALL
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_TRADITIONAL
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_DIAGNOSTIC
 Calculates quality metrics for hexahedral elements. More...
 
#define V_TRI_ALGEBRAIC   ( V_TRI_SHAPE + V_TRI_SHAPE_AND_SIZE + V_TRI_RELATIVE_SIZE_SQUARED )
 Calculates quality metrics for hexahedral elements. More...
 
#define V_EDGE_LENGTH
 Calculates quality metrics for hexahedral elements. More...
 
C_FUNC_DEF void v_hex_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct HexMetricVals *metric_vals)
 Calculates quality metrics for hexahedral elements. More...
 
C_FUNC_DEF void v_tet_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct TetMetricVals *metric_vals)
 Calculates quality metrics for tetrahedral elements. More...
 
C_FUNC_DEF void v_pyramid_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct PyramidMetricVals *metric_vals)
 Calculates quality metrics for pyramid elements. More...
 
C_FUNC_DEF void v_wedge_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct WedgeMetricVals *metric_vals)
 Calculates quality metrics for wedge elements. More...
 
C_FUNC_DEF void v_knife_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct KnifeMetricVals *metric_vals)
 Calculates quality metrics for knife elements. More...
 
C_FUNC_DEF void v_quad_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct QuadMetricVals *metric_vals)
 Calculates quality metrics for quadrilateral elements. More...
 
C_FUNC_DEF void v_tri_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct TriMetricVals *metric_vals)
 Calculates quality metrics for triangle elements. More...
 
C_FUNC_DEF void v_edge_quality (int num_nodes, double coordinates[][3], unsigned int metrics_request_flag, struct EdgeMetricVals *metric_vals)
 Calculates quality metrics for edge elements. More...
 
C_FUNC_DEF void v_set_hex_size (double size)
 Sets average size (volume) of hex, needed for v_hex_relative_size(...) More...
 
C_FUNC_DEF double v_hex_edge_ratio (int num_nodes, double coordinates[][3])
 Calculates hex edge ratio metric. More...
 
C_FUNC_DEF double v_hex_max_edge_ratio (int num_nodes, double coordinates[][3])
 Calculates hex maximum of edge ratio. More...
 
C_FUNC_DEF double v_hex_skew (int num_nodes, double coordinates[][3])
 Calculates hex skew metric. More...
 
C_FUNC_DEF double v_hex_taper (int num_nodes, double coordinates[][3])
 Calculates hex taper metric. More...
 
C_FUNC_DEF double v_hex_volume (int num_nodes, double coordinates[][3])
 Calculates hex volume. More...
 
C_FUNC_DEF double v_hex_stretch (int num_nodes, double coordinates[][3])
 Calculates hex stretch metric. More...
 
C_FUNC_DEF double v_hex_diagonal (int num_nodes, double coordinates[][3])
 Calculates hex diagonal metric. More...
 
C_FUNC_DEF double v_hex_dimension (int num_nodes, double coordinates[][3])
 Calculates hex dimension metric. More...
 
C_FUNC_DEF double v_hex_oddy (int num_nodes, double coordinates[][3])
 Calculates hex oddy metric. More...
 
C_FUNC_DEF double v_hex_med_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates hex condition metric. More...
 
C_FUNC_DEF double v_hex_max_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates hex condition metric. More...
 
C_FUNC_DEF double v_hex_condition (int num_nodes, double coordinates[][3])
 
C_FUNC_DEF double v_hex_jacobian (int num_nodes, double coordinates[][3])
 Calculates hex jacobian metric. More...
 
C_FUNC_DEF double v_hex_scaled_jacobian (int num_nodes, double coordinates[][3])
 Calculates hex scaled jacobian metric. More...
 
C_FUNC_DEF double v_hex_shear (int num_nodes, double coordinates[][3])
 Calculates hex shear metric. More...
 
C_FUNC_DEF double v_hex_shape (int num_nodes, double coordinates[][3])
 Calculates hex shape metric. More...
 
C_FUNC_DEF double v_hex_relative_size_squared (int num_nodes, double coordinates[][3])
 Calculates hex relative size metric. More...
 
C_FUNC_DEF double v_hex_shape_and_size (int num_nodes, double coordinates[][3])
 Calculates hex shape-size metric. More...
 
C_FUNC_DEF double v_hex_shear_and_size (int num_nodes, double coordinates[][3])
 Calculates hex shear-size metric. More...
 
C_FUNC_DEF double v_hex_distortion (int num_nodes, double coordinates[][3])
 Calculates hex distortion metric. More...
 
C_FUNC_DEF void v_set_tet_size (double size)
 Sets average size (volume) of tet, needed for v_tet_relative_size(...) More...
 
C_FUNC_DEF double v_tet_edge_ratio (int num_nodes, double coordinates[][3])
 Calculates tet edge ratio metric. More...
 
C_FUNC_DEF double v_tet_radius_ratio (int num_nodes, double coordinates[][3])
 Calculates tet radius ratio metric. More...
 
C_FUNC_DEF double v_tet_aspect_beta (int num_nodes, double coordinates[][3])
 Calculates the radius ratio metric of a positively oriented tet. More...
 
C_FUNC_DEF double v_tet_aspect_ratio (int num_nodes, double coordinates[][3])
 Calculates tet aspect ratio metric. More...
 
C_FUNC_DEF double v_tet_aspect_gamma (int num_nodes, double coordinates[][3])
 Calculates tet aspect gamma metric. More...
 
C_FUNC_DEF double v_tet_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates tet aspect frobenius metric. More...
 
C_FUNC_DEF double v_tet_minimum_angle (int num_nodes, double coordinates[][3])
 Calculates tet minimum dihedral angle. More...
 
C_FUNC_DEF double v_tet_collapse_ratio (int num_nodes, double coordinates[][3])
 Calculates tet collapse ratio metric. More...
 
C_FUNC_DEF double v_tet_volume (int num_nodes, double coordinates[][3])
 Calculates tet volume. More...
 
C_FUNC_DEF double v_tet_condition (int num_nodes, double coordinates[][3])
 Calculates tet condition metric. More...
 
C_FUNC_DEF double v_tet_jacobian (int num_nodes, double coordinates[][3])
 Calculates tet jacobian. More...
 
C_FUNC_DEF double v_tet_scaled_jacobian (int num_nodes, double coordinates[][3])
 Calculates tet scaled jacobian. More...
 
C_FUNC_DEF double v_tet_shape (int num_nodes, double coordinates[][3])
 Calculates tet shape metric. More...
 
C_FUNC_DEF double v_tet_relative_size_squared (int num_nodes, 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 double v_pyramid_volume (int num_nodes, double coordinates[][3])
 Calculates pyramid volume. More...
 
C_FUNC_DEF double v_wedge_volume (int num_nodes, double coordinates[][3])
 Calculates wedge volume. More...
 
C_FUNC_DEF double v_knife_volume (int num_nodes, double coordinates[][3])
 Calculates knife volume. More...
 
C_FUNC_DEF double v_edge_length (int num_nodes, double coordinates[][3])
 Calculates edge length. More...
 
C_FUNC_DEF void v_set_quad_size (double size)
 Sets average size (area) of quad, needed for v_quad_relative_size(...) More...
 
C_FUNC_DEF double v_quad_edge_ratio (int num_nodes, double coordinates[][3])
 Calculates quad edge ratio. More...
 
C_FUNC_DEF double v_quad_max_edge_ratio (int num_nodes, double coordinates[][3])
 Calculates quad maximum of edge ratio. More...
 
C_FUNC_DEF double v_quad_aspect_ratio (int num_nodes, double coordinates[][3])
 Calculates quad aspect ratio. More...
 
C_FUNC_DEF double v_quad_radius_ratio (int num_nodes, double coordinates[][3])
 Calculates quad radius ratio. More...
 
C_FUNC_DEF double v_quad_med_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates quad average Frobenius aspect. More...
 
C_FUNC_DEF double v_quad_max_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates quad maximum Frobenius aspect. More...
 
C_FUNC_DEF double v_quad_skew (int num_nodes, double coordinates[][3])
 Calculates quad skew metric. More...
 
C_FUNC_DEF double v_quad_taper (int num_nodes, double coordinates[][3])
 Calculates quad taper metric. More...
 
C_FUNC_DEF double v_quad_warpage (int num_nodes, double coordinates[][3])
 Calculates quad warpage metric. More...
 
C_FUNC_DEF double v_quad_area (int num_nodes, double coordinates[][3])
 Calculates quad area. More...
 
C_FUNC_DEF double v_quad_stretch (int num_nodes, double coordinates[][3])
 Calculates quad strech metric. More...
 
C_FUNC_DEF double v_quad_minimum_angle (int num_nodes, double coordinates[][3])
 Calculates quad's smallest angle. More...
 
C_FUNC_DEF double v_quad_maximum_angle (int num_nodes, double coordinates[][3])
 Calculates quad's largest angle. More...
 
C_FUNC_DEF double v_quad_oddy (int num_nodes, double coordinates[][3])
 Calculates quad oddy metric. More...
 
C_FUNC_DEF double v_quad_condition (int num_nodes, double coordinates[][3])
 Calculates quad condition number metric. More...
 
C_FUNC_DEF double v_quad_jacobian (int num_nodes, double coordinates[][3])
 Calculates quad jacobian. More...
 
C_FUNC_DEF double v_quad_scaled_jacobian (int num_nodes, double coordinates[][3])
 Calculates quad scaled jacobian. More...
 
C_FUNC_DEF double v_quad_shear (int num_nodes, double coordinates[][3])
 Calculates quad shear metric. More...
 
C_FUNC_DEF double v_quad_shape (int num_nodes, double coordinates[][3])
 Calculates quad shape metric. More...
 
C_FUNC_DEF double v_quad_relative_size_squared (int num_nodes, double coordinates[][3])
 Calculates quad relative size metric. More...
 
C_FUNC_DEF double v_quad_shape_and_size (int num_nodes, double coordinates[][3])
 Calculates quad shape-size metric. More...
 
C_FUNC_DEF double v_quad_shear_and_size (int num_nodes, double coordinates[][3])
 Calculates quad shear-size metric. More...
 
C_FUNC_DEF double v_quad_distortion (int num_nodes, double coordinates[][3])
 Calculates quad distortion metric. More...
 
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 num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_aspect_ratio (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_radius_ratio (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_aspect_frobenius (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_area (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_minimum_angle (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_maximum_angle (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_condition (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_scaled_jacobian (int num_nodes, double coordinates[][3])
 Calculates tri metric. More...
 
C_FUNC_DEF double v_tri_relative_size_squared (int num_nodes, 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_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...
 

Detailed Description

Header file for verdict library that calculates metrics for finite elements. Also see: Main Page.

verdict.h is the header file for applications/libraries to include to compute quality metrics.

This file is part of VERDICT

Definition in file verdict.h.

Macro Definition Documentation

◆ C_FUNC_DEF

#define C_FUNC_DEF

Definition at line 58 of file verdict.h.

◆ V_EDGE_LENGTH

#define V_EDGE_LENGTH

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 465 of file verdict.h.

◆ V_HEX_ALGEBRAIC

#define V_HEX_ALGEBRAIC

Definition at line 351 of file verdict.h.

◆ V_HEX_ALL

#define V_HEX_ALL

Definition at line 341 of file verdict.h.

◆ V_HEX_CONDITION

#define V_HEX_CONDITION

Definition at line 329 of file verdict.h.

◆ V_HEX_DIAGNOSTIC

#define V_HEX_DIAGNOSTIC

Definition at line 348 of file verdict.h.

◆ V_HEX_DIAGONAL

#define V_HEX_DIAGONAL

Definition at line 325 of file verdict.h.

◆ V_HEX_DIMENSION

#define V_HEX_DIMENSION

Definition at line 326 of file verdict.h.

◆ V_HEX_DISTORTION

#define V_HEX_DISTORTION

Definition at line 337 of file verdict.h.

◆ V_HEX_EDGE_RATIO

#define V_HEX_EDGE_RATIO

Definition at line 338 of file verdict.h.

◆ V_HEX_JACOBIAN

#define V_HEX_JACOBIAN

Definition at line 330 of file verdict.h.

◆ V_HEX_MAX_ASPECT_FROBENIUS

#define V_HEX_MAX_ASPECT_FROBENIUS

Definition at line 328 of file verdict.h.

◆ V_HEX_MAX_EDGE_RATIO

#define V_HEX_MAX_EDGE_RATIO

Definition at line 320 of file verdict.h.

◆ V_HEX_MED_ASPECT_FROBENIUS

#define V_HEX_MED_ASPECT_FROBENIUS

Definition at line 339 of file verdict.h.

◆ V_HEX_ODDY

#define V_HEX_ODDY

Definition at line 327 of file verdict.h.

◆ V_HEX_RELATIVE_SIZE_SQUARED

#define V_HEX_RELATIVE_SIZE_SQUARED

Definition at line 334 of file verdict.h.

◆ V_HEX_ROBINSON

#define V_HEX_ROBINSON   ( V_HEX_SKEW + V_HEX_TAPER )

Definition at line 352 of file verdict.h.

◆ V_HEX_SCALED_JACOBIAN

#define V_HEX_SCALED_JACOBIAN

Definition at line 331 of file verdict.h.

◆ V_HEX_SHAPE

#define V_HEX_SHAPE

Definition at line 333 of file verdict.h.

◆ V_HEX_SHAPE_AND_SIZE

#define V_HEX_SHAPE_AND_SIZE

Definition at line 335 of file verdict.h.

◆ V_HEX_SHEAR

#define V_HEX_SHEAR

Definition at line 332 of file verdict.h.

◆ V_HEX_SHEAR_AND_SIZE

#define V_HEX_SHEAR_AND_SIZE

Definition at line 336 of file verdict.h.

◆ V_HEX_SKEW

#define V_HEX_SKEW

Definition at line 321 of file verdict.h.

◆ V_HEX_STRETCH

#define V_HEX_STRETCH

Definition at line 324 of file verdict.h.

◆ V_HEX_TAPER

#define V_HEX_TAPER

Definition at line 322 of file verdict.h.

◆ V_HEX_TRADITIONAL

#define V_HEX_TRADITIONAL

Definition at line 346 of file verdict.h.

◆ V_HEX_VOLUME

#define V_HEX_VOLUME

Definition at line 323 of file verdict.h.

◆ V_KNIFE_VOLUME

#define V_KNIFE_VOLUME

Definition at line 399 of file verdict.h.

◆ V_PYRAMID_VOLUME

#define V_PYRAMID_VOLUME

Definition at line 387 of file verdict.h.

◆ V_QUAD_ALGEBRAIC

#define V_QUAD_ALGEBRAIC

Definition at line 437 of file verdict.h.

◆ V_QUAD_ALL

#define V_QUAD_ALL

Definition at line 429 of file verdict.h.

◆ V_QUAD_AREA

#define V_QUAD_AREA

Definition at line 409 of file verdict.h.

◆ V_QUAD_ASPECT_RATIO

#define V_QUAD_ASPECT_RATIO

Definition at line 424 of file verdict.h.

◆ V_QUAD_CONDITION

#define V_QUAD_CONDITION

Definition at line 414 of file verdict.h.

◆ V_QUAD_DIAGNOSTIC

#define V_QUAD_DIAGNOSTIC

Definition at line 435 of file verdict.h.

◆ V_QUAD_DISTORTION

#define V_QUAD_DISTORTION

Definition at line 422 of file verdict.h.

◆ V_QUAD_EDGE_RATIO

#define V_QUAD_EDGE_RATIO

Definition at line 423 of file verdict.h.

◆ V_QUAD_JACOBIAN

#define V_QUAD_JACOBIAN

Definition at line 415 of file verdict.h.

◆ V_QUAD_MAX_ASPECT_FROBENIUS

#define V_QUAD_MAX_ASPECT_FROBENIUS

Definition at line 427 of file verdict.h.

◆ V_QUAD_MAX_EDGE_RATIO

#define V_QUAD_MAX_EDGE_RATIO

Definition at line 405 of file verdict.h.

◆ V_QUAD_MAXIMUM_ANGLE

#define V_QUAD_MAXIMUM_ANGLE

Definition at line 412 of file verdict.h.

◆ V_QUAD_MED_ASPECT_FROBENIUS

#define V_QUAD_MED_ASPECT_FROBENIUS

Definition at line 426 of file verdict.h.

◆ V_QUAD_MINIMUM_ANGLE

#define V_QUAD_MINIMUM_ANGLE

Definition at line 411 of file verdict.h.

◆ V_QUAD_ODDY

#define V_QUAD_ODDY

Definition at line 413 of file verdict.h.

◆ V_QUAD_RADIUS_RATIO

#define V_QUAD_RADIUS_RATIO

Definition at line 425 of file verdict.h.

◆ V_QUAD_RELATIVE_SIZE_SQUARED

#define V_QUAD_RELATIVE_SIZE_SQUARED

Definition at line 419 of file verdict.h.

◆ V_QUAD_ROBINSON

#define V_QUAD_ROBINSON   ( V_QUAD_MAX_EDGE_RATIO + V_QUAD_SKEW + V_QUAD_TAPER )

Definition at line 438 of file verdict.h.

◆ V_QUAD_SCALED_JACOBIAN

#define V_QUAD_SCALED_JACOBIAN

Definition at line 416 of file verdict.h.

◆ V_QUAD_SHAPE

#define V_QUAD_SHAPE

Definition at line 418 of file verdict.h.

◆ V_QUAD_SHAPE_AND_SIZE

#define V_QUAD_SHAPE_AND_SIZE

Definition at line 420 of file verdict.h.

◆ V_QUAD_SHEAR

#define V_QUAD_SHEAR

Definition at line 417 of file verdict.h.

◆ V_QUAD_SHEAR_AND_SIZE

#define V_QUAD_SHEAR_AND_SIZE

Definition at line 421 of file verdict.h.

◆ V_QUAD_SKEW

#define V_QUAD_SKEW

Definition at line 406 of file verdict.h.

◆ V_QUAD_STRETCH

#define V_QUAD_STRETCH

Definition at line 410 of file verdict.h.

◆ V_QUAD_TAPER

#define V_QUAD_TAPER

Definition at line 407 of file verdict.h.

◆ V_QUAD_TRADITIONAL

#define V_QUAD_TRADITIONAL

Definition at line 433 of file verdict.h.

◆ V_QUAD_WARPAGE

#define V_QUAD_WARPAGE

Definition at line 408 of file verdict.h.

◆ V_TET_ALGEBRAIC

#define V_TET_ALGEBRAIC   ( V_TET_SHAPE + V_TET_RELATIVE_SIZE_SQUARED + V_TET_SHAPE_AND_SIZE )

Definition at line 381 of file verdict.h.

◆ V_TET_ALL

#define V_TET_ALL

Definition at line 375 of file verdict.h.

◆ V_TET_ASPECT_BETA

#define V_TET_ASPECT_BETA

Definition at line 359 of file verdict.h.

◆ V_TET_ASPECT_FROBENIUS

#define V_TET_ASPECT_FROBENIUS

Definition at line 371 of file verdict.h.

◆ V_TET_ASPECT_GAMMA

#define V_TET_ASPECT_GAMMA

Definition at line 360 of file verdict.h.

◆ V_TET_ASPECT_RATIO

#define V_TET_ASPECT_RATIO

Definition at line 370 of file verdict.h.

◆ V_TET_COLLAPSE_RATIO

#define V_TET_COLLAPSE_RATIO

Definition at line 373 of file verdict.h.

◆ V_TET_CONDITION

#define V_TET_CONDITION

Definition at line 362 of file verdict.h.

◆ V_TET_DIAGNOSTIC

#define V_TET_DIAGNOSTIC

Definition at line 380 of file verdict.h.

◆ V_TET_DISTORTION

#define V_TET_DISTORTION

Definition at line 368 of file verdict.h.

◆ V_TET_EDGE_RATIO

#define V_TET_EDGE_RATIO

Definition at line 369 of file verdict.h.

◆ V_TET_JACOBIAN

#define V_TET_JACOBIAN

Definition at line 363 of file verdict.h.

◆ V_TET_MINIMUM_ANGLE

#define V_TET_MINIMUM_ANGLE

Definition at line 372 of file verdict.h.

◆ V_TET_RADIUS_RATIO

#define V_TET_RADIUS_RATIO

Definition at line 358 of file verdict.h.

◆ V_TET_RELATIVE_SIZE_SQUARED

#define V_TET_RELATIVE_SIZE_SQUARED

Definition at line 366 of file verdict.h.

◆ V_TET_SCALED_JACOBIAN

#define V_TET_SCALED_JACOBIAN

Definition at line 364 of file verdict.h.

◆ V_TET_SHAPE

#define V_TET_SHAPE

Definition at line 365 of file verdict.h.

◆ V_TET_SHAPE_AND_SIZE

#define V_TET_SHAPE_AND_SIZE

Definition at line 367 of file verdict.h.

◆ V_TET_TRADITIONAL

#define V_TET_TRADITIONAL

Definition at line 378 of file verdict.h.

◆ V_TET_VOLUME

#define V_TET_VOLUME

Definition at line 361 of file verdict.h.

◆ V_TRI_ALGEBRAIC

#define V_TRI_ALGEBRAIC   ( V_TRI_SHAPE + V_TRI_SHAPE_AND_SIZE + V_TRI_RELATIVE_SIZE_SQUARED )

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 463 of file verdict.h.

◆ V_TRI_ALL

#define V_TRI_ALL

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 457 of file verdict.h.

◆ V_TRI_AREA

#define V_TRI_AREA

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 445 of file verdict.h.

◆ V_TRI_ASPECT_FROBENIUS

#define V_TRI_ASPECT_FROBENIUS

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 444 of file verdict.h.

◆ V_TRI_CONDITION

#define V_TRI_CONDITION

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 448 of file verdict.h.

◆ V_TRI_DIAGNOSTIC

#define V_TRI_DIAGNOSTIC

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 462 of file verdict.h.

◆ V_TRI_DISTORTION

#define V_TRI_DISTORTION

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 453 of file verdict.h.

◆ V_TRI_EDGE_RATIO

#define V_TRI_EDGE_RATIO

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 455 of file verdict.h.

◆ V_TRI_MAXIMUM_ANGLE

#define V_TRI_MAXIMUM_ANGLE

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 447 of file verdict.h.

◆ V_TRI_MINIMUM_ANGLE

#define V_TRI_MINIMUM_ANGLE

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 446 of file verdict.h.

◆ V_TRI_RADIUS_RATIO

#define V_TRI_RADIUS_RATIO

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 454 of file verdict.h.

◆ V_TRI_RELATIVE_SIZE_SQUARED

#define V_TRI_RELATIVE_SIZE_SQUARED

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 451 of file verdict.h.

◆ V_TRI_SCALED_JACOBIAN

#define V_TRI_SCALED_JACOBIAN

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 449 of file verdict.h.

◆ V_TRI_SHAPE

#define V_TRI_SHAPE

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 450 of file verdict.h.

◆ V_TRI_SHAPE_AND_SIZE

#define V_TRI_SHAPE_AND_SIZE

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 452 of file verdict.h.

◆ V_TRI_TRADITIONAL

#define V_TRI_TRADITIONAL

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 460 of file verdict.h.

◆ V_WEDGE_VOLUME

#define V_WEDGE_VOLUME

Definition at line 393 of file verdict.h.

◆ VERDICT_DBL_MAX

#define VERDICT_DBL_MAX   1.0E+30

Definition at line 37 of file verdict.h.

◆ VERDICT_DBL_MIN

#define VERDICT_DBL_MIN   1.0E-30

Definition at line 36 of file verdict.h.

◆ VERDICT_PI

#define VERDICT_PI   3.1415926535897932384626

Definition at line 38 of file verdict.h.

◆ VERDICT_VERSION

#define VERDICT_VERSION   120

Definition at line 33 of file verdict.h.

Typedef Documentation

◆ ComputeNormal

typedef int( * ComputeNormal) (double point[3], double normal[3])

Definition at line 68 of file verdict.h.

◆ VerdictFunction

typedef double( * VerdictFunction) (int, double[][3])

Definition at line 67 of file verdict.h.

Function Documentation

◆ v_edge_length()

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

Calculates edge length.

length of and edge length is calculated by taking the distance between the end nodes

Definition at line 32 of file V_EdgeMetric.cpp.

33 { 34  35  double x = coordinates[1][0] - coordinates[0][0]; 36  double y = coordinates[1][1] - coordinates[0][1]; 37  double z = coordinates[1][2] - coordinates[0][2]; 38  return (double)( sqrt( x * x + y * y + z * z ) ); 39 }

Referenced by moab::VerdictWrapper::all_quality_measures(), edge_quality(), and moab::VerdictWrapper::quality_measure().

◆ v_edge_quality()

C_FUNC_DEF void v_edge_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
struct EdgeMetricVals metric_vals 
)

Calculates quality metrics for edge elements.

◆ v_hex_condition()

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

The maximum Frobenius condition of a hex, a.k.a. condition NB (P. Pebay 01/25/07): this method is maintained for backwards compatibility only. It will become deprecated at some point.

Definition at line 1371 of file V_HexMetric.cpp.

1372 { 1373  1374  return v_hex_max_aspect_frobenius( 8, coordinates ); 1375 }

References v_hex_max_aspect_frobenius().

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

◆ v_hex_diagonal()

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

Calculates hex diagonal metric.

Minimum diagonal length / maximum diagonal length. Reference — Unknown

diagonal ratio of a hex

Minimum diagonal length / maximum diagonal length

Definition at line 771 of file V_HexMetric.cpp.

772 { 773  774  double min_diag = diag_length( 0, coordinates ); 775  double max_diag = diag_length( 1, coordinates ); 776  777  double diagonal = safe_ratio( min_diag, max_diag ); 778  779  if( diagonal > 0 ) return (double)VERDICT_MIN( diagonal, VERDICT_DBL_MAX ); 780  return (double)VERDICT_MAX( diagonal, -VERDICT_DBL_MAX ); 781 }

References diag_length(), safe_ratio(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_dimension()

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

Calculates hex dimension metric.

Pronto-specific characteristic length for stable time step calculation.
Char_length = Volume / 2 grad Volume. Reference — L.M. Taylor, and D.P. Flanagan, Pronto3D - A Three Dimensional Transient Solid Dynamics Program, SAND87-1912, Sandia National Laboratories, 1989.

dimension of a hex

Pronto-specific characteristic length for stable time step calculation. Char_length = Volume / 2 grad Volume

Definition at line 791 of file V_HexMetric.cpp.

792 { 793  794  double gradop[9][4]; 795  796  double x1 = coordinates[0][0]; 797  double x2 = coordinates[1][0]; 798  double x3 = coordinates[2][0]; 799  double x4 = coordinates[3][0]; 800  double x5 = coordinates[4][0]; 801  double x6 = coordinates[5][0]; 802  double x7 = coordinates[6][0]; 803  double x8 = coordinates[7][0]; 804  805  double y1 = coordinates[0][1]; 806  double y2 = coordinates[1][1]; 807  double y3 = coordinates[2][1]; 808  double y4 = coordinates[3][1]; 809  double y5 = coordinates[4][1]; 810  double y6 = coordinates[5][1]; 811  double y7 = coordinates[6][1]; 812  double y8 = coordinates[7][1]; 813  814  double z1 = coordinates[0][2]; 815  double z2 = coordinates[1][2]; 816  double z3 = coordinates[2][2]; 817  double z4 = coordinates[3][2]; 818  double z5 = coordinates[4][2]; 819  double z6 = coordinates[5][2]; 820  double z7 = coordinates[6][2]; 821  double z8 = coordinates[7][2]; 822  823  double z24 = z2 - z4; 824  double z52 = z5 - z2; 825  double z45 = z4 - z5; 826  gradop[1][1] = 827  ( y2 * ( z6 - z3 - z45 ) + y3 * z24 + y4 * ( z3 - z8 - z52 ) + y5 * ( z8 - z6 - z24 ) + y6 * z52 + y8 * z45 ) / 828  12.0; 829  830  double z31 = z3 - z1; 831  double z63 = z6 - z3; 832  double z16 = z1 - z6; 833  gradop[2][1] = 834  ( y3 * ( z7 - z4 - z16 ) + y4 * z31 + y1 * ( z4 - z5 - z63 ) + y6 * ( z5 - z7 - z31 ) + y7 * z63 + y5 * z16 ) / 835  12.0; 836  837  double z42 = z4 - z2; 838  double z74 = z7 - z4; 839  double z27 = z2 - z7; 840  gradop[3][1] = 841  ( y4 * ( z8 - z1 - z27 ) + y1 * z42 + y2 * ( z1 - z6 - z74 ) + y7 * ( z6 - z8 - z42 ) + y8 * z74 + y6 * z27 ) / 842  12.0; 843  844  double z13 = z1 - z3; 845  double z81 = z8 - z1; 846  double z38 = z3 - z8; 847  gradop[4][1] = 848  ( y1 * ( z5 - z2 - z38 ) + y2 * z13 + y3 * ( z2 - z7 - z81 ) + y8 * ( z7 - z5 - z13 ) + y5 * z81 + y7 * z38 ) / 849  12.0; 850  851  double z86 = z8 - z6; 852  double z18 = z1 - z8; 853  double z61 = z6 - z1; 854  gradop[5][1] = 855  ( y8 * ( z4 - z7 - z61 ) + y7 * z86 + y6 * ( z7 - z2 - z18 ) + y1 * ( z2 - z4 - z86 ) + y4 * z18 + y2 * z61 ) / 856  12.0; 857  858  double z57 = z5 - z7; 859  double z25 = z2 - z5; 860  double z72 = z7 - z2; 861  gradop[6][1] = 862  ( y5 * ( z1 - z8 - z72 ) + y8 * z57 + y7 * ( z8 - z3 - z25 ) + y2 * ( z3 - z1 - z57 ) + y1 * z25 + y3 * z72 ) / 863  12.0; 864  865  double z68 = z6 - z8; 866  double z36 = z3 - z6; 867  double z83 = z8 - z3; 868  gradop[7][1] = 869  ( y6 * ( z2 - z5 - z83 ) + y5 * z68 + y8 * ( z5 - z4 - z36 ) + y3 * ( z4 - z2 - z68 ) + y2 * z36 + y4 * z83 ) / 870  12.0; 871  872  double z75 = z7 - z5; 873  double z47 = z4 - z7; 874  double z54 = z5 - z4; 875  gradop[8][1] = 876  ( y7 * ( z3 - z6 - z54 ) + y6 * z75 + y5 * ( z6 - z1 - z47 ) + y4 * ( z1 - z3 - z75 ) + y3 * z47 + y1 * z54 ) / 877  12.0; 878  879  double x24 = x2 - x4; 880  double x52 = x5 - x2; 881  double x45 = x4 - x5; 882  gradop[1][2] = 883  ( z2 * ( x6 - x3 - x45 ) + z3 * x24 + z4 * ( x3 - x8 - x52 ) + z5 * ( x8 - x6 - x24 ) + z6 * x52 + z8 * x45 ) / 884  12.0; 885  886  double x31 = x3 - x1; 887  double x63 = x6 - x3; 888  double x16 = x1 - x6; 889  gradop[2][2] = 890  ( z3 * ( x7 - x4 - x16 ) + z4 * x31 + z1 * ( x4 - x5 - x63 ) + z6 * ( x5 - x7 - x31 ) + z7 * x63 + z5 * x16 ) / 891  12.0; 892  893  double x42 = x4 - x2; 894  double x74 = x7 - x4; 895  double x27 = x2 - x7; 896  gradop[3][2] = 897  ( z4 * ( x8 - x1 - x27 ) + z1 * x42 + z2 * ( x1 - x6 - x74 ) + z7 * ( x6 - x8 - x42 ) + z8 * x74 + z6 * x27 ) / 898  12.0; 899  900  double x13 = x1 - x3; 901  double x81 = x8 - x1; 902  double x38 = x3 - x8; 903  gradop[4][2] = 904  ( z1 * ( x5 - x2 - x38 ) + z2 * x13 + z3 * ( x2 - x7 - x81 ) + z8 * ( x7 - x5 - x13 ) + z5 * x81 + z7 * x38 ) / 905  12.0; 906  907  double x86 = x8 - x6; 908  double x18 = x1 - x8; 909  double x61 = x6 - x1; 910  gradop[5][2] = 911  ( z8 * ( x4 - x7 - x61 ) + z7 * x86 + z6 * ( x7 - x2 - x18 ) + z1 * ( x2 - x4 - x86 ) + z4 * x18 + z2 * x61 ) / 912  12.0; 913  914  double x57 = x5 - x7; 915  double x25 = x2 - x5; 916  double x72 = x7 - x2; 917  gradop[6][2] = 918  ( z5 * ( x1 - x8 - x72 ) + z8 * x57 + z7 * ( x8 - x3 - x25 ) + z2 * ( x3 - x1 - x57 ) + z1 * x25 + z3 * x72 ) / 919  12.0; 920  921  double x68 = x6 - x8; 922  double x36 = x3 - x6; 923  double x83 = x8 - x3; 924  gradop[7][2] = 925  ( z6 * ( x2 - x5 - x83 ) + z5 * x68 + z8 * ( x5 - x4 - x36 ) + z3 * ( x4 - x2 - x68 ) + z2 * x36 + z4 * x83 ) / 926  12.0; 927  928  double x75 = x7 - x5; 929  double x47 = x4 - x7; 930  double x54 = x5 - x4; 931  gradop[8][2] = 932  ( z7 * ( x3 - x6 - x54 ) + z6 * x75 + z5 * ( x6 - x1 - x47 ) + z4 * ( x1 - x3 - x75 ) + z3 * x47 + z1 * x54 ) / 933  12.0; 934  935  double y24 = y2 - y4; 936  double y52 = y5 - y2; 937  double y45 = y4 - y5; 938  gradop[1][3] = 939  ( x2 * ( y6 - y3 - y45 ) + x3 * y24 + x4 * ( y3 - y8 - y52 ) + x5 * ( y8 - y6 - y24 ) + x6 * y52 + x8 * y45 ) / 940  12.0; 941  942  double y31 = y3 - y1; 943  double y63 = y6 - y3; 944  double y16 = y1 - y6; 945  gradop[2][3] = 946  ( x3 * ( y7 - y4 - y16 ) + x4 * y31 + x1 * ( y4 - y5 - y63 ) + x6 * ( y5 - y7 - y31 ) + x7 * y63 + x5 * y16 ) / 947  12.0; 948  949  double y42 = y4 - y2; 950  double y74 = y7 - y4; 951  double y27 = y2 - y7; 952  gradop[3][3] = 953  ( x4 * ( y8 - y1 - y27 ) + x1 * y42 + x2 * ( y1 - y6 - y74 ) + x7 * ( y6 - y8 - y42 ) + x8 * y74 + x6 * y27 ) / 954  12.0; 955  956  double y13 = y1 - y3; 957  double y81 = y8 - y1; 958  double y38 = y3 - y8; 959  gradop[4][3] = 960  ( x1 * ( y5 - y2 - y38 ) + x2 * y13 + x3 * ( y2 - y7 - y81 ) + x8 * ( y7 - y5 - y13 ) + x5 * y81 + x7 * y38 ) / 961  12.0; 962  963  double y86 = y8 - y6; 964  double y18 = y1 - y8; 965  double y61 = y6 - y1; 966  gradop[5][3] = 967  ( x8 * ( y4 - y7 - y61 ) + x7 * y86 + x6 * ( y7 - y2 - y18 ) + x1 * ( y2 - y4 - y86 ) + x4 * y18 + x2 * y61 ) / 968  12.0; 969  970  double y57 = y5 - y7; 971  double y25 = y2 - y5; 972  double y72 = y7 - y2; 973  gradop[6][3] = 974  ( x5 * ( y1 - y8 - y72 ) + x8 * y57 + x7 * ( y8 - y3 - y25 ) + x2 * ( y3 - y1 - y57 ) + x1 * y25 + x3 * y72 ) / 975  12.0; 976  977  double y68 = y6 - y8; 978  double y36 = y3 - y6; 979  double y83 = y8 - y3; 980  gradop[7][3] = 981  ( x6 * ( y2 - y5 - y83 ) + x5 * y68 + x8 * ( y5 - y4 - y36 ) + x3 * ( y4 - y2 - y68 ) + x2 * y36 + x4 * y83 ) / 982  12.0; 983  984  double y75 = y7 - y5; 985  double y47 = y4 - y7; 986  double y54 = y5 - y4; 987  gradop[8][3] = 988  ( x7 * ( y3 - y6 - y54 ) + x6 * y75 + x5 * ( y6 - y1 - y47 ) + x4 * ( y1 - y3 - y75 ) + x3 * y47 + x1 * y54 ) / 989  12.0; 990  991  // calculate element volume and characteristic element aspect ratio 992  // (used in time step and hourglass control) - 993  994  double volume = coordinates[0][0] * gradop[1][1] + coordinates[1][0] * gradop[2][1] + 995  coordinates[2][0] * gradop[3][1] + coordinates[3][0] * gradop[4][1] + 996  coordinates[4][0] * gradop[5][1] + coordinates[5][0] * gradop[6][1] + 997  coordinates[6][0] * gradop[7][1] + coordinates[7][0] * gradop[8][1]; 998  double aspect = 999  .5 * SQR( volume ) / 1000  ( SQR( gradop[1][1] ) + SQR( gradop[2][1] ) + SQR( gradop[3][1] ) + SQR( gradop[4][1] ) + SQR( gradop[5][1] ) + 1001  SQR( gradop[6][1] ) + SQR( gradop[7][1] ) + SQR( gradop[8][1] ) + SQR( gradop[1][2] ) + SQR( gradop[2][2] ) + 1002  SQR( gradop[3][2] ) + SQR( gradop[4][2] ) + SQR( gradop[5][2] ) + SQR( gradop[6][2] ) + SQR( gradop[7][2] ) + 1003  SQR( gradop[8][2] ) + SQR( gradop[1][3] ) + SQR( gradop[2][3] ) + SQR( gradop[3][3] ) + SQR( gradop[4][3] ) + 1004  SQR( gradop[5][3] ) + SQR( gradop[6][3] ) + SQR( gradop[7][3] ) + SQR( gradop[8][3] ) ); 1005  1006  return (double)sqrt( aspect ); 1007 }

References SQR.

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

◆ v_hex_distortion()

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

Calculates hex distortion metric.

{min(|J|)/actual volume}*parent volume, parent volume = 8 for hex. Reference — SDRC/IDEAS Simulation: Finite Element Modeling–User's Guide

distortion of a hex

Definition at line 2228 of file V_HexMetric.cpp.

2229 { 2230  2231  // use 2x2 gauss points for linear hex and 3x3 for 2nd order hex 2232  int number_of_gauss_points = 0; 2233  if( num_nodes == 8 ) 2234  // 2x2 quadrature rule 2235  number_of_gauss_points = 2; 2236  else if( num_nodes == 20 ) 2237  // 3x3 quadrature rule 2238  number_of_gauss_points = 3; 2239  2240  int number_dimension = 3; 2241  int total_number_of_gauss_points = number_of_gauss_points * number_of_gauss_points * number_of_gauss_points; 2242  double distortion = VERDICT_DBL_MAX; 2243  2244  // maxTotalNumberGaussPoints =27, maxNumberNodes = 20 2245  // they are defined in GaussIntegration.hpp 2246  // This is used to make these arrays static. 2247  // I tried dynamically allocated arrays but the new and delete 2248  // was very expensive 2249  2250  double shape_function[maxTotalNumberGaussPoints][maxNumberNodes]; 2251  double dndy1[maxTotalNumberGaussPoints][maxNumberNodes]; 2252  double dndy2[maxTotalNumberGaussPoints][maxNumberNodes]; 2253  double dndy3[maxTotalNumberGaussPoints][maxNumberNodes]; 2254  double weight[maxTotalNumberGaussPoints]; 2255  2256  // create an object of GaussIntegration 2257  GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dimension ); 2258  GaussIntegration::calculate_shape_function_3d_hex(); 2259  GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], dndy3[0], weight ); 2260  2261  VerdictVector xxi, xet, xze, xin; 2262  2263  double jacobian, minimum_jacobian; 2264  double element_volume = 0.0; 2265  minimum_jacobian = VERDICT_DBL_MAX; 2266  // calculate element volume 2267  int ife, ja; 2268  for( ife = 0; ife < total_number_of_gauss_points; ife++ ) 2269  { 2270  2271  xxi.set( 0.0, 0.0, 0.0 ); 2272  xet.set( 0.0, 0.0, 0.0 ); 2273  xze.set( 0.0, 0.0, 0.0 ); 2274  2275  for( ja = 0; ja < num_nodes; ja++ ) 2276  { 2277  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); 2278  xxi += dndy1[ife][ja] * xin; 2279  xet += dndy2[ife][ja] * xin; 2280  xze += dndy3[ife][ja] * xin; 2281  } 2282  2283  jacobian = xxi % ( xet * xze ); 2284  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian; 2285  2286  element_volume += weight[ife] * jacobian; 2287  } 2288  2289  // loop through all nodes 2290  double dndy1_at_node[maxNumberNodes][maxNumberNodes]; 2291  double dndy2_at_node[maxNumberNodes][maxNumberNodes]; 2292  double dndy3_at_node[maxNumberNodes][maxNumberNodes]; 2293  2294  GaussIntegration::calculate_derivative_at_nodes_3d( dndy1_at_node, dndy2_at_node, dndy3_at_node ); 2295  int node_id; 2296  for( node_id = 0; node_id < num_nodes; node_id++ ) 2297  { 2298  2299  xxi.set( 0.0, 0.0, 0.0 ); 2300  xet.set( 0.0, 0.0, 0.0 ); 2301  xze.set( 0.0, 0.0, 0.0 ); 2302  2303  for( ja = 0; ja < num_nodes; ja++ ) 2304  { 2305  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); 2306  xxi += dndy1_at_node[node_id][ja] * xin; 2307  xet += dndy2_at_node[node_id][ja] * xin; 2308  xze += dndy3_at_node[node_id][ja] * xin; 2309  } 2310  2311  jacobian = xxi % ( xet * xze ); 2312  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian; 2313  } 2314  distortion = minimum_jacobian / element_volume * 8.; 2315  return (double)distortion; 2316 }

References GaussIntegration::calculate_derivative_at_nodes_3d(), GaussIntegration::calculate_shape_function_3d_hex(), GaussIntegration::get_shape_func(), GaussIntegration::initialize(), maxNumberNodes, maxTotalNumberGaussPoints, VerdictVector::set(), and VERDICT_DBL_MAX.

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

◆ v_hex_edge_ratio()

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

Calculates hex edge ratio metric.

Hmax / Hmin where Hmax and Hmin are respectively the maximum and the minimum edge lengths

the edge ratio of a hex

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

Definition at line 529 of file V_HexMetric.cpp.

530 { 531  532  VerdictVector edges[12]; 533  make_hex_edges( coordinates, edges ); 534  535  double a2 = edges[0].length_squared(); 536  double b2 = edges[1].length_squared(); 537  double c2 = edges[2].length_squared(); 538  double d2 = edges[3].length_squared(); 539  double e2 = edges[4].length_squared(); 540  double f2 = edges[5].length_squared(); 541  double g2 = edges[6].length_squared(); 542  double h2 = edges[7].length_squared(); 543  double i2 = edges[8].length_squared(); 544  double j2 = edges[9].length_squared(); 545  double k2 = edges[10].length_squared(); 546  double l2 = edges[11].length_squared(); 547  548  double mab, mcd, mef, Mab, Mcd, Mef; 549  double mgh, mij, mkl, Mgh, Mij, Mkl; 550  551  if( a2 < b2 ) 552  { 553  mab = a2; 554  Mab = b2; 555  } 556  else // b2 <= a2 557  { 558  mab = b2; 559  Mab = a2; 560  } 561  if( c2 < d2 ) 562  { 563  mcd = c2; 564  Mcd = d2; 565  } 566  else // d2 <= c2 567  { 568  mcd = d2; 569  Mcd = c2; 570  } 571  if( e2 < f2 ) 572  { 573  mef = e2; 574  Mef = f2; 575  } 576  else // f2 <= e2 577  { 578  mef = f2; 579  Mef = e2; 580  } 581  if( g2 < h2 ) 582  { 583  mgh = g2; 584  Mgh = h2; 585  } 586  else // h2 <= g2 587  { 588  mgh = h2; 589  Mgh = g2; 590  } 591  if( i2 < j2 ) 592  { 593  mij = i2; 594  Mij = j2; 595  } 596  else // j2 <= i2 597  { 598  mij = j2; 599  Mij = i2; 600  } 601  if( k2 < l2 ) 602  { 603  mkl = k2; 604  Mkl = l2; 605  } 606  else // l2 <= k2 607  { 608  mkl = l2; 609  Mkl = k2; 610  } 611  612  double m2; 613  m2 = mab < mcd ? mab : mcd; 614  m2 = m2 < mef ? m2 : mef; 615  m2 = m2 < mgh ? m2 : mgh; 616  m2 = m2 < mij ? m2 : mij; 617  m2 = m2 < mkl ? m2 : mkl; 618  619  if( m2 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; 620  621  double M2; 622  M2 = Mab > Mcd ? Mab : Mcd; 623  M2 = M2 > Mef ? M2 : Mef; 624  M2 = M2 > Mgh ? M2 : Mgh; 625  M2 = M2 > Mij ? M2 : Mij; 626  M2 = M2 > Mkl ? M2 : Mkl; 627  m2 = m2 < mef ? m2 : mef; 628  629  M2 = Mab > Mcd ? Mab : Mcd; 630  M2 = M2 > Mef ? M2 : Mef; 631  632  double edge_ratio = sqrt( M2 / m2 ); 633  634  if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX ); 635  return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX ); 636 }

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

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

◆ v_hex_jacobian()

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

Calculates hex jacobian metric.

Minimum pointwise volume of local map at 8 corners & center of hex. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

jacobian of a hex

Minimum pointwise volume of local map at 8 corners & center of hex

Definition at line 1382 of file V_HexMetric.cpp.

1383 { 1384  1385  VerdictVector node_pos[8]; 1386  make_hex_nodes( coordinates, node_pos ); 1387  1388  double jacobian = VERDICT_DBL_MAX; 1389  double current_jacobian; 1390  VerdictVector xxi, xet, xze; 1391  1392  xxi = calc_hex_efg( 1, node_pos ); 1393  xet = calc_hex_efg( 2, node_pos ); 1394  xze = calc_hex_efg( 3, node_pos ); 1395  1396  current_jacobian = xxi % ( xet * xze ) / 64.0; 1397  if( current_jacobian < jacobian ) 1398  { 1399  jacobian = current_jacobian; 1400  } 1401  1402  // J(0,0,0): 1403  1404  xxi = node_pos[1] - node_pos[0]; 1405  xet = node_pos[3] - node_pos[0]; 1406  xze = node_pos[4] - node_pos[0]; 1407  1408  current_jacobian = xxi % ( xet * xze ); 1409  if( current_jacobian < jacobian ) 1410  { 1411  jacobian = current_jacobian; 1412  } 1413  1414  // J(1,0,0): 1415  1416  xxi = node_pos[2] - node_pos[1]; 1417  xet = node_pos[0] - node_pos[1]; 1418  xze = node_pos[5] - node_pos[1]; 1419  1420  current_jacobian = xxi % ( xet * xze ); 1421  if( current_jacobian < jacobian ) 1422  { 1423  jacobian = current_jacobian; 1424  } 1425  1426  // J(1,1,0): 1427  1428  xxi = node_pos[3] - node_pos[2]; 1429  xet = node_pos[1] - node_pos[2]; 1430  xze = node_pos[6] - node_pos[2]; 1431  1432  current_jacobian = xxi % ( xet * xze ); 1433  if( current_jacobian < jacobian ) 1434  { 1435  jacobian = current_jacobian; 1436  } 1437  1438  // J(0,1,0): 1439  1440  xxi = node_pos[0] - node_pos[3]; 1441  xet = node_pos[2] - node_pos[3]; 1442  xze = node_pos[7] - node_pos[3]; 1443  1444  current_jacobian = xxi % ( xet * xze ); 1445  if( current_jacobian < jacobian ) 1446  { 1447  jacobian = current_jacobian; 1448  } 1449  1450  // J(0,0,1): 1451  1452  xxi = node_pos[7] - node_pos[4]; 1453  xet = node_pos[5] - node_pos[4]; 1454  xze = node_pos[0] - node_pos[4]; 1455  1456  current_jacobian = xxi % ( xet * xze ); 1457  if( current_jacobian < jacobian ) 1458  { 1459  jacobian = current_jacobian; 1460  } 1461  1462  // J(1,0,1): 1463  1464  xxi = node_pos[4] - node_pos[5]; 1465  xet = node_pos[6] - node_pos[5]; 1466  xze = node_pos[1] - node_pos[5]; 1467  1468  current_jacobian = xxi % ( xet * xze ); 1469  if( current_jacobian < jacobian ) 1470  { 1471  jacobian = current_jacobian; 1472  } 1473  1474  // J(1,1,1): 1475  1476  xxi = node_pos[5] - node_pos[6]; 1477  xet = node_pos[7] - node_pos[6]; 1478  xze = node_pos[2] - node_pos[6]; 1479  1480  current_jacobian = xxi % ( xet * xze ); 1481  if( current_jacobian < jacobian ) 1482  { 1483  jacobian = current_jacobian; 1484  } 1485  1486  // J(0,1,1): 1487  1488  xxi = node_pos[6] - node_pos[7]; 1489  xet = node_pos[4] - node_pos[7]; 1490  xze = node_pos[3] - node_pos[7]; 1491  1492  current_jacobian = xxi % ( xet * xze ); 1493  if( current_jacobian < jacobian ) 1494  { 1495  jacobian = current_jacobian; 1496  } 1497  1498  if( jacobian > 0 ) return (double)VERDICT_MIN( jacobian, VERDICT_DBL_MAX ); 1499  return (double)VERDICT_MAX( jacobian, -VERDICT_DBL_MAX ); 1500 }

References calc_hex_efg(), make_hex_nodes, VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_max_aspect_frobenius()

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

Calculates hex condition metric.

Maximum Frobenius condition number of the Jacobian matrix at 8 corners. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

maximum Frobenius condition number of a hex

Maximum Frobenius condition number of the Jacobian matrix at 8 corners NB (P. Pebay 01/25/07): this metric is calculated by taking the maximum of the 8 Frobenius aspects at each corner of the hex, when the reference corner is right isosceles.

Definition at line 1243 of file V_HexMetric.cpp.

1244 { 1245  1246  VerdictVector node_pos[8]; 1247  make_hex_nodes( coordinates, node_pos ); 1248  1249  double condition = 0.0, current_condition; 1250  VerdictVector xxi, xet, xze; 1251  1252  xxi = calc_hex_efg( 1, node_pos ); 1253  xet = calc_hex_efg( 2, node_pos ); 1254  xze = calc_hex_efg( 3, node_pos ); 1255  1256  current_condition = condition_comp( xxi, xet, xze ); 1257  if( current_condition > condition ) 1258  { 1259  condition = current_condition; 1260  } 1261  1262  // J(0,0,0): 1263  1264  xxi = node_pos[1] - node_pos[0]; 1265  xet = node_pos[3] - node_pos[0]; 1266  xze = node_pos[4] - node_pos[0]; 1267  1268  current_condition = condition_comp( xxi, xet, xze ); 1269  if( current_condition > condition ) 1270  { 1271  condition = current_condition; 1272  } 1273  1274  // J(1,0,0): 1275  1276  xxi = node_pos[2] - node_pos[1]; 1277  xet = node_pos[0] - node_pos[1]; 1278  xze = node_pos[5] - node_pos[1]; 1279  1280  current_condition = condition_comp( xxi, xet, xze ); 1281  if( current_condition > condition ) 1282  { 1283  condition = current_condition; 1284  } 1285  1286  // J(1,1,0): 1287  1288  xxi = node_pos[3] - node_pos[2]; 1289  xet = node_pos[1] - node_pos[2]; 1290  xze = node_pos[6] - node_pos[2]; 1291  1292  current_condition = condition_comp( xxi, xet, xze ); 1293  if( current_condition > condition ) 1294  { 1295  condition = current_condition; 1296  } 1297  1298  // J(0,1,0): 1299  1300  xxi = node_pos[0] - node_pos[3]; 1301  xet = node_pos[2] - node_pos[3]; 1302  xze = node_pos[7] - node_pos[3]; 1303  1304  current_condition = condition_comp( xxi, xet, xze ); 1305  if( current_condition > condition ) 1306  { 1307  condition = current_condition; 1308  } 1309  1310  // J(0,0,1): 1311  1312  xxi = node_pos[7] - node_pos[4]; 1313  xet = node_pos[5] - node_pos[4]; 1314  xze = node_pos[0] - node_pos[4]; 1315  1316  current_condition = condition_comp( xxi, xet, xze ); 1317  if( current_condition > condition ) 1318  { 1319  condition = current_condition; 1320  } 1321  1322  // J(1,0,1): 1323  1324  xxi = node_pos[4] - node_pos[5]; 1325  xet = node_pos[6] - node_pos[5]; 1326  xze = node_pos[1] - node_pos[5]; 1327  1328  current_condition = condition_comp( xxi, xet, xze ); 1329  if( current_condition > condition ) 1330  { 1331  condition = current_condition; 1332  } 1333  1334  // J(1,1,1): 1335  1336  xxi = node_pos[5] - node_pos[6]; 1337  xet = node_pos[7] - node_pos[6]; 1338  xze = node_pos[2] - node_pos[6]; 1339  1340  current_condition = condition_comp( xxi, xet, xze ); 1341  if( current_condition > condition ) 1342  { 1343  condition = current_condition; 1344  } 1345  1346  // J(1,1,1): 1347  1348  xxi = node_pos[6] - node_pos[7]; 1349  xet = node_pos[4] - node_pos[7]; 1350  xze = node_pos[3] - node_pos[7]; 1351  1352  current_condition = condition_comp( xxi, xet, xze ); 1353  if( current_condition > condition ) 1354  { 1355  condition = current_condition; 1356  } 1357  1358  condition /= 3.0; 1359  1360  if( condition > 0 ) return (double)VERDICT_MIN( condition, VERDICT_DBL_MAX ); 1361  return (double)VERDICT_MAX( condition, -VERDICT_DBL_MAX ); 1362 }

References calc_hex_efg(), condition_comp(), make_hex_nodes, VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_max_edge_ratio()

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

Calculates hex maximum of edge ratio.

Maximum edge length ratio at hex center. Reference — L.M. Taylor, and D.P. Flanagan, Pronto3D - A Three Dimensional Transient Solid Dynamics Program, SAND87-1912, Sandia National Laboratories, 1989.

max edge ratio of a hex

Maximum edge length ratio at hex center

Definition at line 643 of file V_HexMetric.cpp.

644 { 645  double aspect; 646  VerdictVector node_pos[8]; 647  make_hex_nodes( coordinates, node_pos ); 648  649  double aspect_12, aspect_13, aspect_23; 650  651  VerdictVector efg1 = calc_hex_efg( 1, node_pos ); 652  VerdictVector efg2 = calc_hex_efg( 2, node_pos ); 653  VerdictVector efg3 = calc_hex_efg( 3, node_pos ); 654  655  double mag_efg1 = efg1.length(); 656  double mag_efg2 = efg2.length(); 657  double mag_efg3 = efg3.length(); 658  659  aspect_12 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg2 ), VERDICT_MIN( mag_efg1, mag_efg2 ) ); 660  aspect_13 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg3 ), VERDICT_MIN( mag_efg1, mag_efg3 ) ); 661  aspect_23 = safe_ratio( VERDICT_MAX( mag_efg2, mag_efg3 ), VERDICT_MIN( mag_efg2, mag_efg3 ) ); 662  663  aspect = VERDICT_MAX( aspect_12, VERDICT_MAX( aspect_13, aspect_23 ) ); 664  665  if( aspect > 0 ) return (double)VERDICT_MIN( aspect, VERDICT_DBL_MAX ); 666  return (double)VERDICT_MAX( aspect, -VERDICT_DBL_MAX ); 667 }

References calc_hex_efg(), VerdictVector::length(), make_hex_nodes, safe_ratio(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_med_aspect_frobenius()

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

Calculates hex condition metric.

Average Frobenius condition number of the Jacobian matrix at 8 corners.

the average Frobenius aspect of a hex

NB (P. Pebay 01/20/07): this metric is calculated by averaging the 8 Frobenius aspects at each corner of the hex, when the reference corner is right isosceles.

Definition at line 1164 of file V_HexMetric.cpp.

1165 { 1166  1167  VerdictVector node_pos[8]; 1168  make_hex_nodes( coordinates, node_pos ); 1169  1170  double med_aspect_frobenius = 0.; 1171  VerdictVector xxi, xet, xze; 1172  1173  // J(0,0,0): 1174  1175  xxi = node_pos[1] - node_pos[0]; 1176  xet = node_pos[3] - node_pos[0]; 1177  xze = node_pos[4] - node_pos[0]; 1178  1179  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1180  // J(1,0,0): 1181  1182  xxi = node_pos[2] - node_pos[1]; 1183  xet = node_pos[0] - node_pos[1]; 1184  xze = node_pos[5] - node_pos[1]; 1185  1186  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1187  // J(1,1,0): 1188  1189  xxi = node_pos[3] - node_pos[2]; 1190  xet = node_pos[1] - node_pos[2]; 1191  xze = node_pos[6] - node_pos[2]; 1192  1193  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1194  // J(0,1,0): 1195  1196  xxi = node_pos[0] - node_pos[3]; 1197  xet = node_pos[2] - node_pos[3]; 1198  xze = node_pos[7] - node_pos[3]; 1199  1200  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1201  // J(0,0,1): 1202  1203  xxi = node_pos[7] - node_pos[4]; 1204  xet = node_pos[5] - node_pos[4]; 1205  xze = node_pos[0] - node_pos[4]; 1206  1207  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1208  // J(1,0,1): 1209  1210  xxi = node_pos[4] - node_pos[5]; 1211  xet = node_pos[6] - node_pos[5]; 1212  xze = node_pos[1] - node_pos[5]; 1213  1214  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1215  // J(1,1,1): 1216  1217  xxi = node_pos[5] - node_pos[6]; 1218  xet = node_pos[7] - node_pos[6]; 1219  xze = node_pos[2] - node_pos[6]; 1220  1221  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1222  // J(1,1,1): 1223  1224  xxi = node_pos[6] - node_pos[7]; 1225  xet = node_pos[4] - node_pos[7]; 1226  xze = node_pos[3] - node_pos[7]; 1227  1228  med_aspect_frobenius += condition_comp( xxi, xet, xze ); 1229  med_aspect_frobenius /= 24.; 1230  1231  if( med_aspect_frobenius > 0 ) return (double)VERDICT_MIN( med_aspect_frobenius, VERDICT_DBL_MAX ); 1232  return (double)VERDICT_MAX( med_aspect_frobenius, -VERDICT_DBL_MAX ); 1233 }

References condition_comp(), make_hex_nodes, VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_oddy()

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

Calculates hex oddy metric.

oddy of a hex

General distortion measure based on left Cauchy-Green Tensor

Definition at line 1014 of file V_HexMetric.cpp.

1015 { 1016  1017  double oddy = 0.0, current_oddy; 1018  VerdictVector xxi, xet, xze; 1019  1020  VerdictVector node_pos[8]; 1021  make_hex_nodes( coordinates, node_pos ); 1022  1023  xxi = calc_hex_efg( 1, node_pos ); 1024  xet = calc_hex_efg( 2, node_pos ); 1025  xze = calc_hex_efg( 3, node_pos ); 1026  1027  current_oddy = oddy_comp( xxi, xet, xze ); 1028  if( current_oddy > oddy ) 1029  { 1030  oddy = current_oddy; 1031  } 1032  1033  xxi.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 1034  coordinates[1][2] - coordinates[0][2] ); 1035  1036  xet.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], 1037  coordinates[3][2] - coordinates[0][2] ); 1038  1039  xze.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1], 1040  coordinates[4][2] - coordinates[0][2] ); 1041  1042  current_oddy = oddy_comp( xxi, xet, xze ); 1043  if( current_oddy > oddy ) 1044  { 1045  oddy = current_oddy; 1046  } 1047  1048  xxi.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], 1049  coordinates[2][2] - coordinates[1][2] ); 1050  1051  xet.set( coordinates[0][0] - coordinates[1][0], coordinates[0][1] - coordinates[1][1], 1052  coordinates[0][2] - coordinates[1][2] ); 1053  1054  xze.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1], 1055  coordinates[5][2] - coordinates[1][2] ); 1056  1057  current_oddy = oddy_comp( xxi, xet, xze ); 1058  if( current_oddy > oddy ) 1059  { 1060  oddy = current_oddy; 1061  } 1062  1063  xxi.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], 1064  coordinates[3][2] - coordinates[2][2] ); 1065  1066  xet.set( coordinates[1][0] - coordinates[2][0], coordinates[1][1] - coordinates[2][1], 1067  coordinates[1][2] - coordinates[2][2] ); 1068  1069  xze.set( coordinates[6][0] - coordinates[2][0], coordinates[6][1] - coordinates[2][1], 1070  coordinates[6][2] - coordinates[2][2] ); 1071  1072  current_oddy = oddy_comp( xxi, xet, xze ); 1073  if( current_oddy > oddy ) 1074  { 1075  oddy = current_oddy; 1076  } 1077  1078  xxi.set( coordinates[0][0] - coordinates[3][0], coordinates[0][1] - coordinates[3][1], 1079  coordinates[0][2] - coordinates[3][2] ); 1080  1081  xet.set( coordinates[2][0] - coordinates[3][0], coordinates[2][1] - coordinates[3][1], 1082  coordinates[2][2] - coordinates[3][2] ); 1083  1084  xze.set( coordinates[7][0] - coordinates[3][0], coordinates[7][1] - coordinates[3][1], 1085  coordinates[7][2] - coordinates[3][2] ); 1086  1087  current_oddy = oddy_comp( xxi, xet, xze ); 1088  if( current_oddy > oddy ) 1089  { 1090  oddy = current_oddy; 1091  } 1092  1093  xxi.set( coordinates[7][0] - coordinates[4][0], coordinates[7][1] - coordinates[4][1], 1094  coordinates[7][2] - coordinates[4][2] ); 1095  1096  xet.set( coordinates[5][0] - coordinates[4][0], coordinates[5][1] - coordinates[4][1], 1097  coordinates[5][2] - coordinates[4][2] ); 1098  1099  xze.set( coordinates[0][0] - coordinates[4][0], coordinates[0][1] - coordinates[4][1], 1100  coordinates[0][2] - coordinates[4][2] ); 1101  1102  current_oddy = oddy_comp( xxi, xet, xze ); 1103  if( current_oddy > oddy ) 1104  { 1105  oddy = current_oddy; 1106  } 1107  1108  xxi.set( coordinates[4][0] - coordinates[5][0], coordinates[4][1] - coordinates[5][1], 1109  coordinates[4][2] - coordinates[5][2] ); 1110  1111  xet.set( coordinates[6][0] - coordinates[5][0], coordinates[6][1] - coordinates[5][1], 1112  coordinates[6][2] - coordinates[5][2] ); 1113  1114  xze.set( coordinates[1][0] - coordinates[5][0], coordinates[1][1] - coordinates[5][1], 1115  coordinates[1][2] - coordinates[5][2] ); 1116  1117  current_oddy = oddy_comp( xxi, xet, xze ); 1118  if( current_oddy > oddy ) 1119  { 1120  oddy = current_oddy; 1121  } 1122  1123  xxi.set( coordinates[5][0] - coordinates[6][0], coordinates[5][1] - coordinates[6][1], 1124  coordinates[5][2] - coordinates[6][2] ); 1125  1126  xet.set( coordinates[7][0] - coordinates[6][0], coordinates[7][1] - coordinates[6][1], 1127  coordinates[7][2] - coordinates[6][2] ); 1128  1129  xze.set( coordinates[2][0] - coordinates[6][0], coordinates[2][1] - coordinates[6][1], 1130  coordinates[2][2] - coordinates[6][2] ); 1131  1132  current_oddy = oddy_comp( xxi, xet, xze ); 1133  if( current_oddy > oddy ) 1134  { 1135  oddy = current_oddy; 1136  } 1137  1138  xxi.set( coordinates[6][0] - coordinates[7][0], coordinates[6][1] - coordinates[7][1], 1139  coordinates[6][2] - coordinates[7][2] ); 1140  1141  xet.set( coordinates[4][0] - coordinates[7][0], coordinates[4][1] - coordinates[7][1], 1142  coordinates[4][2] - coordinates[7][2] ); 1143  1144  xze.set( coordinates[3][0] - coordinates[7][0], coordinates[3][1] - coordinates[7][1], 1145  coordinates[3][2] - coordinates[7][2] ); 1146  1147  current_oddy = oddy_comp( xxi, xet, xze ); 1148  if( current_oddy > oddy ) 1149  { 1150  oddy = current_oddy; 1151  } 1152  1153  if( oddy > 0 ) return (double)VERDICT_MIN( oddy, VERDICT_DBL_MAX ); 1154  return (double)VERDICT_MAX( oddy, -VERDICT_DBL_MAX ); 1155 }

References calc_hex_efg(), make_hex_nodes, oddy_comp(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_quality()

C_FUNC_DEF void v_hex_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
HexMetricVals metric_vals 
)

Calculates quality metrics for hexahedral elements.

multiple quality metrics of a hex

Definition at line 2651 of file V_HexMetric.cpp.

2655 { 2656  memset( metric_vals, 0, sizeof( HexMetricVals ) ); 2657  2658  // max edge ratio, skew, taper, and volume 2659  if( metrics_request_flag & ( V_HEX_MAX_EDGE_RATIO | V_HEX_SKEW | V_HEX_TAPER ) ) 2660  { 2661  VerdictVector node_pos[8]; 2662  make_hex_nodes( coordinates, node_pos ); 2663  2664  VerdictVector efg1, efg2, efg3; 2665  efg1 = calc_hex_efg( 1, node_pos ); 2666  efg2 = calc_hex_efg( 2, node_pos ); 2667  efg3 = calc_hex_efg( 3, node_pos ); 2668  2669  if( metrics_request_flag & V_HEX_MAX_EDGE_RATIO ) 2670  { 2671  double max_edge_ratio_12, max_edge_ratio_13, max_edge_ratio_23; 2672  2673  double mag_efg1 = efg1.length(); 2674  double mag_efg2 = efg2.length(); 2675  double mag_efg3 = efg3.length(); 2676  2677  max_edge_ratio_12 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg2 ), VERDICT_MIN( mag_efg1, mag_efg2 ) ); 2678  max_edge_ratio_13 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg3 ), VERDICT_MIN( mag_efg1, mag_efg3 ) ); 2679  max_edge_ratio_23 = safe_ratio( VERDICT_MAX( mag_efg2, mag_efg3 ), VERDICT_MIN( mag_efg2, mag_efg3 ) ); 2680  2681  metric_vals->max_edge_ratio = 2682  (double)VERDICT_MAX( max_edge_ratio_12, VERDICT_MAX( max_edge_ratio_13, max_edge_ratio_23 ) ); 2683  } 2684  2685  if( metrics_request_flag & V_HEX_SKEW ) 2686  { 2687  2688  VerdictVector vec1 = efg1; 2689  VerdictVector vec2 = efg2; 2690  VerdictVector vec3 = efg3; 2691  2692  if( vec1.normalize() <= VERDICT_DBL_MIN || vec2.normalize() <= VERDICT_DBL_MIN || 2693  vec3.normalize() <= VERDICT_DBL_MIN ) 2694  { 2695  metric_vals->skew = (double)VERDICT_DBL_MAX; 2696  } 2697  else 2698  { 2699  double skewx = fabs( vec1 % vec2 ); 2700  double skewy = fabs( vec1 % vec3 ); 2701  double skewz = fabs( vec2 % vec3 ); 2702  2703  metric_vals->skew = (double)( VERDICT_MAX( skewx, VERDICT_MAX( skewy, skewz ) ) ); 2704  } 2705  } 2706  2707  if( metrics_request_flag & V_HEX_TAPER ) 2708  { 2709  VerdictVector efg12 = calc_hex_efg( 12, node_pos ); 2710  VerdictVector efg13 = calc_hex_efg( 13, node_pos ); 2711  VerdictVector efg23 = calc_hex_efg( 23, node_pos ); 2712  2713  double taperx = fabs( safe_ratio( efg12.length(), VERDICT_MIN( efg1.length(), efg2.length() ) ) ); 2714  double tapery = fabs( safe_ratio( efg13.length(), VERDICT_MIN( efg1.length(), efg3.length() ) ) ); 2715  double taperz = fabs( safe_ratio( efg23.length(), VERDICT_MIN( efg2.length(), efg3.length() ) ) ); 2716  2717  metric_vals->taper = (double)VERDICT_MAX( taperx, VERDICT_MAX( tapery, taperz ) ); 2718  } 2719  } 2720  2721  if( metrics_request_flag & V_HEX_VOLUME ) 2722  { 2723  metric_vals->volume = v_hex_volume( 8, coordinates ); 2724  } 2725  2726  if( metrics_request_flag & 2727  ( V_HEX_JACOBIAN | V_HEX_SCALED_JACOBIAN | V_HEX_CONDITION | V_HEX_SHEAR | V_HEX_SHAPE | 2728  V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE | V_HEX_STRETCH ) ) 2729  { 2730  2731  static const double two_thirds = 2.0 / 3.0; 2732  VerdictVector edges[12]; 2733  // the length squares 2734  double length_squared[12]; 2735  // make vectors from coordinates 2736  make_hex_edges( coordinates, edges ); 2737  2738  // calculate the length squares if we need to 2739  if( metrics_request_flag & 2740  ( V_HEX_JACOBIAN | V_HEX_SHEAR | V_HEX_SCALED_JACOBIAN | V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE | 2741  V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHEAR_AND_SIZE | V_HEX_STRETCH ) ) 2742  make_edge_length_squares( edges, length_squared ); 2743  2744  double jacobian = VERDICT_DBL_MAX, scaled_jacobian = VERDICT_DBL_MAX, condition = 0.0, shear = 1.0, shape = 1.0, 2745  oddy = 0.0; 2746  double current_jacobian, current_scaled_jacobian, current_condition, current_shape, detw = 0, det_sum = 0, 2747  current_oddy; 2748  VerdictBoolean rel_size_error = VERDICT_FALSE; 2749  2750  VerdictVector xxi, xet, xze; 2751  2752  // get weights if we need based on average size of a hex 2753  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 2754  { 2755  v_hex_get_weight( xxi, xet, xze ); 2756  detw = xxi % ( xet * xze ); 2757  if( detw < VERDICT_DBL_MIN ) rel_size_error = VERDICT_TRUE; 2758  } 2759  2760  xxi = edges[0] - edges[2] + edges[4] - edges[6]; 2761  xet = edges[1] - edges[3] + edges[5] - edges[7]; 2762  xze = edges[8] + edges[9] + edges[10] + edges[11]; 2763  2764  current_jacobian = xxi % ( xet * xze ) / 64.0; 2765  if( current_jacobian < jacobian ) jacobian = current_jacobian; 2766  2767  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 2768  { 2769  current_jacobian *= 64.0; 2770  current_scaled_jacobian = 2771  current_jacobian / sqrt( xxi.length_squared() * xet.length_squared() * xze.length_squared() ); 2772  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 2773  } 2774  2775  if( metrics_request_flag & V_HEX_CONDITION ) 2776  { 2777  current_condition = condition_comp( xxi, xet, xze ); 2778  if( current_condition > condition ) 2779  { 2780  condition = current_condition; 2781  } 2782  } 2783  2784  if( metrics_request_flag & V_HEX_ODDY ) 2785  { 2786  current_oddy = oddy_comp( xxi, xet, xze ); 2787  if( current_oddy > oddy ) 2788  { 2789  oddy = current_oddy; 2790  } 2791  } 2792  2793  // J(0,0,0) 2794  current_jacobian = edges[0] % ( -edges[3] * edges[8] ); 2795  if( current_jacobian < jacobian ) jacobian = current_jacobian; 2796  2797  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 2798  { 2799  det_sum += current_jacobian; 2800  } 2801  2802  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 2803  { 2804  if( length_squared[0] <= VERDICT_DBL_MIN || length_squared[3] <= VERDICT_DBL_MIN || 2805  length_squared[8] <= VERDICT_DBL_MIN ) 2806  { 2807  current_scaled_jacobian = VERDICT_DBL_MAX; 2808  } 2809  else 2810  { 2811  current_scaled_jacobian = 2812  current_jacobian / sqrt( length_squared[0] * length_squared[3] * length_squared[8] ); 2813  } 2814  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 2815  } 2816  2817  if( metrics_request_flag & V_HEX_CONDITION ) 2818  { 2819  current_condition = condition_comp( edges[0], -edges[3], edges[8] ); 2820  if( current_condition > condition ) 2821  { 2822  condition = current_condition; 2823  } 2824  } 2825  2826  if( metrics_request_flag & V_HEX_ODDY ) 2827  { 2828  current_oddy = oddy_comp( edges[0], -edges[3], edges[8] ); 2829  if( current_oddy > oddy ) 2830  { 2831  oddy = current_oddy; 2832  } 2833  } 2834  2835  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 2836  { 2837  if( current_jacobian > VERDICT_DBL_MIN ) 2838  current_shape = 3 * pow( current_jacobian, two_thirds ) / 2839  ( length_squared[0] + length_squared[3] + length_squared[8] ); 2840  else 2841  current_shape = 0; 2842  2843  if( current_shape < shape ) 2844  { 2845  shape = current_shape; 2846  } 2847  } 2848  2849  // J(1,0,0) 2850  current_jacobian = edges[1] % ( -edges[0] * edges[9] ); 2851  if( current_jacobian < jacobian ) jacobian = current_jacobian; 2852  2853  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 2854  { 2855  det_sum += current_jacobian; 2856  } 2857  2858  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 2859  { 2860  if( length_squared[1] <= VERDICT_DBL_MIN || length_squared[0] <= VERDICT_DBL_MIN || 2861  length_squared[9] <= VERDICT_DBL_MIN ) 2862  { 2863  current_scaled_jacobian = VERDICT_DBL_MAX; 2864  } 2865  else 2866  { 2867  current_scaled_jacobian = 2868  current_jacobian / sqrt( length_squared[1] * length_squared[0] * length_squared[9] ); 2869  } 2870  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 2871  } 2872  2873  if( metrics_request_flag & V_HEX_CONDITION ) 2874  { 2875  current_condition = condition_comp( edges[1], -edges[0], edges[9] ); 2876  if( current_condition > condition ) 2877  { 2878  condition = current_condition; 2879  } 2880  } 2881  2882  if( metrics_request_flag & V_HEX_ODDY ) 2883  { 2884  current_oddy = oddy_comp( edges[1], -edges[0], edges[9] ); 2885  if( current_oddy > oddy ) 2886  { 2887  oddy = current_oddy; 2888  } 2889  } 2890  2891  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 2892  { 2893  if( current_jacobian > VERDICT_DBL_MIN ) 2894  current_shape = 3 * pow( current_jacobian, two_thirds ) / 2895  ( length_squared[1] + length_squared[0] + length_squared[9] ); 2896  else 2897  current_shape = 0; 2898  2899  if( current_shape < shape ) 2900  { 2901  shape = current_shape; 2902  } 2903  } 2904  2905  // J(1,1,0) 2906  current_jacobian = edges[2] % ( -edges[1] * edges[10] ); 2907  if( current_jacobian < jacobian ) jacobian = current_jacobian; 2908  2909  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 2910  { 2911  det_sum += current_jacobian; 2912  } 2913  2914  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 2915  { 2916  if( length_squared[2] <= VERDICT_DBL_MIN || length_squared[1] <= VERDICT_DBL_MIN || 2917  length_squared[10] <= VERDICT_DBL_MIN ) 2918  { 2919  current_scaled_jacobian = VERDICT_DBL_MAX; 2920  } 2921  else 2922  { 2923  current_scaled_jacobian = 2924  current_jacobian / sqrt( length_squared[2] * length_squared[1] * length_squared[10] ); 2925  } 2926  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 2927  } 2928  2929  if( metrics_request_flag & V_HEX_CONDITION ) 2930  { 2931  current_condition = condition_comp( edges[2], -edges[1], edges[10] ); 2932  if( current_condition > condition ) 2933  { 2934  condition = current_condition; 2935  } 2936  } 2937  2938  if( metrics_request_flag & V_HEX_ODDY ) 2939  { 2940  current_oddy = oddy_comp( edges[2], -edges[1], edges[10] ); 2941  if( current_oddy > oddy ) 2942  { 2943  oddy = current_oddy; 2944  } 2945  } 2946  2947  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 2948  { 2949  if( current_jacobian > VERDICT_DBL_MIN ) 2950  current_shape = 3 * pow( current_jacobian, two_thirds ) / 2951  ( length_squared[2] + length_squared[1] + length_squared[10] ); 2952  else 2953  current_shape = 0; 2954  2955  if( current_shape < shape ) 2956  { 2957  shape = current_shape; 2958  } 2959  } 2960  2961  // J(0,1,0) 2962  current_jacobian = edges[3] % ( -edges[2] * edges[11] ); 2963  if( current_jacobian < jacobian ) jacobian = current_jacobian; 2964  2965  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 2966  { 2967  det_sum += current_jacobian; 2968  } 2969  2970  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 2971  { 2972  if( length_squared[3] <= VERDICT_DBL_MIN || length_squared[2] <= VERDICT_DBL_MIN || 2973  length_squared[11] <= VERDICT_DBL_MIN ) 2974  { 2975  current_scaled_jacobian = VERDICT_DBL_MAX; 2976  } 2977  else 2978  { 2979  current_scaled_jacobian = 2980  current_jacobian / sqrt( length_squared[3] * length_squared[2] * length_squared[11] ); 2981  } 2982  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 2983  } 2984  2985  if( metrics_request_flag & V_HEX_CONDITION ) 2986  { 2987  current_condition = condition_comp( edges[3], -edges[2], edges[11] ); 2988  if( current_condition > condition ) 2989  { 2990  condition = current_condition; 2991  } 2992  } 2993  2994  if( metrics_request_flag & V_HEX_ODDY ) 2995  { 2996  current_oddy = oddy_comp( edges[3], -edges[2], edges[11] ); 2997  if( current_oddy > oddy ) 2998  { 2999  oddy = current_oddy; 3000  } 3001  } 3002  3003  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 3004  { 3005  if( current_jacobian > VERDICT_DBL_MIN ) 3006  current_shape = 3 * pow( current_jacobian, two_thirds ) / 3007  ( length_squared[3] + length_squared[2] + length_squared[11] ); 3008  else 3009  current_shape = 0; 3010  3011  if( current_shape < shape ) 3012  { 3013  shape = current_shape; 3014  } 3015  } 3016  3017  // J(0,0,1) 3018  current_jacobian = edges[4] % ( -edges[8] * -edges[7] ); 3019  if( current_jacobian < jacobian ) jacobian = current_jacobian; 3020  3021  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 3022  { 3023  det_sum += current_jacobian; 3024  } 3025  3026  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 3027  { 3028  if( length_squared[4] <= VERDICT_DBL_MIN || length_squared[8] <= VERDICT_DBL_MIN || 3029  length_squared[7] <= VERDICT_DBL_MIN ) 3030  { 3031  current_scaled_jacobian = VERDICT_DBL_MAX; 3032  } 3033  else 3034  { 3035  current_scaled_jacobian = 3036  current_jacobian / sqrt( length_squared[4] * length_squared[8] * length_squared[7] ); 3037  } 3038  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 3039  } 3040  3041  if( metrics_request_flag & V_HEX_CONDITION ) 3042  { 3043  current_condition = condition_comp( edges[4], -edges[8], -edges[7] ); 3044  if( current_condition > condition ) 3045  { 3046  condition = current_condition; 3047  } 3048  } 3049  3050  if( metrics_request_flag & V_HEX_ODDY ) 3051  { 3052  current_oddy = oddy_comp( edges[4], -edges[8], -edges[7] ); 3053  if( current_oddy > oddy ) 3054  { 3055  oddy = current_oddy; 3056  } 3057  } 3058  3059  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 3060  { 3061  if( current_jacobian > VERDICT_DBL_MIN ) 3062  current_shape = 3 * pow( current_jacobian, two_thirds ) / 3063  ( length_squared[4] + length_squared[8] + length_squared[7] ); 3064  else 3065  current_shape = 0; 3066  3067  if( current_shape < shape ) 3068  { 3069  shape = current_shape; 3070  } 3071  } 3072  3073  // J(1,0,1) 3074  current_jacobian = -edges[4] % ( edges[5] * -edges[9] ); 3075  if( current_jacobian < jacobian ) jacobian = current_jacobian; 3076  3077  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 3078  { 3079  det_sum += current_jacobian; 3080  } 3081  3082  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 3083  { 3084  if( length_squared[4] <= VERDICT_DBL_MIN || length_squared[5] <= VERDICT_DBL_MIN || 3085  length_squared[9] <= VERDICT_DBL_MIN ) 3086  { 3087  current_scaled_jacobian = VERDICT_DBL_MAX; 3088  } 3089  else 3090  { 3091  current_scaled_jacobian = 3092  current_jacobian / sqrt( length_squared[4] * length_squared[5] * length_squared[9] ); 3093  } 3094  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 3095  } 3096  3097  if( metrics_request_flag & V_HEX_CONDITION ) 3098  { 3099  current_condition = condition_comp( -edges[4], edges[5], -edges[9] ); 3100  if( current_condition > condition ) 3101  { 3102  condition = current_condition; 3103  } 3104  } 3105  3106  if( metrics_request_flag & V_HEX_ODDY ) 3107  { 3108  current_oddy = oddy_comp( -edges[4], edges[5], -edges[9] ); 3109  if( current_oddy > oddy ) 3110  { 3111  oddy = current_oddy; 3112  } 3113  } 3114  3115  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 3116  { 3117  if( current_jacobian > VERDICT_DBL_MIN ) 3118  current_shape = 3 * pow( current_jacobian, two_thirds ) / 3119  ( length_squared[4] + length_squared[5] + length_squared[9] ); 3120  else 3121  current_shape = 0; 3122  3123  if( current_shape < shape ) 3124  { 3125  shape = current_shape; 3126  } 3127  } 3128  3129  // J(1,1,1) 3130  current_jacobian = -edges[5] % ( edges[6] * -edges[10] ); 3131  if( current_jacobian < jacobian ) jacobian = current_jacobian; 3132  3133  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 3134  { 3135  det_sum += current_jacobian; 3136  } 3137  3138  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 3139  { 3140  if( length_squared[5] <= VERDICT_DBL_MIN || length_squared[6] <= VERDICT_DBL_MIN || 3141  length_squared[10] <= VERDICT_DBL_MIN ) 3142  { 3143  current_scaled_jacobian = VERDICT_DBL_MAX; 3144  } 3145  else 3146  { 3147  current_scaled_jacobian = 3148  current_jacobian / sqrt( length_squared[5] * length_squared[6] * length_squared[10] ); 3149  } 3150  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 3151  } 3152  3153  if( metrics_request_flag & V_HEX_CONDITION ) 3154  { 3155  current_condition = condition_comp( -edges[5], edges[6], -edges[10] ); 3156  if( current_condition > condition ) 3157  { 3158  condition = current_condition; 3159  } 3160  } 3161  3162  if( metrics_request_flag & V_HEX_ODDY ) 3163  { 3164  current_oddy = oddy_comp( -edges[5], edges[6], -edges[10] ); 3165  if( current_oddy > oddy ) 3166  { 3167  oddy = current_oddy; 3168  } 3169  } 3170  3171  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 3172  { 3173  if( current_jacobian > VERDICT_DBL_MIN ) 3174  current_shape = 3 * pow( current_jacobian, two_thirds ) / 3175  ( length_squared[5] + length_squared[6] + length_squared[10] ); 3176  else 3177  current_shape = 0; 3178  3179  if( current_shape < shape ) 3180  { 3181  shape = current_shape; 3182  } 3183  } 3184  3185  // J(0,1,1) 3186  current_jacobian = -edges[6] % ( edges[7] * -edges[11] ); 3187  if( current_jacobian < jacobian ) jacobian = current_jacobian; 3188  3189  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 3190  { 3191  det_sum += current_jacobian; 3192  } 3193  3194  if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) ) 3195  { 3196  if( length_squared[6] <= VERDICT_DBL_MIN || length_squared[7] <= VERDICT_DBL_MIN || 3197  length_squared[11] <= VERDICT_DBL_MIN ) 3198  { 3199  current_scaled_jacobian = VERDICT_DBL_MAX; 3200  } 3201  else 3202  { 3203  current_scaled_jacobian = 3204  current_jacobian / sqrt( length_squared[6] * length_squared[7] * length_squared[11] ); 3205  } 3206  if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian; 3207  } 3208  3209  if( metrics_request_flag & V_HEX_CONDITION ) 3210  { 3211  current_condition = condition_comp( -edges[6], edges[7], -edges[11] ); 3212  if( current_condition > condition ) 3213  { 3214  condition = current_condition; 3215  } 3216  } 3217  3218  if( metrics_request_flag & V_HEX_ODDY ) 3219  { 3220  current_oddy = oddy_comp( -edges[6], edges[7], -edges[11] ); 3221  if( current_oddy > oddy ) 3222  { 3223  oddy = current_oddy; 3224  } 3225  } 3226  3227  if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) ) 3228  { 3229  if( current_jacobian > VERDICT_DBL_MIN ) 3230  current_shape = 3 * pow( current_jacobian, two_thirds ) / 3231  ( length_squared[6] + length_squared[7] + length_squared[11] ); 3232  else 3233  current_shape = 0; 3234  3235  if( current_shape < shape ) 3236  { 3237  shape = current_shape; 3238  } 3239  } 3240  3241  if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) ) 3242  { 3243  if( det_sum > VERDICT_DBL_MIN && rel_size_error != VERDICT_TRUE ) 3244  { 3245  double tau = det_sum / ( 8 * detw ); 3246  metric_vals->relative_size_squared = (double)VERDICT_MIN( tau * tau, 1.0 / tau / tau ); 3247  } 3248  else 3249  metric_vals->relative_size_squared = 0.0; 3250  } 3251  3252  // set values from above calculations 3253  if( metrics_request_flag & V_HEX_JACOBIAN ) metric_vals->jacobian = (double)jacobian; 3254  3255  if( metrics_request_flag & V_HEX_SCALED_JACOBIAN ) metric_vals->scaled_jacobian = (double)scaled_jacobian; 3256  3257  if( metrics_request_flag & V_HEX_CONDITION ) metric_vals->condition = (double)( condition / 3.0 ); 3258  3259  if( metrics_request_flag & V_HEX_SHEAR ) 3260  { 3261  if( shear < VERDICT_DBL_MIN ) // shear has range 0 to +1 3262  shear = 0; 3263  metric_vals->shear = (double)shear; 3264  } 3265  3266  if( metrics_request_flag & V_HEX_SHAPE ) metric_vals->shape = (double)shape; 3267  3268  if( metrics_request_flag & V_HEX_SHAPE_AND_SIZE ) 3269  metric_vals->shape_and_size = (double)( shape * metric_vals->relative_size_squared ); 3270  3271  if( metrics_request_flag & V_HEX_SHEAR_AND_SIZE ) 3272  metric_vals->shear_and_size = (double)( shear * metric_vals->relative_size_squared ); 3273  3274  if( metrics_request_flag & V_HEX_ODDY ) metric_vals->oddy = (double)oddy; 3275  3276  if( metrics_request_flag & V_HEX_STRETCH ) 3277  { 3278  static const double HEX_STRETCH_SCALE_FACTOR = sqrt( 3.0 ); 3279  double min_edge = length_squared[0]; 3280  for( int j = 1; j < 12; j++ ) 3281  min_edge = VERDICT_MIN( min_edge, length_squared[j] ); 3282  3283  double max_diag = diag_length( 1, coordinates ); 3284  3285  metric_vals->stretch = (double)( HEX_STRETCH_SCALE_FACTOR * ( safe_ratio( sqrt( min_edge ), max_diag ) ) ); 3286  } 3287  } 3288  3289  if( metrics_request_flag & V_HEX_DIAGONAL ) metric_vals->diagonal = v_hex_diagonal( num_nodes, coordinates ); 3290  if( metrics_request_flag & V_HEX_DIMENSION ) metric_vals->dimension = v_hex_dimension( num_nodes, coordinates ); 3291  if( metrics_request_flag & V_HEX_DISTORTION ) metric_vals->distortion = v_hex_distortion( num_nodes, coordinates ); 3292  3293  // take care of any overflow problems 3294  // max_edge_ratio 3295  if( metric_vals->max_edge_ratio > 0 ) 3296  metric_vals->max_edge_ratio = (double)VERDICT_MIN( metric_vals->max_edge_ratio, VERDICT_DBL_MAX ); 3297  else 3298  metric_vals->max_edge_ratio = (double)VERDICT_MAX( metric_vals->max_edge_ratio, -VERDICT_DBL_MAX ); 3299  3300  // skew 3301  if( metric_vals->skew > 0 ) 3302  metric_vals->skew = (double)VERDICT_MIN( metric_vals->skew, VERDICT_DBL_MAX ); 3303  else 3304  metric_vals->skew = (double)VERDICT_MAX( metric_vals->skew, -VERDICT_DBL_MAX ); 3305  3306  // taper 3307  if( metric_vals->taper > 0 ) 3308  metric_vals->taper = (double)VERDICT_MIN( metric_vals->taper, VERDICT_DBL_MAX ); 3309  else 3310  metric_vals->taper = (double)VERDICT_MAX( metric_vals->taper, -VERDICT_DBL_MAX ); 3311  3312  // volume 3313  if( metric_vals->volume > 0 ) 3314  metric_vals->volume = (double)VERDICT_MIN( metric_vals->volume, VERDICT_DBL_MAX ); 3315  else 3316  metric_vals->volume = (double)VERDICT_MAX( metric_vals->volume, -VERDICT_DBL_MAX ); 3317  3318  // stretch 3319  if( metric_vals->stretch > 0 ) 3320  metric_vals->stretch = (double)VERDICT_MIN( metric_vals->stretch, VERDICT_DBL_MAX ); 3321  else 3322  metric_vals->stretch = (double)VERDICT_MAX( metric_vals->stretch, -VERDICT_DBL_MAX ); 3323  3324  // diagonal 3325  if( metric_vals->diagonal > 0 ) 3326  metric_vals->diagonal = (double)VERDICT_MIN( metric_vals->diagonal, VERDICT_DBL_MAX ); 3327  else 3328  metric_vals->diagonal = (double)VERDICT_MAX( metric_vals->diagonal, -VERDICT_DBL_MAX ); 3329  3330  // dimension 3331  if( metric_vals->dimension > 0 ) 3332  metric_vals->dimension = (double)VERDICT_MIN( metric_vals->dimension, VERDICT_DBL_MAX ); 3333  else 3334  metric_vals->dimension = (double)VERDICT_MAX( metric_vals->dimension, -VERDICT_DBL_MAX ); 3335  3336  // oddy 3337  if( metric_vals->oddy > 0 ) 3338  metric_vals->oddy = (double)VERDICT_MIN( metric_vals->oddy, VERDICT_DBL_MAX ); 3339  else 3340  metric_vals->oddy = (double)VERDICT_MAX( metric_vals->oddy, -VERDICT_DBL_MAX ); 3341  3342  // condition 3343  if( metric_vals->condition > 0 ) 3344  metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX ); 3345  else 3346  metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX ); 3347  3348  // jacobian 3349  if( metric_vals->jacobian > 0 ) 3350  metric_vals->jacobian = (double)VERDICT_MIN( metric_vals->jacobian, VERDICT_DBL_MAX ); 3351  else 3352  metric_vals->jacobian = (double)VERDICT_MAX( metric_vals->jacobian, -VERDICT_DBL_MAX ); 3353  3354  // scaled_jacobian 3355  if( metric_vals->scaled_jacobian > 0 ) 3356  metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX ); 3357  else 3358  metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX ); 3359  3360  // shear 3361  if( metric_vals->shear > 0 ) 3362  metric_vals->shear = (double)VERDICT_MIN( metric_vals->shear, VERDICT_DBL_MAX ); 3363  else 3364  metric_vals->shear = (double)VERDICT_MAX( metric_vals->shear, -VERDICT_DBL_MAX ); 3365  3366  // shape 3367  if( metric_vals->shape > 0 ) 3368  metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX ); 3369  else 3370  metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX ); 3371  3372  // relative_size_squared 3373  if( metric_vals->relative_size_squared > 0 ) 3374  metric_vals->relative_size_squared = (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX ); 3375  else 3376  metric_vals->relative_size_squared = 3377  (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX ); 3378  3379  // shape_and_size 3380  if( metric_vals->shape_and_size > 0 ) 3381  metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX ); 3382  else 3383  metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX ); 3384  3385  // shear_and_size 3386  if( metric_vals->shear_and_size > 0 ) 3387  metric_vals->shear_and_size = (double)VERDICT_MIN( metric_vals->shear_and_size, VERDICT_DBL_MAX ); 3388  else 3389  metric_vals->shear_and_size = (double)VERDICT_MAX( metric_vals->shear_and_size, -VERDICT_DBL_MAX ); 3390  3391  // distortion 3392  if( metric_vals->distortion > 0 ) 3393  metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX ); 3394  else 3395  metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX ); 3396  3397  if( metrics_request_flag & V_HEX_MED_ASPECT_FROBENIUS ) 3398  metric_vals->med_aspect_frobenius = v_hex_med_aspect_frobenius( 8, coordinates ); 3399  3400  if( metrics_request_flag & V_HEX_EDGE_RATIO ) metric_vals->edge_ratio = v_hex_edge_ratio( 8, coordinates ); 3401 }

References calc_hex_efg(), HexMetricVals::condition, condition_comp(), diag_length(), HexMetricVals::diagonal, HexMetricVals::dimension, HexMetricVals::distortion, HexMetricVals::edge_ratio, HexMetricVals::jacobian, VerdictVector::length(), VerdictVector::length_squared(), length_squared(), make_edge_length_squares, make_hex_edges(), make_hex_nodes, HexMetricVals::max_edge_ratio, HexMetricVals::med_aspect_frobenius, VerdictVector::normalize(), HexMetricVals::oddy, oddy_comp(), HexMetricVals::relative_size_squared, safe_ratio(), HexMetricVals::scaled_jacobian, HexMetricVals::shape, HexMetricVals::shape_and_size, HexMetricVals::shear, HexMetricVals::shear_and_size, HexMetricVals::skew, HexMetricVals::stretch, HexMetricVals::taper, V_HEX_CONDITION, V_HEX_DIAGONAL, v_hex_diagonal(), V_HEX_DIMENSION, v_hex_dimension(), V_HEX_DISTORTION, v_hex_distortion(), V_HEX_EDGE_RATIO, v_hex_edge_ratio(), v_hex_get_weight(), V_HEX_JACOBIAN, V_HEX_MAX_EDGE_RATIO, V_HEX_MED_ASPECT_FROBENIUS, v_hex_med_aspect_frobenius(), V_HEX_ODDY, V_HEX_RELATIVE_SIZE_SQUARED, V_HEX_SCALED_JACOBIAN, V_HEX_SHAPE, V_HEX_SHAPE_AND_SIZE, V_HEX_SHEAR, V_HEX_SHEAR_AND_SIZE, V_HEX_SKEW, V_HEX_STRETCH, V_HEX_TAPER, V_HEX_VOLUME, v_hex_volume(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_FALSE, VERDICT_MAX, VERDICT_MIN, VERDICT_TRUE, and HexMetricVals::volume.

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

◆ v_hex_relative_size_squared()

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

Calculates hex relative size metric.

3/Mean Ratio of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

relative size of a hex

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

Definition at line 2090 of file V_HexMetric.cpp.

2091 { 2092  double size = 0; 2093  double tau; 2094  2095  VerdictVector xxi, xet, xze; 2096  double det, det_sum = 0; 2097  2098  v_hex_get_weight( xxi, xet, xze ); 2099  2100  // This is the average relative size 2101  double detw = xxi % ( xet * xze ); 2102  2103  if( detw < VERDICT_DBL_MIN ) return 0; 2104  2105  VerdictVector node_pos[8]; 2106  make_hex_nodes( coordinates, node_pos ); 2107  2108  // J(0,0,0): 2109  2110  xxi = node_pos[1] - node_pos[0]; 2111  xet = node_pos[3] - node_pos[0]; 2112  xze = node_pos[4] - node_pos[0]; 2113  2114  det = xxi % ( xet * xze ); 2115  det_sum += det; 2116  2117  // J(1,0,0): 2118  2119  xxi = node_pos[2] - node_pos[1]; 2120  xet = node_pos[0] - node_pos[1]; 2121  xze = node_pos[5] - node_pos[1]; 2122  2123  det = xxi % ( xet * xze ); 2124  det_sum += det; 2125  2126  // J(0,1,0): 2127  2128  xxi = node_pos[3] - node_pos[2]; 2129  xet = node_pos[1] - node_pos[2]; 2130  xze = node_pos[6] - node_pos[2]; 2131  2132  det = xxi % ( xet * xze ); 2133  det_sum += det; 2134  2135  // J(1,1,0): 2136  2137  xxi = node_pos[0] - node_pos[3]; 2138  xet = node_pos[2] - node_pos[3]; 2139  xze = node_pos[7] - node_pos[3]; 2140  2141  det = xxi % ( xet * xze ); 2142  det_sum += det; 2143  2144  // J(0,1,0): 2145  2146  xxi = node_pos[7] - node_pos[4]; 2147  xet = node_pos[5] - node_pos[4]; 2148  xze = node_pos[0] - node_pos[4]; 2149  2150  det = xxi % ( xet * xze ); 2151  det_sum += det; 2152  2153  // J(1,0,1): 2154  2155  xxi = node_pos[4] - node_pos[5]; 2156  xet = node_pos[6] - node_pos[5]; 2157  xze = node_pos[1] - node_pos[5]; 2158  2159  det = xxi % ( xet * xze ); 2160  det_sum += det; 2161  2162  // J(1,1,1): 2163  2164  xxi = node_pos[5] - node_pos[6]; 2165  xet = node_pos[7] - node_pos[6]; 2166  xze = node_pos[2] - node_pos[6]; 2167  2168  det = xxi % ( xet * xze ); 2169  det_sum += det; 2170  2171  // J(1,1,1): 2172  2173  xxi = node_pos[6] - node_pos[7]; 2174  xet = node_pos[4] - node_pos[7]; 2175  xze = node_pos[3] - node_pos[7]; 2176  2177  det = xxi % ( xet * xze ); 2178  det_sum += det; 2179  2180  if( det_sum > VERDICT_DBL_MIN ) 2181  { 2182  tau = det_sum / ( 8 * detw ); 2183  2184  tau = VERDICT_MIN( tau, 1.0 / tau ); 2185  2186  size = tau * tau; 2187  } 2188  2189  if( size > 0 ) return (double)VERDICT_MIN( size, VERDICT_DBL_MAX ); 2190  return (double)VERDICT_MAX( size, -VERDICT_DBL_MAX ); 2191 }

References make_hex_nodes, size, v_hex_get_weight(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), v_hex_shape_and_size(), and v_hex_shear_and_size().

◆ v_hex_scaled_jacobian()

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

Calculates hex scaled jacobian metric.

Minimum Jacobian divided by the lengths of the 3 edge vectors. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

scaled jacobian of a hex

Minimum Jacobian divided by the lengths of the 3 edge vectors

Definition at line 1507 of file V_HexMetric.cpp.

1508 { 1509  1510  double jacobi, min_norm_jac = VERDICT_DBL_MAX; 1511  // double min_jacobi = VERDICT_DBL_MAX; 1512  double temp_norm_jac, lengths; 1513  double len1_sq, len2_sq, len3_sq; 1514  VerdictVector xxi, xet, xze; 1515  1516  VerdictVector node_pos[8]; 1517  make_hex_nodes( coordinates, node_pos ); 1518  1519  xxi = calc_hex_efg( 1, node_pos ); 1520  xet = calc_hex_efg( 2, node_pos ); 1521  xze = calc_hex_efg( 3, node_pos ); 1522  1523  jacobi = xxi % ( xet * xze ); 1524  // if( jacobi < min_jacobi) { min_jacobi = jacobi; } 1525  1526  len1_sq = xxi.length_squared(); 1527  len2_sq = xet.length_squared(); 1528  len3_sq = xze.length_squared(); 1529  1530  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1531  return (double)VERDICT_DBL_MAX; 1532  1533  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1534  temp_norm_jac = jacobi / lengths; 1535  1536  if( temp_norm_jac < min_norm_jac ) 1537  min_norm_jac = temp_norm_jac; 1538  else 1539  temp_norm_jac = jacobi; 1540  1541  // J(0,0,0): 1542  1543  xxi = node_pos[1] - node_pos[0]; 1544  xet = node_pos[3] - node_pos[0]; 1545  xze = node_pos[4] - node_pos[0]; 1546  1547  jacobi = xxi % ( xet * xze ); 1548  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1549  1550  len1_sq = xxi.length_squared(); 1551  len2_sq = xet.length_squared(); 1552  len3_sq = xze.length_squared(); 1553  1554  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1555  return (double)VERDICT_DBL_MAX; 1556  1557  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1558  temp_norm_jac = jacobi / lengths; 1559  if( temp_norm_jac < min_norm_jac ) 1560  min_norm_jac = temp_norm_jac; 1561  else 1562  temp_norm_jac = jacobi; 1563  1564  // J(1,0,0): 1565  1566  xxi = node_pos[2] - node_pos[1]; 1567  xet = node_pos[0] - node_pos[1]; 1568  xze = node_pos[5] - node_pos[1]; 1569  1570  jacobi = xxi % ( xet * xze ); 1571  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1572  1573  len1_sq = xxi.length_squared(); 1574  len2_sq = xet.length_squared(); 1575  len3_sq = xze.length_squared(); 1576  1577  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1578  return (double)VERDICT_DBL_MAX; 1579  1580  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1581  temp_norm_jac = jacobi / lengths; 1582  if( temp_norm_jac < min_norm_jac ) 1583  min_norm_jac = temp_norm_jac; 1584  else 1585  temp_norm_jac = jacobi; 1586  1587  // J(1,1,0): 1588  1589  xxi = node_pos[3] - node_pos[2]; 1590  xet = node_pos[1] - node_pos[2]; 1591  xze = node_pos[6] - node_pos[2]; 1592  1593  jacobi = xxi % ( xet * xze ); 1594  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1595  1596  len1_sq = xxi.length_squared(); 1597  len2_sq = xet.length_squared(); 1598  len3_sq = xze.length_squared(); 1599  1600  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1601  return (double)VERDICT_DBL_MAX; 1602  1603  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1604  temp_norm_jac = jacobi / lengths; 1605  if( temp_norm_jac < min_norm_jac ) 1606  min_norm_jac = temp_norm_jac; 1607  else 1608  temp_norm_jac = jacobi; 1609  1610  // J(0,1,0): 1611  1612  xxi = node_pos[0] - node_pos[3]; 1613  xet = node_pos[2] - node_pos[3]; 1614  xze = node_pos[7] - node_pos[3]; 1615  1616  jacobi = xxi % ( xet * xze ); 1617  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1618  1619  len1_sq = xxi.length_squared(); 1620  len2_sq = xet.length_squared(); 1621  len3_sq = xze.length_squared(); 1622  1623  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1624  return (double)VERDICT_DBL_MAX; 1625  1626  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1627  temp_norm_jac = jacobi / lengths; 1628  if( temp_norm_jac < min_norm_jac ) 1629  min_norm_jac = temp_norm_jac; 1630  else 1631  temp_norm_jac = jacobi; 1632  1633  // J(0,0,1): 1634  1635  xxi = node_pos[7] - node_pos[4]; 1636  xet = node_pos[5] - node_pos[4]; 1637  xze = node_pos[0] - node_pos[4]; 1638  1639  jacobi = xxi % ( xet * xze ); 1640  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1641  1642  len1_sq = xxi.length_squared(); 1643  len2_sq = xet.length_squared(); 1644  len3_sq = xze.length_squared(); 1645  1646  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1647  return (double)VERDICT_DBL_MAX; 1648  1649  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1650  temp_norm_jac = jacobi / lengths; 1651  if( temp_norm_jac < min_norm_jac ) 1652  min_norm_jac = temp_norm_jac; 1653  else 1654  temp_norm_jac = jacobi; 1655  1656  // J(1,0,1): 1657  1658  xxi = node_pos[4] - node_pos[5]; 1659  xet = node_pos[6] - node_pos[5]; 1660  xze = node_pos[1] - node_pos[5]; 1661  1662  jacobi = xxi % ( xet * xze ); 1663  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1664  1665  len1_sq = xxi.length_squared(); 1666  len2_sq = xet.length_squared(); 1667  len3_sq = xze.length_squared(); 1668  1669  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1670  return (double)VERDICT_DBL_MAX; 1671  1672  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1673  temp_norm_jac = jacobi / lengths; 1674  if( temp_norm_jac < min_norm_jac ) 1675  min_norm_jac = temp_norm_jac; 1676  else 1677  temp_norm_jac = jacobi; 1678  1679  // J(1,1,1): 1680  1681  xxi = node_pos[5] - node_pos[6]; 1682  xet = node_pos[7] - node_pos[6]; 1683  xze = node_pos[2] - node_pos[6]; 1684  1685  jacobi = xxi % ( xet * xze ); 1686  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1687  1688  len1_sq = xxi.length_squared(); 1689  len2_sq = xet.length_squared(); 1690  len3_sq = xze.length_squared(); 1691  1692  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1693  return (double)VERDICT_DBL_MAX; 1694  1695  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1696  temp_norm_jac = jacobi / lengths; 1697  if( temp_norm_jac < min_norm_jac ) 1698  min_norm_jac = temp_norm_jac; 1699  else 1700  temp_norm_jac = jacobi; 1701  1702  // J(0,1,1): 1703  1704  xxi = node_pos[6] - node_pos[7]; 1705  xet = node_pos[4] - node_pos[7]; 1706  xze = node_pos[3] - node_pos[7]; 1707  1708  jacobi = xxi % ( xet * xze ); 1709  // if( jacobi < min_jacobi ) { min_jacobi = jacobi; } 1710  1711  len1_sq = xxi.length_squared(); 1712  len2_sq = xet.length_squared(); 1713  len3_sq = xze.length_squared(); 1714  1715  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) 1716  return (double)VERDICT_DBL_MAX; 1717  1718  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1719  temp_norm_jac = jacobi / lengths; 1720  if( temp_norm_jac < min_norm_jac ) min_norm_jac = temp_norm_jac; 1721  // else 1722  // temp_norm_jac = jacobi; 1723  1724  if( min_norm_jac > 0 ) return (double)VERDICT_MIN( min_norm_jac, VERDICT_DBL_MAX ); 1725  return (double)VERDICT_MAX( min_norm_jac, -VERDICT_DBL_MAX ); 1726 }

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

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

◆ v_hex_shape()

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

Calculates hex shape metric.

3/Mean Ratio of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

shape of a hex

3/Condition number of weighted Jacobian matrix

Definition at line 1931 of file V_HexMetric.cpp.

1932 { 1933  1934  double det, shape; 1935  double min_shape = 1.0; 1936  static const double two_thirds = 2.0 / 3.0; 1937  1938  VerdictVector xxi, xet, xze; 1939  1940  VerdictVector node_pos[8]; 1941  make_hex_nodes( coordinates, node_pos ); 1942  1943  // J(0,0,0): 1944  1945  xxi = node_pos[1] - node_pos[0]; 1946  xet = node_pos[3] - node_pos[0]; 1947  xze = node_pos[4] - node_pos[0]; 1948  1949  det = xxi % ( xet * xze ); 1950  if( det > VERDICT_DBL_MIN ) 1951  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 1952  else 1953  return 0; 1954  1955  if( shape < min_shape ) 1956  { 1957  min_shape = shape; 1958  } 1959  1960  // J(1,0,0): 1961  1962  xxi = node_pos[2] - node_pos[1]; 1963  xet = node_pos[0] - node_pos[1]; 1964  xze = node_pos[5] - node_pos[1]; 1965  1966  det = xxi % ( xet * xze ); 1967  if( det > VERDICT_DBL_MIN ) 1968  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 1969  else 1970  return 0; 1971  1972  if( shape < min_shape ) 1973  { 1974  min_shape = shape; 1975  } 1976  1977  // J(1,1,0): 1978  1979  xxi = node_pos[3] - node_pos[2]; 1980  xet = node_pos[1] - node_pos[2]; 1981  xze = node_pos[6] - node_pos[2]; 1982  1983  det = xxi % ( xet * xze ); 1984  if( det > VERDICT_DBL_MIN ) 1985  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 1986  else 1987  return 0; 1988  1989  if( shape < min_shape ) 1990  { 1991  min_shape = shape; 1992  } 1993  1994  // J(0,1,0): 1995  1996  xxi = node_pos[0] - node_pos[3]; 1997  xet = node_pos[2] - node_pos[3]; 1998  xze = node_pos[7] - node_pos[3]; 1999  2000  det = xxi % ( xet * xze ); 2001  if( det > VERDICT_DBL_MIN ) 2002  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 2003  else 2004  return 0; 2005  2006  if( shape < min_shape ) 2007  { 2008  min_shape = shape; 2009  } 2010  2011  // J(0,0,1): 2012  2013  xxi = node_pos[7] - node_pos[4]; 2014  xet = node_pos[5] - node_pos[4]; 2015  xze = node_pos[0] - node_pos[4]; 2016  2017  det = xxi % ( xet * xze ); 2018  if( det > VERDICT_DBL_MIN ) 2019  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 2020  else 2021  return 0; 2022  2023  if( shape < min_shape ) 2024  { 2025  min_shape = shape; 2026  } 2027  2028  // J(1,0,1): 2029  2030  xxi = node_pos[4] - node_pos[5]; 2031  xet = node_pos[6] - node_pos[5]; 2032  xze = node_pos[1] - node_pos[5]; 2033  2034  det = xxi % ( xet * xze ); 2035  if( det > VERDICT_DBL_MIN ) 2036  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 2037  else 2038  return 0; 2039  2040  if( shape < min_shape ) 2041  { 2042  min_shape = shape; 2043  } 2044  2045  // J(1,1,1): 2046  2047  xxi = node_pos[5] - node_pos[6]; 2048  xet = node_pos[7] - node_pos[6]; 2049  xze = node_pos[2] - node_pos[6]; 2050  2051  det = xxi % ( xet * xze ); 2052  if( det > VERDICT_DBL_MIN ) 2053  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 2054  else 2055  return 0; 2056  2057  if( shape < min_shape ) 2058  { 2059  min_shape = shape; 2060  } 2061  2062  // J(1,1,1): 2063  2064  xxi = node_pos[6] - node_pos[7]; 2065  xet = node_pos[4] - node_pos[7]; 2066  xze = node_pos[3] - node_pos[7]; 2067  2068  det = xxi % ( xet * xze ); 2069  if( det > VERDICT_DBL_MIN ) 2070  shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze ); 2071  else 2072  return 0; 2073  2074  if( shape < min_shape ) 2075  { 2076  min_shape = shape; 2077  } 2078  2079  if( min_shape <= VERDICT_DBL_MIN ) min_shape = 0; 2080  2081  if( min_shape > 0 ) return (double)VERDICT_MIN( min_shape, VERDICT_DBL_MAX ); 2082  return (double)VERDICT_MAX( min_shape, -VERDICT_DBL_MAX ); 2083 }

References make_hex_nodes, VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_shape_and_size()

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

Calculates hex shape-size metric.

Product of Shape and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

shape and size of a hex

Product of Shape and Relative Size

Definition at line 2198 of file V_HexMetric.cpp.

2199 { 2200  double size = v_hex_relative_size_squared( num_nodes, coordinates ); 2201  double shape = v_hex_shape( num_nodes, coordinates ); 2202  2203  double shape_size = size * shape; 2204  2205  if( shape_size > 0 ) return (double)VERDICT_MIN( shape_size, VERDICT_DBL_MAX ); 2206  return (double)VERDICT_MAX( shape_size, -VERDICT_DBL_MAX ); 2207 }

References size, v_hex_relative_size_squared(), v_hex_shape(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_shear()

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

Calculates hex shear metric.

3/Mean Ratio of Jacobian Skew matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

shear of a hex

3/Condition number of Jacobian Skew matrix

Definition at line 1733 of file V_HexMetric.cpp.

1734 { 1735  1736  double shear; 1737  double min_shear = 1.0; 1738  VerdictVector xxi, xet, xze; 1739  double det, len1_sq, len2_sq, len3_sq, lengths; 1740  1741  VerdictVector node_pos[8]; 1742  make_hex_nodes( coordinates, node_pos ); 1743  1744  // J(0,0,0): 1745  1746  xxi = node_pos[1] - node_pos[0]; 1747  xet = node_pos[3] - node_pos[0]; 1748  xze = node_pos[4] - node_pos[0]; 1749  1750  len1_sq = xxi.length_squared(); 1751  len2_sq = xet.length_squared(); 1752  len3_sq = xze.length_squared(); 1753  1754  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1755  1756  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1757  det = xxi % ( xet * xze ); 1758  if( det < VERDICT_DBL_MIN ) 1759  { 1760  return 0; 1761  } 1762  1763  shear = det / lengths; 1764  min_shear = VERDICT_MIN( shear, min_shear ); 1765  1766  // J(1,0,0): 1767  1768  xxi = node_pos[2] - node_pos[1]; 1769  xet = node_pos[0] - node_pos[1]; 1770  xze = node_pos[5] - node_pos[1]; 1771  1772  len1_sq = xxi.length_squared(); 1773  len2_sq = xet.length_squared(); 1774  len3_sq = xze.length_squared(); 1775  1776  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1777  1778  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1779  det = xxi % ( xet * xze ); 1780  if( det < VERDICT_DBL_MIN ) 1781  { 1782  return 0; 1783  } 1784  1785  shear = det / lengths; 1786  min_shear = VERDICT_MIN( shear, min_shear ); 1787  1788  // J(1,1,0): 1789  1790  xxi = node_pos[3] - node_pos[2]; 1791  xet = node_pos[1] - node_pos[2]; 1792  xze = node_pos[6] - node_pos[2]; 1793  1794  len1_sq = xxi.length_squared(); 1795  len2_sq = xet.length_squared(); 1796  len3_sq = xze.length_squared(); 1797  1798  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1799  1800  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1801  det = xxi % ( xet * xze ); 1802  if( det < VERDICT_DBL_MIN ) 1803  { 1804  return 0; 1805  } 1806  1807  shear = det / lengths; 1808  min_shear = VERDICT_MIN( shear, min_shear ); 1809  1810  // J(0,1,0): 1811  1812  xxi = node_pos[0] - node_pos[3]; 1813  xet = node_pos[2] - node_pos[3]; 1814  xze = node_pos[7] - node_pos[3]; 1815  1816  len1_sq = xxi.length_squared(); 1817  len2_sq = xet.length_squared(); 1818  len3_sq = xze.length_squared(); 1819  1820  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1821  1822  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1823  det = xxi % ( xet * xze ); 1824  if( det < VERDICT_DBL_MIN ) 1825  { 1826  return 0; 1827  } 1828  1829  shear = det / lengths; 1830  min_shear = VERDICT_MIN( shear, min_shear ); 1831  1832  // J(0,0,1): 1833  1834  xxi = node_pos[7] - node_pos[4]; 1835  xet = node_pos[5] - node_pos[4]; 1836  xze = node_pos[0] - node_pos[4]; 1837  1838  len1_sq = xxi.length_squared(); 1839  len2_sq = xet.length_squared(); 1840  len3_sq = xze.length_squared(); 1841  1842  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1843  1844  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1845  det = xxi % ( xet * xze ); 1846  if( det < VERDICT_DBL_MIN ) 1847  { 1848  return 0; 1849  } 1850  1851  shear = det / lengths; 1852  min_shear = VERDICT_MIN( shear, min_shear ); 1853  1854  // J(1,0,1): 1855  1856  xxi = node_pos[4] - node_pos[5]; 1857  xet = node_pos[6] - node_pos[5]; 1858  xze = node_pos[1] - node_pos[5]; 1859  1860  len1_sq = xxi.length_squared(); 1861  len2_sq = xet.length_squared(); 1862  len3_sq = xze.length_squared(); 1863  1864  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1865  1866  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1867  det = xxi % ( xet * xze ); 1868  if( det < VERDICT_DBL_MIN ) 1869  { 1870  return 0; 1871  } 1872  1873  shear = det / lengths; 1874  min_shear = VERDICT_MIN( shear, min_shear ); 1875  1876  // J(1,1,1): 1877  1878  xxi = node_pos[5] - node_pos[6]; 1879  xet = node_pos[7] - node_pos[6]; 1880  xze = node_pos[2] - node_pos[6]; 1881  1882  len1_sq = xxi.length_squared(); 1883  len2_sq = xet.length_squared(); 1884  len3_sq = xze.length_squared(); 1885  1886  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1887  1888  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1889  det = xxi % ( xet * xze ); 1890  if( det < VERDICT_DBL_MIN ) 1891  { 1892  return 0; 1893  } 1894  1895  shear = det / lengths; 1896  min_shear = VERDICT_MIN( shear, min_shear ); 1897  1898  // J(0,1,1): 1899  1900  xxi = node_pos[6] - node_pos[7]; 1901  xet = node_pos[4] - node_pos[7]; 1902  xze = node_pos[3] - node_pos[7]; 1903  1904  len1_sq = xxi.length_squared(); 1905  len2_sq = xet.length_squared(); 1906  len3_sq = xze.length_squared(); 1907  1908  if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0; 1909  1910  lengths = sqrt( len1_sq * len2_sq * len3_sq ); 1911  det = xxi % ( xet * xze ); 1912  if( det < VERDICT_DBL_MIN ) 1913  { 1914  return 0; 1915  } 1916  1917  shear = det / lengths; 1918  min_shear = VERDICT_MIN( shear, min_shear ); 1919  1920  if( min_shear <= VERDICT_DBL_MIN ) min_shear = 0; 1921  1922  if( min_shear > 0 ) return (double)VERDICT_MIN( min_shear, VERDICT_DBL_MAX ); 1923  return (double)VERDICT_MAX( min_shear, -VERDICT_DBL_MAX ); 1924 }

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

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

◆ v_hex_shear_and_size()

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

Calculates hex shear-size metric.

Product of Shear and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

shear and size of a hex

Product of Shear and Relative Size

Definition at line 2214 of file V_HexMetric.cpp.

2215 { 2216  double size = v_hex_relative_size_squared( num_nodes, coordinates ); 2217  double shear = v_hex_shear( num_nodes, coordinates ); 2218  2219  double shear_size = shear * size; 2220  2221  if( shear_size > 0 ) return (double)VERDICT_MIN( shear_size, VERDICT_DBL_MAX ); 2222  return (double)VERDICT_MAX( shear_size, -VERDICT_DBL_MAX ); 2223 }

References size, v_hex_relative_size_squared(), v_hex_shear(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_skew()

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

Calculates hex skew metric.

Maximum |cos A| where A is the angle between edges at hex center.
Reference — L.M. Taylor, and D.P. Flanagan, Pronto3D - A Three Dimensional Transient Solid Dynamics Program, SAND87-1912, Sandia National Laboratories, 1989.

skew of a hex

Maximum ||cosA|| where A is the angle between edges at hex center.

Definition at line 674 of file V_HexMetric.cpp.

675 { 676  VerdictVector node_pos[8]; 677  make_hex_nodes( coordinates, node_pos ); 678  679  double skew_1, skew_2, skew_3; 680  681  VerdictVector efg1 = calc_hex_efg( 1, node_pos ); 682  VerdictVector efg2 = calc_hex_efg( 2, node_pos ); 683  VerdictVector efg3 = calc_hex_efg( 3, node_pos ); 684  685  if( efg1.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX; 686  if( efg2.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX; 687  if( efg3.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX; 688  689  skew_1 = fabs( efg1 % efg2 ); 690  skew_2 = fabs( efg1 % efg3 ); 691  skew_3 = fabs( efg2 % efg3 ); 692  693  double skew = ( VERDICT_MAX( skew_1, VERDICT_MAX( skew_2, skew_3 ) ) ); 694  695  if( skew > 0 ) return (double)VERDICT_MIN( skew, VERDICT_DBL_MAX ); 696  return (double)VERDICT_MAX( skew, -VERDICT_DBL_MAX ); 697 }

References calc_hex_efg(), make_hex_nodes, VerdictVector::normalize(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_stretch()

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

Calculates hex stretch metric.

Sqrt(3) * minimum edge length / maximum diagonal length. Reference — FIMESH code

stretch of a hex

sqrt(3) * minimum edge length / maximum diagonal length

Definition at line 753 of file V_HexMetric.cpp.

754 { 755  static const double HEX_STRETCH_SCALE_FACTOR = sqrt( 3.0 ); 756  757  double min_edge = hex_edge_length( 0, coordinates ); 758  double max_diag = diag_length( 1, coordinates ); 759  760  double stretch = HEX_STRETCH_SCALE_FACTOR * safe_ratio( min_edge, max_diag ); 761  762  if( stretch > 0 ) return (double)VERDICT_MIN( stretch, VERDICT_DBL_MAX ); 763  return (double)VERDICT_MAX( stretch, -VERDICT_DBL_MAX ); 764 }

References diag_length(), hex_edge_length(), safe_ratio(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_taper()

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

Calculates hex taper metric.

Maximum ratio of lengths derived from opposite edges. Reference — L.M. Taylor, and D.P. Flanagan, Pronto3D - A Three Dimensional Transient Solid Dynamics Program, SAND87-1912, Sandia National Laboratories, 1989.

taper of a hex

Maximum ratio of lengths derived from opposite edges.

Definition at line 704 of file V_HexMetric.cpp.

705 { 706  VerdictVector node_pos[8]; 707  make_hex_nodes( coordinates, node_pos ); 708  709  VerdictVector efg1 = calc_hex_efg( 1, node_pos ); 710  VerdictVector efg2 = calc_hex_efg( 2, node_pos ); 711  VerdictVector efg3 = calc_hex_efg( 3, node_pos ); 712  713  VerdictVector efg12 = calc_hex_efg( 12, node_pos ); 714  VerdictVector efg13 = calc_hex_efg( 13, node_pos ); 715  VerdictVector efg23 = calc_hex_efg( 23, node_pos ); 716  717  double taper_1 = fabs( safe_ratio( efg12.length(), VERDICT_MIN( efg1.length(), efg2.length() ) ) ); 718  double taper_2 = fabs( safe_ratio( efg13.length(), VERDICT_MIN( efg1.length(), efg3.length() ) ) ); 719  double taper_3 = fabs( safe_ratio( efg23.length(), VERDICT_MIN( efg2.length(), efg3.length() ) ) ); 720  721  double taper = (double)VERDICT_MAX( taper_1, VERDICT_MAX( taper_2, taper_3 ) ); 722  723  if( taper > 0 ) return (double)VERDICT_MIN( taper, VERDICT_DBL_MAX ); 724  return (double)VERDICT_MAX( taper, -VERDICT_DBL_MAX ); 725 }

References calc_hex_efg(), VerdictVector::length(), make_hex_nodes, safe_ratio(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_hex_volume()

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

Calculates hex volume.

Jacobian at hex center. Reference — L.M. Taylor, and D.P. Flanagan, Pronto3D - A Three Dimensional Transient Solid Dynamics Program, SAND87-1912, Sandia National Laboratories, 1989.

volume of a hex

Jacobian at hex center

Definition at line 732 of file V_HexMetric.cpp.

733 { 734  VerdictVector node_pos[8]; 735  make_hex_nodes( coordinates, node_pos ); 736  737  VerdictVector efg1 = calc_hex_efg( 1, node_pos ); 738  VerdictVector efg2 = calc_hex_efg( 2, node_pos ); 739  VerdictVector efg3 = calc_hex_efg( 3, node_pos ); 740  741  double volume; 742  volume = (double)( efg1 % ( efg2 * efg3 ) ) / 64.0; 743  744  if( volume > 0 ) return (double)VERDICT_MIN( volume, VERDICT_DBL_MAX ); 745  return (double)VERDICT_MAX( volume, -VERDICT_DBL_MAX ); 746 }

References calc_hex_efg(), make_hex_nodes, VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_knife_quality()

C_FUNC_DEF void v_knife_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
KnifeMetricVals metric_vals 
)

Calculates quality metrics for knife elements.

calculate the quality metrics of a knife element.

There is only one, but we put this here to be consistent with functions for other element types. Who knows if we'll add more metrics.

Definition at line 117 of file V_KnifeMetric.cpp.

121 { 122  memset( metric_vals, 0, sizeof( KnifeMetricVals ) ); 123  124  if( metrics_request_flag & V_KNIFE_VOLUME ) metric_vals->volume = v_knife_volume( num_nodes, coordinates ); 125 }

References V_KNIFE_VOLUME, v_knife_volume(), and KnifeMetricVals::volume.

◆ v_knife_volume()

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

Calculates knife volume.

calculates the volume of a knife element

this is done by dividing the knife into 4 tets and summing the volumes of each.

Definition at line 58 of file V_KnifeMetric.cpp.

59 { 60  double volume = 0; 61  VerdictVector side1, side2, side3; 62  63  if( num_nodes == 7 ) 64  { 65  66  // divide the knife into 4 tets and calculate the volume 67  68  side1.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 69  coordinates[1][2] - coordinates[0][2] ); 70  side2.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], 71  coordinates[3][2] - coordinates[0][2] ); 72  side3.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1], 73  coordinates[4][2] - coordinates[0][2] ); 74  75  volume = side3 % ( side1 * side2 ) / 6; 76  77  side1.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1], 78  coordinates[5][2] - coordinates[1][2] ); 79  side2.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 80  coordinates[3][2] - coordinates[1][2] ); 81  side3.set( coordinates[4][0] - coordinates[1][0], coordinates[4][1] - coordinates[1][1], 82  coordinates[4][2] - coordinates[1][2] ); 83  84  volume += side3 % ( side1 * side2 ) / 6; 85  86  side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], 87  coordinates[2][2] - coordinates[1][2] ); 88  side2.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 89  coordinates[3][2] - coordinates[1][2] ); 90  side3.set( coordinates[6][0] - coordinates[1][0], coordinates[6][1] - coordinates[1][1], 91  coordinates[6][2] - coordinates[1][2] ); 92  93  volume += side3 % ( side1 * side2 ) / 6; 94  95  side1.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 96  coordinates[3][2] - coordinates[1][2] ); 97  side2.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1], 98  coordinates[5][2] - coordinates[1][2] ); 99  side3.set( coordinates[6][0] - coordinates[1][0], coordinates[6][1] - coordinates[1][1], 100  coordinates[6][2] - coordinates[1][2] ); 101  102  volume += side3 % ( side1 * side2 ) / 6; 103  } 104  105  return (double)volume; 106 }

References VerdictVector::set().

Referenced by moab::VerdictWrapper::all_quality_measures(), moab::VerdictWrapper::quality_measure(), and v_knife_quality().

◆ v_pyramid_quality()

C_FUNC_DEF void v_pyramid_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
struct PyramidMetricVals metric_vals 
)

Calculates quality metrics for pyramid elements.

Definition at line 96 of file V_PyramidMetric.cpp.

100 { 101  memset( metric_vals, 0, sizeof( PyramidMetricVals ) ); 102  103  if( metrics_request_flag & V_PYRAMID_VOLUME ) metric_vals->volume = v_pyramid_volume( num_nodes, coordinates ); 104 }

References V_PYRAMID_VOLUME, v_pyramid_volume(), and PyramidMetricVals::volume.

◆ v_pyramid_volume()

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

Calculates pyramid volume.

the volume of a pyramid

the volume is calculated by dividing the pyramid into 2 tets and summing the volumes of the 2 tets.

Definition at line 59 of file V_PyramidMetric.cpp.

60 { 61  62  double volume = 0; 63  VerdictVector side1, side2, side3; 64  65  if( num_nodes == 5 ) 66  { 67  // divide the pyramid into 2 tets and calculate each 68  69  side1.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 70  coordinates[1][2] - coordinates[0][2] ); 71  72  side2.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], 73  coordinates[3][2] - coordinates[0][2] ); 74  75  side3.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1], 76  coordinates[4][2] - coordinates[0][2] ); 77  78  // volume of the first tet 79  volume = ( side3 % ( side1 * side2 ) ) / 6.0; 80  81  side1.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], 82  coordinates[3][2] - coordinates[2][2] ); 83  84  side2.set( coordinates[1][0] - coordinates[2][0], coordinates[1][1] - coordinates[2][1], 85  coordinates[1][2] - coordinates[2][2] ); 86  87  side3.set( coordinates[4][0] - coordinates[2][0], coordinates[4][1] - coordinates[2][1], 88  coordinates[4][2] - coordinates[2][2] ); 89  90  // volume of the second tet 91  volume += ( side3 % ( side1 * side2 ) ) / 6.0; 92  } 93  return (double)volume; 94 }

References VerdictVector::set().

Referenced by v_pyramid_quality().

◆ v_quad_area()

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

Calculates quad area.

Jacobian at quad center. Reference — J. Robinson, CRE Method of element testing and the Jacobian shape parameters, Eng. Comput., Vol 4, 1987.

the area of a quad

jacobian at quad center

Definition at line 611 of file V_QuadMetric.cpp.

612 { 613  614  double corner_areas[4]; 615  signed_corner_areas( corner_areas, coordinates ); 616  617  double area = 0.25 * ( corner_areas[0] + corner_areas[1] + corner_areas[2] + corner_areas[3] ); 618  619  if( area > 0 ) return (double)VERDICT_MIN( area, VERDICT_DBL_MAX ); 620  return (double)VERDICT_MAX( area, -VERDICT_DBL_MAX ); 621 }

References signed_corner_areas(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), v_quad_quality(), and v_quad_relative_size_squared().

◆ v_quad_aspect_ratio()

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

Calculates quad aspect ratio.

aspect ratio Reference — P. P. Pebay, Planar Quadrangle Quality Measures, Eng. Comp., 2004, 20(2):157-173

the aspect ratio of a quad

NB (P. Pebay 01/20/07): this is a generalization of the triangle aspect ratio using Heron's formula.

Definition at line 351 of file V_QuadMetric.cpp.

352 { 353  354  VerdictVector edges[4]; 355  make_quad_edges( edges, coordinates ); 356  357  double a1 = edges[0].length(); 358  double b1 = edges[1].length(); 359  double c1 = edges[2].length(); 360  double d1 = edges[3].length(); 361  362  double ma = a1 > b1 ? a1 : b1; 363  double mb = c1 > d1 ? c1 : d1; 364  double hm = ma > mb ? ma : mb; 365  366  VerdictVector ab = edges[0] * edges[1]; 367  VerdictVector cd = edges[2] * edges[3]; 368  double denominator = ab.length() + cd.length(); 369  370  if( denominator < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; 371  372  double aspect_ratio = .5 * hm * ( a1 + b1 + c1 + d1 ) / denominator; 373  374  if( aspect_ratio > 0 ) return (double)VERDICT_MIN( aspect_ratio, VERDICT_DBL_MAX ); 375  return (double)VERDICT_MAX( aspect_ratio, -VERDICT_DBL_MAX ); 376 }

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

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

◆ v_quad_condition()

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

Calculates quad condition number metric.

Maximum condition number of the Jacobian matrix at 4 corners. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

the condition of a quad

maximum condition number of the Jacobian matrix at 4 corners

Definition at line 828 of file V_QuadMetric.cpp.

829 { 830  831  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) return v_tri_condition( 3, coordinates ); 832  833  double areas[4]; 834  signed_corner_areas( areas, coordinates ); 835  836  double max_condition = 0.; 837  838  VerdictVector xxi, xet; 839  840  double condition; 841  842  for( int i = 0; i < 4; i++ ) 843  { 844  845  xxi.set( coordinates[i][0] - coordinates[( i + 1 ) % 4][0], coordinates[i][1] - coordinates[( i + 1 ) % 4][1], 846  coordinates[i][2] - coordinates[( i + 1 ) % 4][2] ); 847  848  xet.set( coordinates[i][0] - coordinates[( i + 3 ) % 4][0], coordinates[i][1] - coordinates[( i + 3 ) % 4][1], 849  coordinates[i][2] - coordinates[( i + 3 ) % 4][2] ); 850  851  if( areas[i] < VERDICT_DBL_MIN ) 852  condition = VERDICT_DBL_MAX; 853  else 854  condition = ( xxi % xxi + xet % xet ) / areas[i]; 855  856  max_condition = VERDICT_MAX( max_condition, condition ); 857  } 858  859  max_condition /= 2; 860  861  if( max_condition > 0 ) return (double)VERDICT_MIN( max_condition, VERDICT_DBL_MAX ); 862  return (double)VERDICT_MAX( max_condition, -VERDICT_DBL_MAX ); 863 }

References is_collapsed_quad(), VerdictVector::set(), signed_corner_areas(), v_tri_condition(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, VERDICT_MIN, and VERDICT_TRUE.

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

◆ v_quad_distortion()

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

Calculates quad distortion metric.

{min(|J|)/actual area}*parent area, parent area = 4 for quad. Reference — SDRC/IDEAS Simulation: Finite Element Modeling–User's Guide

the distortion of a quad

Definition at line 1052 of file V_QuadMetric.cpp.

1053 { 1054  // To calculate distortion for linear and 2nd order quads 1055  // distortion = {min(|J|)/actual area}*{parent area} 1056  // parent area = 4 for a quad. 1057  // min |J| is the minimum over nodes and gaussian integration points 1058  // created by Ling Pan, CAT on 4/30/01 1059  1060  double element_area = 0.0, distrt, thickness_gauss; 1061  double cur_jacobian = 0., sign_jacobian, jacobian; 1062  VerdictVector aa, bb, cc, normal_at_point, xin; 1063  1064  // use 2x2 gauss points for linear quads and 3x3 for 2nd order quads 1065  int number_of_gauss_points = 0; 1066  if( num_nodes == 4 ) 1067  { // 2x2 quadrature rule 1068  number_of_gauss_points = 2; 1069  } 1070  else if( num_nodes == 8 ) 1071  { // 3x3 quadrature rule 1072  number_of_gauss_points = 3; 1073  } 1074  1075  int total_number_of_gauss_points = number_of_gauss_points * number_of_gauss_points; 1076  1077  VerdictVector face_normal = quad_normal( coordinates ); 1078  1079  double distortion = VERDICT_DBL_MAX; 1080  1081  VerdictVector first, second; 1082  1083  int i; 1084  // Will work out the case for collapsed quad later 1085  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) 1086  { 1087  for( i = 0; i < 3; i++ ) 1088  { 1089  1090  first.set( coordinates[i][0] - coordinates[( i + 1 ) % 3][0], 1091  coordinates[i][1] - coordinates[( i + 1 ) % 3][1], 1092  coordinates[i][2] - coordinates[( i + 1 ) % 3][2] ); 1093  1094  second.set( coordinates[i][0] - coordinates[( i + 2 ) % 3][0], 1095  coordinates[i][1] - coordinates[( i + 2 ) % 3][1], 1096  coordinates[i][2] - coordinates[( i + 2 ) % 3][2] ); 1097  1098  sign_jacobian = ( face_normal % ( first * second ) ) > 0 ? 1. : -1.; 1099  cur_jacobian = sign_jacobian * ( first * second ).length(); 1100  distortion = VERDICT_MIN( distortion, cur_jacobian ); 1101  } 1102  element_area = ( first * second ).length() / 2.0; 1103  distortion /= element_area; 1104  } 1105  else 1106  { 1107  double shape_function[maxTotalNumberGaussPoints][maxNumberNodes]; 1108  double dndy1[maxTotalNumberGaussPoints][maxNumberNodes]; 1109  double dndy2[maxTotalNumberGaussPoints][maxNumberNodes]; 1110  double weight[maxTotalNumberGaussPoints]; 1111  1112  // create an object of GaussIntegration 1113  GaussIntegration::initialize( number_of_gauss_points, num_nodes ); 1114  GaussIntegration::calculate_shape_function_2d_quad(); 1115  GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], weight ); 1116  1117  // calculate element area 1118  int ife, ja; 1119  for( ife = 0; ife < total_number_of_gauss_points; ife++ ) 1120  { 1121  aa.set( 0.0, 0.0, 0.0 ); 1122  bb.set( 0.0, 0.0, 0.0 ); 1123  1124  for( ja = 0; ja < num_nodes; ja++ ) 1125  { 1126  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); 1127  aa += dndy1[ife][ja] * xin; 1128  bb += dndy2[ife][ja] * xin; 1129  } 1130  normal_at_point = aa * bb; 1131  jacobian = normal_at_point.length(); 1132  element_area += weight[ife] * jacobian; 1133  } 1134  1135  double dndy1_at_node[maxNumberNodes][maxNumberNodes]; 1136  double dndy2_at_node[maxNumberNodes][maxNumberNodes]; 1137  1138  GaussIntegration::calculate_derivative_at_nodes( dndy1_at_node, dndy2_at_node ); 1139  1140  VerdictVector normal_at_nodes[9]; 1141  1142  // evaluate normal at nodes and distortion values at nodes 1143  int jai; 1144  for( ja = 0; ja < num_nodes; ja++ ) 1145  { 1146  aa.set( 0.0, 0.0, 0.0 ); 1147  bb.set( 0.0, 0.0, 0.0 ); 1148  for( jai = 0; jai < num_nodes; jai++ ) 1149  { 1150  xin.set( coordinates[jai][0], coordinates[jai][1], coordinates[jai][2] ); 1151  aa += dndy1_at_node[ja][jai] * xin; 1152  bb += dndy2_at_node[ja][jai] * xin; 1153  } 1154  normal_at_nodes[ja] = aa * bb; 1155  normal_at_nodes[ja].normalize(); 1156  } 1157  1158  // determine if element is flat 1159  bool flat_element = true; 1160  double dot_product; 1161  1162  for( ja = 0; ja < num_nodes; ja++ ) 1163  { 1164  dot_product = normal_at_nodes[0] % normal_at_nodes[ja]; 1165  if( fabs( dot_product ) < 0.99 ) 1166  { 1167  flat_element = false; 1168  break; 1169  } 1170  } 1171  1172  // take into consideration of the thickness of the element 1173  double thickness; 1174  // get_quad_thickness(face, element_area, thickness ); 1175  thickness = 0.001 * sqrt( element_area ); 1176  1177  // set thickness gauss point location 1178  double zl = 0.5773502691896; 1179  if( flat_element ) zl = 0.0; 1180  1181  int no_gauss_pts_z = ( flat_element ) ? 1 : 2; 1182  double thickness_z; 1183  int igz; 1184  // loop on Gauss points 1185  for( ife = 0; ife < total_number_of_gauss_points; ife++ ) 1186  { 1187  // loop on the thickness direction gauss points 1188  for( igz = 0; igz < no_gauss_pts_z; igz++ ) 1189  { 1190  zl = -zl; 1191  thickness_z = zl * thickness / 2.0; 1192  1193  aa.set( 0.0, 0.0, 0.0 ); 1194  bb.set( 0.0, 0.0, 0.0 ); 1195  cc.set( 0.0, 0.0, 0.0 ); 1196  1197  for( ja = 0; ja < num_nodes; ja++ ) 1198  { 1199  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] ); 1200  xin += thickness_z * normal_at_nodes[ja]; 1201  aa += dndy1[ife][ja] * xin; 1202  bb += dndy2[ife][ja] * xin; 1203  thickness_gauss = shape_function[ife][ja] * thickness / 2.0; 1204  cc += thickness_gauss * normal_at_nodes[ja]; 1205  } 1206  1207  normal_at_point = aa * bb; 1208  // jacobian = normal_at_point.length(); 1209  distrt = cc % normal_at_point; 1210  if( distrt < distortion ) distortion = distrt; 1211  } 1212  } 1213  1214  // loop through nodal points 1215  for( ja = 0; ja < num_nodes; ja++ ) 1216  { 1217  for( igz = 0; igz < no_gauss_pts_z; igz++ ) 1218  { 1219  zl = -zl; 1220  thickness_z = zl * thickness / 2.0; 1221  1222  aa.set( 0.0, 0.0, 0.0 ); 1223  bb.set( 0.0, 0.0, 0.0 ); 1224  cc.set( 0.0, 0.0, 0.0 ); 1225  1226  for( jai = 0; jai < num_nodes; jai++ ) 1227  { 1228  xin.set( coordinates[jai][0], coordinates[jai][1], coordinates[jai][2] ); 1229  xin += thickness_z * normal_at_nodes[ja]; 1230  aa += dndy1_at_node[ja][jai] * xin; 1231  bb += dndy2_at_node[ja][jai] * xin; 1232  if( jai == ja ) 1233  thickness_gauss = thickness / 2.0; 1234  else 1235  thickness_gauss = 0.; 1236  cc += thickness_gauss * normal_at_nodes[jai]; 1237  } 1238  } 1239  normal_at_point = aa * bb; 1240  sign_jacobian = ( face_normal % normal_at_point ) > 0 ? 1. : -1.; 1241  distrt = sign_jacobian * ( cc % normal_at_point ); 1242  1243  if( distrt < distortion ) distortion = distrt; 1244  } 1245  1246  if( element_area * thickness != 0 ) 1247  distortion *= 8. / ( element_area * thickness ); 1248  else 1249  distortion *= 8.; 1250  } 1251  1252  return (double)distortion; 1253 }

References GaussIntegration::calculate_derivative_at_nodes(), GaussIntegration::calculate_shape_function_2d_quad(), dot_product(), moab::GeomUtil::first(), GaussIntegration::get_shape_func(), GaussIntegration::initialize(), is_collapsed_quad(), VerdictVector::length(), length(), maxNumberNodes, maxTotalNumberGaussPoints, VerdictVector::normalize(), quad_normal(), VerdictVector::set(), VERDICT_DBL_MAX, VERDICT_MIN, and VERDICT_TRUE.

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

◆ v_quad_edge_ratio()

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

Calculates quad edge ratio.

edge ratio Reference — P. P. Pebay, Planar Quadrangle Quality Measures, Eng. Comp., 2004, 20(2):157-173

the edge ratio of a quad

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

Definition at line 271 of file V_QuadMetric.cpp.

272 { 273  VerdictVector edges[4]; 274  make_quad_edges( edges, coordinates ); 275  276  double a2 = edges[0].length_squared(); 277  double b2 = edges[1].length_squared(); 278  double c2 = edges[2].length_squared(); 279  double d2 = edges[3].length_squared(); 280  281  double mab, Mab, mcd, Mcd, m2, M2; 282  if( a2 < b2 ) 283  { 284  mab = a2; 285  Mab = b2; 286  } 287  else // b2 <= a2 288  { 289  mab = b2; 290  Mab = a2; 291  } 292  if( c2 < d2 ) 293  { 294  mcd = c2; 295  Mcd = d2; 296  } 297  else // d2 <= c2 298  { 299  mcd = d2; 300  Mcd = c2; 301  } 302  m2 = mab < mcd ? mab : mcd; 303  M2 = Mab > Mcd ? Mab : Mcd; 304  305  if( m2 < VERDICT_DBL_MIN ) 306  return (double)VERDICT_DBL_MAX; 307  else 308  { 309  double edge_ratio = sqrt( M2 / m2 ); 310  311  if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX ); 312  return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX ); 313  } 314 }

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

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

◆ v_quad_jacobian()

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

Calculates quad jacobian.

Minimum pointwise volume of local map at 4 corners & center of quad. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

the jacobian of a quad

minimum pointwise volume of local map at 4 corners and center of quad

Definition at line 870 of file V_QuadMetric.cpp.

871 { 872  873  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) return (double)( v_tri_area( 3, coordinates ) * 2.0 ); 874  875  double areas[4]; 876  signed_corner_areas( areas, coordinates ); 877  878  double jacobian = VERDICT_MIN( VERDICT_MIN( areas[0], areas[1] ), VERDICT_MIN( areas[2], areas[3] ) ); 879  if( jacobian > 0 ) return (double)VERDICT_MIN( jacobian, VERDICT_DBL_MAX ); 880  return (double)VERDICT_MAX( jacobian, -VERDICT_DBL_MAX ); 881 }

References is_collapsed_quad(), signed_corner_areas(), v_tri_area(), VERDICT_DBL_MAX, VERDICT_MAX, VERDICT_MIN, and VERDICT_TRUE.

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

◆ v_quad_max_aspect_frobenius()

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

Calculates quad maximum Frobenius aspect.

average Frobenius aspect Reference — P. P. Pebay, Planar Quadrangle Quality Measures, Eng. Comp., 2004, 20(2):157-173

the maximum Frobenius aspect of a quad

NB (P. Pebay 01/20/07): this metric is calculated by taking the maximum of the 4 Frobenius aspects at each corner of the quad, when the reference triangle is right isosceles.

Definition at line 484 of file V_QuadMetric.cpp.

485 { 486  487  VerdictVector edges[4]; 488  make_quad_edges( edges, coordinates ); 489  490  double a2 = edges[0].length_squared(); 491  double b2 = edges[1].length_squared(); 492  double c2 = edges[2].length_squared(); 493  double d2 = edges[3].length_squared(); 494  495  VerdictVector ab = edges[0] * edges[1]; 496  VerdictVector bc = edges[1] * edges[2]; 497  VerdictVector cd = edges[2] * edges[3]; 498  VerdictVector da = edges[3] * edges[0]; 499  500  double ab1 = ab.length(); 501  double bc1 = bc.length(); 502  double cd1 = cd.length(); 503  double da1 = da.length(); 504  505  if( ab1 < VERDICT_DBL_MIN || bc1 < VERDICT_DBL_MIN || cd1 < VERDICT_DBL_MIN || da1 < VERDICT_DBL_MIN ) 506  return (double)VERDICT_DBL_MAX; 507  508  double qmax = ( a2 + b2 ) / ab1; 509  510  double qcur = ( b2 + c2 ) / bc1; 511  qmax = qmax > qcur ? qmax : qcur; 512  513  qcur = ( c2 + d2 ) / cd1; 514  qmax = qmax > qcur ? qmax : qcur; 515  516  qcur = ( d2 + a2 ) / da1; 517  qmax = qmax > qcur ? qmax : qcur; 518  519  double max_aspect_frobenius = .5 * qmax; 520  521  if( max_aspect_frobenius > 0 ) return (double)VERDICT_MIN( max_aspect_frobenius, VERDICT_DBL_MAX ); 522  return (double)VERDICT_MAX( max_aspect_frobenius, -VERDICT_DBL_MAX ); 523 }

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

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

◆ v_quad_max_edge_ratio()

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

Calculates quad maximum of edge ratio.

Maximum edge length ratio at quad center. Reference — J. Robinson, CRE Method of element testing and the Jacobian shape parameters, Eng. Comput., Vol 4, 1987.

maximum of edge ratio of a quad

maximum edge length ratio at quad center

Definition at line 321 of file V_QuadMetric.cpp.

322 { 323  VerdictVector quad_nodes[4]; 324  quad_nodes[0].set( coordinates[0][0], coordinates[0][1], coordinates[0][2] ); 325  quad_nodes[1].set( coordinates[1][0], coordinates[1][1], coordinates[1][2] ); 326  quad_nodes[2].set( coordinates[2][0], coordinates[2][1], coordinates[2][2] ); 327  quad_nodes[3].set( coordinates[3][0], coordinates[3][1], coordinates[3][2] ); 328  329  VerdictVector principal_axes[2]; 330  principal_axes[0] = quad_nodes[1] + quad_nodes[2] - quad_nodes[0] - quad_nodes[3]; 331  principal_axes[1] = quad_nodes[2] + quad_nodes[3] - quad_nodes[0] - quad_nodes[1]; 332  333  double len1 = principal_axes[0].length(); 334  double len2 = principal_axes[1].length(); 335  336  if( len1 < VERDICT_DBL_MIN || len2 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; 337  338  double max_edge_ratio = VERDICT_MAX( len1 / len2, len2 / len1 ); 339  340  if( max_edge_ratio > 0 ) return (double)VERDICT_MIN( max_edge_ratio, VERDICT_DBL_MAX ); 341  return (double)VERDICT_MAX( max_edge_ratio, -VERDICT_DBL_MAX ); 342 }

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

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

◆ v_quad_maximum_angle()

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

Calculates quad's largest angle.

Largest included quad angle (degrees). Reference — Unknown.

the largest angle of a quad

largest included quad area (degrees)

Definition at line 670 of file V_QuadMetric.cpp.

671 { 672  673  // if this is a collapsed quad, just pass it on to 674  // the tri_largest_angle routine 675  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) return v_tri_maximum_angle( 3, coordinates ); 676  677  double angle; 678  double max_angle = 0.0; 679  680  VerdictVector edges[4]; 681  edges[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 682  coordinates[1][2] - coordinates[0][2] ); 683  edges[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], 684  coordinates[2][2] - coordinates[1][2] ); 685  edges[2].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], 686  coordinates[3][2] - coordinates[2][2] ); 687  edges[3].set( coordinates[0][0] - coordinates[3][0], coordinates[0][1] - coordinates[3][1], 688  coordinates[0][2] - coordinates[3][2] ); 689  690  // go around each node and calculate the angle 691  // at each node 692  double length[4]; 693  length[0] = edges[0].length(); 694  length[1] = edges[1].length(); 695  length[2] = edges[2].length(); 696  length[3] = edges[3].length(); 697  698  if( length[0] <= VERDICT_DBL_MIN || length[1] <= VERDICT_DBL_MIN || length[2] <= VERDICT_DBL_MIN || 699  length[3] <= VERDICT_DBL_MIN ) 700  return 0.0; 701  702  angle = acos( -( edges[0] % edges[1] ) / ( length[0] * length[1] ) ); 703  max_angle = VERDICT_MAX( angle, max_angle ); 704  705  angle = acos( -( edges[1] % edges[2] ) / ( length[1] * length[2] ) ); 706  max_angle = VERDICT_MAX( angle, max_angle ); 707  708  angle = acos( -( edges[2] % edges[3] ) / ( length[2] * length[3] ) ); 709  max_angle = VERDICT_MAX( angle, max_angle ); 710  711  angle = acos( -( edges[3] % edges[0] ) / ( length[3] * length[0] ) ); 712  max_angle = VERDICT_MAX( angle, max_angle ); 713  714  max_angle = max_angle * 180.0 / VERDICT_PI; 715  716  // if any signed areas are < 0, then you are getting the wrong angle 717  double areas[4]; 718  signed_corner_areas( areas, coordinates ); 719  720  if( areas[0] < 0 || areas[1] < 0 || areas[2] < 0 || areas[3] < 0 ) 721  { 722  max_angle = 360 - max_angle; 723  } 724  725  if( max_angle > 0 ) return (double)VERDICT_MIN( max_angle, VERDICT_DBL_MAX ); 726  return (double)VERDICT_MAX( max_angle, -VERDICT_DBL_MAX ); 727 }

References moab::angle(), is_collapsed_quad(), VerdictVector::length(), length(), VerdictVector::set(), signed_corner_areas(), v_tri_maximum_angle(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, VERDICT_MIN, VERDICT_PI, and VERDICT_TRUE.

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

◆ v_quad_med_aspect_frobenius()

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

Calculates quad average Frobenius aspect.

average Frobenius aspect Reference — P. P. Pebay, Planar Quadrangle Quality Measures, Eng. Comp., 2004, 20(2):157-173

the average Frobenius aspect of a quad

NB (P. Pebay 01/20/07): this metric is calculated by averaging the 4 Frobenius aspects at each corner of the quad, when the reference triangle is right isosceles.

Definition at line 442 of file V_QuadMetric.cpp.

443 { 444  445  VerdictVector edges[4]; 446  make_quad_edges( edges, coordinates ); 447  448  double a2 = edges[0].length_squared(); 449  double b2 = edges[1].length_squared(); 450  double c2 = edges[2].length_squared(); 451  double d2 = edges[3].length_squared(); 452  453  VerdictVector ab = edges[0] * edges[1]; 454  VerdictVector bc = edges[1] * edges[2]; 455  VerdictVector cd = edges[2] * edges[3]; 456  VerdictVector da = edges[3] * edges[0]; 457  458  double ab1 = ab.length(); 459  double bc1 = bc.length(); 460  double cd1 = cd.length(); 461  double da1 = da.length(); 462  463  if( ab1 < VERDICT_DBL_MIN || bc1 < VERDICT_DBL_MIN || cd1 < VERDICT_DBL_MIN || da1 < VERDICT_DBL_MIN ) 464  return (double)VERDICT_DBL_MAX; 465  466  double qsum = ( a2 + b2 ) / ab1; 467  qsum += ( b2 + c2 ) / bc1; 468  qsum += ( c2 + d2 ) / cd1; 469  qsum += ( d2 + a2 ) / da1; 470  471  double med_aspect_frobenius = .125 * qsum; 472  473  if( med_aspect_frobenius > 0 ) return (double)VERDICT_MIN( med_aspect_frobenius, VERDICT_DBL_MAX ); 474  return (double)VERDICT_MAX( med_aspect_frobenius, -VERDICT_DBL_MAX ); 475 }

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

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

◆ v_quad_minimum_angle()

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

Calculates quad's smallest angle.

Smallest included quad angle (degrees). Reference — Unknown.

the smallest angle of a quad

smallest included quad angle (degrees)

Definition at line 734 of file V_QuadMetric.cpp.

735 { 736  // if this quad is a collapsed quad, then just 737  // send it to the tri_smallest_angle routine 738  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) return v_tri_minimum_angle( 3, coordinates ); 739  740  double angle; 741  double min_angle = 360.0; 742  743  VerdictVector edges[4]; 744  edges[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 745  coordinates[1][2] - coordinates[0][2] ); 746  edges[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], 747  coordinates[2][2] - coordinates[1][2] ); 748  edges[2].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1], 749  coordinates[3][2] - coordinates[2][2] ); 750  edges[3].set( coordinates[0][0] - coordinates[3][0], coordinates[0][1] - coordinates[3][1], 751  coordinates[0][2] - coordinates[3][2] ); 752  753  // go around each node and calculate the angle 754  // at each node 755  double length[4]; 756  length[0] = edges[0].length(); 757  length[1] = edges[1].length(); 758  length[2] = edges[2].length(); 759  length[3] = edges[3].length(); 760  761  if( length[0] <= VERDICT_DBL_MIN || length[1] <= VERDICT_DBL_MIN || length[2] <= VERDICT_DBL_MIN || 762  length[3] <= VERDICT_DBL_MIN ) 763  return 360.0; 764  765  angle = acos( -( edges[0] % edges[1] ) / ( length[0] * length[1] ) ); 766  min_angle = VERDICT_MIN( angle, min_angle ); 767  768  angle = acos( -( edges[1] % edges[2] ) / ( length[1] * length[2] ) ); 769  min_angle = VERDICT_MIN( angle, min_angle ); 770  771  angle = acos( -( edges[2] % edges[3] ) / ( length[2] * length[3] ) ); 772  min_angle = VERDICT_MIN( angle, min_angle ); 773  774  angle = acos( -( edges[3] % edges[0] ) / ( length[3] * length[0] ) ); 775  min_angle = VERDICT_MIN( angle, min_angle ); 776  777  min_angle = min_angle * 180.0 / VERDICT_PI; 778  779  if( min_angle > 0 ) return (double)VERDICT_MIN( min_angle, VERDICT_DBL_MAX ); 780  return (double)VERDICT_MAX( min_angle, -VERDICT_DBL_MAX ); 781 }

References moab::angle(), is_collapsed_quad(), VerdictVector::length(), length(), VerdictVector::set(), v_tri_minimum_angle(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, VERDICT_MIN, VERDICT_PI, and VERDICT_TRUE.

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

◆ v_quad_oddy()

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

Calculates quad oddy metric.

the oddy of a quad

general distortion measure based on left Cauchy-Green Tensor

Definition at line 788 of file V_QuadMetric.cpp.

789 { 790  791  double max_oddy = 0.; 792  793  VerdictVector first, second, node_pos[4]; 794  795  double g, g11, g12, g22, cur_oddy; 796  int i; 797  798  for( i = 0; i < 4; i++ ) 799  node_pos[i].set( coordinates[i][0], coordinates[i][1], coordinates[i][2] ); 800  801  for( i = 0; i < 4; i++ ) 802  { 803  first = node_pos[i] - node_pos[( i + 1 ) % 4]; 804  second = node_pos[i] - node_pos[( i + 3 ) % 4]; 805  806  g11 = first % first; 807  g12 = first % second; 808  g22 = second % second; 809  g = g11 * g22 - g12 * g12; 810  811  if( g < VERDICT_DBL_MIN ) 812  cur_oddy = VERDICT_DBL_MAX; 813  else 814  cur_oddy = ( ( g11 - g22 ) * ( g11 - g22 ) + 4. * g12 * g12 ) / 2. / g; 815  816  max_oddy = VERDICT_MAX( max_oddy, cur_oddy ); 817  } 818  819  if( max_oddy > 0 ) return (double)VERDICT_MIN( max_oddy, VERDICT_DBL_MAX ); 820  return (double)VERDICT_MAX( max_oddy, -VERDICT_DBL_MAX ); 821 }

References moab::GeomUtil::first(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_quad_quality()

C_FUNC_DEF void v_quad_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
QuadMetricVals metric_vals 
)

Calculates quality metrics for quadrilateral elements.

multiple quality measures of a quad

Definition at line 1258 of file V_QuadMetric.cpp.

1262 { 1263  1264  memset( metric_vals, 0, sizeof( QuadMetricVals ) ); 1265  1266  // for starts, lets set up some basic and common information 1267  1268  /* node numbers and side numbers used below 1269  1270  2 1271  3 +--------- 2 1272  / + 1273  / | 1274  3 / | 1 1275  / | 1276  + | 1277  0 -------------+ 1 1278  0 1279  */ 1280  1281  // vectors for each side 1282  VerdictVector edges[4]; 1283  make_quad_edges( edges, coordinates ); 1284  1285  double areas[4]; 1286  signed_corner_areas( areas, coordinates ); 1287  1288  double lengths[4]; 1289  lengths[0] = edges[0].length(); 1290  lengths[1] = edges[1].length(); 1291  lengths[2] = edges[2].length(); 1292  lengths[3] = edges[3].length(); 1293  1294  VerdictBoolean is_collapsed = is_collapsed_quad( coordinates ); 1295  1296  // handle collapsed quads metrics here 1297  if( is_collapsed == VERDICT_TRUE && metrics_request_flag & ( V_QUAD_MINIMUM_ANGLE | V_QUAD_MAXIMUM_ANGLE | 1298  V_QUAD_JACOBIAN | V_QUAD_SCALED_JACOBIAN ) ) 1299  { 1300  if( metrics_request_flag & V_QUAD_MINIMUM_ANGLE ) 1301  metric_vals->minimum_angle = v_tri_minimum_angle( 3, coordinates ); 1302  if( metrics_request_flag & V_QUAD_MAXIMUM_ANGLE ) 1303  metric_vals->maximum_angle = v_tri_maximum_angle( 3, coordinates ); 1304  if( metrics_request_flag & V_QUAD_JACOBIAN ) 1305  metric_vals->jacobian = (double)( v_tri_area( 3, coordinates ) * 2.0 ); 1306  if( metrics_request_flag & V_QUAD_SCALED_JACOBIAN ) 1307  metric_vals->jacobian = (double)( v_tri_scaled_jacobian( 3, coordinates ) * 2.0 ); 1308  } 1309  1310  // calculate both largest and smallest angles 1311  if( metrics_request_flag & ( V_QUAD_MINIMUM_ANGLE | V_QUAD_MAXIMUM_ANGLE ) && is_collapsed == VERDICT_FALSE ) 1312  { 1313  // gather the angles 1314  double angles[4]; 1315  angles[0] = acos( -( edges[0] % edges[1] ) / ( lengths[0] * lengths[1] ) ); 1316  angles[1] = acos( -( edges[1] % edges[2] ) / ( lengths[1] * lengths[2] ) ); 1317  angles[2] = acos( -( edges[2] % edges[3] ) / ( lengths[2] * lengths[3] ) ); 1318  angles[3] = acos( -( edges[3] % edges[0] ) / ( lengths[3] * lengths[0] ) ); 1319  1320  if( lengths[0] <= VERDICT_DBL_MIN || lengths[1] <= VERDICT_DBL_MIN || lengths[2] <= VERDICT_DBL_MIN || 1321  lengths[3] <= VERDICT_DBL_MIN ) 1322  { 1323  metric_vals->minimum_angle = 360.0; 1324  metric_vals->maximum_angle = 0.0; 1325  } 1326  else 1327  { 1328  // if smallest angle, find the smallest angle 1329  if( metrics_request_flag & V_QUAD_MINIMUM_ANGLE ) 1330  { 1331  metric_vals->minimum_angle = VERDICT_DBL_MAX; 1332  for( int i = 0; i < 4; i++ ) 1333  metric_vals->minimum_angle = VERDICT_MIN( angles[i], metric_vals->minimum_angle ); 1334  metric_vals->minimum_angle *= 180.0 / VERDICT_PI; 1335  } 1336  // if largest angle, find the largest angle 1337  if( metrics_request_flag & V_QUAD_MAXIMUM_ANGLE ) 1338  { 1339  metric_vals->maximum_angle = 0.0; 1340  for( int i = 0; i < 4; i++ ) 1341  metric_vals->maximum_angle = VERDICT_MAX( angles[i], metric_vals->maximum_angle ); 1342  metric_vals->maximum_angle *= 180.0 / VERDICT_PI; 1343  1344  if( areas[0] < 0 || areas[1] < 0 || areas[2] < 0 || areas[3] < 0 ) 1345  metric_vals->maximum_angle = 360 - metric_vals->maximum_angle; 1346  } 1347  } 1348  } 1349  1350  // handle max_edge_ratio, skew, taper, and area together 1351  if( metrics_request_flag & ( V_QUAD_MAX_EDGE_RATIO | V_QUAD_SKEW | V_QUAD_TAPER ) ) 1352  { 1353  // get principle axes 1354  VerdictVector principal_axes[2]; 1355  principal_axes[0] = edges[0] - edges[2]; 1356  principal_axes[1] = edges[1] - edges[3]; 1357  1358  if( metrics_request_flag & ( V_QUAD_MAX_EDGE_RATIO | V_QUAD_SKEW | V_QUAD_TAPER ) ) 1359  { 1360  double len1 = principal_axes[0].length(); 1361  double len2 = principal_axes[1].length(); 1362  1363  // calculate the max_edge_ratio ratio 1364  if( metrics_request_flag & V_QUAD_MAX_EDGE_RATIO ) 1365  { 1366  if( len1 < VERDICT_DBL_MIN || len2 < VERDICT_DBL_MIN ) 1367  metric_vals->max_edge_ratio = VERDICT_DBL_MAX; 1368  else 1369  metric_vals->max_edge_ratio = VERDICT_MAX( len1 / len2, len2 / len1 ); 1370  } 1371  1372  // calculate the taper 1373  if( metrics_request_flag & V_QUAD_TAPER ) 1374  { 1375  double min_length = VERDICT_MIN( len1, len2 ); 1376  1377  VerdictVector cross_derivative = edges[1] + edges[3]; 1378  1379  if( min_length < VERDICT_DBL_MIN ) 1380  metric_vals->taper = VERDICT_DBL_MAX; 1381  else 1382  metric_vals->taper = cross_derivative.length() / min_length; 1383  } 1384  1385  // calculate the skew 1386  if( metrics_request_flag & V_QUAD_SKEW ) 1387  { 1388  if( principal_axes[0].normalize() < VERDICT_DBL_MIN || principal_axes[1].normalize() < VERDICT_DBL_MIN ) 1389  metric_vals->skew = 0.0; 1390  else 1391  metric_vals->skew = fabs( principal_axes[0] % principal_axes[1] ); 1392  } 1393  } 1394  } 1395  1396  // calculate the area 1397  if( metrics_request_flag & ( V_QUAD_AREA | V_QUAD_RELATIVE_SIZE_SQUARED ) ) 1398  { 1399  metric_vals->area = 0.25 * ( areas[0] + areas[1] + areas[2] + areas[3] ); 1400  } 1401  1402  // calculate the relative size 1403  if( metrics_request_flag & ( V_QUAD_RELATIVE_SIZE_SQUARED | V_QUAD_SHAPE_AND_SIZE | V_QUAD_SHEAR_AND_SIZE ) ) 1404  { 1405  double quad_area = v_quad_area( 4, coordinates ); 1406  v_set_quad_size( quad_area ); 1407  double w11, w21, w12, w22; 1408  get_weight( w11, w21, w12, w22 ); 1409  double avg_area = determinant( w11, w21, w12, w22 ); 1410  1411  if( avg_area < VERDICT_DBL_MIN ) 1412  metric_vals->relative_size_squared = 0.0; 1413  else 1414  metric_vals->relative_size_squared = 1415  pow( VERDICT_MIN( metric_vals->area / avg_area, avg_area / metric_vals->area ), 2 ); 1416  } 1417  1418  // calculate the jacobian 1419  if( metrics_request_flag & V_QUAD_JACOBIAN ) 1420  { 1421  metric_vals->jacobian = VERDICT_MIN( VERDICT_MIN( areas[0], areas[1] ), VERDICT_MIN( areas[2], areas[3] ) ); 1422  } 1423  1424  if( metrics_request_flag & ( V_QUAD_SCALED_JACOBIAN | V_QUAD_SHEAR | V_QUAD_SHEAR_AND_SIZE ) ) 1425  { 1426  double scaled_jac, min_scaled_jac = VERDICT_DBL_MAX; 1427  1428  if( lengths[0] < VERDICT_DBL_MIN || lengths[1] < VERDICT_DBL_MIN || lengths[2] < VERDICT_DBL_MIN || 1429  lengths[3] < VERDICT_DBL_MIN ) 1430  { 1431  metric_vals->scaled_jacobian = 0.0; 1432  metric_vals->shear = 0.0; 1433  } 1434  else 1435  { 1436  scaled_jac = areas[0] / ( lengths[0] * lengths[3] ); 1437  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 1438  1439  scaled_jac = areas[1] / ( lengths[1] * lengths[0] ); 1440  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 1441  1442  scaled_jac = areas[2] / ( lengths[2] * lengths[1] ); 1443  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 1444  1445  scaled_jac = areas[3] / ( lengths[3] * lengths[2] ); 1446  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 1447  1448  metric_vals->scaled_jacobian = min_scaled_jac; 1449  1450  // what the heck...set shear as well 1451  if( min_scaled_jac <= VERDICT_DBL_MIN ) 1452  metric_vals->shear = 0.0; 1453  else 1454  metric_vals->shear = min_scaled_jac; 1455  } 1456  } 1457  1458  if( metrics_request_flag & ( V_QUAD_WARPAGE | V_QUAD_ODDY ) ) 1459  { 1460  VerdictVector corner_normals[4]; 1461  corner_normals[0] = edges[3] * edges[0]; 1462  corner_normals[1] = edges[0] * edges[1]; 1463  corner_normals[2] = edges[1] * edges[2]; 1464  corner_normals[3] = edges[2] * edges[3]; 1465  1466  if( metrics_request_flag & V_QUAD_ODDY ) 1467  { 1468  double oddy, max_oddy = 0.0; 1469  1470  double diff, dot_prod; 1471  1472  double length_squared[4]; 1473  length_squared[0] = corner_normals[0].length_squared(); 1474  length_squared[1] = corner_normals[1].length_squared(); 1475  length_squared[2] = corner_normals[2].length_squared(); 1476  length_squared[3] = corner_normals[3].length_squared(); 1477  1478  if( length_squared[0] < VERDICT_DBL_MIN || length_squared[1] < VERDICT_DBL_MIN || 1479  length_squared[2] < VERDICT_DBL_MIN || length_squared[3] < VERDICT_DBL_MIN ) 1480  metric_vals->oddy = VERDICT_DBL_MAX; 1481  else 1482  { 1483  diff = ( lengths[0] * lengths[0] ) - ( lengths[1] * lengths[1] ); 1484  dot_prod = edges[0] % edges[1]; 1485  oddy = ( ( diff * diff ) + 4 * dot_prod * dot_prod ) / ( 2 * length_squared[1] ); 1486  max_oddy = VERDICT_MAX( oddy, max_oddy ); 1487  1488  diff = ( lengths[1] * lengths[1] ) - ( lengths[2] * lengths[2] ); 1489  dot_prod = edges[1] % edges[2]; 1490  oddy = ( ( diff * diff ) + 4 * dot_prod * dot_prod ) / ( 2 * length_squared[2] ); 1491  max_oddy = VERDICT_MAX( oddy, max_oddy ); 1492  1493  diff = ( lengths[2] * lengths[2] ) - ( lengths[3] * lengths[3] ); 1494  dot_prod = edges[2] % edges[3]; 1495  oddy = ( ( diff * diff ) + 4 * dot_prod * dot_prod ) / ( 2 * length_squared[3] ); 1496  max_oddy = VERDICT_MAX( oddy, max_oddy ); 1497  1498  diff = ( lengths[3] * lengths[3] ) - ( lengths[0] * lengths[0] ); 1499  dot_prod = edges[3] % edges[0]; 1500  oddy = ( ( diff * diff ) + 4 * dot_prod * dot_prod ) / ( 2 * length_squared[0] ); 1501  max_oddy = VERDICT_MAX( oddy, max_oddy ); 1502  1503  metric_vals->oddy = max_oddy; 1504  } 1505  } 1506  1507  if( metrics_request_flag & V_QUAD_WARPAGE ) 1508  { 1509  if( corner_normals[0].normalize() < VERDICT_DBL_MIN || corner_normals[1].normalize() < VERDICT_DBL_MIN || 1510  corner_normals[2].normalize() < VERDICT_DBL_MIN || corner_normals[3].normalize() < VERDICT_DBL_MIN ) 1511  metric_vals->warpage = VERDICT_DBL_MAX; 1512  else 1513  { 1514  metric_vals->warpage = 1515  pow( VERDICT_MIN( corner_normals[0] % corner_normals[2], corner_normals[1] % corner_normals[3] ), 1516  3 ); 1517  } 1518  } 1519  } 1520  1521  if( metrics_request_flag & V_QUAD_STRETCH ) 1522  { 1523  VerdictVector temp; 1524  1525  temp.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], 1526  coordinates[2][2] - coordinates[0][2] ); 1527  double diag02 = temp.length_squared(); 1528  1529  temp.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 1530  coordinates[3][2] - coordinates[1][2] ); 1531  double diag13 = temp.length_squared(); 1532  1533  static const double QUAD_STRETCH_FACTOR = sqrt( 2.0 ); 1534  1535  // 'diag02' is now the max diagonal of the quad 1536  diag02 = VERDICT_MAX( diag02, diag13 ); 1537  1538  if( diag02 < VERDICT_DBL_MIN ) 1539  metric_vals->stretch = VERDICT_DBL_MAX; 1540  else 1541  metric_vals->stretch = 1542  QUAD_STRETCH_FACTOR * 1543  VERDICT_MIN( VERDICT_MIN( lengths[0], lengths[1] ), VERDICT_MIN( lengths[2], lengths[3] ) ) / 1544  sqrt( diag02 ); 1545  } 1546  1547  if( metrics_request_flag & ( V_QUAD_CONDITION | V_QUAD_SHAPE | V_QUAD_SHAPE_AND_SIZE ) ) 1548  { 1549  double lengths_squared[4]; 1550  lengths_squared[0] = edges[0].length_squared(); 1551  lengths_squared[1] = edges[1].length_squared(); 1552  lengths_squared[2] = edges[2].length_squared(); 1553  lengths_squared[3] = edges[3].length_squared(); 1554  1555  if( areas[0] < VERDICT_DBL_MIN || areas[1] < VERDICT_DBL_MIN || areas[2] < VERDICT_DBL_MIN || 1556  areas[3] < VERDICT_DBL_MIN ) 1557  { 1558  metric_vals->condition = VERDICT_DBL_MAX; 1559  metric_vals->shape = 0.0; 1560  } 1561  else 1562  { 1563  double max_condition = 0.0, condition; 1564  1565  condition = ( lengths_squared[0] + lengths_squared[3] ) / areas[0]; 1566  max_condition = VERDICT_MAX( max_condition, condition ); 1567  1568  condition = ( lengths_squared[1] + lengths_squared[0] ) / areas[1]; 1569  max_condition = VERDICT_MAX( max_condition, condition ); 1570  1571  condition = ( lengths_squared[2] + lengths_squared[1] ) / areas[2]; 1572  max_condition = VERDICT_MAX( max_condition, condition ); 1573  1574  condition = ( lengths_squared[3] + lengths_squared[2] ) / areas[3]; 1575  max_condition = VERDICT_MAX( max_condition, condition ); 1576  1577  metric_vals->condition = 0.5 * max_condition; 1578  metric_vals->shape = 2 / max_condition; 1579  } 1580  } 1581  1582  if( metrics_request_flag & V_QUAD_AREA ) 1583  { 1584  if( metric_vals->area > 0 ) metric_vals->area = (double)VERDICT_MIN( metric_vals->area, VERDICT_DBL_MAX ); 1585  metric_vals->area = (double)VERDICT_MAX( metric_vals->area, -VERDICT_DBL_MAX ); 1586  } 1587  1588  if( metrics_request_flag & V_QUAD_MAX_EDGE_RATIO ) 1589  { 1590  if( metric_vals->max_edge_ratio > 0 ) 1591  metric_vals->max_edge_ratio = (double)VERDICT_MIN( metric_vals->max_edge_ratio, VERDICT_DBL_MAX ); 1592  metric_vals->max_edge_ratio = (double)VERDICT_MAX( metric_vals->max_edge_ratio, -VERDICT_DBL_MAX ); 1593  } 1594  1595  if( metrics_request_flag & V_QUAD_CONDITION ) 1596  { 1597  if( metric_vals->condition > 0 ) 1598  metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX ); 1599  metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX ); 1600  } 1601  1602  // calculate distortion 1603  if( metrics_request_flag & V_QUAD_DISTORTION ) 1604  { 1605  metric_vals->distortion = v_quad_distortion( num_nodes, coordinates ); 1606  1607  if( metric_vals->distortion > 0 ) 1608  metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX ); 1609  metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX ); 1610  } 1611  1612  if( metrics_request_flag & V_QUAD_JACOBIAN ) 1613  { 1614  if( metric_vals->jacobian > 0 ) 1615  metric_vals->jacobian = (double)VERDICT_MIN( metric_vals->jacobian, VERDICT_DBL_MAX ); 1616  metric_vals->jacobian = (double)VERDICT_MAX( metric_vals->jacobian, -VERDICT_DBL_MAX ); 1617  } 1618  1619  if( metrics_request_flag & V_QUAD_MAXIMUM_ANGLE ) 1620  { 1621  if( metric_vals->maximum_angle > 0 ) 1622  metric_vals->maximum_angle = (double)VERDICT_MIN( metric_vals->maximum_angle, VERDICT_DBL_MAX ); 1623  metric_vals->maximum_angle = (double)VERDICT_MAX( metric_vals->maximum_angle, -VERDICT_DBL_MAX ); 1624  } 1625  1626  if( metrics_request_flag & V_QUAD_MINIMUM_ANGLE ) 1627  { 1628  if( metric_vals->minimum_angle > 0 ) 1629  metric_vals->minimum_angle = (double)VERDICT_MIN( metric_vals->minimum_angle, VERDICT_DBL_MAX ); 1630  metric_vals->minimum_angle = (double)VERDICT_MAX( metric_vals->minimum_angle, -VERDICT_DBL_MAX ); 1631  } 1632  1633  if( metrics_request_flag & V_QUAD_ODDY ) 1634  { 1635  if( metric_vals->oddy > 0 ) metric_vals->oddy = (double)VERDICT_MIN( metric_vals->oddy, VERDICT_DBL_MAX ); 1636  metric_vals->oddy = (double)VERDICT_MAX( metric_vals->oddy, -VERDICT_DBL_MAX ); 1637  } 1638  1639  if( metrics_request_flag & V_QUAD_RELATIVE_SIZE_SQUARED ) 1640  { 1641  if( metric_vals->relative_size_squared > 0 ) 1642  metric_vals->relative_size_squared = 1643  (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX ); 1644  metric_vals->relative_size_squared = 1645  (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX ); 1646  } 1647  1648  if( metrics_request_flag & V_QUAD_SCALED_JACOBIAN ) 1649  { 1650  if( metric_vals->scaled_jacobian > 0 ) 1651  metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX ); 1652  metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX ); 1653  } 1654  1655  if( metrics_request_flag & V_QUAD_SHEAR ) 1656  { 1657  if( metric_vals->shear > 0 ) metric_vals->shear = (double)VERDICT_MIN( metric_vals->shear, VERDICT_DBL_MAX ); 1658  metric_vals->shear = (double)VERDICT_MAX( metric_vals->shear, -VERDICT_DBL_MAX ); 1659  } 1660  1661  // calculate shear and size 1662  // reuse values from above 1663  if( metrics_request_flag & V_QUAD_SHEAR_AND_SIZE ) 1664  { 1665  metric_vals->shear_and_size = metric_vals->shear * metric_vals->relative_size_squared; 1666  1667  if( metric_vals->shear_and_size > 0 ) 1668  metric_vals->shear_and_size = (double)VERDICT_MIN( metric_vals->shear_and_size, VERDICT_DBL_MAX ); 1669  metric_vals->shear_and_size = (double)VERDICT_MAX( metric_vals->shear_and_size, -VERDICT_DBL_MAX ); 1670  } 1671  1672  if( metrics_request_flag & V_QUAD_SHAPE ) 1673  { 1674  if( metric_vals->shape > 0 ) metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX ); 1675  metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX ); 1676  } 1677  1678  // calculate shape and size 1679  // reuse values from above 1680  if( metrics_request_flag & V_QUAD_SHAPE_AND_SIZE ) 1681  { 1682  metric_vals->shape_and_size = metric_vals->shape * metric_vals->relative_size_squared; 1683  1684  if( metric_vals->shape_and_size > 0 ) 1685  metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX ); 1686  metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX ); 1687  } 1688  1689  if( metrics_request_flag & V_QUAD_SKEW ) 1690  { 1691  if( metric_vals->skew > 0 ) metric_vals->skew = (double)VERDICT_MIN( metric_vals->skew, VERDICT_DBL_MAX ); 1692  metric_vals->skew = (double)VERDICT_MAX( metric_vals->skew, -VERDICT_DBL_MAX ); 1693  } 1694  1695  if( metrics_request_flag & V_QUAD_STRETCH ) 1696  { 1697  if( metric_vals->stretch > 0 ) 1698  metric_vals->stretch = (double)VERDICT_MIN( metric_vals->stretch, VERDICT_DBL_MAX ); 1699  metric_vals->stretch = (double)VERDICT_MAX( metric_vals->stretch, -VERDICT_DBL_MAX ); 1700  } 1701  1702  if( metrics_request_flag & V_QUAD_TAPER ) 1703  { 1704  if( metric_vals->taper > 0 ) metric_vals->taper = (double)VERDICT_MIN( metric_vals->taper, VERDICT_DBL_MAX ); 1705  metric_vals->taper = (double)VERDICT_MAX( metric_vals->taper, -VERDICT_DBL_MAX ); 1706  } 1707  1708  if( metrics_request_flag & V_QUAD_WARPAGE ) 1709  { 1710  if( metric_vals->warpage > 0 ) 1711  metric_vals->warpage = (double)VERDICT_MIN( metric_vals->warpage, VERDICT_DBL_MAX ); 1712  metric_vals->warpage = (double)VERDICT_MAX( metric_vals->warpage, -VERDICT_DBL_MAX ); 1713  } 1714  1715  if( metrics_request_flag & V_QUAD_MED_ASPECT_FROBENIUS ) 1716  metric_vals->med_aspect_frobenius = v_quad_med_aspect_frobenius( 4, coordinates ); 1717  if( metrics_request_flag & V_QUAD_MAX_ASPECT_FROBENIUS ) 1718  metric_vals->max_aspect_frobenius = v_quad_max_aspect_frobenius( 4, coordinates ); 1719  if( metrics_request_flag & V_QUAD_EDGE_RATIO ) metric_vals->edge_ratio = v_quad_edge_ratio( 4, coordinates ); 1720  if( metrics_request_flag & V_QUAD_ASPECT_RATIO ) metric_vals->aspect_ratio = v_quad_aspect_ratio( 4, coordinates ); 1721  if( metrics_request_flag & V_QUAD_RADIUS_RATIO ) metric_vals->radius_ratio = v_quad_radius_ratio( 4, coordinates ); 1722 }

References QuadMetricVals::area, QuadMetricVals::aspect_ratio, QuadMetricVals::condition, determinant(), QuadMetricVals::distortion, QuadMetricVals::edge_ratio, get_weight(), is_collapsed_quad(), QuadMetricVals::jacobian, VerdictVector::length(), VerdictVector::length_squared(), length_squared(), make_quad_edges(), QuadMetricVals::max_aspect_frobenius, QuadMetricVals::max_edge_ratio, QuadMetricVals::maximum_angle, QuadMetricVals::med_aspect_frobenius, QuadMetricVals::minimum_angle, normalize(), QuadMetricVals::oddy, QuadMetricVals::radius_ratio, QuadMetricVals::relative_size_squared, QuadMetricVals::scaled_jacobian, VerdictVector::set(), QuadMetricVals::shape, QuadMetricVals::shape_and_size, QuadMetricVals::shear, QuadMetricVals::shear_and_size, signed_corner_areas(), QuadMetricVals::skew, QuadMetricVals::stretch, QuadMetricVals::taper, V_QUAD_AREA, v_quad_area(), V_QUAD_ASPECT_RATIO, v_quad_aspect_ratio(), V_QUAD_CONDITION, V_QUAD_DISTORTION, v_quad_distortion(), V_QUAD_EDGE_RATIO, v_quad_edge_ratio(), V_QUAD_JACOBIAN, V_QUAD_MAX_ASPECT_FROBENIUS, v_quad_max_aspect_frobenius(), V_QUAD_MAX_EDGE_RATIO, V_QUAD_MAXIMUM_ANGLE, V_QUAD_MED_ASPECT_FROBENIUS, v_quad_med_aspect_frobenius(), V_QUAD_MINIMUM_ANGLE, V_QUAD_ODDY, V_QUAD_RADIUS_RATIO, v_quad_radius_ratio(), V_QUAD_RELATIVE_SIZE_SQUARED, V_QUAD_SCALED_JACOBIAN, V_QUAD_SHAPE, V_QUAD_SHAPE_AND_SIZE, V_QUAD_SHEAR, V_QUAD_SHEAR_AND_SIZE, V_QUAD_SKEW, V_QUAD_STRETCH, V_QUAD_TAPER, V_QUAD_WARPAGE, v_set_quad_size(), v_tri_area(), v_tri_maximum_angle(), v_tri_minimum_angle(), v_tri_scaled_jacobian(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_FALSE, VERDICT_MAX, VERDICT_MIN, VERDICT_PI, VERDICT_TRUE, and QuadMetricVals::warpage.

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

◆ v_quad_radius_ratio()

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

Calculates quad radius ratio.

radius ratio Reference — P. P. Pebay, Planar Quadrangle Quality Measures, Eng. Comp., 2004, 20(2):157-173

the radius ratio of a quad

NB (P. Pebay 01/19/07): this metric is called "radius ratio" by extension of a concept that does not exist in general with quads – although a different name should probably be used in the future.

Definition at line 386 of file V_QuadMetric.cpp.

387 { 388  static const double normal_coeff = 1. / ( 2. * sqrt( 2. ) ); 389  390  VerdictVector edges[4]; 391  make_quad_edges( edges, coordinates ); 392  393  double a2 = edges[0].length_squared(); 394  double b2 = edges[1].length_squared(); 395  double c2 = edges[2].length_squared(); 396  double d2 = edges[3].length_squared(); 397  398  VerdictVector diag; 399  diag.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], 400  coordinates[2][2] - coordinates[0][2] ); 401  double m2 = diag.length_squared(); 402  403  diag.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 404  coordinates[3][2] - coordinates[1][2] ); 405  double n2 = diag.length_squared(); 406  407  double t0 = a2 > b2 ? a2 : b2; 408  double t1 = c2 > d2 ? c2 : d2; 409  double t2 = m2 > n2 ? m2 : n2; 410  double h2 = t0 > t1 ? t0 : t1; 411  h2 = h2 > t2 ? h2 : t2; 412  413  VerdictVector ab = edges[0] * edges[1]; 414  VerdictVector bc = edges[1] * edges[2]; 415  VerdictVector cd = edges[2] * edges[3]; 416  VerdictVector da = edges[3] * edges[0]; 417  418  t0 = da.length(); 419  t1 = ab.length(); 420  t2 = bc.length(); 421  double t3 = cd.length(); 422  423  t0 = t0 < t1 ? t0 : t1; 424  t2 = t2 < t3 ? t2 : t3; 425  t0 = t0 < t2 ? t0 : t2; 426  427  if( t0 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX; 428  429  double radius_ratio = normal_coeff * sqrt( ( a2 + b2 + c2 + d2 ) * h2 ) / t0; 430  431  if( radius_ratio > 0 ) return (double)VERDICT_MIN( radius_ratio, VERDICT_DBL_MAX ); 432  return (double)VERDICT_MAX( radius_ratio, -VERDICT_DBL_MAX ); 433 }

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

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

◆ v_quad_relative_size_squared()

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

Calculates quad relative size metric.

Min( J, 1/J ), where J is determinant of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

the relative size of a quad

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

Definition at line 988 of file V_QuadMetric.cpp.

989 { 990  991  double quad_area = v_quad_area( 4, coordinates ); 992  double rel_size = 0; 993  994  v_set_quad_size( quad_area ); 995  double w11, w21, w12, w22; 996  get_weight( w11, w21, w12, w22 ); 997  double avg_area = determinant( w11, w21, w12, w22 ); 998  999  if( avg_area > VERDICT_DBL_MIN ) 1000  { 1001  1002  w11 = quad_area / avg_area; 1003  1004  if( w11 > VERDICT_DBL_MIN ) 1005  { 1006  rel_size = VERDICT_MIN( w11, 1 / w11 ); 1007  rel_size *= rel_size; 1008  } 1009  } 1010  1011  if( rel_size > 0 ) return (double)VERDICT_MIN( rel_size, VERDICT_DBL_MAX ); 1012  return (double)VERDICT_MAX( rel_size, -VERDICT_DBL_MAX ); 1013 }

References determinant(), get_weight(), v_quad_area(), v_set_quad_size(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

Referenced by moab::VerdictWrapper::quality_measure(), v_quad_shape_and_size(), and v_quad_shear_and_size().

◆ v_quad_scaled_jacobian()

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

Calculates quad scaled jacobian.

Minimum Jacobian divided by the lengths of the 2 edge vectors. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

scaled jacobian of a quad

Minimum Jacobian divided by the lengths of the 2 edge vector

Definition at line 888 of file V_QuadMetric.cpp.

889 { 890  if( is_collapsed_quad( coordinates ) == VERDICT_TRUE ) return v_tri_scaled_jacobian( 3, coordinates ); 891  892  double corner_areas[4], min_scaled_jac = VERDICT_DBL_MAX, scaled_jac; 893  signed_corner_areas( corner_areas, coordinates ); 894  895  VerdictVector edges[4]; 896  make_quad_edges( edges, coordinates ); 897  898  double length[4]; 899  length[0] = edges[0].length(); 900  length[1] = edges[1].length(); 901  length[2] = edges[2].length(); 902  length[3] = edges[3].length(); 903  904  if( length[0] < VERDICT_DBL_MIN || length[1] < VERDICT_DBL_MIN || length[2] < VERDICT_DBL_MIN || 905  length[3] < VERDICT_DBL_MIN ) 906  return 0.0; 907  908  scaled_jac = corner_areas[0] / ( length[0] * length[3] ); 909  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 910  911  scaled_jac = corner_areas[1] / ( length[1] * length[0] ); 912  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 913  914  scaled_jac = corner_areas[2] / ( length[2] * length[1] ); 915  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 916  917  scaled_jac = corner_areas[3] / ( length[3] * length[2] ); 918  min_scaled_jac = VERDICT_MIN( scaled_jac, min_scaled_jac ); 919  920  if( min_scaled_jac > 0 ) return (double)VERDICT_MIN( min_scaled_jac, VERDICT_DBL_MAX ); 921  return (double)VERDICT_MAX( min_scaled_jac, -VERDICT_DBL_MAX ); 922 }

References is_collapsed_quad(), VerdictVector::length(), length(), make_quad_edges(), signed_corner_areas(), v_tri_scaled_jacobian(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, VERDICT_MIN, and VERDICT_TRUE.

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

◆ v_quad_shape()

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

Calculates quad shape metric.

2/Condition number of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

the shape of a quad

2/Condition number of weighted Jacobian matrix

Definition at line 944 of file V_QuadMetric.cpp.

945 { 946  947  double corner_areas[4], min_shape = VERDICT_DBL_MAX, shape; 948  signed_corner_areas( corner_areas, coordinates ); 949  950  VerdictVector edges[4]; 951  make_quad_edges( edges, coordinates ); 952  953  double length_squared[4]; 954  length_squared[0] = edges[0].length_squared(); 955  length_squared[1] = edges[1].length_squared(); 956  length_squared[2] = edges[2].length_squared(); 957  length_squared[3] = edges[3].length_squared(); 958  959  if( length_squared[0] <= VERDICT_DBL_MIN || length_squared[1] <= VERDICT_DBL_MIN || 960  length_squared[2] <= VERDICT_DBL_MIN || length_squared[3] <= VERDICT_DBL_MIN ) 961  return 0.0; 962  963  shape = corner_areas[0] / ( length_squared[0] + length_squared[3] ); 964  min_shape = VERDICT_MIN( shape, min_shape ); 965  966  shape = corner_areas[1] / ( length_squared[1] + length_squared[0] ); 967  min_shape = VERDICT_MIN( shape, min_shape ); 968  969  shape = corner_areas[2] / ( length_squared[2] + length_squared[1] ); 970  min_shape = VERDICT_MIN( shape, min_shape ); 971  972  shape = corner_areas[3] / ( length_squared[3] + length_squared[2] ); 973  min_shape = VERDICT_MIN( shape, min_shape ); 974  975  min_shape *= 2; 976  977  if( min_shape < VERDICT_DBL_MIN ) min_shape = 0; 978  979  if( min_shape > 0 ) return (double)VERDICT_MIN( min_shape, VERDICT_DBL_MAX ); 980  return (double)VERDICT_MAX( min_shape, -VERDICT_DBL_MAX ); 981 }

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

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

◆ v_quad_shape_and_size()

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

Calculates quad shape-size metric.

Product of Shape and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

the relative shape and size of a quad

Product of Shape and Relative Size

Definition at line 1020 of file V_QuadMetric.cpp.

1021 { 1022  double shape, size; 1023  size = v_quad_relative_size_squared( num_nodes, coordinates ); 1024  shape = v_quad_shape( num_nodes, coordinates ); 1025  1026  double shape_and_size = shape * size; 1027  1028  if( shape_and_size > 0 ) return (double)VERDICT_MIN( shape_and_size, VERDICT_DBL_MAX ); 1029  return (double)VERDICT_MAX( shape_and_size, -VERDICT_DBL_MAX ); 1030 }

References size, v_quad_relative_size_squared(), v_quad_shape(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_quad_shear()

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

Calculates quad shear metric.

2/Condition number of Jacobian Skew matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

the shear of a quad

2/Condition number of Jacobian Skew matrix

Definition at line 929 of file V_QuadMetric.cpp.

930 { 931  double scaled_jacobian = v_quad_scaled_jacobian( 4, coordinates ); 932  933  if( scaled_jacobian <= VERDICT_DBL_MIN ) 934  return 0.0; 935  else 936  return (double)VERDICT_MIN( scaled_jacobian, VERDICT_DBL_MAX ); 937 }

References v_quad_scaled_jacobian(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, and VERDICT_MIN.

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

◆ v_quad_shear_and_size()

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

Calculates quad shear-size metric.

Product of Shear and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

the shear and size of a quad

product of shear and relative size

Definition at line 1037 of file V_QuadMetric.cpp.

1038 { 1039  double shear, size; 1040  shear = v_quad_shear( num_nodes, coordinates ); 1041  size = v_quad_relative_size_squared( num_nodes, coordinates ); 1042  1043  double shear_and_size = shear * size; 1044  1045  if( shear_and_size > 0 ) return (double)VERDICT_MIN( shear_and_size, VERDICT_DBL_MAX ); 1046  return (double)VERDICT_MAX( shear_and_size, -VERDICT_DBL_MAX ); 1047 }

References size, v_quad_relative_size_squared(), v_quad_shear(), VERDICT_DBL_MAX, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_quad_skew()

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

Calculates quad skew metric.

Maximum |cos A| where A is the angle between edges at quad center. Reference — J. Robinson, CRE Method of element testing and the Jacobian shape parameters, Eng. Comput., Vol 4, 1987.

skew of a quad

maximum ||cos A|| where A is the angle between edges at quad center

Definition at line 530 of file V_QuadMetric.cpp.

531 { 532  VerdictVector node_pos[4]; 533  for( int i = 0; i < 4; i++ ) 534  node_pos[i].set( coordinates[i][0], coordinates[i][1], coordinates[i][2] ); 535  536  VerdictVector principle_axes[2]; 537  principle_axes[0] = node_pos[1] + node_pos[2] - node_pos[3] - node_pos[0]; 538  principle_axes[1] = node_pos[2] + node_pos[3] - node_pos[0] - node_pos[1]; 539  540  if( principle_axes[0].normalize() < VERDICT_DBL_MIN ) return 0.0; 541  if( principle_axes[1].normalize() < VERDICT_DBL_MIN ) return 0.0; 542  543  double skew = fabs( principle_axes[0] % principle_axes[1] ); 544  545  return (double)VERDICT_MIN( skew, VERDICT_DBL_MAX ); 546 }

References normalize(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, and VERDICT_MIN.

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

◆ v_quad_stretch()

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

Calculates quad strech metric.

Sqrt(2) * minimum edge length / maximum diagonal length. Reference — FIMESH code.

the stretch of a quad

sqrt(2) * minimum edge length / maximum diagonal length

Definition at line 628 of file V_QuadMetric.cpp.

629 { 630  VerdictVector edges[4], temp; 631  make_quad_edges( edges, coordinates ); 632  633  double lengths_squared[4]; 634  lengths_squared[0] = edges[0].length_squared(); 635  lengths_squared[1] = edges[1].length_squared(); 636  lengths_squared[2] = edges[2].length_squared(); 637  lengths_squared[3] = edges[3].length_squared(); 638  639  temp.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], 640  coordinates[2][2] - coordinates[0][2] ); 641  double diag02 = temp.length_squared(); 642  643  temp.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 644  coordinates[3][2] - coordinates[1][2] ); 645  double diag13 = temp.length_squared(); 646  647  static const double QUAD_STRETCH_FACTOR = sqrt( 2.0 ); 648  649  // 'diag02' is now the max diagonal of the quad 650  diag02 = VERDICT_MAX( diag02, diag13 ); 651  652  if( diag02 < VERDICT_DBL_MIN ) 653  return (double)VERDICT_DBL_MAX; 654  else 655  { 656  double stretch = 657  (double)( QUAD_STRETCH_FACTOR * sqrt( VERDICT_MIN( VERDICT_MIN( lengths_squared[0], lengths_squared[1] ), 658  VERDICT_MIN( lengths_squared[2], lengths_squared[3] ) ) / 659  diag02 ) ); 660  661  return (double)VERDICT_MIN( stretch, VERDICT_DBL_MAX ); 662  } 663 }

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

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

◆ v_quad_taper()

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

Calculates quad taper metric.

Maximum ratio of lengths derived from opposite edges. Reference — J. Robinson, CRE Method of element testing and the Jacobian shape parameters, Eng. Comput., Vol 4, 1987.

taper of a quad

maximum ratio of lengths derived from opposite edges

Definition at line 553 of file V_QuadMetric.cpp.

554 { 555  VerdictVector node_pos[4]; 556  for( int i = 0; i < 4; i++ ) 557  node_pos[i].set( coordinates[i][0], coordinates[i][1], coordinates[i][2] ); 558  559  VerdictVector principle_axes[2]; 560  principle_axes[0] = node_pos[1] + node_pos[2] - node_pos[3] - node_pos[0]; 561  principle_axes[1] = node_pos[2] + node_pos[3] - node_pos[0] - node_pos[1]; 562  563  VerdictVector cross_derivative = node_pos[0] + node_pos[2] - node_pos[1] - node_pos[3]; 564  565  double lengths[2]; 566  lengths[0] = principle_axes[0].length(); 567  lengths[1] = principle_axes[1].length(); 568  569  // get min length 570  lengths[0] = VERDICT_MIN( lengths[0], lengths[1] ); 571  572  if( lengths[0] < VERDICT_DBL_MIN ) return VERDICT_DBL_MAX; 573  574  double taper = cross_derivative.length() / lengths[0]; 575  return (double)VERDICT_MIN( taper, VERDICT_DBL_MAX ); 576 }

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

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

◆ v_quad_warpage()

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

Calculates quad warpage metric.

Cosine of Minimum Dihedral Angle formed by Planes Intersecting in Diagonals. Reference — J. Robinson, CRE Method of element testing and the Jacobian shape parameters, Eng. Comput., Vol 4, 1987.

warpage of a quad

deviation of element from planarity

Definition at line 583 of file V_QuadMetric.cpp.

584 { 585  586  VerdictVector edges[4]; 587  make_quad_edges( edges, coordinates ); 588  589  VerdictVector corner_normals[4]; 590  corner_normals[0] = edges[3] * edges[0]; 591  corner_normals[1] = edges[0] * edges[1]; 592  corner_normals[2] = edges[1] * edges[2]; 593  corner_normals[3] = edges[2] * edges[3]; 594  595  if( corner_normals[0].normalize() < VERDICT_DBL_MIN || corner_normals[1].normalize() < VERDICT_DBL_MIN || 596  corner_normals[2].normalize() < VERDICT_DBL_MIN || corner_normals[3].normalize() < VERDICT_DBL_MIN ) 597  return (double)VERDICT_DBL_MIN; 598  599  double warpage = 600  pow( VERDICT_MIN( corner_normals[0] % corner_normals[2], corner_normals[1] % corner_normals[3] ), 3 ); 601  602  if( warpage > 0 ) return (double)VERDICT_MIN( warpage, VERDICT_DBL_MAX ); 603  return (double)VERDICT_MAX( warpage, -VERDICT_DBL_MAX ); 604 }

References make_quad_edges(), normalize(), VERDICT_DBL_MAX, VERDICT_DBL_MIN, VERDICT_MAX, and VERDICT_MIN.

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

◆ v_set_hex_size()

C_FUNC_DEF void v_set_hex_size ( double  size)

Sets average size (volume) of hex, needed for v_hex_relative_size(...)

Sets average size (volume) of hex, needed for v_hex_relative_size(...)

Definition at line 57 of file V_HexMetric.cpp.

58 { 59  verdict_hex_size = size; 60 }

References size, and verdict_hex_size.

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

◆ v_set_quad_size()

C_FUNC_DEF void v_set_quad_size ( double  size)

Sets average size (area) of quad, needed for v_quad_relative_size(...)

Sets average size (area) of quad, needed for v_quad_relative_size(...)

Definition at line 56 of file V_QuadMetric.cpp.

57 { 58  verdict_quad_size = size; 59 }

References size, and verdict_quad_size.

Referenced by moab::VerdictWrapper::set_size(), v_quad_quality(), and v_quad_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 { 39  verdict_tet_size = size; 40 }

References size, and verdict_tet_size.

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

◆ v_set_tri_normal_func()

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.

◆ v_set_tri_size()

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().

◆ 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.

CR / (3.0 * IR) where CR = circumsphere radius, IR = inscribed sphere radius if the element is positively-oriented. Reference — V. N. Parthasarathy et al, A comparison of tetrahedron quality measures, Finite Elem. Anal. Des., Vol 15(1993), 255-261.

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.

Frobenius condition number when the reference element is regular Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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.

Srms**3 / (8.479670*V) where Srms = sqrt(Sum(Si**2)/6), Si = edge length. Reference — V. N. Parthasarathy et al, A comparison of tetrahedron quality measures, Finite Elem. Anal. Des., Vol 15(1993), 255-261.

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.

Hmax / (2 sqrt(6) r) where Hmax and r respectively denote the greatest edge length and the inradius of the tetrahedron Reference — P. Frey and P.-L. George, Meshing, Hermes (2000).

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.

Collapse ratio

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.

Condition number of the Jacobian matrix at any corner. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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.

{min(|J|)/actual volume}*parent volume, parent volume = 1/6 for tet. Reference — SDRC/IDEAS Simulation: Finite Element Modeling–User's Guide

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]; 785  double dndy1[maxTotalNumberGaussPoints][maxNumberNodes]; 786  double dndy2[maxTotalNumberGaussPoints][maxNumberNodes]; 787  double dndy3[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 ); 792  GaussIntegration::calculate_shape_function_3d_tet(); 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.

Hmax / Hmin where Hmax and Hmin are respectively the maximum and the minimum edge lengths

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.

Minimum pointwise volume at any corner. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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.

Minimum (nonoriented) dihedral angle of a tetrahedron, expressed in degrees.

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 | 915  V_TET_SHAPE | V_TET_RELATIVE_SIZE_SQUARED | V_TET_SHAPE_AND_SIZE | 916  V_TET_SCALED_JACOBIAN | V_TET_CONDITION; 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.

CR / (3.0 * IR) where CR = circumsphere radius, IR = inscribed sphere radius. Reference — V. N. Parthasarathy et al, A comparison of tetrahedron quality measures, Finite Elem. Anal. Des., Vol 15(1993), 255-261.

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.

Min( J, 1/J ), where J is determinant of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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.

Minimum Jacobian divided by the lengths of 3 edge vectors Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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.

3/Mean Ratio of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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.

Product of Shape and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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.

(1/6) * Jacobian at corner node. Reference — V. N. Parthasarathy et al, A comparison of tetrahedron quality measures, Finite Elem. Anal. Des., Vol 15(1993), 255-261.

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().

◆ v_tri_area()

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

Calculates tri metric.

Maximum included angle in triangle

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().

◆ v_tri_aspect_frobenius()

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

Calculates tri metric.

Frobenius aspect

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().

◆ v_tri_aspect_ratio()

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

Calculates tri metric.

aspect ratio Reference — P. P. Pebay & T. J. Baker, Analysis of Triangle Quality Measures, AMS Math. Comp., 2003, 72(244):1817-1839

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().

◆ v_tri_condition()

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

Calculates tri metric.

Condition number of the Jacobian matrix. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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().

◆ v_tri_distortion()

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

Calculates tri metric.

{min(|J|)/actual area}*parent area, parent area = 1/2 for triangular element. Reference — SDRC/IDEAS Simulation: Finite Element Modeling–User's Guide

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().

◆ v_tri_edge_ratio()

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

Calculates tri metric.

edge ratio Reference — P. P. Pebay & T. J. Baker, Analysis of Triangle Quality Measures, AMS Math. Comp., 2003, 72(244):1817-1839

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().

◆ v_tri_maximum_angle()

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

Calculates tri metric.

Maximum included angle in triangle

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().

◆ v_tri_minimum_angle()

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

Calculates tri metric.

Minimum included angle in triangle

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().

◆ v_tri_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().

◆ v_tri_radius_ratio()

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

Calculates tri metric.

radius ratio Reference — P. P. Pebay & T. J. Baker, Analysis of Triangle Quality Measures, AMS Math. Comp., 2003, 72(244):1817-1839

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().

◆ v_tri_relative_size_squared()

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

Calculates tri metric.

Min( J, 1/J ), where J is determinant of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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().

◆ v_tri_scaled_jacobian()

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

Calculates tri metric.

Minimum Jacobian divided by the lengths of 2 edge vectors. Reference — P. Knupp, Achieving Finite Element Mesh Quality via Optimization of the Jacobian Matrix Norm and Associated Quantities, Intl. J. Numer. Meth. Engng. 2000, 48:1165-1185.

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().

◆ v_tri_shape()

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

Calculates tri metric.

2/Condition number of weighted Jacobian matrix. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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().

◆ v_tri_shape_and_size()

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

Calculates tri metric.

Product of Shape and Relative Size. Reference — P. Knupp, Algebraic Mesh Quality Metrics for Unstructured Initial Meshes, submitted for publication.

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().

◆ v_wedge_quality()

C_FUNC_DEF void v_wedge_quality ( int  num_nodes,
double  coordinates[][3],
unsigned int  metrics_request_flag,
struct WedgeMetricVals metric_vals 
)

Calculates quality metrics for wedge elements.

Definition at line 102 of file V_WedgeMetric.cpp.

106 { 107  memset( metric_vals, 0, sizeof( WedgeMetricVals ) ); 108  109  if( metrics_request_flag & V_WEDGE_VOLUME ) metric_vals->volume = v_wedge_volume( num_nodes, coordinates ); 110 }

References V_WEDGE_VOLUME, v_wedge_volume(), and WedgeMetricVals::volume.

◆ v_wedge_volume()

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

Calculates wedge volume.

calculate the volume of a wedge

this is done by dividing the wedge into 3 tets and summing the volume of each tet

Definition at line 54 of file V_WedgeMetric.cpp.

55 { 56  57  double volume = 0; 58  VerdictVector side1, side2, side3; 59  60  if( num_nodes == 6 ) 61  { 62  63  // divide the wedge into 3 tets and calculate each volume 64  65  side1.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1], 66  coordinates[1][2] - coordinates[0][2] ); 67  68  side2.set( coordinates[2][0] - coordinates[0][0], coordinates[2][1] - coordinates[0][1], 69  coordinates[2][2] - coordinates[0][2] ); 70  71  side3.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1], 72  coordinates[3][2] - coordinates[0][2] ); 73  74  volume = side3 % ( side1 * side2 ) / 6; 75  76  side1.set( coordinates[4][0] - coordinates[1][0], coordinates[4][1] - coordinates[1][1], 77  coordinates[4][2] - coordinates[1][2] ); 78  79  side2.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1], 80  coordinates[5][2] - coordinates[1][2] ); 81  82  side3.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 83  coordinates[3][2] - coordinates[1][2] ); 84  85  volume += side3 % ( side1 * side2 ) / 6; 86  87  side1.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1], 88  coordinates[5][2] - coordinates[1][2] ); 89  90  side2.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1], 91  coordinates[2][2] - coordinates[1][2] ); 92  93  side3.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1], 94  coordinates[3][2] - coordinates[1][2] ); 95  96  volume += side3 % ( side1 * side2 ) / 6; 97  } 98  99  return (double)volume; 100 }

References VerdictVector::set().

Referenced by moab::VerdictWrapper::all_quality_measures(), moab::VerdictWrapper::quality_measure(), and v_wedge_quality().