Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
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];
2254  double weight[maxTotalNumberGaussPoints];
2255 
2256  // create an object of GaussIntegration
2257  GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dimension );
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 &
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 &
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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];
1110  double weight[maxTotalNumberGaussPoints];
1111 
1112  // create an object of GaussIntegration
1113  GaussIntegration::initialize( number_of_gauss_points, num_nodes );
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 |
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 
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 
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 
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 {
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 {
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 {
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 {
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];
788  double weight[maxTotalNumberGaussPoints];
789 
790  // create an object of GaussIntegration for tet
791  GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dims, is_tri );
793  GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], dndy3[0], weight );
794 
795  // vector xxi is the derivative vector of coordinates w.r.t local xi coordinate in the
796  // computation space
797  // vector xet is the derivative vector of coordinates w.r.t local et coordinate in the
798  // computation space
799  // vector xze is the derivative vector of coordinates w.r.t local ze coordinate in the
800  // computation space
801  VerdictVector xxi, xet, xze, xin;
802 
803  double jacobian, minimum_jacobian;
804  double element_volume = 0.0;
805  minimum_jacobian = VERDICT_DBL_MAX;
806 
807  // calculate element volume
808  int ife, ja;
809  for( ife = 0; ife < total_number_of_gauss_points; ife++ )
810  {
811  xxi.set( 0.0, 0.0, 0.0 );
812  xet.set( 0.0, 0.0, 0.0 );
813  xze.set( 0.0, 0.0, 0.0 );
814 
815  for( ja = 0; ja < num_nodes; ja++ )
816  {
817  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
818  xxi += dndy1[ife][ja] * xin;
819  xet += dndy2[ife][ja] * xin;
820  xze += dndy3[ife][ja] * xin;
821  }
822 
823  // determinant
824  jacobian = xxi % ( xet * xze );
825  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
826 
827  element_volume += weight[ife] * jacobian;
828  } // element_volume is 6 times the actual volume
829 
830  // loop through all nodes
831  double dndy1_at_node[maxNumberNodes][maxNumberNodes];
832  double dndy2_at_node[maxNumberNodes][maxNumberNodes];
833  double dndy3_at_node[maxNumberNodes][maxNumberNodes];
834 
835  GaussIntegration::calculate_derivative_at_nodes_3d_tet( dndy1_at_node, dndy2_at_node, dndy3_at_node );
836  int node_id;
837  for( node_id = 0; node_id < num_nodes; node_id++ )
838  {
839  xxi.set( 0.0, 0.0, 0.0 );
840  xet.set( 0.0, 0.0, 0.0 );
841  xze.set( 0.0, 0.0, 0.0 );
842 
843  for( ja = 0; ja < num_nodes; ja++ )
844  {
845  xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
846  xxi += dndy1_at_node[node_id][ja] * xin;
847  xet += dndy2_at_node[node_id][ja] * xin;
848  xze += dndy3_at_node[node_id][ja] * xin;
849  }
850 
851  jacobian = xxi % ( xet * xze );
852  if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
853  }
854  distortion = minimum_jacobian / element_volume;
855 
856  return (double)distortion;
857 }

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

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

◆ v_tet_edge_ratio()

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

Calculates tet edge ratio metric.

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 |
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];
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 );
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 &
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().